/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2017 Serge Rider (serge@jkiss.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jkiss.dbeaver.ext.erd.editor;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.draw2d.*;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.*;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.palette.*;
import org.eclipse.gef.requests.CreationFactory;
import org.eclipse.gef.ui.actions.*;
import org.eclipse.gef.ui.palette.FlyoutPaletteComposite.FlyoutPreferences;
import org.eclipse.gef.ui.palette.PaletteViewerProvider;
import org.eclipse.gef.ui.parts.GraphicalEditorWithFlyoutPalette;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.gef.ui.properties.UndoablePropertySheetEntry;
import org.eclipse.jface.action.*;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.model.IWorkbenchAdapter;
import org.eclipse.ui.model.WorkbenchAdapter;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.PropertySheetPage;
import org.jkiss.dbeaver.Log;
import org.jkiss.dbeaver.core.DBeaverCore;
import org.jkiss.dbeaver.ext.erd.ERDActivator;
import org.jkiss.dbeaver.ext.erd.ERDConstants;
import org.jkiss.dbeaver.ext.erd.action.DiagramLayoutAction;
import org.jkiss.dbeaver.ext.erd.action.DiagramRefreshAction;
import org.jkiss.dbeaver.ext.erd.action.DiagramToggleGridAction;
import org.jkiss.dbeaver.ext.erd.action.ERDEditorPropertyTester;
import org.jkiss.dbeaver.ext.erd.directedit.StatusLineValidationMessageHandler;
import org.jkiss.dbeaver.ext.erd.dnd.DataEditDropTargetListener;
import org.jkiss.dbeaver.ext.erd.dnd.NodeDropTargetListener;
import org.jkiss.dbeaver.ext.erd.model.ERDNote;
import org.jkiss.dbeaver.ext.erd.model.EntityDiagram;
import org.jkiss.dbeaver.ext.erd.part.DiagramPart;
import org.jkiss.dbeaver.model.DBPDataSourceUser;
import org.jkiss.dbeaver.model.DBPNamedObject;
import org.jkiss.dbeaver.ui.*;
import org.jkiss.dbeaver.ui.controls.ProgressPageControl;
import org.jkiss.dbeaver.ui.controls.itemlist.ObjectSearcher;
import org.jkiss.dbeaver.ui.dialogs.DialogUtils;
import org.jkiss.utils.ArrayUtils;
import org.jkiss.utils.CommonUtils;
import java.io.FileOutputStream;
import java.util.*;
/**
* Editor implementation based on the the example editor skeleton that is built in <i>Building
* an editor </i> in chapter <i>Introduction to GEF </i>
*/
public abstract class ERDEditorPart extends GraphicalEditorWithFlyoutPalette
implements DBPDataSourceUser, ISearchContextProvider, IRefreshablePart
{
private static final Log log = Log.getLog(ERDEditorPart.class);
protected ProgressControl progressControl;
/**
* the undoable <code>IPropertySheetPage</code>
*/
private PropertySheetPage undoablePropertySheetPage;
/**
* the graphical viewer
*/
private ScalableFreeformRootEditPart rootPart;
/**
* the list of action ids that are to EditPart actions
*/
private List<String> editPartActionIDs = new ArrayList<>();
/**
* the overview outline page
*/
private ERDOutlinePage outlinePage;
/**
* the <code>EditDomain</code>
*/
private DefaultEditDomain editDomain;
/**
* the dirty state
*/
private boolean isDirty;
private boolean isLoaded;
protected LoadingJob<EntityDiagram> diagramLoadingJob;
private IPropertyChangeListener configPropertyListener;
private PaletteRoot paletteRoot;
/**
* No-arg constructor
*/
protected ERDEditorPart()
{
}
@Override
protected ERDGraphicalViewer getGraphicalViewer() {
return (ERDGraphicalViewer) super.getGraphicalViewer();
}
/**
* Initializes the editor.
*/
@Override
public void init(IEditorSite site, IEditorInput input) throws PartInitException
{
editDomain = new DefaultEditDomain(this);
setEditDomain(editDomain);
super.init(site, input);
// add selection change listener
//getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(this);
configPropertyListener = new ConfigPropertyListener();
ERDActivator.getDefault().getPreferenceStore().addPropertyChangeListener(configPropertyListener);
}
@Override
public void createPartControl(Composite parent)
{
progressControl = new ProgressControl(parent, SWT.SHEET);
progressControl.setShowDivider(true);
Composite contentContainer = progressControl.createContentContainer();
super.createPartControl(contentContainer);
progressControl.createProgressPanel();
}
/**
* The <code>CommandStackListener</code> that listens for
* <code>CommandStack </code> changes.
*/
@Override
public void commandStackChanged(EventObject event)
{
// Reevaluate properties
ActionUtils.evaluatePropertyState(ERDEditorPropertyTester.NAMESPACE + "." + ERDEditorPropertyTester.PROP_CAN_UNDO);
ActionUtils.evaluatePropertyState(ERDEditorPropertyTester.NAMESPACE + "." + ERDEditorPropertyTester.PROP_CAN_REDO);
// Update actions
setDirty(getCommandStack().isDirty());
super.commandStackChanged(event);
}
@Override
public void dispose()
{
ERDActivator.getDefault().getPreferenceStore().removePropertyChangeListener(configPropertyListener);
if (diagramLoadingJob != null) {
diagramLoadingJob.cancel();
diagramLoadingJob = null;
}
// remove selection listener
//getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(this);
// dispose the ActionRegistry (will dispose all actions)
getActionRegistry().dispose();
// important: always call super implementation of dispose
super.dispose();
}
/**
* Adaptable implementation for Editor
*/
@Override
public Object getAdapter(Class adapter)
{
// we need to handle common GEF elements we created
if (adapter == GraphicalViewer.class || adapter == EditPartViewer.class) {
return getGraphicalViewer();
} else if (adapter == CommandStack.class) {
return getCommandStack();
} else if (adapter == EditDomain.class) {
return getEditDomain();
} else if (adapter == ActionRegistry.class) {
return getActionRegistry();
} else if (adapter == IPropertySheetPage.class) {
return getPropertySheetPage();
} else if (adapter == IContentOutlinePage.class) {
return getOverviewOutlinePage();
} else if (adapter == ZoomManager.class) {
return getGraphicalViewer().getProperty(ZoomManager.class.toString());
} else if (IWorkbenchAdapter.class.equals(adapter)) {
return new WorkbenchAdapter() {
@Override
public String getLabel(Object o)
{
return "ERD Editor";
}
};
}
// the super implementation handles the rest
return super.getAdapter(adapter);
}
@Override
public void doSave(IProgressMonitor monitor)
{
}
/**
* Save as not allowed
*/
@Override
public void doSaveAs()
{
saveDiagramAs();
}
/**
* Save as not allowed
*/
@Override
public boolean isSaveAsAllowed()
{
return true;
}
/**
* Indicates if the editor has unsaved changes.
*
* @see org.eclipse.ui.part.EditorPart#isDirty
*/
@Override
public boolean isDirty()
{
return !isReadOnly() && isDirty;
}
public abstract boolean isReadOnly();
/**
* Returns the <code>CommandStack</code> of this editor's
* <code>EditDomain</code>.
*
* @return the <code>CommandStack</code>
*/
@Override
public CommandStack getCommandStack()
{
return getEditDomain().getCommandStack();
}
/**
* Returns the schema model associated with the editor
*
* @return an instance of <code>Schema</code>
*/
public EntityDiagram getDiagram()
{
return getDiagramPart().getDiagram();
}
public DiagramPart getDiagramPart()
{
return rootPart == null ? null : (DiagramPart) rootPart.getContents();
}
/**
* @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput)
*/
@Override
protected void setInput(IEditorInput input)
{
super.setInput(input);
}
/**
* Creates a PaletteViewerProvider that will be used to create palettes for
* the view and the flyout.
*
* @return the palette provider
*/
@Override
protected PaletteViewerProvider createPaletteViewerProvider()
{
return new ERDPaletteViewerProvider(editDomain);
}
public GraphicalViewer getViewer()
{
return super.getGraphicalViewer();
}
/**
* Creates a new <code>GraphicalViewer</code>, configures, registers and
* initializes it.
*
* @param parent the parent composite
*/
@Override
protected void createGraphicalViewer(Composite parent)
{
GraphicalViewer viewer = createViewer(parent);
// hook the viewer into the EditDomain
setGraphicalViewer(viewer);
configureGraphicalViewer();
hookGraphicalViewer();
initializeGraphicalViewer();
// Set initial (empty) contents
viewer.setContents(new EntityDiagram(null, "empty"));
// Set context menu
ContextMenuProvider provider = new ERDEditorContextMenuProvider(this);
viewer.setContextMenu(provider);
getSite().registerContextMenu(ERDEditorPart.class.getName() + ".EditorContext", provider, viewer);
}
private GraphicalViewer createViewer(Composite parent)
{
StatusLineValidationMessageHandler validationMessageHandler = new StatusLineValidationMessageHandler(getEditorSite());
GraphicalViewer viewer = new ERDGraphicalViewer(this, validationMessageHandler);
viewer.createControl(parent);
// configure the viewer
viewer.getControl().setBackground(ColorConstants.white);
rootPart = new ScalableFreeformRootEditPart();
viewer.setRootEditPart(rootPart);
viewer.setKeyHandler(new GraphicalViewerKeyHandler(viewer));
viewer.addDropTargetListener(new DataEditDropTargetListener(viewer));
viewer.addDropTargetListener(new NodeDropTargetListener(viewer));
// initialize the viewer with input
viewer.setEditPartFactory(new ERDEditPartFactory());
return viewer;
}
@Override
protected void configureGraphicalViewer()
{
super.configureGraphicalViewer();
GraphicalViewer graphicalViewer = getGraphicalViewer();
/*
MenuManager manager = new MenuManager(getClass().getName(), getClass().getName());
manager.setRemoveAllWhenShown(true);
getEditorSite().registerContextMenu(getClass().getName() + ".EditorContext", manager, graphicalViewer, true); //$NON-NLS-1$
*/
IPreferenceStore store = ERDActivator.getDefault().getPreferenceStore();
graphicalViewer.setProperty(SnapToGrid.PROPERTY_GRID_ENABLED, store.getBoolean(ERDConstants.PREF_GRID_ENABLED));
graphicalViewer.setProperty(SnapToGrid.PROPERTY_GRID_VISIBLE, store.getBoolean(ERDConstants.PREF_GRID_ENABLED));
graphicalViewer.setProperty(SnapToGrid.PROPERTY_GRID_SPACING, new Dimension(
store.getInt(ERDConstants.PREF_GRID_WIDTH),
store.getInt(ERDConstants.PREF_GRID_HEIGHT)));
// initialize actions
createActions();
// Setup zoom manager
ZoomManager zoomManager = rootPart.getZoomManager();
List<String> zoomLevels = new ArrayList<>(3);
zoomLevels.add(ZoomManager.FIT_ALL);
zoomLevels.add(ZoomManager.FIT_WIDTH);
zoomLevels.add(ZoomManager.FIT_HEIGHT);
zoomManager.setZoomLevelContributions(zoomLevels);
zoomManager.setZoomLevels(
new double[]{.1, .25, .5, .75, 1.0, 1.5, 2.0, 2.5, 3, 4}
);
IAction zoomIn = new ZoomInAction(zoomManager);
IAction zoomOut = new ZoomOutAction(zoomManager);
addAction(zoomIn);
addAction(zoomOut);
graphicalViewer.addSelectionChangedListener(new ISelectionChangedListener() {
@Override
public void selectionChanged(SelectionChangedEvent event)
{
String status;
IStructuredSelection selection = (IStructuredSelection)event.getSelection();
if (selection.isEmpty()) {
status = "";
} else if (selection.size() == 1) {
status = CommonUtils.toString(selection.getFirstElement());
} else {
status = String.valueOf(selection.size()) + " objects";
}
progressControl.setInfo(status);
updateActions(editPartActionIDs);
}
});
}
/**
* Sets the dirty state of this editor.
* <p/>
* <p/>
* An event will be fired immediately if the new state is different than the
* current one.
*
* @param dirty the new dirty state to set
*/
protected void setDirty(boolean dirty)
{
if (isDirty != dirty) {
isDirty = dirty;
firePropertyChange(IEditorPart.PROP_DIRTY);
}
}
/**
* Adds an action to this editor's <code>ActionRegistry</code>. (This is
* a helper method.)
*
* @param action the action to add.
*/
protected void addAction(IAction action)
{
getActionRegistry().registerAction(action);
UIUtils.registerKeyBinding(getSite(), action);
}
/**
* Updates the specified actions.
*
* @param actionIds the list of ids of actions to update
*/
@Override
protected void updateActions(List actionIds)
{
for (Iterator<?> ids = actionIds.iterator(); ids.hasNext();) {
IAction action = getActionRegistry().getAction(ids.next());
if (null != action && action instanceof UpdateAction) {
((UpdateAction) action).update();
}
}
}
/**
* Returns the overview for the outline view.
*
* @return the overview
*/
protected ERDOutlinePage getOverviewOutlinePage()
{
if (null == outlinePage && null != getGraphicalViewer()) {
RootEditPart rootEditPart = getGraphicalViewer().getRootEditPart();
if (rootEditPart instanceof ScalableFreeformRootEditPart) {
outlinePage = new ERDOutlinePage((ScalableFreeformRootEditPart) rootEditPart);
}
}
return outlinePage;
}
/**
* Returns the undoable <code>PropertySheetPage</code> for this editor.
*
* @return the undoable <code>PropertySheetPage</code>
*/
protected PropertySheetPage getPropertySheetPage()
{
if (null == undoablePropertySheetPage) {
undoablePropertySheetPage = new PropertySheetPage();
undoablePropertySheetPage.setRootEntry(new UndoablePropertySheetEntry(getCommandStack()));
}
return undoablePropertySheetPage;
}
/**
* @return the preferences for the Palette Flyout
*/
@Override
protected FlyoutPreferences getPalettePreferences()
{
return new ERDPalettePreferences();
}
/**
* @return the PaletteRoot to be used with the PaletteViewer
*/
@Override
protected PaletteRoot getPaletteRoot()
{
if (paletteRoot == null) {
paletteRoot = createPaletteRoot();
}
return paletteRoot;
}
public PaletteRoot createPaletteRoot()
{
// create root
PaletteRoot paletteRoot = new PaletteRoot();
paletteRoot.setLabel("Entity Diagram");
{
// a group of default control tools
PaletteDrawer controls = new PaletteDrawer("Tools", DBeaverIcons.getImageDescriptor(UIIcon.CONFIGURATION));
paletteRoot.add(controls);
// the selection tool
ToolEntry selectionTool = new SelectionToolEntry();
controls.add(selectionTool);
// use selection tool as default entry
paletteRoot.setDefaultEntry(selectionTool);
// the marquee selection tool
controls.add(new MarqueeToolEntry());
if (!isReadOnly()) {
// separator
PaletteSeparator separator = new PaletteSeparator("tools");
separator.setUserModificationPermission(PaletteEntry.PERMISSION_NO_MODIFICATION);
controls.add(separator);
final ImageDescriptor connectImage = ERDActivator.getImageDescriptor("icons/connect.png");
controls.add(new ConnectionCreationToolEntry("Connection", "Create Connection", null, connectImage, connectImage));
final ImageDescriptor noteImage = ERDActivator.getImageDescriptor("icons/note.png");
controls.add(new CreationToolEntry(
"Note",
"Create Note",
new CreationFactory() {
@Override
public Object getNewObject()
{
return new ERDNote("Note");
}
@Override
public Object getObjectType()
{
return RequestConstants.REQ_CREATE;
}
},
noteImage,
noteImage));
}
}
/*
PaletteDrawer drawer = new PaletteDrawer("New Component",
ERDActivator.getImageDescriptor("icons/connection.gif"));
List<CombinedTemplateCreationEntry> entries = new ArrayList<CombinedTemplateCreationEntry>();
CombinedTemplateCreationEntry tableEntry = new CombinedTemplateCreationEntry("New Table", "Create a new table",
ERDEntity.class, new DataElementFactory(ERDEntity.class),
ERDActivator.getImageDescriptor("icons/table.gif"),
ERDActivator.getImageDescriptor("icons/table.gif"));
CombinedTemplateCreationEntry columnEntry = new CombinedTemplateCreationEntry("New Column", "Add a new column",
ERDEntityAttribute.class, new DataElementFactory(ERDEntityAttribute.class),
ERDActivator.getImageDescriptor("icons/column.gif"),
ERDActivator.getImageDescriptor("icons/column.gif"));
entries.add(tableEntry);
entries.add(columnEntry);
drawer.addAll(entries);
paletteRoot.add(drawer);
*/
return paletteRoot;
}
public boolean isLoaded()
{
return isLoaded;
}
public void refreshDiagram(boolean force)
{
if (isLoaded && force) {
loadDiagram(true);
}
}
@Override
public void refreshPart(Object source, boolean force)
{
refreshDiagram(false);
}
public void saveDiagramAs()
{
final Shell shell = getSite().getShell();
FileDialog saveDialog = new FileDialog(shell, SWT.SAVE);
saveDialog.setFilterExtensions(new String[]{"*.png", "*.gif", "*.bmp", "*.graphml"});
saveDialog.setFilterNames(new String[]{
"PNG format (*.png)",
"GIF format (*.gif)",
// "JPEG format (*.jpg)",
"Bitmap format (*.bmp)",
"GraphML (*.graphml)"
});
String filePath = DialogUtils.openFileDialog(saveDialog);
if (filePath == null || filePath.trim().length() == 0) {
return;
}
int imageType = SWT.IMAGE_BMP;
if (filePath.toLowerCase().endsWith(".jpg")) {
imageType = SWT.IMAGE_JPEG;
} else if (filePath.toLowerCase().endsWith(".png")) {
imageType = SWT.IMAGE_PNG;
} else if (filePath.toLowerCase().endsWith(".gif")) {
imageType = SWT.IMAGE_GIF;
} else if (filePath.toLowerCase().endsWith(".graphml")) {
new ERDExportGraphML(getDiagram(), getDiagramPart()).exportDiagramToGraphML(filePath);
return;
}
IFigure figure = rootPart.getLayer(ScalableFreeformRootEditPart.PRINTABLE_LAYERS);
Rectangle contentBounds = figure instanceof FreeformLayeredPane ? ((FreeformLayeredPane) figure).getFreeformExtent() : figure.getBounds();
try {
try (FileOutputStream fos = new FileOutputStream(filePath)) {
Rectangle r = figure.getBounds();
GC gc = null;
Graphics g = null;
try {
Image image = new Image(null, contentBounds.x * 2 + contentBounds.width, contentBounds.y * 2 + contentBounds.height);
try {
gc = new GC(image);
gc.setClipping(contentBounds.x, contentBounds.y, contentBounds.width, contentBounds.height);
g = new SWTGraphics(gc);
g.translate(r.x * -1, r.y * -1);
figure.paint(g);
ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[1];
if (imageType != SWT.IMAGE_JPEG) {
// Convert to 8bit color
imageLoader.data[0] = ImageUtils.makeWebImageData(image);
} else {
// Use maximum colors for JPEG
imageLoader.data[0] = image.getImageData();
}
imageLoader.save(fos, imageType);
} finally {
UIUtils.dispose(image);
}
} finally {
if (g != null) {
g.dispose();
}
UIUtils.dispose(gc);
}
fos.flush();
}
UIUtils.launchProgram(filePath);
//UIUtils.showMessageBox(shell, "Save ERD", "Diagram has been exported to " + filePath, SWT.ICON_INFORMATION);
} catch (Exception e) {
UIUtils.showErrorDialog(getSite().getShell(), "Save ERD as image", null, e);
}
}
public void fillAttributeVisibilityMenu(IMenuManager menu)
{
MenuManager asMenu = new MenuManager("Attribute Styles");
asMenu.add(new ChangeAttributePresentationAction(ERDAttributeStyle.ICONS));
asMenu.add(new ChangeAttributePresentationAction(ERDAttributeStyle.TYPES));
asMenu.add(new ChangeAttributePresentationAction(ERDAttributeStyle.NULLABILITY));
menu.add(asMenu);
MenuManager avMenu = new MenuManager("Show Attributes");
avMenu.add(new ChangeAttributeVisibilityAction(ERDAttributeVisibility.ALL));
avMenu.add(new ChangeAttributeVisibilityAction(ERDAttributeVisibility.KEYS));
avMenu.add(new ChangeAttributeVisibilityAction(ERDAttributeVisibility.PRIMARY));
avMenu.add(new ChangeAttributeVisibilityAction(ERDAttributeVisibility.NONE));
menu.add(avMenu);
}
public void printDiagram()
{
GraphicalViewer viewer = getGraphicalViewer();
PrintDialog dialog = new PrintDialog(viewer.getControl().getShell(), SWT.NULL);
PrinterData data = dialog.open();
if (data != null) {
IFigure rootFigure = rootPart.getLayer(ScalableFreeformRootEditPart.PRINTABLE_LAYERS);
//EntityDiagramFigure diagramFigure = findFigure(rootFigure, EntityDiagramFigure.class);
if (rootFigure != null) {
PrintFigureOperation printOp = new PrintFigureOperation(new Printer(data), rootFigure);
// Set print preferences
IPreferenceStore store = ERDActivator.getDefault().getPreferenceStore();
printOp.setPrintMode(store.getInt(ERDConstants.PREF_PRINT_PAGE_MODE));
printOp.setPrintMargin(new Insets(
store.getInt(ERDConstants.PREF_PRINT_MARGIN_TOP),
store.getInt(ERDConstants.PREF_PRINT_MARGIN_LEFT),
store.getInt(ERDConstants.PREF_PRINT_MARGIN_BOTTOM),
store.getInt(ERDConstants.PREF_PRINT_MARGIN_RIGHT)
));
// Run print
printOp.run("Print ER diagram");
}
}
//new PrintAction(this).run();
}
@Override
public boolean isSearchPossible()
{
return true;
}
@Override
public boolean isSearchEnabled()
{
return progressControl != null && progressControl.isSearchEnabled();
}
@Override
public boolean performSearch(SearchType searchType)
{
return progressControl != null && progressControl.performSearch(searchType);
}
protected abstract void loadDiagram(boolean refreshMetadata);
private class ChangeAttributePresentationAction extends Action {
private final ERDAttributeStyle style;
public ChangeAttributePresentationAction(ERDAttributeStyle style) {
super("Show " + style.getTitle(), AS_CHECK_BOX);
this.style = style;
}
@Override
public boolean isChecked()
{
return ArrayUtils.contains(
ERDAttributeStyle.getDefaultStyles(ERDActivator.getDefault().getPreferenceStore()),
style);
}
@Override
public void run()
{
getDiagram().setAttributeStyle(style, !isChecked());
refreshDiagram(true);
}
}
private class ChangeAttributeVisibilityAction extends Action {
private final ERDAttributeVisibility visibility;
private ChangeAttributeVisibilityAction(ERDAttributeVisibility visibility)
{
super(visibility.getTitle(), IAction.AS_RADIO_BUTTON);
this.visibility = visibility;
}
@Override
public boolean isChecked()
{
return visibility == getDiagram().getAttributeVisibility();
}
@Override
public void run()
{
getDiagram().setAttributeVisibility(visibility);
refreshDiagram(true);
}
}
private class ConfigPropertyListener implements IPropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent event)
{
GraphicalViewer graphicalViewer = getGraphicalViewer();
if (graphicalViewer == null) {
return;
}
if (ERDConstants.PREF_GRID_ENABLED.equals(event.getProperty())) {
Boolean enabled = Boolean.valueOf(event.getNewValue().toString());
graphicalViewer.setProperty(SnapToGrid.PROPERTY_GRID_ENABLED, enabled);
graphicalViewer.setProperty(SnapToGrid.PROPERTY_GRID_VISIBLE, enabled);
} else if (ERDConstants.PREF_GRID_WIDTH.equals(event.getProperty()) || ERDConstants.PREF_GRID_HEIGHT.equals(event.getProperty())) {
final IPreferenceStore store = ERDActivator.getDefault().getPreferenceStore();
graphicalViewer.setProperty(SnapToGrid.PROPERTY_GRID_SPACING, new Dimension(
store.getInt(ERDConstants.PREF_GRID_WIDTH),
store.getInt(ERDConstants.PREF_GRID_HEIGHT)));
}
}
}
protected class ProgressControl extends ProgressPageControl {
private Searcher searcher;
private ZoomComboContributionItem zoomCombo;
private ProgressControl(Composite parent, int style)
{
super(parent, style);
searcher = new Searcher();
}
@Override
protected boolean cancelProgress()
{
if (diagramLoadingJob != null) {
diagramLoadingJob.cancel();
return true;
}
return false;
}
public ProgressVisualizer<EntityDiagram> createLoadVisualizer()
{
getGraphicalControl().setBackground(ColorConstants.lightGray);
return new LoadVisualizer();
}
@Override
protected void fillCustomActions(IContributionManager toolBarManager) {
ZoomManager zoomManager = rootPart.getZoomManager();
String[] zoomStrings = new String[]{
ZoomManager.FIT_ALL,
ZoomManager.FIT_HEIGHT,
ZoomManager.FIT_WIDTH
};
// Init zoom combo with dummy part service
// to prevent zoom disable on part change - as it is standalone zoom control, not global one
zoomCombo = new ZoomComboContributionItem(
new IPartService() {
@Override
public void addPartListener(IPartListener listener)
{
}
@Override
public void addPartListener(IPartListener2 listener)
{
}
@Override
public IWorkbenchPart getActivePart()
{
return ERDEditorPart.this;
}
@Override
public IWorkbenchPartReference getActivePartReference()
{
return null;
}
@Override
public void removePartListener(IPartListener listener)
{
}
@Override
public void removePartListener(IPartListener2 listener)
{
}
},
zoomStrings);
toolBarManager.add(zoomCombo);
//toolBarManager.add(new UndoAction(ERDEditorPart.this));
//toolBarManager.add(new RedoAction(ERDEditorPart.this));
//toolBarManager.add(new PrintAction(ERDEditorPart.this));
toolBarManager.add(new ZoomInAction(zoomManager));
toolBarManager.add(new ZoomOutAction(zoomManager));
toolBarManager.add(new Separator());
//toolBarManager.add(createAttributeVisibilityMenu());
toolBarManager.add(new DiagramLayoutAction(ERDEditorPart.this));
toolBarManager.add(new DiagramToggleGridAction());
toolBarManager.add(new DiagramRefreshAction(ERDEditorPart.this));
toolBarManager.add(new Separator());
{
toolBarManager.add(ActionUtils.makeCommandContribution(
getSite(),
IWorkbenchCommandConstants.FILE_SAVE_AS,
"Save diagram in external format",
UIIcon.PICTURE_SAVE));
toolBarManager.add(ActionUtils.makeCommandContribution(
getSite(),
IWorkbenchCommandConstants.FILE_PRINT,
"Print Diagram",
UIIcon.PRINT));
}
{
Action configAction = new Action("Configuration") {
@Override
public void run()
{
UIUtils.showPreferencesFor(
getSite().getShell(),
ERDEditorPart.this,
ERDPreferencePage.PAGE_ID);
}
};
configAction.setImageDescriptor(DBeaverIcons.getImageDescriptor(UIIcon.CONFIGURATION));
toolBarManager.add(configAction);
}
}
@Override
protected ISearchExecutor getSearchRunner()
{
return searcher;
}
private class LoadVisualizer extends ProgressVisualizer<EntityDiagram> {
@Override
public void visualizeLoading()
{
super.visualizeLoading();
}
@Override
public void completeLoading(EntityDiagram entityDiagram)
{
super.completeLoading(entityDiagram);
Control graphicalControl = getGraphicalControl();
if (graphicalControl == null) {
return;
}
graphicalControl.setBackground(ColorConstants.white);
isLoaded = true;
Control control = getGraphicalViewer().getControl();
if (control == null || control.isDisposed()) {
return;
}
if (entityDiagram != null) {
List<String> errorMessages = entityDiagram.getErrorMessages();
if (!errorMessages.isEmpty()) {
// log.debug(message);
List<Status> messageStatuses = new ArrayList<>(errorMessages.size());
for (String error : errorMessages) {
messageStatuses.add(new Status(Status.ERROR, DBeaverCore.getCorePluginID(), error));
}
MultiStatus status = new MultiStatus(DBeaverCore.getCorePluginID(), 0, messageStatuses.toArray(new IStatus[messageStatuses.size()]), null, null);
UIUtils.showErrorDialog(
control.getShell(),
"Diagram loading errors",
"Error(s) occurred during diagram loading. If these errors are recoverable then fix errors and then refresh/reopen diagram",
status);
}
setInfo(entityDiagram.getEntityCount() + " objects");
} else {
setInfo("Empty diagram due to error (see error log)");
}
getCommandStack().flush();
getGraphicalViewer().setContents(entityDiagram);
zoomCombo.setZoomManager(rootPart.getZoomManager());
//toolBarManager.getControl().setEnabled(true);
}
}
}
private class Searcher extends ObjectSearcher<DBPNamedObject> {
@Override
protected void setInfo(String message)
{
progressControl.setInfo(message);
}
@Override
protected Collection<DBPNamedObject> getContent()
{
return getDiagramPart().getChildren();
}
@Override
protected void selectObject(DBPNamedObject object)
{
if (object == null) {
getGraphicalViewer().deselectAll();
} else {
getGraphicalViewer().select((EditPart)object);
}
}
@Override
protected void updateObject(DBPNamedObject object)
{
}
@Override
protected void revealObject(DBPNamedObject object)
{
getGraphicalViewer().reveal((EditPart)object);
}
}
}