diff --git a/designer/src/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java b/designer/src/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java index f707e0500f..fd24573fe3 100644 --- a/designer/src/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java +++ b/designer/src/com/fr/design/report/freeze/RepeatAndFreezeSettingPane.java @@ -1,17 +1,23 @@ package com.fr.design.report.freeze; -import java.awt.BorderLayout; -import java.awt.Color; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; -import javax.swing.BorderFactory; -import javax.swing.JPanel; +import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.UIDialog; +import com.fr.design.extra.PluginManagerPane; +import com.fr.design.extra.PluginShopDialog; +import com.fr.design.extra.PluginWebBridge; import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.ActionLabel; import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; import com.fr.general.Inter; import com.fr.page.ReportPageAttrProvider; import com.fr.stable.ColumnRow; @@ -22,6 +28,10 @@ import com.fr.stable.bridge.StableFactory; * Sets Report Page Attributes */ public class RepeatAndFreezeSettingPane extends BasicPane { + + //边框高度 + private static final int LABEL_HEIGHT = 45; + // 重复标题行 private RepeatRowPane repeatTitleRowPane; // 重复标题列 @@ -206,7 +216,15 @@ public class RepeatAndFreezeSettingPane extends BasicPane { JPanel repeatPanel = FRGUIPaneFactory.createNColumnGridInnerContainer_S_Pane(1); repeatPanel.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); JPanel freezePanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + //自适应插件 + JPanel infoPane = FRGUIPaneFactory.createTitledBorderPane(Inter.getLocText("FR-Designer_Attention")); + + BoxCenterAligmentPane actionLabel = getURLActionLabel(Inter.getLocText("FR-Designer_Form-Fit-Tip")); + infoPane.add(actionLabel, BorderLayout.SOUTH); + outfreezePanel.add(freezePanel); + this.add(infoPane, BorderLayout.SOUTH); // 重复打印部分 // 重复打印标题的起始行 JPanel labelPanel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); @@ -536,4 +554,58 @@ public class RepeatAndFreezeSettingPane extends BasicPane { return null; } + private BoxCenterAligmentPane getURLActionLabel(final String text) { + ActionLabel actionLabel = new ActionLabel(text); + + actionLabel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + //Desktop.getDesktop().browse(new URI(url)); + final PluginManagerPane managerPane = new PluginManagerPane(); + UIDialog dlg = new PluginShopDialog(DesignerContext.getDesignerFrame(),managerPane); + PluginWebBridge.getHelper().setDialogHandle(dlg); + dlg.setVisible(true); + RepeatAndFreezeSettingPane.this.getTopLevelAncestor().setVisible(false); + } catch (Exception exp) { + + } + } + }); + + return new BoxCenterAligmentPane(actionLabel); + } + + class BoxCenterAligmentPane extends JPanel { + + private UILabel textLabel; + + public BoxCenterAligmentPane(String text) { + this(new UILabel(text)); + } + + public BoxCenterAligmentPane(UILabel label) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + + JPanel centerPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + this.add(centerPane, BorderLayout.CENTER); + UILabel label1 = new UILabel(Inter.getLocText("FR-Designer_Form-Frozen-Tip")); + label1.setForeground(new Color(255, 0, 0)); + UILabel label2 = new UILabel(Inter.getLocText("FR-Designer_Form-Forzen-Speed")); + label2.setForeground(new Color(255, 0, 0)); + this.textLabel = label; + centerPane.add(label1); + centerPane.add(textLabel); + centerPane.add(label2); + } + + public void setFont(Font font) { + super.setFont(font); + + if (textLabel != null) { + textLabel.setFont(font); + } + } + } + } \ No newline at end of file diff --git a/designer/src/com/fr/design/webattr/EditToolBar.java b/designer/src/com/fr/design/webattr/EditToolBar.java index c147b1b0f0..da5ebe2b05 100644 --- a/designer/src/com/fr/design/webattr/EditToolBar.java +++ b/designer/src/com/fr/design/webattr/EditToolBar.java @@ -63,16 +63,8 @@ public class EditToolBar extends BasicPane { private ListSelectionListener listSelectionListener = new ListSelectionListener() { public void valueChanged(ListSelectionEvent evt) { - if (lastButton != null && lastButton.getWidget() instanceof Button) { - if (!((list.getSelectedValue() instanceof ToolBarButton) - && ((ToolBarButton)(list.getSelectedValue())).getWidget() instanceof CustomToolBarButton)) { - lastButton.setWidget(bp.update()); - } else { - ((Button) lastButton.getWidget()).setShowIcon(bp.icon.isSelected()); - ((Button) lastButton.getWidget()).setShowText(bp.text.isSelected()); - ((Button) lastButton.getWidget()).setText(bp.nameField.getText()); - ((Button) lastButton.getWidget()).setIconName(bp.iconPane.update()); - } + if (lastButton != null) { + lastButton.setWidget(bp.update()); } if (list.getSelectedValue() instanceof ToolBarButton) { lastButton = (ToolBarButton) list.getSelectedValue(); diff --git a/designer/src/com/fr/poly/hanlder/BottomCornerMouseHanlder.java b/designer/src/com/fr/poly/hanlder/BottomCornerMouseHanlder.java index e98ce6d02f..7668411c85 100644 --- a/designer/src/com/fr/poly/hanlder/BottomCornerMouseHanlder.java +++ b/designer/src/com/fr/poly/hanlder/BottomCornerMouseHanlder.java @@ -103,7 +103,7 @@ public class BottomCornerMouseHanlder extends MouseInputAdapter { Rectangle bounds = block.getBounds().toRectangle(resolution); Point resultPoint = MoveUtils.sorption(bounds.x + dragStart.x < 0 ? 0 : bounds.x + dragStart.x, bounds.y - + dragStart.y < 0 ? 0 : bounds.y + dragStart.y, bounds.width, bounds.height, rectDesigner); + + dragStart.y < 0 ? 0 : bounds.y + dragStart.y, bounds.width, bounds.height, rectDesigner, false); block.setBounds(new UnitRectangle(new Rectangle(resultPoint.x, resultPoint.y, bounds.width, bounds.height), resolution)); designer.repaint(); @@ -124,7 +124,17 @@ public class BottomCornerMouseHanlder extends MouseInputAdapter { public RectangleIterator createRectangleIterator() { return getRectangleIt(); } - + + /** + * 设置等距线 + * + * @param line 吸附线 + */ + @Override + public void setEquidistantLine(Absorptionline line) { + + } + /** * 获取当前选中块的垂直线数组 * @@ -145,6 +155,34 @@ public class BottomCornerMouseHanlder extends MouseInputAdapter { return editor.getValue().getHorizontalLine(); } + /** + * 设置designer内部组件是否重叠的标志位 + * + * @param isIntersects 是否重叠 + */ + @Override + public void setWidgetsIntersects(boolean isIntersects) { + } + + /** + * 获取designer内部组件是否重叠的标志位 + * + * @return 重叠 + */ + @Override + public boolean getWidgetsIntersects() { + return false; + } + + /** + * 获取designer相对屏幕的位置 + * + * @return 位置 + */ + @Override + public Point getDesignerLocationOnScreen() { + return null; + } }; private RectangleIterator getRectangleIt(){ diff --git a/designer_base/src/com/fr/design/actions/help/AboutPane.java b/designer_base/src/com/fr/design/actions/help/AboutPane.java index caa3190889..680aa9b95b 100644 --- a/designer_base/src/com/fr/design/actions/help/AboutPane.java +++ b/designer_base/src/com/fr/design/actions/help/AboutPane.java @@ -11,6 +11,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralUtils; import com.fr.general.Inter; +import com.fr.general.SiteCenter; import com.fr.stable.ProductConstants; import com.fr.stable.StringUtils; import com.fr.stable.bridge.StableFactory; @@ -69,6 +70,8 @@ public class AboutPane extends JPanel { boxCenterAlignmentPane = new BoxCenterAligmentPane(Inter.getLocText("Service_Phone") + ProductConstants.COMPARE_TELEPHONE); contentPane.add(boxCenterAlignmentPane); } + boxCenterAlignmentPane = new BoxCenterAligmentPane("QQ:" + SiteCenter.getInstance().acquireUrlByKind("help.qq")); + contentPane.add(boxCenterAlignmentPane); BoxCenterAligmentPane actionLabel = getURLActionLabel(ProductConstants.WEBSITE_URL); BoxCenterAligmentPane emailLabel = getEmailActionLabel(ProductConstants.SUPPORT_EMAIL); diff --git a/designer_base/src/com/fr/design/beans/location/Absorptionline.java b/designer_base/src/com/fr/design/beans/location/Absorptionline.java index f72892eef7..a0ff0d0e46 100644 --- a/designer_base/src/com/fr/design/beans/location/Absorptionline.java +++ b/designer_base/src/com/fr/design/beans/location/Absorptionline.java @@ -1,23 +1,42 @@ package com.fr.design.beans.location; -import java.awt.Color; -import java.awt.Graphics; +import java.awt.*; import com.fr.base.GraphHelper; import com.fr.design.scrollruler.ScrollRulerComponent; import com.fr.stable.ArrayUtils; +import com.fr.third.org.hsqldb.lib.Collection; public class Absorptionline { + //箭头线前段为4px的等边三角形,给定了一个点的坐标,计算一下剩下两个点的坐标偏移量 + //而且箭头分为四个朝向,故有四组坐标(2根号3 约为 3) + // 1.(x,y)(x+2,y±2根号3)(x-2,y±2根号3) + // 2.(x,y)(x±2根号3,y-2)(x±2根号3,y+2) + private static int RECTANGLE_OFFSET_X = 2; + private static int RECTANGLE_OFFSET_Y = 3; + //控件周围八个拖拽框的大小 + private static int RESIZE_BOX_SIZE = 5; + private static Absorptionline lineInX = new Absorptionline(null, null, null, true); private static Absorptionline lineInY = new Absorptionline(null, null, null, false); + private static Absorptionline lineEquidistant = new Absorptionline(null, null, null, true); + private Color lineColor = new Color(228, 225, 199); private Color midLineColor = new Color(196, 227, 237); + private Color equidistantLineColor = new Color(0xff, 0x0d, 0x7b); + private Integer x1; private Integer x2; private Integer middle; private int[] verticalLines; private int[] horizontalLines; + + private int top; + private int left; + private int bottom; + private int right; + private Rectangle equidistantStart; private boolean trans; @@ -89,6 +108,19 @@ public class Absorptionline { return lineInY; } + /** + * 创建等距线 + * @return 等距线 + */ + public static Absorptionline createEquidistantAbsorptionline(Rectangle equidistantStart, int top, int left, int bottom, int right) { + lineEquidistant.equidistantStart = equidistantStart; + lineEquidistant.top = top; + lineEquidistant.left = left; + lineEquidistant.bottom = bottom; + lineEquidistant.right = right; + return lineEquidistant; + } + private Absorptionline(Integer x1, Integer x2, Integer middleInX, boolean trans) { this.x1 = x1; this.x2 = x2; @@ -186,5 +218,134 @@ public class Absorptionline { } } + //画等距线 + if (equidistantStart != null) { + g.setColor(equidistantLineColor); + if (top > 0) { + paintTopEquidistantLine(g); + } + if (left > 0) { + paintLeftEquidistantLine(g); + } + if (bottom > 0) { + paintBottomEquidistantLine(g); + } + if (right > 0) { + paintRightEquidistantLine(g); + } + } + } + + //朝向上方的等距线 + private void paintTopEquidistantLine(Graphics g){ + int x1[] = { + equidistantStart.x + equidistantStart.width / 2, + equidistantStart.x + equidistantStart.width / 2 - RECTANGLE_OFFSET_X, + equidistantStart.x + equidistantStart.width / 2 + RECTANGLE_OFFSET_X + }; + int y1[] = { + top, + top + RECTANGLE_OFFSET_Y, + top + RECTANGLE_OFFSET_Y + }; + int x2[] = { + equidistantStart.x + equidistantStart.width / 2, + equidistantStart.x + equidistantStart.width / 2 + RECTANGLE_OFFSET_X, + equidistantStart.x + equidistantStart.width / 2 - RECTANGLE_OFFSET_X + }; + int y2[] = { + equidistantStart.y - RESIZE_BOX_SIZE, + equidistantStart.y - RESIZE_BOX_SIZE - RECTANGLE_OFFSET_Y, + equidistantStart.y - RESIZE_BOX_SIZE - RECTANGLE_OFFSET_Y + }; + g.fillPolygon(x1, y1, 3); + g.fillPolygon(x2, y2, 3); + GraphHelper.drawLine(g, + equidistantStart.x + equidistantStart.width / 2, top, + equidistantStart.x + equidistantStart.width / 2, equidistantStart.y - RESIZE_BOX_SIZE); + } + //朝向左侧的等距线 + private void paintLeftEquidistantLine(Graphics g){ + int x1[] = { + left, + left + RECTANGLE_OFFSET_Y, + left + RECTANGLE_OFFSET_Y, + }; + int y1[] = { + equidistantStart.y + equidistantStart.height / 2, + equidistantStart.y + equidistantStart.height / 2 - RECTANGLE_OFFSET_X, + equidistantStart.y + equidistantStart.height / 2 + RECTANGLE_OFFSET_X, + }; + int x2[] = { + equidistantStart.x - RESIZE_BOX_SIZE, + equidistantStart.x - RESIZE_BOX_SIZE - RECTANGLE_OFFSET_Y, + equidistantStart.x - RESIZE_BOX_SIZE - RECTANGLE_OFFSET_Y + }; + int y2[] = { + equidistantStart.y + equidistantStart.height / 2, + equidistantStart.y + equidistantStart.height / 2 + RECTANGLE_OFFSET_X, + equidistantStart.y + equidistantStart.height / 2 - RECTANGLE_OFFSET_X + }; + g.fillPolygon(x1, y1, 3); + g.fillPolygon(x2, y2, 3); + GraphHelper.drawLine(g, + left, equidistantStart.y + equidistantStart.height / 2, + equidistantStart.x - RESIZE_BOX_SIZE, equidistantStart.y + equidistantStart.height / 2); + } + //朝向下方的等距线 + private void paintBottomEquidistantLine(Graphics g) { + int x1[] = { + equidistantStart.x + equidistantStart.width / 2, + equidistantStart.x + equidistantStart.width / 2 + RECTANGLE_OFFSET_X, + equidistantStart.x + equidistantStart.width / 2 - RECTANGLE_OFFSET_X, + }; + int y1[] = { + equidistantStart.y + equidistantStart.height + RESIZE_BOX_SIZE, + equidistantStart.y + equidistantStart.height + RESIZE_BOX_SIZE + RECTANGLE_OFFSET_Y, + equidistantStart.y + equidistantStart.height + RESIZE_BOX_SIZE + RECTANGLE_OFFSET_Y, + }; + int x2[] = { + equidistantStart.x + equidistantStart.width / 2, + equidistantStart.x + equidistantStart.width / 2 + RECTANGLE_OFFSET_X, + equidistantStart.x + equidistantStart.width / 2 - RECTANGLE_OFFSET_X + }; + int y2[] = { + bottom, + bottom - RECTANGLE_OFFSET_Y, + bottom - RECTANGLE_OFFSET_Y + }; + g.fillPolygon(x1, y1, 3); + g.fillPolygon(x2, y2, 3); + GraphHelper.drawLine(g, + equidistantStart.x + equidistantStart.width / 2, equidistantStart.y + equidistantStart.height + RESIZE_BOX_SIZE, + equidistantStart.x + equidistantStart.width / 2, bottom); + } + //朝向右侧的等距线 + private void paintRightEquidistantLine(Graphics g){ + int x1[] = { + right, + right - 3, + right - 3 + }; + int y1[] = { + equidistantStart.y + equidistantStart.height / 2, + equidistantStart.y + equidistantStart.height / 2 - RECTANGLE_OFFSET_X, + equidistantStart.y + equidistantStart.height / 2 + RECTANGLE_OFFSET_X + }; + int x2[] = { + equidistantStart.x + equidistantStart.width + RESIZE_BOX_SIZE, + equidistantStart.x + equidistantStart.width + RESIZE_BOX_SIZE + RECTANGLE_OFFSET_Y, + equidistantStart.x + equidistantStart.width + RESIZE_BOX_SIZE + RECTANGLE_OFFSET_Y + }; + int y2[] = { + equidistantStart.y + equidistantStart.height / 2, + equidistantStart.y + equidistantStart.height / 2 - RECTANGLE_OFFSET_X, + equidistantStart.y + equidistantStart.height / 2 + RECTANGLE_OFFSET_X, + }; + g.fillPolygon(x1, y1, 3); + g.fillPolygon(x2, y2, 3); + GraphHelper.drawLine(g, + equidistantStart.x + equidistantStart.width + RESIZE_BOX_SIZE, equidistantStart.y + equidistantStart.height / 2, + right, equidistantStart.y + equidistantStart.height / 2); } } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/beans/location/MoveUtils.java b/designer_base/src/com/fr/design/beans/location/MoveUtils.java index fddb87648f..e0bed7ca13 100644 --- a/designer_base/src/com/fr/design/beans/location/MoveUtils.java +++ b/designer_base/src/com/fr/design/beans/location/MoveUtils.java @@ -3,6 +3,8 @@ */ package com.fr.design.beans.location; +import com.fr.stable.ArrayUtils; + import javax.swing.*; import java.awt.*; import java.util.ArrayList; @@ -17,6 +19,10 @@ public class MoveUtils { public static final int SORPTION_UNIT = 5; + public static WidgetForbidWindow widgetForbidWindow = new WidgetForbidWindow(); + + public static ArrayList equidistantLines = new ArrayList<>(); + private MoveUtils() { } @@ -68,6 +74,30 @@ public class MoveUtils { * */ int[] getHorizontalLine(); + + /** + * 设置designer内部组件是否重叠的标志位 + * @param isIntersects 是否重叠 + */ + void setWidgetsIntersects(boolean isIntersects); + + /** + * 获取designer内部组件是否重叠的标志位 + * @return 重叠 + */ + boolean getWidgetsIntersects(); + + /** + * 获取designer相对屏幕的位置 + * @return 位置 + */ + Point getDesignerLocationOnScreen(); + + /** + * 设置等距线 + * @param line 吸附线 + */ + void setEquidistantLine(Absorptionline line); } public interface RectangleIterator { @@ -183,6 +213,53 @@ public class MoveUtils { } } + private static void findEquidistantLine(Rectangle bounds, int left, int top, int height, int width) { + //最近的距离与坐标 + EquidistantLine equidistantLineInfo = new EquidistantLine(0, 0, 0); + //等距线从各边中点画出,先要判断是不是在范围内 + int topMiddleX = left + width / 2; + int leftMiddleY = top + height / 2; + if ((topMiddleX > bounds.getX()) && (topMiddleX < (bounds.getX() + bounds.getWidth()))){ + //当前操作rec在bounds的下方 + if (top > (bounds.getY() + bounds.getHeight())){ + equidistantLineInfo.setDistance(top - (bounds.y + bounds.height)); + equidistantLineInfo.setReference(bounds.y + bounds.height); + equidistantLineInfo.setDirection(SwingConstants.TOP); + } + //当前操作rec在bounds上方 + if ((top + height) < bounds.getY()){ + equidistantLineInfo.setDistance(bounds.y - (top + height)); + equidistantLineInfo.setReference(bounds.y); + equidistantLineInfo.setDirection(SwingConstants.BOTTOM); + } + } + else if ((leftMiddleY > bounds.getY()) && (leftMiddleY < (bounds.getY() + bounds.getHeight()))){ + //当前操作rec在bounds的右侧 + if (left > (bounds.getX() + bounds.getWidth())){ + equidistantLineInfo.setDistance(left - (bounds.x + bounds.width)); + equidistantLineInfo.setReference(bounds.x + bounds.width); + equidistantLineInfo.setDirection(SwingConstants.LEFT); + } + //当前操作rec在bounds的左侧 + if ((left + width) < bounds.getX()){ + equidistantLineInfo.setDistance(bounds.x - (left + width)); + equidistantLineInfo.setReference(bounds.x); + equidistantLineInfo.setDirection(SwingConstants.RIGHT); + } + } + if(equidistantLineInfo.getDistance() > 0) { + equidistantLines.add(equidistantLineInfo); + } + } + + public static void displayForbidWindow(int x, int y) { + widgetForbidWindow.showWindow(x, y); + } + + public static void hideForbidWindow() { + widgetForbidWindow.hideWindow(); + } + /** * 吸附 * @@ -197,28 +274,67 @@ public class MoveUtils { * @date 2015-2-12-下午2:39:16 * */ - public static Point sorption(int x, int y, int width, int height, RectangleDesigner designer) { + public static Point sorption(int x, int y, int width, int height, RectangleDesigner designer, boolean isParameterLayout) { int left = x, top = y, bottom = top + height, right = left + width; + Rectangle operatingRectangle = new Rectangle(x, y, width, height); + + equidistantLines.clear(); + PlacePointing px = new PlacePointing(x); PlacePointing py = new PlacePointing(y); + + PlacePointing pEquidistantX = new PlacePointing(x); + PlacePointing pEquidistantY = new PlacePointing(y); + RectangleIterator iterator = designer.createRectangleIterator(); java.util.List cacheRecs = new ArrayList(); + //是否存在控件重叠 + boolean isWidgetsIntersects = false; while (iterator.hasNext()) { Rectangle bounds = iterator.nextRectangle(); cacheRecs.add(bounds); + boolean isIntersects = operatingRectangle.intersects(bounds); findX(px, bounds, left, right, width); findY(py, bounds, top, bottom, height); - if (px.isFind() && py.isFind()) { - break; + + if(isIntersects && !isParameterLayout){ + isWidgetsIntersects = true; + } + else{ + findEquidistantLine(bounds, left, top, height, width); } } + showForbiddenWindow(designer, x, y, isWidgetsIntersects); createXAbsorptionline(px, designer, width, cacheRecs); createYAbsorptionline(py, designer, height, cacheRecs); - return new Point(px.palce, py.palce); + operatingRectangle.x = px.palce; + operatingRectangle.y = py.palce; + createEquidistantLine(pEquidistantX, pEquidistantY, operatingRectangle, designer); + Point sorptionPoint = new Point(px.palce,py.palce); + if (!px.isFind()){ + sorptionPoint.x = pEquidistantX.palce; + } + if (!py.isFind()){ + sorptionPoint.y = pEquidistantY.palce; + } + return sorptionPoint; + } + + public static void showForbiddenWindow(RectangleDesigner designer, int x, int y, boolean isIntersects){ + if (isIntersects){ + if(designer.getDesignerLocationOnScreen() != null) { + displayForbidWindow(x + designer.getDesignerLocationOnScreen().x, y + designer.getDesignerLocationOnScreen().y); + } + designer.setWidgetsIntersects(true); + } + else{ + designer.setWidgetsIntersects(false); + hideForbidWindow(); + } } private static void createXAbsorptionline(PlacePointing px, RectangleDesigner designer, int width, java.util.List cacheRecs) { @@ -300,6 +416,70 @@ public class MoveUtils { } designer.setYAbsorptionline(line); } + + private static void createEquidistantLine(PlacePointing px, PlacePointing py, Rectangle operatingRectangle, RectangleDesigner designer){ + processEquidistantLinesList(px, py, operatingRectangle); + Absorptionline line = null; + if(equidistantLines.size() > 0) { + int top = -1; + int left = -1; + int bottom = -1; + int right = -1; + for(int i = 0; i < equidistantLines.size(); i++){ + if (equidistantLines.get(i).getDirection() == SwingConstants.TOP){ + top = equidistantLines.get(i).getReference(); + } + if (equidistantLines.get(i).getDirection() == SwingConstants.LEFT){ + left = equidistantLines.get(i).getReference(); + } + if (equidistantLines.get(i).getDirection() == SwingConstants.BOTTOM){ + bottom = equidistantLines.get(i).getReference(); + } + if (equidistantLines.get(i).getDirection() == SwingConstants.RIGHT){ + right = equidistantLines.get(i).getReference(); + } + } + line = Absorptionline.createEquidistantAbsorptionline(operatingRectangle, top, left, bottom, right); + } + designer.setEquidistantLine(line); + } + + private static void processEquidistantLinesList(PlacePointing pEquidistantX, PlacePointing pEquidistantY, Rectangle operatingRectangle){ + EquidistantLine[] equidistantLines1 = new EquidistantLine[4]; + //先按方向处理,只保留四个方向上距离最近 + for(int count = 0; count < equidistantLines.size(); count++){ + for (int direction = 0; direction < 4; direction++){ + if(equidistantLines.get(count).getDirection() == (direction + 1)){//direction 1,2,3,4 分别对应top,left,bottom,right + if(equidistantLines1[direction] != null + && equidistantLines1[direction].getDistance() > equidistantLines.get(count).getDistance() + || equidistantLines1[direction] == null) { + equidistantLines1[direction] = equidistantLines.get(count); + } + } + } + } + + equidistantLines.clear(); + //找list中横纵分别等距的组合 + if (equidistantLines1[0] != null && equidistantLines1[2] != null){//top, bottom + int offset = equidistantLines1[0].getDistance() - equidistantLines1[2].getDistance(); + if (Math.abs(offset) <= SORPTION_UNIT * 2){ + pEquidistantY.direction = SwingConstants.TOP; + equidistantLines.add(equidistantLines1[0]); + equidistantLines.add(equidistantLines1[2]); + pEquidistantY.palce = operatingRectangle.y - offset / 2; + } + } + if (equidistantLines1[1] != null && equidistantLines1[3] != null){//left, right + int offset = equidistantLines1[1].getDistance() - equidistantLines1[3].getDistance(); + if (Math.abs(offset) <= SORPTION_UNIT * 2){ + pEquidistantX.direction = SwingConstants.LEFT; + equidistantLines.add(equidistantLines1[1]); + equidistantLines.add(equidistantLines1[3]); + pEquidistantX.palce = operatingRectangle.x - offset / 2; + } + } + } //更新纵向行列线 private static void updateVerticalLine(int[] selfVertical, RectangleIterator iterator, Absorptionline line){ @@ -329,4 +509,43 @@ public class MoveUtils { return false; } + + private static class EquidistantLine{ + //与操作rectangle的距离 + private int distance; + //参考rectangle的位置 + private int reference; + //等距线的方向 + private int direction; + + EquidistantLine(int distance, int reference, int direction){ + this.distance = distance; + this.reference = reference; + this.direction = direction; + } + + public void setDistance(int distance){ + this.distance = distance; + } + + public int getDistance(){ + return this.distance; + } + + public void setReference(int reference){ + this.reference = reference; + } + + public int getReference(){ + return this.reference; + } + + public void setDirection(int direction){ + this.direction = direction; + } + + public int getDirection(){ + return this.direction; + } + } } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/beans/location/WidgetForbidWindow.java b/designer_base/src/com/fr/design/beans/location/WidgetForbidWindow.java new file mode 100644 index 0000000000..acf934e251 --- /dev/null +++ b/designer_base/src/com/fr/design/beans/location/WidgetForbidWindow.java @@ -0,0 +1,48 @@ +package com.fr.design.beans.location; + +import com.fr.base.BaseUtils; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.icon.IconPathConstants; +import com.fr.general.Inter; + +import javax.swing.*; + +/** + * Created by zhouping on 2016/7/24. + */ +public class WidgetForbidWindow extends JWindow { + + private static final int WIDTH = 150; + private static final int HEIGHT = 20; + + private UIButton promptButton = new UIButton(Inter.getLocText("FR-Designer_Forbid_Widgets_Intersects"), BaseUtils.readIcon(IconPathConstants.FORBID_ICON_PATH)); + + /** + * 构造函数 + */ + public WidgetForbidWindow() { + this.add(promptButton); + + this.setSize(WIDTH, HEIGHT); + } + + /** + * 在指定位置显示窗口, 默认将window的中心点放到指定位置上 + * + * @param x x坐标 + * @param y y坐标 + * + */ + public void showWindow(int x, int y){ + this.setLocation(x - WIDTH / 2, y - HEIGHT / 2); + this.setVisible(true); + } + + /** + * 隐藏当前窗口 + * + */ + public void hideWindow(){ + this.setVisible(false); + } +} diff --git a/designer_form/src/com/fr/design/designer/creator/CRPropertyDescriptor.java b/designer_base/src/com/fr/design/designer/creator/CRPropertyDescriptor.java similarity index 92% rename from designer_form/src/com/fr/design/designer/creator/CRPropertyDescriptor.java rename to designer_base/src/com/fr/design/designer/creator/CRPropertyDescriptor.java index c56e150c0b..3155653243 100644 --- a/designer_form/src/com/fr/design/designer/creator/CRPropertyDescriptor.java +++ b/designer_base/src/com/fr/design/designer/creator/CRPropertyDescriptor.java @@ -3,7 +3,6 @@ */ package com.fr.design.designer.creator; -import com.fr.design.gui.xtable.AbstractPropertyGroupModel; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; @@ -15,6 +14,7 @@ import java.beans.PropertyDescriptor; * @since 6.5.3 */ public final class CRPropertyDescriptor extends PropertyDescriptor { + public static final String RENDERER = "renderer"; private PropertyChangeAdapter l; @@ -51,7 +51,7 @@ public final class CRPropertyDescriptor extends PropertyDescriptor { } public CRPropertyDescriptor setRendererClass(Class clazz) { - this.putKeyValue(AbstractPropertyGroupModel.RENDERER, clazz); + this.putKeyValue(RENDERER, clazz); return this; } diff --git a/designer_base/src/com/fr/design/fun/ParameterWindowEditorProcessor.java b/designer_base/src/com/fr/design/fun/ParameterWindowEditorProcessor.java new file mode 100644 index 0000000000..d1eb60a889 --- /dev/null +++ b/designer_base/src/com/fr/design/fun/ParameterWindowEditorProcessor.java @@ -0,0 +1,20 @@ +package com.fr.design.fun; + +import com.fr.design.designer.creator.CRPropertyDescriptor; +import com.fr.stable.fun.mark.Immutable; + +/** + * Created by zpc on 16/7/21. + */ +public interface ParameterWindowEditorProcessor extends Immutable { + + String MARK_STRING = "ParameterWindowEditorProcessor"; + + int CURRENT_LEVEL = 1; + + /** + * 生成属性表 + */ + CRPropertyDescriptor[] createPropertyDescriptor(Class temp); +} + diff --git a/designer_base/src/com/fr/design/fun/impl/AbstractParameterWindowEditorProcessor.java b/designer_base/src/com/fr/design/fun/impl/AbstractParameterWindowEditorProcessor.java new file mode 100644 index 0000000000..0d449090f7 --- /dev/null +++ b/designer_base/src/com/fr/design/fun/impl/AbstractParameterWindowEditorProcessor.java @@ -0,0 +1,31 @@ +package com.fr.design.fun.impl; + +import com.fr.design.designer.creator.CRPropertyDescriptor; +import com.fr.design.fun.ParameterWindowEditorProcessor; +import com.fr.stable.fun.mark.API; + + +/** + * Created by zpc on 2016/7/21. + */ +@API(level = ParameterWindowEditorProcessor.CURRENT_LEVEL) +public abstract class AbstractParameterWindowEditorProcessor implements ParameterWindowEditorProcessor { + + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } + + + + /** + * 生成属性表 + */ + @Override + public CRPropertyDescriptor[] createPropertyDescriptor(Class temp) { + return new CRPropertyDescriptor[0]; + } +} \ No newline at end of file diff --git a/designer_base/src/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer_base/src/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index f0b1eac9fb..d0177d4046 100644 --- a/designer_base/src/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/designer_base/src/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java @@ -301,7 +301,6 @@ public abstract class ToolBarMenuDock { if (ComparatorUtils.equals(ProductConstants.APP_NAME,FINEREPORT)) { shortCuts.add(new FeedBackAction()); shortCuts.add(SeparatorDef.DEFAULT); - shortCuts.add(new SupportQQAction()); shortCuts.add(SeparatorDef.DEFAULT); // shortCuts.add(new ForumAction()); } diff --git a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java index dadfed5047..8ce0d0529e 100644 --- a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java +++ b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java @@ -1,8 +1,10 @@ package com.fr.design.designer.beans.adapters.layout; -import java.awt.Rectangle; +import java.awt.*; import com.fr.design.designer.beans.ConstraintsGroupModel; +import com.fr.design.designer.beans.HoverPainter; +import com.fr.design.designer.beans.painters.FRAbsoluteLayoutPainter; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; @@ -13,10 +15,16 @@ import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; public class FRAbsoluteLayoutAdapter extends AbstractLayoutAdapter { - + private HoverPainter painter; public FRAbsoluteLayoutAdapter(XLayoutContainer container) { super(container); + painter = new FRAbsoluteLayoutPainter(container); } + + @Override + public HoverPainter getPainter() { + return painter; + } /** * 是否能在指定位置添加组件 @@ -27,8 +35,15 @@ public class FRAbsoluteLayoutAdapter extends AbstractLayoutAdapter { */ @Override public boolean accept(XCreator creator, int x, int y) { - return x >= 0 && y >= 0 && creator.getHeight() <= container.getHeight() + Component comp = container.getComponentAt(x, y); + //布局控件要先判断是不是可编辑 + XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator)comp).getTopLayout(); + if(topLayout != null && !topLayout.isEditable()){ + return false; + } + boolean isAccept = x >= 0 && y >= 0 && creator.getHeight() <= container.getHeight() && creator.getWidth() <= container.getWidth(); + return isAccept; } @Override @@ -46,10 +61,20 @@ public class FRAbsoluteLayoutAdapter extends AbstractLayoutAdapter { } fix(creator, x, y); - container.add(creator); + + if (creator.shouldScaleCreator() || creator.hasTitleStyle()) { + addParentCreator(creator); + } else { + container.add(creator, creator.toData().getWidgetName()); + } LayoutUtils.layoutRootContainer(container); } - + + private void addParentCreator(XCreator child) { + XLayoutContainer parentPanel = child.initCreatorWrapper(child.getHeight()); + container.add(parentPanel, child.toData().getWidgetName()); + } + /** * 组件拖拽后调整大小 * @param creator 组件 diff --git a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java index 840d3a7dbc..2777c4476d 100644 --- a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java +++ b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java @@ -117,9 +117,6 @@ public class FRFitLayoutAdapter extends AbstractLayoutAdapter { */ @Override public void addComp(XCreator child, int x, int y) { - if (ComparatorUtils.equals(child.getIconPath(), WIDGETPANEICONPATH)) { - return; - } fix(child, x, y); if (child.shouldScaleCreator() || child.hasTitleStyle()) { addParentCreator(child); diff --git a/designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java b/designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java index a5758639be..b44145c0c4 100644 --- a/designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java +++ b/designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java @@ -3,20 +3,17 @@ */ package com.fr.design.designer.beans.location; -import java.awt.Cursor; -import java.awt.Point; -import java.awt.Rectangle; +import java.awt.*; import com.fr.design.beans.location.Absorptionline; import com.fr.design.beans.location.MoveUtils; +import com.fr.design.designer.creator.*; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormSelection; -import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWBorderLayout; -import com.fr.design.designer.creator.XWParameterLayout; +import com.fr.design.utils.ComponentUtils; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; +import com.fr.form.ui.container.WParameterLayout; /** * @author richer @@ -39,10 +36,7 @@ public abstract class AccessDirection implements Direction { return new int[] { x, y }; } else { int posy = current_bounds.y; - if (posy >= designer.getParaHeight() && !designer.isFormParaDesigner()) { - return new int[] { x, y }; - } - + Point relativePoint = getRelativePoint(x, y, current_bounds,designer); sorptionPoint(relativePoint,current_bounds, designer); return new int[] { relativePoint.x, relativePoint.y }; @@ -72,12 +66,14 @@ public abstract class AccessDirection implements Direction { WAbsoluteLayout layout =getLayout(designer); FormSelection selection = designer.getSelectionModel().getSelection(); + + boolean isWidgetsIntersect = false; for (int i = 0, count = layout.getWidgetCount(); i < count; i++) { BoundsWidget temp = (BoundsWidget) layout.getWidget(i); if (!temp.isVisible() || selection.contains(temp.getWidget())) { continue; } - Rectangle bounds = temp.getBounds(); + Rectangle bounds = getWidgetRelativeBounds(temp.getBounds(), selection); if (!findInX) { int x1 = bounds.x; if (Math.abs(x1 - point.x) <= MoveUtils.SORPTION_UNIT) { @@ -106,18 +102,54 @@ public abstract class AccessDirection implements Direction { if (findInX && findInY) { break; } + + if (current_bounds.intersects(bounds) && !(layout instanceof WParameterLayout)){ + isWidgetsIntersect = true; + } } + processRectangleIntersects(designer, point.x, point.y, isWidgetsIntersect); designer.getStateModel().setXAbsorptionline(findInX && current_bounds.getWidth() > MoveUtils.SORPTION_UNIT ? Absorptionline.createXAbsorptionline(point.x) : null); designer.getStateModel().setYAbsorptionline(findInY && current_bounds.getHeight() > MoveUtils.SORPTION_UNIT ? Absorptionline.createYAbsorptionline(point.y) : null); } + private Rectangle getWidgetRelativeBounds(Rectangle bounds, FormSelection selection){ + Rectangle relativeRec = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator()); + if (parent == null) { + return relativeRec; + } + Rectangle rec = ComponentUtils.getRelativeBounds(parent); + relativeRec.x += rec.x; + relativeRec.y += rec.y; + return relativeRec; + } + + private void processRectangleIntersects(FormDesigner designer, int x, int y, boolean isIntersects){ + if(isIntersects){ + if(designer.getLocationOnScreen() != null) { + MoveUtils.displayForbidWindow(x + designer.getLocationOnScreen().x, y + designer.getLocationOnScreen().y); + } + designer.setWidgetsIntersect(true); + } + else{ + MoveUtils.hideForbidWindow(); + designer.setWidgetsIntersect(false); + } + } + private WAbsoluteLayout getLayout(final FormDesigner designer){ XLayoutContainer formLayoutContainer = (XLayoutContainer) XCreatorUtils.createXCreator( designer.getTarget().getContainer()); WAbsoluteLayout layout; - if (formLayoutContainer.acceptType(XWBorderLayout.class)){ - layout = (WAbsoluteLayout) designer.getParaComponent().toData(); + if (formLayoutContainer.acceptType(XWBorderLayout.class)){//看起来这边的作用应该是为了区别cpt(得到XWParameterLayout)还是frm(得到XWBorderLayout)的参数界面 + Container container = designer.getSelectionModel().getSelection().getSelectedCreator().getParent(); + if(container instanceof XWAbsoluteLayout){ + layout = ((XWAbsoluteLayout)container).toData(); + } + else { + layout = (WAbsoluteLayout) designer.getParaComponent().toData(); + } } else{ layout = (WAbsoluteLayout) designer.getTarget().getContainer(); } diff --git a/designer_form/src/com/fr/design/designer/beans/location/Inner.java b/designer_form/src/com/fr/design/designer/beans/location/Inner.java index 68db5241e0..9e17b4ac30 100644 --- a/designer_form/src/com/fr/design/designer/beans/location/Inner.java +++ b/designer_form/src/com/fr/design/designer/beans/location/Inner.java @@ -4,16 +4,17 @@ import com.fr.design.beans.location.Absorptionline; import com.fr.design.beans.location.MoveUtils; import com.fr.design.beans.location.MoveUtils.RectangleDesigner; import com.fr.design.beans.location.MoveUtils.RectangleIterator; -import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWBorderLayout; +import com.fr.design.designer.creator.*; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormSelection; +import com.fr.design.utils.ComponentUtils; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; import com.fr.stable.ArrayUtils; +import com.fr.third.com.lowagie.text.*; import java.awt.*; +import java.awt.Rectangle; public class Inner extends AccessDirection { @@ -78,17 +79,72 @@ public class Inner extends AccessDirection { public RectangleIterator createRectangleIterator() { return getRectangleIterator(designer); } + + /** + * 设置designer内部组件是否重叠的标志位 + * + * @param isIntersects 是否重叠 + */ + @Override + public void setWidgetsIntersects(boolean isIntersects) { + designer.setWidgetsIntersect(isIntersects); + } + + /** + * 获取designer内部组件是否重叠的标志位 + * + * @return 重叠 + */ + @Override + public boolean getWidgetsIntersects() { + return designer.isWidgetsIntersect(); + } + + /** + * 获取designer相对屏幕的位置 + * + * @return 位置 + */ + @Override + public Point getDesignerLocationOnScreen() { + return designer.getLocationOnScreen(); + } + + /** + * 设置等距线 + * + * @param line 吸附线 + */ + @Override + public void setEquidistantLine(Absorptionline line) { + designer.getStateModel().setEquidistantLine(line); + } }; - point.setLocation(MoveUtils.sorption(point.x, point.y, current_bounds.width, current_bounds.height, rd)); + //判断当前操作的是不是参数面板,要特殊处理 + boolean isParameterLayout = ((XCreator)(designer.getSelectionModel().getSelection().getSelectedCreator().getParent())).acceptType(XWParameterLayout.class); + point.setLocation(MoveUtils.sorption(point.x, point.y, current_bounds.width, current_bounds.height, rd, isParameterLayout)); } private RectangleIterator getRectangleIterator(final FormDesigner designer){ + return new RectangleIterator() { private int i; private WAbsoluteLayout layout = getLayout(designer); private int count = layout.getWidgetCount(); private FormSelection selection = designer.getSelectionModel().getSelection(); + private Rectangle getWidgetRelativeBounds(Rectangle bounds){ + Rectangle relativeRec = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator()); + if (parent == null) { + return relativeRec; + } + Rectangle rec = ComponentUtils.getRelativeBounds(parent); + relativeRec.x += rec.x; + relativeRec.y += rec.y; + return relativeRec; + } + public boolean hasNext() { if (i >= count) { return false; @@ -110,7 +166,7 @@ public class Inner extends AccessDirection { } public Rectangle nextRectangle() { BoundsWidget temp = (BoundsWidget) layout.getWidget(i++); - return temp.getBounds(); + return getWidgetRelativeBounds(temp.getBounds()); } }; } @@ -119,8 +175,14 @@ public class Inner extends AccessDirection { XLayoutContainer formLayoutContainer = (XLayoutContainer) XCreatorUtils.createXCreator( designer.getTarget().getContainer()); WAbsoluteLayout layout; - if (formLayoutContainer.acceptType(XWBorderLayout.class)){ - layout = (WAbsoluteLayout) designer.getParaComponent().toData(); + if (formLayoutContainer.acceptType(XWBorderLayout.class)){//看起来这边的作用应该是为了区别cpt(得到XWParameterLayout)还是frm(得到XWBorderLayout)的参数界面 + Container container = designer.getSelectionModel().getSelection().getSelectedCreator().getParent(); + if(container instanceof XWAbsoluteLayout){ + layout = ((XWAbsoluteLayout)container).toData(); + } + else { + layout = (WAbsoluteLayout) designer.getParaComponent().toData(); + } } else{ layout = (WAbsoluteLayout) designer.getTarget().getContainer(); } diff --git a/designer_form/src/com/fr/design/designer/beans/models/StateModel.java b/designer_form/src/com/fr/design/designer/beans/models/StateModel.java index d92cd9c76f..a623caddcf 100644 --- a/designer_form/src/com/fr/design/designer/beans/models/StateModel.java +++ b/designer_form/src/com/fr/design/designer/beans/models/StateModel.java @@ -44,6 +44,8 @@ public class StateModel { private Absorptionline lineInX; private Absorptionline lineInY; + //等距线 + private Absorptionline lineEquidistant; // 当前是否处于拖拽选择状态 private boolean selecting; @@ -357,6 +359,14 @@ public class StateModel { this.lineInY = line; } + /** + * 等距线赋值 + * @param line 线 + */ + public void setEquidistantLine(Absorptionline line){ + this.lineEquidistant = line; + } + /** *画吸附线 * @param g Graphics类 @@ -368,6 +378,9 @@ public class StateModel { if(lineInY != null) { lineInY.paint(g,designer.getArea()); } + if(lineEquidistant != null){ + lineEquidistant.paint(g,designer.getArea()); + } } /** diff --git a/designer_form/src/com/fr/design/designer/beans/painters/FRAbsoluteLayoutPainter.java b/designer_form/src/com/fr/design/designer/beans/painters/FRAbsoluteLayoutPainter.java new file mode 100644 index 0000000000..04e6018fc2 --- /dev/null +++ b/designer_form/src/com/fr/design/designer/beans/painters/FRAbsoluteLayoutPainter.java @@ -0,0 +1,26 @@ +package com.fr.design.designer.beans.painters; + +import com.fr.design.designer.creator.XLayoutContainer; + +import java.awt.*; + +/** + * Created by zhouping on 2016/7/11. + */ +public class FRAbsoluteLayoutPainter extends AbstractPainter { + public FRAbsoluteLayoutPainter(XLayoutContainer container) { + super(container); + } + + /** + * 组件渲染 + * + * @param g 画图类 + * @param startX 开始位置x + * @param startY 开始位置y + */ + @Override + public void paint(Graphics g, int startX, int startY) { + super.paint(g, startX, startY); + } +} diff --git a/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java index 6cf0fc2169..46e1c42c2b 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java @@ -3,26 +3,38 @@ */ package com.fr.design.designer.creator; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Rectangle; +import java.awt.*; import java.awt.event.ContainerEvent; +import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; import java.util.HashMap; +import com.fr.design.designer.beans.AdapterBus; +import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.AbsoluteLayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRAbsoluteLayoutAdapter; import com.fr.design.designer.beans.location.Direction; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.form.layout.FRAbsoluteLayout; +import com.fr.design.icon.IconPathConstants; +import com.fr.design.mainframe.EditingMouseListener; +import com.fr.design.mainframe.FormDesigner; import com.fr.form.ui.Connector; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; +import com.fr.general.IOUtils; +import com.fr.general.Inter; /** * @author richer * @since 6.5.3 */ public class XWAbsoluteLayout extends XLayoutContainer { + + private static final int EDIT_BTN_WIDTH = 60; + private static final int EDIT_BTN_HEIGHT = 24; private HashMap xConnectorMap; @@ -158,7 +170,7 @@ public class XWAbsoluteLayout extends XLayoutContainer { WAbsoluteLayout wabs = this.toData(); if (!creator.acceptType(XWFitLayout.class)) { creator.setDirections(Direction.ALL); - } + } wabs.addWidget(new BoundsWidget(creator.toData(), creator.getBounds())); } @@ -187,4 +199,74 @@ public class XWAbsoluteLayout extends XLayoutContainer { public LayoutAdapter getLayoutAdapter() { return new FRAbsoluteLayoutAdapter(this); } + + @Override + public XLayoutContainer getTopLayout() { + XLayoutContainer xTopLayout = XCreatorUtils.getParentXLayoutContainer(this).getTopLayout(); + if (xTopLayout != null && !xTopLayout.isEditable()){ + return xTopLayout; + } + else{ + return this; + } + } + + public void paint(Graphics g) { + super.paint(g); + //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 + if (isMouseEnter && !this.editable) { + int x = 0; + int y = 0; + int w = getWidth(); + int h = getHeight(); + + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + //画白色的编辑层 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 60 / 100.0F)); + g2d.setColor(Color.WHITE); + g2d.fillRect(x, y, w, h); + //画编辑按钮所在框 + g2d.setComposite(oldComposite); + g2d.setColor(new Color(176, 196, 222)); + g2d.fillRect((x + w / 2 - EDIT_BTN_WIDTH / 2), (y + h / 2 - EDIT_BTN_HEIGHT / 2), EDIT_BTN_WIDTH, EDIT_BTN_HEIGHT); + //画编辑按钮图标 + BufferedImage image = IOUtils.readImage(IconPathConstants.TD_EDIT_ICON_PATH); + g2d.drawImage( + image, + (x + w / 2 - 23), + (y + h / 2 - image.getHeight() / 2), + image.getWidth(), + image.getHeight(), + null, + this + ); + g2d.setColor(Color.BLACK); + //画编辑文字 + g2d.drawString(Inter.getLocText("Edit"), x + w / 2 - 2, y + h / 2 + 5); + } + } + + /** + * 响应点击事件 + * + * @param editingMouseListener 鼠标点击,位置处理器 + * @param e 鼠标点击事件 + */ + public void respondClick(EditingMouseListener editingMouseListener,MouseEvent e){ + FormDesigner designer = editingMouseListener.getDesigner(); + SelectionModel selectionModel = editingMouseListener.getSelectionModel(); + boolean isEditing = isEditable() || designer.getCursor().getType() == Cursor.HAND_CURSOR || e.getClickCount() == 2; + setEditable(isEditing); + + selectionModel.selectACreatorAtMouseEvent(e); + designer.repaint(); + + if (editingMouseListener.stopEditing()) { + if (this != designer.getRootComponent()) { + ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); + editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); + } + } + } } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java b/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java index 38652b3d4c..489aab52ba 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java @@ -825,7 +825,7 @@ public class XWFitLayout extends XLayoutContainer { /** * 处理自适应布局的directions - * @param creator 组件 + * @param xcreator 组件 */ private void dealDirections(XCreator xcreator, boolean isInit) { if (xcreator == null) { diff --git a/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java b/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java index 9f92b97861..890612ccc5 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/XWParameterLayout.java @@ -3,6 +3,7 @@ */ package com.fr.design.designer.creator; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRParameterLayoutAdapter; import com.fr.design.form.util.XCreatorConstants; @@ -16,9 +17,12 @@ import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WParameterLayout; import com.fr.general.Background; import com.fr.general.Inter; +import com.fr.design.fun.ParameterWindowEditorProcessor; +import com.fr.stable.ArrayUtils; import java.awt.*; import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; /** * 表单参数界面container @@ -51,7 +55,7 @@ public class XWParameterLayout extends XWAbsoluteLayout { * @throws java.beans.IntrospectionException */ public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException { - return new CRPropertyDescriptor[]{ + CRPropertyDescriptor[] propertyTableEditor = new CRPropertyDescriptor[]{ new CRPropertyDescriptor("widgetName", this.data.getClass()).setI18NName(Inter .getLocText("FR-Designer_Form-Widget_Name")), new CRPropertyDescriptor("background", this.data.getClass()).setEditorClass(BackgroundEditor.class) @@ -61,9 +65,17 @@ public class XWParameterLayout extends XWAbsoluteLayout { .setI18NName(Inter.getLocText("FR-Designer_DisplayNothingBeforeQuery")) .putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Advanced"), new CRPropertyDescriptor("position", this.data.getClass()).setEditorClass(WidgetDisplayPosition.class) - .setRendererClass(WidgetDisplayPositionRender.class).setI18NName(Inter.getLocText("FR-Designer_WidgetDisplyPosition")) + .setRendererClass(WidgetDisplayPositionRender.class).setI18NName(Inter.getLocText("FR-Designer_WidgetDisplyPosition")) .putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Advanced"), }; + + ParameterWindowEditorProcessor processor = ExtraDesignClassManager.getInstance().getSingle(ParameterWindowEditorProcessor.MARK_STRING); + if (processor == null) { + return propertyTableEditor; + } + CRPropertyDescriptor[] extraEditor = processor.createPropertyDescriptor(this.data.getClass()); + + return ArrayUtils.addAll(propertyTableEditor, extraEditor); } @Override @@ -151,4 +163,15 @@ public class XWParameterLayout extends XWAbsoluteLayout { public void setBackground(Background background){ this.toData().setBackground(background); } + + @Override + public void paint(Graphics g) { + //参数面板特殊处理,不出现编辑层 + setEditable(true); + super.paint(g); + } + @Override + public XLayoutContainer getTopLayout() { + return this; + } } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardLayout.java b/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardLayout.java index 621f4c5f5e..346a5ce3a7 100644 --- a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardLayout.java @@ -219,8 +219,7 @@ public class XWCardLayout extends XLayoutContainer { * */ protected void setWrapperName(XLayoutContainer parentPanel, String widgetName) { - //先随便set一个, 以后还是要隐藏的 - parentPanel.toData().setWidgetName("border_card_" + widgetName); + parentPanel.toData().setWidgetName("tablayout" + widgetName.replaceAll(createDefaultName(),"")); } /** diff --git a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java b/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java index b9039b1d6e..42a45c53c3 100644 --- a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java +++ b/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java @@ -11,6 +11,7 @@ import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWBorderLayout; import com.fr.design.icon.IconPathConstants; @@ -263,6 +264,12 @@ public class XWCardMainBorderLayout extends XWBorderLayout{ */ @Override public XLayoutContainer getTopLayout() { - return this; + XLayoutContainer xTopLayout = XCreatorUtils.getParentXLayoutContainer(this).getTopLayout(); + if (xTopLayout != null && !xTopLayout.isEditable()){ + return xTopLayout; + } + else{ + return this; + } } } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java b/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java index 229b549439..76287c30fe 100644 --- a/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java +++ b/designer_form/src/com/fr/design/gui/core/FormWidgetOption.java @@ -1 +1 @@ -package com.fr.design.gui.core; import javax.swing.Icon; import com.fr.base.BaseUtils; import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WBorderLayout; import com.fr.form.ui.container.WCardLayout; import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WHorizontalBoxLayout; import com.fr.form.ui.container.WParameterLayout; import com.fr.form.ui.container.WVerticalBoxLayout; import com.fr.general.Inter; /** * Author : Shockway * Date: 13-6-17 * Time: 上午10:40 */ public class FormWidgetOption extends WidgetOption { /** * 返回名字 * @return 名字 */ @Override public String optionName() { return null; } /** * 返回图标 * @return 图标 */ @Override public Icon optionIcon() { return null; } /** * 组件类 * @return 类 */ @Override public Class widgetClass() { return null; } /** * 返回组件 * @return 控件 */ @Override public Widget createWidget() { return null; } /* * 表单容器 */ public static WidgetOption[] getFormContainerInstance() { return new WidgetOption[] { ABSOLUTELAYOUTCONTAINER, BORDERLAYOUTCONTAINER, HORIZONTALBOXLAYOUTCONTAINER, VERTICALBOXLAYOUTCONTAINER, CARDLAYOUTCONTAINER, FITLAYOUTCONTAINER }; } /** * 表单工具栏上的布局 * @return 控件 */ public static WidgetOption[] getFormLayoutInstance() { return new WidgetOption[] {CARDLAYOUTCONTAINER}; } public static final WidgetOption ABSOLUTELAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_AbsoluteLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_absolute.png"), WAbsoluteLayout.class); public static final WidgetOption BORDERLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_BorderLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_border.png"), WBorderLayout.class); public static final WidgetOption CARDLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_CardLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/card_layout_16.png"), WCardLayout.class); public static final WidgetOption HORIZONTALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Layout-HBox"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_h_16.png"), WHorizontalBoxLayout.class); public static final WidgetOption VERTICALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_VerticalBoxLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WVerticalBoxLayout.class); public static final WidgetOption FITLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Designer-Layout_Adaptive_Layout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WFitLayout.class); public static final WidgetOption PARAMETERCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Para-Body"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_parameter.png"), WParameterLayout.class); public static final WidgetOption ELEMENTCASE = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Form-Report"), BaseUtils.readIcon("/com/fr/web/images/form/resources/report_16.png"), ElementCaseEditor.class); } \ No newline at end of file +package com.fr.design.gui.core; import javax.swing.Icon; import com.fr.base.BaseUtils; import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WBorderLayout; import com.fr.form.ui.container.WCardLayout; import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WHorizontalBoxLayout; import com.fr.form.ui.container.WParameterLayout; import com.fr.form.ui.container.WVerticalBoxLayout; import com.fr.general.Inter; /** * Author : Shockway * Date: 13-6-17 * Time: 上午10:40 */ public class FormWidgetOption extends WidgetOption { /** * 返回名字 * @return 名字 */ @Override public String optionName() { return null; } /** * 返回图标 * @return 图标 */ @Override public Icon optionIcon() { return null; } /** * 组件类 * @return 类 */ @Override public Class widgetClass() { return null; } /** * 返回组件 * @return 控件 */ @Override public Widget createWidget() { return null; } /* * 表单容器 */ public static WidgetOption[] getFormContainerInstance() { return new WidgetOption[] { ABSOLUTELAYOUTCONTAINER, BORDERLAYOUTCONTAINER, HORIZONTALBOXLAYOUTCONTAINER, VERTICALBOXLAYOUTCONTAINER, CARDLAYOUTCONTAINER, FITLAYOUTCONTAINER }; } /** * 表单工具栏上的布局 * @return 控件 */ public static WidgetOption[] getFormLayoutInstance() { return new WidgetOption[] {CARDLAYOUTCONTAINER, ABSOLUTELAYOUTCONTAINER}; } public static final WidgetOption ABSOLUTELAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_AbsoluteLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_absolute.png"), WAbsoluteLayout.class); public static final WidgetOption BORDERLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_BorderLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_border.png"), WBorderLayout.class); public static final WidgetOption CARDLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_CardLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/card_layout_16.png"), WCardLayout.class); public static final WidgetOption HORIZONTALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Layout-HBox"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_h_16.png"), WHorizontalBoxLayout.class); public static final WidgetOption VERTICALBOXLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_VerticalBoxLayout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WVerticalBoxLayout.class); public static final WidgetOption FITLAYOUTCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Designer-Layout_Adaptive_Layout"), BaseUtils.readIcon("/com/fr/web/images/form/resources/boxlayout_v_16.png"), WFitLayout.class); public static final WidgetOption PARAMETERCONTAINER = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Para-Body"), BaseUtils.readIcon("/com/fr/web/images/form/resources/layout_parameter.png"), WParameterLayout.class); public static final WidgetOption ELEMENTCASE = WidgetOptionFactory.createByWidgetClass(Inter .getLocText("FR-Designer_Form-Report"), BaseUtils.readIcon("/com/fr/web/images/form/resources/report_16.png"), ElementCaseEditor.class); } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/mainframe/EditingMouseListener.java b/designer_form/src/com/fr/design/mainframe/EditingMouseListener.java index e66b37552a..fc25bd1245 100644 --- a/designer_form/src/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer_form/src/com/fr/design/mainframe/EditingMouseListener.java @@ -10,6 +10,7 @@ import javax.swing.*; import javax.swing.event.MouseInputAdapter; import com.fr.base.BaseUtils; +import com.fr.design.beans.location.MoveUtils; import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.events.DesignerEditor; @@ -72,6 +73,9 @@ public class EditingMouseListener extends MouseInputAdapter { private DesignerEditor current_editor; private XCreator current_creator; + //备份开始拖动的位置和大小 + private Rectangle dragBackupBounds; + /** * 获取最小移动距离 * @@ -189,6 +193,14 @@ public class EditingMouseListener extends MouseInputAdapter { if (stateModel.isDragging()) { // 当前鼠标所在的组件 XCreator hoveredComponent = designer.getComponentAt(e.getX(), e.getY()); + if(designer.isWidgetsIntersect() && dragBackupBounds != null && hoveredComponent != null){ + XCreator selectionXCreator = designer.getSelectionModel().getSelection().getSelectedCreator(); + if(selectionXCreator != null){ + selectionXCreator.setBounds(dragBackupBounds.x, dragBackupBounds.y, dragBackupBounds.width, dragBackupBounds.height); + MoveUtils.hideForbidWindow(); + } + } + dragBackupBounds = null; // 拉伸时鼠标拖动过快,导致所在组件获取会为空 if (hoveredComponent == null && e.getY() < 0) { // bug63538 @@ -326,10 +338,12 @@ public class EditingMouseListener extends MouseInputAdapter { if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } - if (e.getX() > (parent.getX() + parent.getWidth() / 2 - EDIT_BTN_WIDTH / 2 - GAP) - && e.getX() < (parent.getX() + parent.getWidth() / 2 + EDIT_BTN_WIDTH / 2 + GAP)) { - if (e.getY() > (parent.getY() + parent.getHeight() / 2 - EDIT_BTN_HEIGHT / 2 - GAP) - && e.getY() < (parent.getY() + parent.getHeight() / 2 + EDIT_BTN_HEIGHT / 2 + GAP + designer.getParaHeight())) { + int minX = getParentPositionX(parent, parent.getX()) + parent.getWidth() / 2; + int minY = getParentPositionY(parent, parent.getY()) + parent.getHeight() / 2; + int offsetX = EDIT_BTN_WIDTH / 2 + GAP; + int offsetY = EDIT_BTN_HEIGHT / 2 + GAP; + if (e.getX() > (minX - offsetX) && e.getX() < (minX + offsetX)) { + if (e.getY() > (minY - offsetY) && e.getY() < (minY + offsetY + designer.getParaHeight())) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } @@ -385,6 +399,12 @@ public class EditingMouseListener extends MouseInputAdapter { stateModel.dragging(e); // 获取e所在的焦点组件 XCreator hotspot = designer.getComponentAt(e.getX(), e.getY()); + if(dragBackupBounds == null) { + XCreator selectingXCreator = designer.getSelectionModel().getSelection().getSelectedCreator(); + if(selectingXCreator != null){ + dragBackupBounds = new Rectangle(selectingXCreator.getX(), selectingXCreator.getY(), selectingXCreator.getWidth(), selectingXCreator.getHeight()); + } + } // 拉伸时鼠标拖动过快,导致所在组件获取会为空 if (hotspot == null) { return; @@ -417,11 +437,43 @@ public class EditingMouseListener extends MouseInputAdapter { designer.repaint(); } + //当前编辑的组件是在布局中,鼠标点击布局外部,需要一次性将布局及其父布局都置为不可编辑 + private void setTopLayoutUnEditable(XLayoutContainer clickedTopLayout, XLayoutContainer clickingTopLayout){ + //双击的前后点击click为相同对象,过滤掉 + if (clickedTopLayout == null || clickedTopLayout == clickingTopLayout){ + return; + } + //位于同一层级的控件,父布局相同,过滤掉 + if (clickingTopLayout != null && clickedTopLayout.getParent() == clickingTopLayout.getParent()){ + return; + } + //前后点击的位于不同层级,要置为不可编辑 + XLayoutContainer xLayoutContainer = (XLayoutContainer)clickedTopLayout.getParent(); + if (xLayoutContainer == clickingTopLayout){ + return; + } + if (xLayoutContainer != null){ + xLayoutContainer.setEditable(false); + setTopLayoutUnEditable((XLayoutContainer) clickedTopLayout.getParent(), clickingTopLayout); + } + } + + private boolean isCreatorInLayout(XCreator creator, XCreator layout){ + if (creator == layout){ + return true; + } + if(layout.getParent() != null){ + return isCreatorInLayout(creator, (XCreator)layout.getParent()); + } + return false; + } + private XCreator processTopLayoutMouseClick(XCreator creator){ XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer(creator).getTopLayout(); if(topLayout != null){ - if (clickTopLayout != null && clickTopLayout != topLayout){ + if (clickTopLayout != null && clickTopLayout != topLayout && !isCreatorInLayout(clickTopLayout, topLayout)){ clickTopLayout.setEditable(false); + setTopLayoutUnEditable(clickTopLayout, topLayout); } clickTopLayout = topLayout; if(!topLayout.isEditable()) { @@ -431,6 +483,7 @@ public class EditingMouseListener extends MouseInputAdapter { else{ if(clickTopLayout != null){ clickTopLayout.setEditable(false); + setTopLayoutUnEditable(clickTopLayout, null); } } diff --git a/designer_form/src/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer_form/src/com/fr/design/mainframe/FormCreatorDropTarget.java index a90ba7fb6e..ed4cf4190a 100644 --- a/designer_form/src/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer_form/src/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -9,6 +9,7 @@ import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; +import java.util.ArrayList; import javax.swing.BorderFactory; import javax.swing.JWindow; @@ -85,8 +86,12 @@ public class FormCreatorDropTarget extends DropTarget { if (success) { // 如果添加成功,则触发相应事件 XCreator xCreator = container.acceptType(XWParameterLayout.class) ? designer.getParaComponent() : designer.getRootComponent(); + //SetSelection时要确保选中的是最顶层的布局 + //tab布局添加的时候是初始化了XWCardLayout,实际上最顶层的布局是XWCardMainBorderLayout + XCreator addingXCreator = addingModel.getXCreator(); + Widget widget = (addingXCreator.getTopLayout() != null) ? (addingXCreator.getTopLayout().toData()) : addingXCreator.toData(); designer.getSelectionModel().setSelectedCreators( - FormSelectionUtils.rebuildSelection(xCreator, new Widget[]{addingModel.getXCreator().toData()})); + FormSelectionUtils.rebuildSelection(xCreator, new Widget[]{widget})); designer.getEditListenerTable().fireCreatorModified(addingModel.getXCreator(), DesignerEvent.CREATOR_ADDED); } else { Toolkit.getDefaultToolkit().beep(); diff --git a/designer_form/src/com/fr/design/mainframe/FormDesigner.java b/designer_form/src/com/fr/design/mainframe/FormDesigner.java index 19bf64c70f..40add69153 100644 --- a/designer_form/src/com/fr/design/mainframe/FormDesigner.java +++ b/designer_form/src/com/fr/design/mainframe/FormDesigner.java @@ -84,6 +84,9 @@ public class FormDesigner extends TargetComponent
implements TreeSelection private ConnectorHelper ConnectorHelper; private boolean isReportBlockEditing = false; + //组件重叠 + private boolean isWidgetsIntersect = false; + /** * 下面的变量都是非序列化成员,不记录设计状态,只作为设计时临时状态使用。 */ @@ -539,6 +542,12 @@ public class FormDesigner extends TargetComponent implements TreeSelection if (paraComponent != null && paraComponent.acceptType(XWParameterLayout.class)){ return true; } + else{ + if (this.getSelectionModel().getSelection().getSelectedCreator().getParent() != null + && ((XLayoutContainer)this.getSelectionModel().getSelection().getSelectedCreator().getParent()).acceptType(XWAbsoluteLayout.class)){ + return true; + } + } return false; } @@ -558,6 +567,14 @@ public class FormDesigner extends TargetComponent implements TreeSelection return this.isReportBlockEditing; } + public void setWidgetsIntersect(boolean isWidgetsIntersect){ + this.isWidgetsIntersect = isWidgetsIntersect; + } + + public boolean isWidgetsIntersect(){ + return this.isWidgetsIntersect; + } + /** * 是否重命名控件 * @param creator 组件 diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000000..05253b02f3 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,15 @@ +# must be unique in a given SonarQube instance +sonar.projectKey=finereport.design +# this is the name displayed in the SonarQube UI +sonar.projectName=finereport.design +sonar.projectVersion=1.0 +sonar.branch=dev + +# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. +# Since SonarQube 4.2, this property is optional if sonar.modules is set. +# If not set, SonarQube starts looking for source code from the directory containing +# the sonar-project.properties file. +sonar.sources=. + +# Encoding of the source code. Default is default system encoding +#sonar.sourceEncoding=UTF-8 \ No newline at end of file diff --git a/start.bat b/start.bat new file mode 100644 index 0000000000..7535291dfa --- /dev/null +++ b/start.bat @@ -0,0 +1 @@ +sonar-scanner \ No newline at end of file