|
|
|
/*
|
|
|
|
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved.
|
|
|
|
*/
|
|
|
|
package com.fr.design.mainframe;
|
|
|
|
|
|
|
|
import java.awt.AWTEvent;
|
|
|
|
import java.awt.Adjustable;
|
|
|
|
import java.awt.Dimension;
|
|
|
|
import java.awt.Image;
|
|
|
|
import java.awt.Rectangle;
|
|
|
|
import java.awt.datatransfer.Clipboard;
|
|
|
|
import java.awt.datatransfer.DataFlavor;
|
|
|
|
import java.awt.datatransfer.Transferable;
|
|
|
|
import java.awt.event.ActionEvent;
|
|
|
|
import java.awt.event.ActionListener;
|
|
|
|
import java.awt.event.InputEvent;
|
|
|
|
import java.awt.event.KeyEvent;
|
|
|
|
import java.awt.event.MouseAdapter;
|
|
|
|
import java.awt.event.MouseEvent;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
import javax.swing.AbstractAction;
|
|
|
|
import javax.swing.ActionMap;
|
|
|
|
import javax.swing.Icon;
|
|
|
|
import javax.swing.InputMap;
|
|
|
|
import javax.swing.JComponent;
|
|
|
|
import javax.swing.JPanel;
|
|
|
|
import javax.swing.JPopupMenu;
|
|
|
|
import javax.swing.JScrollBar;
|
|
|
|
import javax.swing.KeyStroke;
|
|
|
|
|
|
|
|
import com.fr.base.BaseUtils;
|
|
|
|
import com.fr.base.DynamicUnitList;
|
|
|
|
import com.fr.base.FRContext;
|
|
|
|
import com.fr.base.Formula;
|
|
|
|
import com.fr.base.ScreenResolution;
|
|
|
|
import com.fr.base.Style;
|
|
|
|
import com.fr.design.DesignState;
|
|
|
|
import com.fr.design.DesignerEnvManager;
|
|
|
|
import com.fr.design.ExtraDesignClassManager;
|
|
|
|
import com.fr.design.actions.AllowAuthorityEditAction;
|
|
|
|
import com.fr.design.actions.ExitAuthorityEditAction;
|
|
|
|
import com.fr.design.actions.UpdateAction;
|
|
|
|
import com.fr.design.actions.cell.BorderAction;
|
|
|
|
import com.fr.design.actions.cell.CleanAuthorityAction;
|
|
|
|
import com.fr.design.actions.cell.style.AlignmentAction;
|
|
|
|
import com.fr.design.actions.cell.style.ReportFontBoldAction;
|
|
|
|
import com.fr.design.actions.cell.style.ReportFontForegroundAction;
|
|
|
|
import com.fr.design.actions.cell.style.ReportFontItalicAction;
|
|
|
|
import com.fr.design.actions.cell.style.ReportFontNameAction;
|
|
|
|
import com.fr.design.actions.cell.style.ReportFontSizeAction;
|
|
|
|
import com.fr.design.actions.cell.style.ReportFontUnderlineAction;
|
|
|
|
import com.fr.design.actions.cell.style.StyleBackgroundAction;
|
|
|
|
import com.fr.design.actions.columnrow.CancelColumnAction;
|
|
|
|
import com.fr.design.actions.columnrow.CancelRowAction;
|
|
|
|
import com.fr.design.actions.columnrow.ColumnHideAction;
|
|
|
|
import com.fr.design.actions.columnrow.ColumnWidthAction;
|
|
|
|
import com.fr.design.actions.columnrow.DeleteColumnAction;
|
|
|
|
import com.fr.design.actions.columnrow.DeleteRowAction;
|
|
|
|
import com.fr.design.actions.columnrow.FootColumnAction;
|
|
|
|
import com.fr.design.actions.columnrow.FootRowAction;
|
|
|
|
import com.fr.design.actions.columnrow.HeadColumnAction;
|
|
|
|
import com.fr.design.actions.columnrow.HeadRowAction;
|
|
|
|
import com.fr.design.actions.columnrow.InsertColumnAction;
|
|
|
|
import com.fr.design.actions.columnrow.InsertRowAction;
|
|
|
|
import com.fr.design.actions.columnrow.ResetColumnHideAction;
|
|
|
|
import com.fr.design.actions.columnrow.ResetRowHideAction;
|
|
|
|
import com.fr.design.actions.columnrow.RowHeightAction;
|
|
|
|
import com.fr.design.actions.columnrow.RowHideAction;
|
|
|
|
import com.fr.design.actions.core.ActionFactory;
|
|
|
|
import com.fr.design.actions.edit.CopyAction;
|
|
|
|
import com.fr.design.actions.edit.CutAction;
|
|
|
|
import com.fr.design.actions.edit.PasteAction;
|
|
|
|
import com.fr.design.actions.edit.merge.MergeCellAction;
|
|
|
|
import com.fr.design.actions.edit.merge.UnmergeCellAction;
|
|
|
|
import com.fr.design.cell.bar.DynamicScrollBar;
|
|
|
|
import com.fr.design.cell.clipboard.CellElementsClip;
|
|
|
|
import com.fr.design.cell.clipboard.ElementsTransferable;
|
|
|
|
import com.fr.design.cell.clipboard.FloatElementsClip;
|
|
|
|
import com.fr.design.cell.editor.*;
|
|
|
|
import com.fr.design.constants.UIConstants;
|
|
|
|
import com.fr.design.designer.EditingState;
|
|
|
|
import com.fr.design.designer.TargetComponent;
|
|
|
|
import com.fr.design.file.HistoryTemplateListPane;
|
|
|
|
import com.fr.design.fun.ElementUIProvider;
|
|
|
|
import com.fr.design.gui.ibutton.UIButton;
|
|
|
|
import com.fr.design.gui.imenu.UIPopupMenu;
|
|
|
|
import com.fr.design.mainframe.cell.QuickEditorRegion;
|
|
|
|
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
|
|
|
|
import com.fr.design.menu.KeySetUtils;
|
|
|
|
import com.fr.design.menu.MenuDef;
|
|
|
|
import com.fr.design.menu.NameSeparator;
|
|
|
|
import com.fr.design.menu.ShortCut;
|
|
|
|
import com.fr.design.menu.ToolBarDef;
|
|
|
|
import com.fr.design.selection.QuickEditor;
|
|
|
|
import com.fr.design.selection.Selectedable;
|
|
|
|
import com.fr.design.selection.SelectionEvent;
|
|
|
|
import com.fr.design.selection.SelectionListener;
|
|
|
|
import com.fr.general.ComparatorUtils;
|
|
|
|
import com.fr.general.FRLogger;
|
|
|
|
import com.fr.general.Inter;
|
|
|
|
import com.fr.grid.Grid;
|
|
|
|
import com.fr.grid.GridColumn;
|
|
|
|
import com.fr.grid.GridCorner;
|
|
|
|
import com.fr.grid.GridRow;
|
|
|
|
import com.fr.grid.GridUtils;
|
|
|
|
import com.fr.grid.dnd.ElementCasePaneDropTarget;
|
|
|
|
import com.fr.grid.selection.CellSelection;
|
|
|
|
import com.fr.grid.selection.Selection;
|
|
|
|
import com.fr.page.PageAttributeGetter;
|
|
|
|
import com.fr.page.ReportPageAttrProvider;
|
|
|
|
import com.fr.poly.creator.PolyElementCasePane;
|
|
|
|
import com.fr.report.ReportHelper;
|
|
|
|
import com.fr.report.cell.DefaultTemplateCellElement;
|
|
|
|
import com.fr.report.cell.FloatElement;
|
|
|
|
import com.fr.report.cell.TemplateCellElement;
|
|
|
|
import com.fr.report.cell.cellattr.core.RichText;
|
|
|
|
import com.fr.report.cell.cellattr.core.SubReport;
|
|
|
|
import com.fr.report.cell.cellattr.core.group.DSColumn;
|
|
|
|
import com.fr.report.cell.painter.BiasTextPainter;
|
|
|
|
import com.fr.report.core.SheetUtils;
|
|
|
|
import com.fr.report.elementcase.ElementCase;
|
|
|
|
import com.fr.report.elementcase.TemplateElementCase;
|
|
|
|
import com.fr.stable.ArrayUtils;
|
|
|
|
import com.fr.stable.ColumnRow;
|
|
|
|
import com.fr.stable.Constants;
|
|
|
|
import com.fr.stable.unit.FU;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This class used to edit Report.
|
|
|
|
*/
|
|
|
|
public abstract class ElementCasePane<T extends TemplateElementCase> extends TargetComponent<T> implements Selectedable<Selection>, PageAttributeGetter {
|
|
|
|
|
|
|
|
public static enum Clear {
|
|
|
|
ALL, FORMATS, CONTENTS, WIDGETS
|
|
|
|
}
|
|
|
|
|
|
|
|
public static final int NO_OVER = 0;
|
|
|
|
public static final int HORIZONTAL_OVER = 1;
|
|
|
|
public static final int VERTICAL_OVER = 2;
|
|
|
|
|
|
|
|
// alex:既可以是选中一片单元格,也可以是选中一个悬浮元素
|
|
|
|
//august:默认是个不存在的选择。方便初始化时触发GridSelectionChangeListener事件
|
|
|
|
private Selection selection = new CellSelection(-1, -1, -1, -1);
|
|
|
|
|
|
|
|
// alex:
|
|
|
|
private boolean supportDefaultParentCalculate = false;
|
|
|
|
// GUI.
|
|
|
|
private Grid grid;
|
|
|
|
private GridRow gridRow;
|
|
|
|
private GridColumn gridColumn;
|
|
|
|
private GridCorner gridCorner;
|
|
|
|
private JScrollBar verScrollBar;
|
|
|
|
private JScrollBar horScrollBar;
|
|
|
|
// Visible
|
|
|
|
private boolean columnHeaderVisible = true;
|
|
|
|
private boolean rowHeaderVisible = true;
|
|
|
|
private boolean verticalScrollBarVisible = true;
|
|
|
|
private boolean horizontalScrollBarVisible = true;
|
|
|
|
|
|
|
|
private int resolution;
|
|
|
|
protected UIButton formatBrush = null;
|
|
|
|
|
|
|
|
private CellSelection formatReferencedCell = null;
|
|
|
|
private CellSelection cellNeedTOFormat = null;
|
|
|
|
private FormatBrushAction formatBrushAction;
|
|
|
|
ActionListener keyListener = new ActionListener() {
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
if (!formatBrush.isSelected()) {
|
|
|
|
DesignerContext.setFormatState(DesignerContext.FORMAT_STATE_ONCE);
|
|
|
|
DesignerContext.setReferencedElementCasePane(ElementCasePane.this);
|
|
|
|
DesignerContext.setReferencedIndex(
|
|
|
|
((JWorkBook) HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()).getEditingReportIndex());
|
|
|
|
formatBrush.setSelected(true);
|
|
|
|
formatBrushAction.executeActionReturnUndoRecordNeeded();
|
|
|
|
} else {
|
|
|
|
cancelFormatBrush();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
ActionListener escKey = new ActionListener() {
|
|
|
|
public void actionPerformed(ActionEvent e) {
|
|
|
|
cancelFormatBrush();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor.
|
|
|
|
*/
|
|
|
|
public ElementCasePane(T t) {
|
|
|
|
super(t);
|
|
|
|
// marks:能触发processEvent,不管是否给component增加listener。这里是使在reportPane中的任意位置滑动鼠标轮都能
|
|
|
|
// 下拉grid。
|
|
|
|
enableEvents(AWTEvent.MOUSE_WHEEL_EVENT_MASK);
|
|
|
|
this.initComponents();
|
|
|
|
|
|
|
|
new ElementCasePaneDropTarget(this);
|
|
|
|
this.setFocusTraversalKeysEnabled(false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 取消格式化
|
|
|
|
*/
|
|
|
|
public void cancelFormat() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void initComponents() {
|
|
|
|
this.setLayout(new RGridLayout());
|
|
|
|
|
|
|
|
this.resolution = ScreenResolution.getScreenResolution();
|
|
|
|
|
|
|
|
this.initGridComponent();
|
|
|
|
|
|
|
|
this.grid.setElementCasePane(this);
|
|
|
|
this.gridColumn.setElementCasePane(this);
|
|
|
|
this.gridRow.setElementCasePane(this);
|
|
|
|
this.gridCorner.setElementCasePane(this);
|
|
|
|
|
|
|
|
this.add(RGridLayout.GridCorner, this.gridCorner);
|
|
|
|
this.add(RGridLayout.GridColumn, this.gridColumn);
|
|
|
|
this.add(RGridLayout.GridRow, this.gridRow);
|
|
|
|
this.add(RGridLayout.Grid, this.grid);
|
|
|
|
|
|
|
|
// ScrollBar
|
|
|
|
verScrollBar = new DynamicScrollBar(Adjustable.VERTICAL, this, this.resolution);
|
|
|
|
horScrollBar = new DynamicScrollBar(Adjustable.HORIZONTAL, this, this.resolution);
|
|
|
|
this.add(RGridLayout.VerticalBar, this.verScrollBar);
|
|
|
|
// this.add(RGridLayout.HorizontalBar, this.horScrollBar);
|
|
|
|
|
|
|
|
// Init input/action map defaultly.
|
|
|
|
initInputActionMap();
|
|
|
|
|
|
|
|
// 设置最小的尺寸,方便 ScrollPane.
|
|
|
|
this.setMinimumSize(new Dimension(0, 0));
|
|
|
|
|
|
|
|
// alex:初始化Editors
|
|
|
|
initDefaultEditors();
|
|
|
|
initFormatBrush();
|
|
|
|
}
|
|
|
|
|
|
|
|
public int getMenuState() {
|
|
|
|
return DesignState.WORK_SHEET;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected void initFormatBrush() {
|
|
|
|
formatBrushAction = new FormatBrushAction(this);
|
|
|
|
formatBrush = (UIButton) formatBrushAction.createToolBarComponent();
|
|
|
|
formatBrush.setSelected(DesignerContext.getFormatState() != DesignerContext.FORMAT_STATE_NULL);
|
|
|
|
formatBrush.removeActionListener(formatBrushAction);
|
|
|
|
formatBrush.addMouseListener(new MouseAdapter() {
|
|
|
|
public void mouseClicked(MouseEvent e) {
|
|
|
|
//如果没有格式刷,点击时就是想使用格式刷
|
|
|
|
if (e.getClickCount() == 1) {
|
|
|
|
if (!formatBrush.isSelected()) {
|
|
|
|
DesignerContext.setFormatState(DesignerContext.FORMAT_STATE_ONCE);
|
|
|
|
DesignerContext.setReferencedElementCasePane(ElementCasePane.this);
|
|
|
|
DesignerContext.setReferencedIndex(
|
|
|
|
((JTemplate) HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()).getEditingReportIndex());
|
|
|
|
formatBrush.setSelected(true);
|
|
|
|
formatBrushAction.executeActionReturnUndoRecordNeeded();
|
|
|
|
} else {
|
|
|
|
cancelFormatBrush();
|
|
|
|
}
|
|
|
|
|
|
|
|
} else if (e.getClickCount() == 2) {
|
|
|
|
if (!formatBrush.isSelected()) {
|
|
|
|
formatBrush.setSelected(true);
|
|
|
|
}
|
|
|
|
DesignerContext.setFormatState(DesignerContext.FORMAT_STATE_MORE);
|
|
|
|
DesignerContext.setReferencedElementCasePane(ElementCasePane.this);
|
|
|
|
DesignerContext.setReferencedIndex(
|
|
|
|
((JTemplate) HistoryTemplateListPane.getInstance().getCurrentEditingTemplate()).getEditingReportIndex());
|
|
|
|
formatBrush.setSelected(true);
|
|
|
|
formatBrushAction.executeActionReturnUndoRecordNeeded();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
formatBrush.registerKeyboardAction(keyListener, KeyStroke.getKeyStroke(KeyEvent.VK_B, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
|
|
|
formatBrush.registerKeyboardAction(escKey, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 取消格式刷
|
|
|
|
*/
|
|
|
|
public void cancelFormatBrush() {
|
|
|
|
//如果正在使用格式刷,点击就是想退出格式刷
|
|
|
|
setFormatState(DesignerContext.FORMAT_STATE_NULL);
|
|
|
|
formatBrush.setSelected(false);
|
|
|
|
grid.setCursor(UIConstants.CELL_DEFAULT_CURSOR);
|
|
|
|
if(DesignerContext.getReferencedElementCasePane() == null){
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setNotShowingTableSelectPane(true);
|
|
|
|
((ElementCasePane) DesignerContext.getReferencedElementCasePane()).getGrid().setCursor(UIConstants.CELL_DEFAULT_CURSOR);
|
|
|
|
DesignerContext.setReferencedElementCasePane(null);
|
|
|
|
DesignerContext.setReferencedIndex(0);
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
public UIButton getFormatBrush() {
|
|
|
|
return formatBrush;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setFormatState(int formatState) {
|
|
|
|
DesignerContext.setFormatState(formatState);
|
|
|
|
if (formatState == DesignerContext.FORMAT_STATE_NULL) {
|
|
|
|
cellNeedTOFormat = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public JPanel getEastUpPane() {
|
|
|
|
return new JPanel();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public JPanel getEastDownPane() {
|
|
|
|
return new JPanel();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public FormatBrushAction getFormatBrushAction() {
|
|
|
|
return formatBrushAction;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void initGridComponent() {
|
|
|
|
// Components
|
|
|
|
if (this.grid == null) {
|
|
|
|
this.grid = new Grid(this.resolution);
|
|
|
|
}
|
|
|
|
if (this.gridColumn == null) {
|
|
|
|
this.gridColumn = new GridColumn();
|
|
|
|
}
|
|
|
|
if (this.gridRow == null) {
|
|
|
|
this.gridRow = new GridRow();
|
|
|
|
}
|
|
|
|
if (this.gridCorner == null) {
|
|
|
|
this.gridCorner = new GridCorner();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 所有的操作都必须在可见范围内,否则不做任何操作
|
|
|
|
*
|
|
|
|
* @return true 必须在可见范围内.
|
|
|
|
*/
|
|
|
|
public boolean mustInVisibleRange() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 初始化默认的Editor
|
|
|
|
*/
|
|
|
|
private void initDefaultEditors() {
|
|
|
|
Grid grid = this.getGrid();
|
|
|
|
grid.setDefaultCellEditor(DSColumn.class, new DSColumnCellEditor(this));
|
|
|
|
grid.setDefaultCellEditor(Formula.class, new FormulaCellEditor(this));
|
|
|
|
grid.setDefaultCellEditor(RichText.class, new RichTextCellEditor(this));
|
|
|
|
|
|
|
|
grid.setDefaultCellEditor(BiasTextPainter.class, new BiasTextPainterCellEditor(this));
|
|
|
|
grid.setDefaultCellEditor(Image.class, new ImageCellEditor(this));
|
|
|
|
grid.setDefaultCellEditor(SubReport.class, new SubReportCellEditor(this));
|
|
|
|
|
|
|
|
Class chartClass = ActionFactory.getChartCollectionClass();
|
|
|
|
if (chartClass != null) {
|
|
|
|
grid.setDefaultCellEditor(chartClass, new ChartCellEditor(this));
|
|
|
|
grid.setDefaultFloatEditor(chartClass, new ChartFloatEditor());
|
|
|
|
}
|
|
|
|
|
|
|
|
addExtraCellEditor(grid);
|
|
|
|
|
|
|
|
grid.setDefaultFloatEditor(Formula.class, new FormulaFloatEditor());
|
|
|
|
grid.setDefaultFloatEditor(Image.class, new ImageFloatEditor());
|
|
|
|
|
|
|
|
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager();
|
|
|
|
grid.setGridLineColor(designerEnvManager.getGridLineColor());
|
|
|
|
grid.setPaginationLineColor(designerEnvManager.getPaginationLineColor());
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addExtraCellEditor(Grid grid) {
|
|
|
|
Set<ElementUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ElementUIProvider.MARK_STRING);
|
|
|
|
for (ElementUIProvider provider : providers) {
|
|
|
|
CellEditor editor = null;
|
|
|
|
Class<?> clazz = provider.targetCellEditorClass();
|
|
|
|
Constructor<?> c;
|
|
|
|
try {
|
|
|
|
c = clazz.getConstructor();
|
|
|
|
editor = (CellEditor) c.newInstance();
|
|
|
|
} catch (NoSuchMethodException e) {
|
|
|
|
try {
|
|
|
|
c = clazz.getConstructor(ElementCase.class);
|
|
|
|
editor = (CellEditor) c.newInstance(this);
|
|
|
|
} catch (Exception e1) {
|
|
|
|
FRLogger.getLogger().error(e1.getMessage(), e1);
|
|
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
|
|
FRLogger.getLogger().error(e.getMessage(), e);
|
|
|
|
}
|
|
|
|
grid.setDefaultCellEditor(provider.targetObjectClass(), editor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 返回当前正在编辑的模板单元格组件
|
|
|
|
*/
|
|
|
|
public final TemplateElementCase getEditingElementCase() {
|
|
|
|
return this.getTarget();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the cell table of rpt pane. Grid implement the the most
|
|
|
|
* functionalities of table.
|
|
|
|
*/
|
|
|
|
public Grid getGrid() {
|
|
|
|
return this.grid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the column header of cell table.
|
|
|
|
*/
|
|
|
|
public GridColumn getGridColumn() {
|
|
|
|
return this.gridColumn;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the row header of cell table.
|
|
|
|
*/
|
|
|
|
public GridRow getGridRow() {
|
|
|
|
return this.gridRow;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the left top corner of cell table
|
|
|
|
*/
|
|
|
|
public GridCorner getGridCorner() {
|
|
|
|
return this.gridCorner;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets vertical scroll bar
|
|
|
|
*/
|
|
|
|
public JScrollBar getVerticalScrollBar() {
|
|
|
|
return this.verScrollBar;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets horizontal scroll bar
|
|
|
|
*/
|
|
|
|
public JScrollBar getHorizontalScrollBar() {
|
|
|
|
return this.horScrollBar;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否支持默认计算父格
|
|
|
|
*
|
|
|
|
* @return 是则返回true
|
|
|
|
*/
|
|
|
|
public boolean isSupportDefaultParentCalculate() {
|
|
|
|
return supportDefaultParentCalculate;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets whether to support auto calculate default parent
|
|
|
|
*
|
|
|
|
* @param supportDefaultParentCalculate whether to support auto calculate default parent.
|
|
|
|
*/
|
|
|
|
public void setSupportDefaultParentCalculate(boolean supportDefaultParentCalculate) {
|
|
|
|
this.supportDefaultParentCalculate = supportDefaultParentCalculate;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 转换选择
|
|
|
|
*
|
|
|
|
* @return 转换
|
|
|
|
*/
|
|
|
|
public ElementsTransferable transferSelection() {
|
|
|
|
ElementsTransferable elementsTransferable = new ElementsTransferable();
|
|
|
|
|
|
|
|
this.selection.asTransferable(elementsTransferable, this);
|
|
|
|
|
|
|
|
return elementsTransferable;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
public QuickEditor getCurrentEditor() {
|
|
|
|
return this.selection.getQuickEditor(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
/**
|
|
|
|
* 加下面的判断是因为聚合报表>>添加报表聚合块>>选中B1单元格>>再选中该聚合块>>再选中B1单元格,发现属性表右下侧还是现实的聚合块的属性
|
|
|
|
* 因为这边判断selection是一个selection,所以不会触发fireSelectionChanged
|
|
|
|
*/
|
|
|
|
public void setSelection(Selection selection) {
|
|
|
|
if (!ComparatorUtils.equals(this.selection, selection) ||
|
|
|
|
!ComparatorUtils.equals(EastRegionContainerPane.getInstance().getDownPane(), CellElementPropertyPane.getInstance())) {
|
|
|
|
this.selection = selection;
|
|
|
|
fireSelectionChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void setOldSelecton(Selection selection) {
|
|
|
|
this.selection = selection;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void setFormatReferencedCell(CellSelection cellSelection) {
|
|
|
|
this.formatReferencedCell = cellSelection;
|
|
|
|
getOldStyles(formatReferencedCell);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void getOldStyles(CellSelection oldSelection) {
|
|
|
|
Style[][] referencedStyle = new Style[formatReferencedCell.getColumnSpan()][formatReferencedCell.getRowSpan()];
|
|
|
|
int cellRectangleCount = oldSelection.getCellRectangleCount();
|
|
|
|
TemplateElementCase elementCase = getEditingElementCase();
|
|
|
|
for (int rect = 0; rect < cellRectangleCount; rect++) {
|
|
|
|
Rectangle cellRectangle = oldSelection.getCellRectangle(rect);
|
|
|
|
for (int j = 0; j < cellRectangle.height; j++) {
|
|
|
|
for (int i = 0; i < cellRectangle.width; i++) {
|
|
|
|
int column = i + cellRectangle.x;
|
|
|
|
int row = j + cellRectangle.y;
|
|
|
|
TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row);
|
|
|
|
if (cellElement == null) {
|
|
|
|
cellElement = new DefaultTemplateCellElement(column, row);
|
|
|
|
elementCase.addCellElement(cellElement);
|
|
|
|
}
|
|
|
|
Style style = cellElement.getStyle();
|
|
|
|
if (style == null) {
|
|
|
|
style = style.DEFAULT_STYLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
referencedStyle[i][j] = style;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DesignerContext.setReferencedStyle(referencedStyle);
|
|
|
|
}
|
|
|
|
|
|
|
|
public CellSelection getFormatReferencedCell() {
|
|
|
|
return this.formatReferencedCell;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
public Selection getSelection() {
|
|
|
|
return selection;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否只选中了一个单元格
|
|
|
|
*
|
|
|
|
* @return 是则返回true
|
|
|
|
*/
|
|
|
|
public boolean isSelectedOneCell() {
|
|
|
|
return selection.isSelectedOneCell(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 停止编辑
|
|
|
|
*/
|
|
|
|
public void stopEditing() {
|
|
|
|
this.getGrid().stopEditing();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 剪切
|
|
|
|
*
|
|
|
|
* @return 成功返回true
|
|
|
|
*/
|
|
|
|
public boolean cut() {
|
|
|
|
this.copy();
|
|
|
|
|
|
|
|
return this.clearAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 复制
|
|
|
|
*/
|
|
|
|
public void copy() {
|
|
|
|
// p:Elements Transferable.
|
|
|
|
ElementsTransferable elementsTransferable = this.transferSelection();
|
|
|
|
|
|
|
|
// peter:这个地方产生String序列,方便从FR当中copy数据到Excel当中.
|
|
|
|
Object firstObject = elementsTransferable.getFirstObject();
|
|
|
|
if (firstObject instanceof CellElementsClip) {
|
|
|
|
elementsTransferable.addObject(((CellElementsClip) firstObject).compateExcelPaste());
|
|
|
|
}
|
|
|
|
|
|
|
|
// p:加到Clipboard里面去.
|
|
|
|
Clipboard clipboard = DesignerContext.getClipboard(this.getGrid());
|
|
|
|
|
|
|
|
clipboard.setContents(elementsTransferable, elementsTransferable);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 黏贴
|
|
|
|
*
|
|
|
|
* @return 成功返回 true
|
|
|
|
*/
|
|
|
|
public boolean paste() {
|
|
|
|
if (!this.isEditable()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Object clipObject = getClipObject();
|
|
|
|
//如果是悬浮元素,则不允许粘贴到表单
|
|
|
|
if (!DesignerContext.getDesignerFrame().getSelectedJTemplate().accept(clipObject)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (clipObject instanceof FloatElementsClip) {
|
|
|
|
return this.selection.pasteFloatElementClip((FloatElementsClip) clipObject, this);
|
|
|
|
} else if (clipObject instanceof CellElementsClip) {
|
|
|
|
return this.selection.pasteCellElementsClip((CellElementsClip) clipObject, this);
|
|
|
|
} else if (clipObject instanceof String) {
|
|
|
|
return this.selection.pasteString((String) clipObject, this);
|
|
|
|
} else {
|
|
|
|
return this.selection.pasteOtherType(clipObject, this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private Object getClipObject() {
|
|
|
|
// 需要检查是否可以编辑。
|
|
|
|
Clipboard clipboard = DesignerContext.getClipboard(this.getGrid());
|
|
|
|
Transferable clipData = clipboard.getContents(this);
|
|
|
|
if (clipData == null) {// 剪贴板里面没有值,直接返回.
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
Object clipObject;
|
|
|
|
try {
|
|
|
|
clipObject = ElementsTransferable.getElementNotStringTransderData(clipData);
|
|
|
|
} catch (Exception exp) {
|
|
|
|
// p:如果是其他不支持的对象,会抛出Exception的,所以变成String。
|
|
|
|
// 所以这里不打印出Exception.
|
|
|
|
try {
|
|
|
|
clipObject = clipData.getTransferData(DataFlavor.stringFlavor);
|
|
|
|
} catch (Exception e) {
|
|
|
|
FRContext.getLogger().error(e.getMessage(), e);
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return clipObject;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 确认行列是否可见
|
|
|
|
*
|
|
|
|
* @param column 列序号
|
|
|
|
* @param row 行序号
|
|
|
|
* @return 类型
|
|
|
|
*/
|
|
|
|
public int ensureColumnRowVisible(int column, int row) {
|
|
|
|
Grid grid = this.getGrid();
|
|
|
|
|
|
|
|
int verticalEndValue = grid.getVerticalValue() + grid.getVerticalExtent() + 1;
|
|
|
|
int horizontalEndValue = grid.getHorizontalValue() + grid.getHorizontalExtent() + 1;
|
|
|
|
|
|
|
|
int overtype = NO_OVER;
|
|
|
|
// 列.
|
|
|
|
if (grid.getHorizontalValue() > column) {
|
|
|
|
this.getHorizontalScrollBar().setValue(column);
|
|
|
|
} else if (horizontalEndValue < (column + 1)) {
|
|
|
|
if (this instanceof PolyElementCasePane) {
|
|
|
|
//如果是聚合块中的Gird,选在边界的时候,会报表会自动向右移
|
|
|
|
overtype += HORIZONTAL_OVER;
|
|
|
|
} else {
|
|
|
|
this.getHorizontalScrollBar().setValue(column - grid.getHorizontalExtent() + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 行.
|
|
|
|
if (grid.getVerticalValue() > row) {
|
|
|
|
this.getVerticalScrollBar().setValue(row);
|
|
|
|
} else if (verticalEndValue <= (row + 1)) {// p: +1是保证最后一行,不能显示半行.
|
|
|
|
if (this instanceof PolyElementCasePane) {
|
|
|
|
//如果是聚合块中的Gird,选在边界的时候,会报表会自动向下移
|
|
|
|
overtype += VERTICAL_OVER;
|
|
|
|
} else {
|
|
|
|
this.getVerticalScrollBar().setValue(row - grid.getVerticalExtent() + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return overtype;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 清空所有.
|
|
|
|
*
|
|
|
|
* @return 返回是否清除全部.
|
|
|
|
*/
|
|
|
|
public boolean clearAll() {
|
|
|
|
boolean b = this.selection.clear(Clear.ALL, this);
|
|
|
|
fireSelectionChanged();
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 清除格式.
|
|
|
|
*
|
|
|
|
* @return 返回是否清除格式.
|
|
|
|
*/
|
|
|
|
public boolean clearFormats() {
|
|
|
|
boolean b = this.selection.clear(Clear.FORMATS, this);
|
|
|
|
fireSelectionChanged();
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 清除内容
|
|
|
|
*
|
|
|
|
* @return 返回是否清除内容.
|
|
|
|
*/
|
|
|
|
public boolean clearContents() {
|
|
|
|
if (BaseUtils.isAuthorityEditing()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
boolean b = this.selection.clear(Clear.CONTENTS, this);
|
|
|
|
fireSelectionChanged();
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 清除控件
|
|
|
|
*
|
|
|
|
* @return 返回是否清除控件.
|
|
|
|
*/
|
|
|
|
public boolean clearWidget() {
|
|
|
|
boolean b = this.selection.clear(Clear.WIDGETS, this);
|
|
|
|
fireSelectionChanged();
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否能合并单元格
|
|
|
|
*
|
|
|
|
* @return 返回是否能合并单元格.
|
|
|
|
*/
|
|
|
|
public boolean canMergeCell() {
|
|
|
|
return this.selection.canMergeCells(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 合并单元格
|
|
|
|
*
|
|
|
|
* @return 成功返回true
|
|
|
|
*/
|
|
|
|
public boolean mergeCell() {
|
|
|
|
boolean b = this.selection.mergeCells(this);
|
|
|
|
fireSelectionChanged();
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否撤销合并单元格
|
|
|
|
*
|
|
|
|
* @return 返回是否撤销合并单元格.
|
|
|
|
*/
|
|
|
|
public boolean canUnMergeCell() {
|
|
|
|
return this.selection.canUnMergeCells(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 撤销合并单元格
|
|
|
|
*
|
|
|
|
* @return 成功返回true
|
|
|
|
*/
|
|
|
|
public boolean unMergeCell() {
|
|
|
|
boolean b = this.selection.unMergeCells(this);
|
|
|
|
fireSelectionChanged();
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fire gridSelection Changed
|
|
|
|
*/
|
|
|
|
private void fireSelectionChanged() {
|
|
|
|
this.fireSelectionChangeListener();
|
|
|
|
this.repaint(15);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 添加选中的SelectionListener
|
|
|
|
*
|
|
|
|
* @param selectionListener 选中的listener
|
|
|
|
*/
|
|
|
|
public void addSelectionChangeListener(SelectionListener selectionListener) {
|
|
|
|
this.listenerList.add(SelectionListener.class, selectionListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 删除选中的ChangeListener
|
|
|
|
*
|
|
|
|
* @param selectionListener 选中的listener
|
|
|
|
*/
|
|
|
|
public void removeSelectionChangeListener(SelectionListener selectionListener) {
|
|
|
|
this.listenerList.remove(SelectionListener.class, selectionListener);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 响应选中的ChangeListener
|
|
|
|
*/
|
|
|
|
public void fireSelectionChangeListener() {
|
|
|
|
// Guaranteed to return a non-null array
|
|
|
|
Object[] listeners = listenerList.getListenerList();
|
|
|
|
|
|
|
|
// Process the listeners last to first, notifying
|
|
|
|
// those that are interested in this event
|
|
|
|
for (int i = listeners.length - 2; i >= 0; i -= 2) {
|
|
|
|
if (listeners[i] == SelectionListener.class) {
|
|
|
|
((SelectionListener) listeners[i + 1]).selectionChanged(new SelectionEvent(this));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 响应目标变动.
|
|
|
|
*/
|
|
|
|
public void fireTargetModified() {
|
|
|
|
// marks:自动计算
|
|
|
|
TemplateElementCase report = this.getEditingElementCase();
|
|
|
|
|
|
|
|
// 计算父格
|
|
|
|
if (this.isSupportDefaultParentCalculate()) {
|
|
|
|
SheetUtils.calculateDefaultParent(report);
|
|
|
|
setSupportDefaultParentCalculate(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
super.fireTargetModified();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Init input/action map.
|
|
|
|
*/
|
|
|
|
protected void initInputActionMap() {
|
|
|
|
InputMap inputMapAncestor = this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
|
|
|
|
ActionMap actionMap = this.getActionMap();
|
|
|
|
// clearReportPage old values.
|
|
|
|
inputMapAncestor.clear();
|
|
|
|
actionMap.clear();
|
|
|
|
inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK), "cut");
|
|
|
|
actionMap.put("cut", new AbstractAction() {
|
|
|
|
public void actionPerformed(ActionEvent evt) {
|
|
|
|
if (cut()) {
|
|
|
|
fireTargetModified();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK), "copy");
|
|
|
|
actionMap.put("copy", new AbstractAction() {
|
|
|
|
public void actionPerformed(ActionEvent evt) {
|
|
|
|
copy();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK), "paste");
|
|
|
|
actionMap.put("paste", new AbstractAction() {
|
|
|
|
public void actionPerformed(ActionEvent evt) {
|
|
|
|
if (paste()) {
|
|
|
|
QuickEditorRegion.getInstance().populate(getCurrentEditor());
|
|
|
|
fireTargetModified();
|
|
|
|
QuickEditorRegion.getInstance().populate(getCurrentEditor());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "delete_content");
|
|
|
|
actionMap.put("delete_content", new AbstractAction() {
|
|
|
|
public void actionPerformed(ActionEvent evt) {
|
|
|
|
if (clearContents()) {
|
|
|
|
fireTargetModified();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_MASK), "delete_all");
|
|
|
|
actionMap.put("delete_all", new AbstractAction() {
|
|
|
|
public void actionPerformed(ActionEvent evt) {
|
|
|
|
if (clearAll()) {
|
|
|
|
fireTargetModified();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否列表头可见
|
|
|
|
*
|
|
|
|
* @return boolean 是否列表头可见.
|
|
|
|
*/
|
|
|
|
public boolean isColumnHeaderVisible() {
|
|
|
|
return this.columnHeaderVisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Makes the column visible or invisible.
|
|
|
|
*
|
|
|
|
* @param isColumnVisible true to make the column visible; false to make it invisible
|
|
|
|
*/
|
|
|
|
public void setColumnHeaderVisible(boolean isColumnVisible) {
|
|
|
|
this.columnHeaderVisible = isColumnVisible;
|
|
|
|
|
|
|
|
this.resizeAndRepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否行表头可见.
|
|
|
|
*
|
|
|
|
* @return boolean 是否行表头可见.
|
|
|
|
*/
|
|
|
|
public boolean isRowHeaderVisible() {
|
|
|
|
return this.rowHeaderVisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Makes the row visible or invisible.
|
|
|
|
*
|
|
|
|
* @param isRowVisible true to make the row visible; false to make it invisible
|
|
|
|
*/
|
|
|
|
public void setRowHeaderVisible(boolean isRowVisible) {
|
|
|
|
this.rowHeaderVisible = isRowVisible;
|
|
|
|
|
|
|
|
this.resizeAndRepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否垂直滚动条可见
|
|
|
|
*
|
|
|
|
* @return boolean 是否垂直滚动条可见.
|
|
|
|
*/
|
|
|
|
public boolean isVerticalScrollBarVisible() {
|
|
|
|
return verticalScrollBarVisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Makes the vertical scrollbar visible or invisible.
|
|
|
|
*
|
|
|
|
* @param verticalScrollBarVisible true to make the vertical scrollbar visible; false to make it
|
|
|
|
* invisible
|
|
|
|
*/
|
|
|
|
public void setVerticalScrollBarVisible(boolean verticalScrollBarVisible) {
|
|
|
|
this.verticalScrollBarVisible = verticalScrollBarVisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否水平滚动条可见.
|
|
|
|
*
|
|
|
|
* @return boolean 是否水平滚动条可见.
|
|
|
|
*/
|
|
|
|
public boolean isHorizontalScrollBarVisible() {
|
|
|
|
return horizontalScrollBarVisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Makes the horizontal scrollbar visible or invisible.
|
|
|
|
*
|
|
|
|
* @param horizontalScrollBarVisible true to make the horizontal scrollbar visible; false to make
|
|
|
|
* it invisible
|
|
|
|
*/
|
|
|
|
public void setHorizontalScrollBarVisible(boolean horizontalScrollBarVisible) {
|
|
|
|
this.horizontalScrollBarVisible = horizontalScrollBarVisible;
|
|
|
|
}
|
|
|
|
|
|
|
|
// //////////////////////////////Max Row and Column.
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 是否可编辑.
|
|
|
|
*
|
|
|
|
* @return boolean 是否可编辑.
|
|
|
|
*/
|
|
|
|
public boolean isEditable() {
|
|
|
|
return this.grid.isEditable();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets whether to editable.
|
|
|
|
*
|
|
|
|
* @param editable 是否可编辑.
|
|
|
|
*/
|
|
|
|
public void setEditable(boolean editable) {
|
|
|
|
this.grid.setEditable(editable);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 弹出列表.
|
|
|
|
*
|
|
|
|
* @return 弹出列表.
|
|
|
|
*/
|
|
|
|
public JPopupMenu createPopupMenu() {
|
|
|
|
return this.selection.createPopupMenu(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 弹出列表
|
|
|
|
*
|
|
|
|
* @param evt 鼠标的响应事件.
|
|
|
|
* @param selectedRows 选中的行..
|
|
|
|
* @return UIPopupMenu 返回行的列表
|
|
|
|
*/
|
|
|
|
public UIPopupMenu createRowPopupMenu(MouseEvent evt, int selectedRows) {
|
|
|
|
UIPopupMenu popupMenu = new UIPopupMenu();
|
|
|
|
if (BaseUtils.isAuthorityEditing()) {
|
|
|
|
popupMenu.add(new CleanAuthorityAction(this).createMenuItem());
|
|
|
|
return popupMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
InsertRowAction insertRowAction = new InsertRowAction(this, Inter.getLocText("Utils-Insert_Row"));
|
|
|
|
|
|
|
|
DeleteRowAction deleteRowAction = new DeleteRowAction(this, Inter.getLocText("Utils-Delete_Row"));
|
|
|
|
|
|
|
|
RowHeightAction rowHeightAction = new RowHeightAction(this, selectedRows);
|
|
|
|
|
|
|
|
RowHideAction rowHideAction = new RowHideAction(this, selectedRows);
|
|
|
|
|
|
|
|
ResetRowHideAction resetRowHideAction = new ResetRowHideAction(this, selectedRows);
|
|
|
|
popupMenu.add(insertRowAction.createMenuItem());
|
|
|
|
popupMenu.add(deleteRowAction.createMenuItem());
|
|
|
|
popupMenu.addSeparator();
|
|
|
|
popupMenu.add(rowHeightAction.createMenuItem());
|
|
|
|
if (supportRepeatedHeaderFooter()) {
|
|
|
|
CellSelection cs = (CellSelection) this.getSelection();
|
|
|
|
addRowMenu(popupMenu, evt, cs.getRow(), cs.getRow() + cs.getRowSpan() - 1);
|
|
|
|
}
|
|
|
|
popupMenu.add(rowHideAction.createMenuItem());
|
|
|
|
popupMenu.add(resetRowHideAction.createMenuItem());
|
|
|
|
return popupMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addRowMenu(JPopupMenu popupMenu, MouseEvent evt, int selectedRowsFrom, int selectedRowsTo) {
|
|
|
|
HeadRowAction headrowAction = new HeadRowAction(this);
|
|
|
|
FootRowAction footrowAction = new FootRowAction(this);
|
|
|
|
|
|
|
|
ElementCase elementCase = this.getEditingElementCase();
|
|
|
|
boolean cancel = false;
|
|
|
|
ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(this, evt.getX(), evt.getY());
|
|
|
|
ReportPageAttrProvider reportPageAttr = elementCase.getReportPageAttr();
|
|
|
|
ElementCase report = this.getEditingElementCase();
|
|
|
|
if (reportPageAttr != null) {
|
|
|
|
popupMenu.addSeparator();
|
|
|
|
popupMenu.add(headrowAction.createMenuItem());
|
|
|
|
popupMenu.add(footrowAction.createMenuItem());
|
|
|
|
int from = report.getReportPageAttr().getRepeatHeaderRowFrom();
|
|
|
|
int to = report.getReportPageAttr().getRepeatHeaderRowTo();
|
|
|
|
int from2 = report.getReportPageAttr().getRepeatFooterRowFrom();
|
|
|
|
int to2 = report.getReportPageAttr().getRepeatFooterRowTo();
|
|
|
|
|
|
|
|
if (selectedCellPoint.getRow() >= selectedRowsFrom && selectedCellPoint.getRow() <= selectedRowsTo) {
|
|
|
|
|
|
|
|
cancel = isCancel(report, selectedRowsFrom, selectedRowsTo, from, to, from2, to2);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
int row = selectedCellPoint.getRow();
|
|
|
|
if (report.getReportPageAttr() != null) {
|
|
|
|
if (row == from || row == to || row == from2 || row == to2) {
|
|
|
|
cancel = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cancel) {
|
|
|
|
CancelRowAction cancelAction = new CancelRowAction(this);
|
|
|
|
popupMenu.add(cancelAction.createMenuItem());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isCancel(ElementCase report, int selectedColumnsFrom, int selectedColumnsTo, int from, int to, int from2, int to2) {
|
|
|
|
|
|
|
|
boolean cancel = false;
|
|
|
|
|
|
|
|
if (report.getReportPageAttr() != null) {
|
|
|
|
|
|
|
|
if (from == selectedColumnsFrom && to == selectedColumnsTo) {
|
|
|
|
cancel = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (from2 == selectedColumnsFrom && to2 == selectedColumnsTo) {
|
|
|
|
cancel = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cancel;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 弹出列表.
|
|
|
|
*
|
|
|
|
* @param evt 鼠标事件
|
|
|
|
* @param selectedColumn 选中的列.
|
|
|
|
* @return 弹出的列表.
|
|
|
|
*/
|
|
|
|
public UIPopupMenu createColumnPopupMenu(MouseEvent evt, int selectedColumn) {
|
|
|
|
UIPopupMenu popupMenu = new UIPopupMenu();
|
|
|
|
|
|
|
|
if (BaseUtils.isAuthorityEditing()) {
|
|
|
|
popupMenu.add(new CleanAuthorityAction(this).createMenuItem());
|
|
|
|
return popupMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
InsertColumnAction insertColumnAction = new InsertColumnAction(this, Inter.getLocText("Utils-Insert_Column"));
|
|
|
|
|
|
|
|
DeleteColumnAction deleteColumnAction = new DeleteColumnAction(this, Inter.getLocText("Utils-Delete_Column"));
|
|
|
|
|
|
|
|
ColumnWidthAction columnWidthAction = new ColumnWidthAction(this, selectedColumn);
|
|
|
|
|
|
|
|
ColumnHideAction columnHideAction = new ColumnHideAction(this, selectedColumn);
|
|
|
|
|
|
|
|
ResetColumnHideAction resetRowHideAction = new ResetColumnHideAction(this, selectedColumn);
|
|
|
|
popupMenu.add(insertColumnAction.createMenuItem());
|
|
|
|
popupMenu.add(deleteColumnAction.createMenuItem());
|
|
|
|
popupMenu.addSeparator();
|
|
|
|
popupMenu.add(columnWidthAction.createMenuItem());
|
|
|
|
|
|
|
|
if (supportRepeatedHeaderFooter()) {
|
|
|
|
CellSelection cs = (CellSelection) this.getSelection();
|
|
|
|
addColumnMenu(popupMenu, evt, cs.getColumn(), cs.getColumn() + cs.getColumnSpan() - 1);
|
|
|
|
}
|
|
|
|
popupMenu.add(columnHideAction.createMenuItem());
|
|
|
|
popupMenu.add(resetRowHideAction.createMenuItem());
|
|
|
|
|
|
|
|
return popupMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void addColumnMenu(UIPopupMenu popupMenu, MouseEvent evt, int selectedColumnsFrom, int selectedColumnsTo) {
|
|
|
|
HeadColumnAction headcolumnAction = new HeadColumnAction(this);
|
|
|
|
FootColumnAction footcolumnAction = new FootColumnAction(this);
|
|
|
|
|
|
|
|
ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow(this, evt.getX(), evt.getY());
|
|
|
|
ElementCase elementCase = this.getEditingElementCase();
|
|
|
|
boolean cancel = false;
|
|
|
|
ReportPageAttrProvider reportPageAttr = elementCase.getReportPageAttr();
|
|
|
|
|
|
|
|
if (reportPageAttr != null) {
|
|
|
|
popupMenu.addSeparator();
|
|
|
|
popupMenu.add(headcolumnAction.createMenuItem());
|
|
|
|
popupMenu.add(footcolumnAction.createMenuItem());
|
|
|
|
int from = reportPageAttr.getRepeatHeaderColumnFrom();
|
|
|
|
int to = reportPageAttr.getRepeatHeaderColumnTo();
|
|
|
|
int from2 = reportPageAttr.getRepeatFooterColumnFrom();
|
|
|
|
int to2 = reportPageAttr.getRepeatFooterColumnTo();
|
|
|
|
int column = selectedCellPoint.getColumn();
|
|
|
|
|
|
|
|
if (column >= selectedColumnsFrom && column <= selectedColumnsTo) {
|
|
|
|
cancel = isCancel(elementCase, selectedColumnsFrom, selectedColumnsTo, from, to, from2, to2);
|
|
|
|
} else {
|
|
|
|
|
|
|
|
if (elementCase.getReportPageAttr() != null) {
|
|
|
|
|
|
|
|
if (column == from || column == to || column == from2 || column == to2) {
|
|
|
|
cancel = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (cancel) {
|
|
|
|
CancelColumnAction cancelAction = new CancelColumnAction(this);
|
|
|
|
popupMenu.add(cancelAction.createMenuItem());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected abstract boolean supportRepeatedHeaderFooter();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 请求焦点
|
|
|
|
*/
|
|
|
|
public void requestFocus() {
|
|
|
|
super.requestFocus();
|
|
|
|
this.getGrid().requestFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Equivalent to <code>revalidate</code> followed by <code>repaint</code>.
|
|
|
|
*/
|
|
|
|
protected void resizeAndRepaint() {
|
|
|
|
revalidate();
|
|
|
|
repaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 模板menu
|
|
|
|
*
|
|
|
|
* @return 返回弹出列表数组.
|
|
|
|
*/
|
|
|
|
public ShortCut[] shortcut4TemplateMenu() {
|
|
|
|
return new ShortCut[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 权限细粒度状态下的菜单
|
|
|
|
*
|
|
|
|
* @return 菜单
|
|
|
|
*/
|
|
|
|
public ShortCut[] shortCuts4Authority() {
|
|
|
|
return new ShortCut[]{
|
|
|
|
new NameSeparator(Inter.getLocText(new String[]{"DashBoard-Potence", "Edit"})),
|
|
|
|
BaseUtils.isAuthorityEditing() ? new ExitAuthorityEditAction(this) : new AllowAuthorityEditAction(this),
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 目标的下列列表
|
|
|
|
*
|
|
|
|
* @return 返回MenuDef数组.
|
|
|
|
*/
|
|
|
|
public MenuDef[] menus4Target() {
|
|
|
|
return new MenuDef[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* kunsnat: 工具栏 快捷键菜单按钮. 最后位置为 "插入悬浮元素" 文本, 公式, 图表, 图片.
|
|
|
|
*
|
|
|
|
* @return 返回工具栏数组.
|
|
|
|
*/
|
|
|
|
public ToolBarDef[] toolbars4Target() {
|
|
|
|
return new ToolBarDef[]{
|
|
|
|
createFontToolBar(),
|
|
|
|
createAlignmentToolBar(),
|
|
|
|
createStyleToolBar(),
|
|
|
|
createCellToolBar(),
|
|
|
|
createInsertToolBar()};
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 表单下的工具按钮
|
|
|
|
*
|
|
|
|
* @return 工具按钮
|
|
|
|
*/
|
|
|
|
public JComponent[] toolBarButton4Form() {
|
|
|
|
formatBrush.setSelected(DesignerContext.getFormatState() != DesignerContext.FORMAT_STATE_NULL);
|
|
|
|
return new JComponent[]{new CutAction(this).createToolBarComponent(), new CopyAction(this).createToolBarComponent(),
|
|
|
|
new PasteAction(this).createToolBarComponent(), formatBrush};
|
|
|
|
}
|
|
|
|
|
|
|
|
protected ToolBarDef createFontToolBar() {
|
|
|
|
return ShortCut.asToolBarDef(new ShortCut[]{
|
|
|
|
new ReportFontNameAction(this),
|
|
|
|
new ReportFontSizeAction(this),
|
|
|
|
new ReportFontBoldAction(this),
|
|
|
|
new ReportFontItalicAction(this),
|
|
|
|
new ReportFontUnderlineAction(this),});
|
|
|
|
}
|
|
|
|
|
|
|
|
protected ToolBarDef createAlignmentToolBar() {
|
|
|
|
return ShortCut.asToolBarDef(new ShortCut[]{
|
|
|
|
new AlignmentAction(this, new Icon[]{
|
|
|
|
BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"),
|
|
|
|
BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"),
|
|
|
|
BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png")},
|
|
|
|
new Integer[]{Constants.LEFT, Constants.CENTER, Constants.RIGHT})}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected ToolBarDef createStyleToolBar() {
|
|
|
|
return ShortCut.asToolBarDef(new ShortCut[]{
|
|
|
|
new BorderAction(this),
|
|
|
|
new StyleBackgroundAction(this),
|
|
|
|
new ReportFontForegroundAction(this),});
|
|
|
|
}
|
|
|
|
|
|
|
|
protected ToolBarDef createCellToolBar() {
|
|
|
|
return ShortCut.asToolBarDef(new ShortCut[]{
|
|
|
|
new MergeCellAction(this),
|
|
|
|
new UnmergeCellAction(this),});
|
|
|
|
}
|
|
|
|
|
|
|
|
protected ToolBarDef createInsertToolBar() {
|
|
|
|
MenuDef insertFloatMenu = new MenuDef();
|
|
|
|
insertFloatMenu.setName(KeySetUtils.INSERT_FLOAT.getMenuKeySetName());
|
|
|
|
insertFloatMenu.setTooltip(Inter.getLocText("T_Insert-Float"));
|
|
|
|
insertFloatMenu.setIconPath("/com/fr/design/images/m_insert/floatPop.png");
|
|
|
|
|
|
|
|
UpdateAction[] actions = ActionFactory.createFloatInsertAction(ElementCasePane.class, this);
|
|
|
|
for (int i = 0; i < actions.length; i++) {
|
|
|
|
insertFloatMenu.addShortCut(actions[i]);
|
|
|
|
}
|
|
|
|
UpdateAction[] cellInsertActions = ActionFactory.createCellInsertAction(ElementCasePane.class, this);
|
|
|
|
ShortCut[] shortCuts = new ShortCut[cellInsertActions.length];
|
|
|
|
System.arraycopy(cellInsertActions, 0, shortCuts, 0, cellInsertActions.length);
|
|
|
|
return ShortCut.asToolBarDef((ShortCut[]) ArrayUtils.add(shortCuts, insertFloatMenu));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 创建权限犀利段编辑面板
|
|
|
|
*
|
|
|
|
* @return 面板
|
|
|
|
*/
|
|
|
|
public AuthorityEditPane createAuthorityEditPane() {
|
|
|
|
return new ElementCasePaneAuthorityEditPane(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
public ToolBarMenuDockPlus getToolBarMenuDockPlus() {
|
|
|
|
return new JWorkBook();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 创建正在编辑的状态.
|
|
|
|
*
|
|
|
|
* @return 返回正在编辑的状态.
|
|
|
|
*/
|
|
|
|
public EditingState createEditingState() {
|
|
|
|
return new ElementCaseEditingState(this.selection, this.verScrollBar.getValue(), this.horScrollBar.getValue());
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setCellNeedTOFormat(CellSelection selection) {
|
|
|
|
cellNeedTOFormat = selection;
|
|
|
|
}
|
|
|
|
|
|
|
|
public CellSelection getCellNeedTOFormat() {
|
|
|
|
return cellNeedTOFormat;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private class ElementCaseEditingState implements EditingState {
|
|
|
|
protected Selection selection;
|
|
|
|
protected int verticalValue = 0;
|
|
|
|
protected int horizontalValue = 0;
|
|
|
|
|
|
|
|
protected ElementCaseEditingState(Selection selection, int verticalValue, int horizontalValue) {
|
|
|
|
try {
|
|
|
|
this.selection = selection.clone();
|
|
|
|
} catch (CloneNotSupportedException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
this.verticalValue = verticalValue;
|
|
|
|
this.horizontalValue = horizontalValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void revert() {
|
|
|
|
try {
|
|
|
|
ElementCasePane.this.selection = this.selection.clone();
|
|
|
|
ElementCasePane.this.fireSelectionChangeListener();
|
|
|
|
} catch (CloneNotSupportedException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
ElementCasePane.this.getVerticalScrollBar().setValue(this.verticalValue);
|
|
|
|
ElementCasePane.this.getHorizontalScrollBar().setValue(this.horizontalValue);
|
|
|
|
|
|
|
|
// 重绘.
|
|
|
|
ElementCasePane.this.repaint();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 增加悬浮元素在面板中
|
|
|
|
*
|
|
|
|
* @param floatElement 元素
|
|
|
|
*/
|
|
|
|
public void addFloatElementToCenterOfElementPane(FloatElement floatElement) {
|
|
|
|
ElementCase report = this.getEditingElementCase();
|
|
|
|
// 500, 270
|
|
|
|
long floatWidth = floatElement.getWidth().toFU();
|
|
|
|
long floatHeight = floatElement.getHeight().toFU();
|
|
|
|
|
|
|
|
int horizontalValue = this.getGrid().getHorizontalValue();
|
|
|
|
int horizontalExtent = this.getGrid().getHorizontalExtent();
|
|
|
|
int verticalValue = this.getGrid().getVerticalValue();
|
|
|
|
int verticalExtent = this.getGrid().getVerticalExtent();
|
|
|
|
|
|
|
|
DynamicUnitList columnWidthList = ReportHelper.getColumnWidthList(report);
|
|
|
|
DynamicUnitList rowHeightList = ReportHelper.getRowHeightList(report);
|
|
|
|
|
|
|
|
long totalWidth = columnWidthList.getRangeValue(horizontalValue, horizontalValue + horizontalExtent).toFU() - floatWidth;
|
|
|
|
long totalHeight = rowHeightList.getRangeValue(verticalValue, verticalValue + verticalExtent).toFU() - floatHeight;
|
|
|
|
|
|
|
|
int columnIndex = horizontalValue;
|
|
|
|
long leftDistance = 0;
|
|
|
|
int rowIndex = verticalValue;
|
|
|
|
long topDistance = 0;
|
|
|
|
if (totalWidth > 0) {
|
|
|
|
int tmpTotalValue = 0;
|
|
|
|
while (true) {
|
|
|
|
tmpTotalValue += columnWidthList.get(columnIndex).toFU();
|
|
|
|
if (tmpTotalValue > totalWidth / 2) {
|
|
|
|
leftDistance = tmpTotalValue - totalWidth / 2 - columnWidthList.get(columnIndex).toFU();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
columnIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (totalHeight > 0) {
|
|
|
|
int tmpTotalValue = 0;
|
|
|
|
while (true) {
|
|
|
|
tmpTotalValue += rowHeightList.get(rowIndex).toFU();
|
|
|
|
if (tmpTotalValue > totalHeight / 2) {
|
|
|
|
topDistance = tmpTotalValue - totalHeight / 2 - rowHeightList.get(rowIndex).toFU();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rowIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
floatElement.setLeftDistance(FU.getInstance(Math.max(leftDistance, 0)));
|
|
|
|
floatElement.setTopDistance(FU.getInstance(Math.max(topDistance, 0)));
|
|
|
|
floatElement.setWidth(FU.getInstance(floatWidth));
|
|
|
|
floatElement.setHeight(FU.getInstance(floatHeight));
|
|
|
|
|
|
|
|
report.addFloatElement(floatElement);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|