X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fpdf%2FPDFExportPage.java;fp=bundles%2Forg.simantics.modeling.ui%2Fsrc%2Forg%2Fsimantics%2Fmodeling%2Fui%2Fpdf%2FPDFExportPage.java;h=fb2f8b0c640adf08c4dcfb845ca46ced5bfb880b;hb=83b58da86c173e771f7083778799b79b2fb152c8;hp=7ef2efb9406f283b578f6bfdcabc7669d91e997a;hpb=75809ec96a58c23cc89131637fbc65435ac482af;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFExportPage.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFExportPage.java index 7ef2efb94..fb2f8b0c6 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFExportPage.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFExportPage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * Copyright (c) 2007, 2017 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -8,145 +8,71 @@ * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - #7297 *******************************************************************************/ package org.simantics.modeling.ui.pdf; import java.io.File; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Deque; import java.util.HashSet; -import java.util.List; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.jface.operation.IRunnableWithProgress; -import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.jface.resource.LocalResourceManager; -import org.eclipse.jface.viewers.CellLabelProvider; -import org.eclipse.jface.viewers.CheckStateChangedEvent; -import org.eclipse.jface.viewers.CheckboxTreeViewer; -import org.eclipse.jface.viewers.ICheckStateListener; -import org.eclipse.jface.viewers.ICheckStateProvider; -import org.eclipse.jface.viewers.ITreeContentProvider; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.viewers.TreeViewer; -import org.eclipse.jface.viewers.Viewer; -import org.eclipse.jface.viewers.ViewerCell; -import org.eclipse.jface.viewers.ViewerComparator; -import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CCombo; -import org.eclipse.swt.events.DisposeEvent; -import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; -import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Text; -import org.eclipse.swt.widgets.TreeItem; -import org.simantics.browsing.ui.common.views.DefaultFilterStrategy; -import org.simantics.browsing.ui.common.views.IFilterStrategy; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.NamedResource; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.exception.DatabaseException; +import org.simantics.modeling.requests.CollectionResult; import org.simantics.modeling.requests.Node; +import org.simantics.modeling.requests.Nodes; +import org.simantics.ui.utils.ResourceAdaptionUtils; import org.simantics.utils.FileUtils; -import org.simantics.utils.strings.AlphanumComparator; -import org.simantics.utils.ui.ISelectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class PDFExportPage extends WizardPage { - protected Display display; + private static final Logger LOGGER = LoggerFactory.getLogger(PDFExportPage.class); - protected PDFExportPlan exportModel; + protected Display display; - protected IFilterStrategy filterStrategy = new DefaultFilterStrategy(); + protected PDFExportPlan exportModel; protected Combo modelSelector; protected SelectionListener modelSelectorListener; - protected Text filter; - - protected Matcher matcher = null; - - protected CheckboxTreeViewer tree; + protected NodeTree nodeTree; protected CCombo exportLocation; protected ModifyListener exportLocationListener; protected Set selectedNodes; - - protected LocalResourceManager resourceManager; - protected Color noDiagramColor; - protected Label toFileLabel; + protected Label toFileLabel; protected boolean exportLocationTouchedByUser = false; - ICheckStateProvider checkStateProvider = new ICheckStateProvider() { - @Override - public boolean isChecked(Object element) { - Node node = (Node) element; - - // Primarily checked if any children are selected. - Collection children = node.getChildren(); - if (!children.isEmpty()) { - for (Node child : node.getChildren()) - if (isChecked(child)) - return true; - - // No children are checked, not checked. - return false; - } - - // Otherwise checked only if selected. - return selectedNodes.contains(node); - } - @Override - public boolean isGrayed(Object element) { - Node node = (Node) element; - - // Grayed if there are children but not all of them are selected. - Collection children = node.getChildren(); - if (!children.isEmpty()) { - for (Node child : children) - if (!selectedNodes.contains(child)) - return true; - } - - // Grayed if the node itself contains no diagram. - if (node.getDiagramResource() == null) - return true; - - // Otherwise never grayed. - return false; - } - }; - protected PDFExportPage(PDFExportPlan model) { super("Export Diagrams to PDF", "Define Exported Items", null); this.exportModel = model; @@ -165,14 +91,6 @@ public class PDFExportPage extends WizardPage { layout.numColumns = 3; container.setLayout(layout); } - resourceManager = new LocalResourceManager(JFaceResources.getResources()); - container.addDisposeListener(new DisposeListener() { - @Override - public void widgetDisposed(DisposeEvent e) { - resourceManager.dispose(); - } - }); - noDiagramColor = container.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY); Label modelSelectorLabel = new Label(container, SWT.NONE); modelSelectorLabel.setText("Model Selector:"); @@ -196,198 +114,9 @@ public class PDFExportPage extends WizardPage { modelSelector.addSelectionListener(modelSelectorListener); -// Label label = new Label(container, SWT.NONE); -// label.setText("Diagrams to Export:"); -// GridDataFactory.fillDefaults().span(3, 1).applyTo(label); - - Label filterLabel = new Label(container, SWT.NONE); - filterLabel.setText("Fi<er:"); - GridDataFactory.fillDefaults().span(1, 1).applyTo(filterLabel); - filter = new Text(container, SWT.BORDER); - GridDataFactory.fillDefaults().span(2, 1).applyTo(filter); - filter.addModifyListener(new ModifyListener() { - @Override - public void modifyText(ModifyEvent e) { - resetFilterString(filter.getText()); - } - }); - - tree = new CheckboxTreeViewer(container, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION); - { - tree.setUseHashlookup(true); - GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(tree.getControl()); - tree.getControl().setToolTipText("Selects the diagram to include in the exported document."); - tree.setAutoExpandLevel(TreeViewer.ALL_LEVELS); - tree.addCheckStateListener(new ICheckStateListener(){ - void addOrRemoveSelection(Node node, boolean add) { - if (add) - selectedNodes.add(node); - else - selectedNodes.remove(node); - } - void addOrRemoveSelectionRec(Node node, boolean add) { - addOrRemoveSelection(node, add); - for (Node child : node.getChildren()) - addOrRemoveSelectionRec(child, add); - } - @Override - public void checkStateChanged(CheckStateChangedEvent event) { - final boolean checked = event.getChecked(); - Node checkedNode = (Node) event.getElement(); - - Set nodes = new HashSet(); - Set selection = ISelectionUtils.filterSetSelection(tree.getSelection(), Node.class); - if (selection.contains(checkedNode)) - nodes.addAll(selection); - else - tree.setSelection(StructuredSelection.EMPTY); - nodes.add(checkedNode); - - for (Node node : nodes) { - addOrRemoveSelectionRec(node, checked); - -// tree.setSubtreeChecked(node, checked); -// The checked node is always either checked or not checked, never grayed. -// tree.setGrayed(node, checkStateProvider.isGrayed(node)); - -// Node parent = node.getParent(); -// if (parent != null) { -// tree.setChecked(parent, checkStateProvider.isChecked(parent)); -// tree.setGrayed(parent, checkStateProvider.isGrayed(parent)); -// } - } - - refreshAndExpandTree(); - validatePage(); - } - }); - - tree.setContentProvider(new ITreeContentProvider(){ - @Override - public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { - } - @Override - public void dispose() { - } - @Override - public Object[] getElements(Object inputElement) { - return exportModel.nodes.roots.toArray(); - } - @Override - public boolean hasChildren(Object element) { - Node n = (Node) element; - if (n.getChildren().isEmpty()) return false; - for (Node c : n.getChildren()) if (hasDiagram(c)) return true; - return false; - - } - @Override - public Object getParent(Object element) { - Node n = (Node) element; - return n.getParent(); - } - @Override - public Object[] getChildren(Object parentElement) { - Node n = (Node) parentElement; - List result = new ArrayList( n.getChildren().size() ); - for (Node c : n.getChildren()) - if (hasDiagram(c)) - result.add(c); - return result.toArray(); - } - - boolean hasDiagram(Node n) - { - if (n.getDiagramResource()!=null) return true; - for (Node c : n.getChildren()) if (hasDiagram(c)) return true; - return false; - } - }); - tree.setLabelProvider(new CellLabelProvider() { - @Override - public void update(ViewerCell cell) { - Object e = cell.getElement(); - if (e instanceof Node) { - Node n = (Node) e; - String name = DiagramPrinter.formDiagramName(n, false); - cell.setText(name); - - if (n.getDiagramResource() == null) - cell.setForeground(noDiagramColor); - else - cell.setForeground(null); - } else { - cell.setText("invalid input: " + e.getClass().getSimpleName()); - } - } - }); - tree.setComparator(new ViewerComparator(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR)); - tree.setFilters(new ViewerFilter[] { - new ViewerFilter() { - @Override - public boolean select(Viewer viewer, Object parentElement, Object element) { - if (matcher == null) - return true; - - Node node = (Node) element; - // If any children are in sight, show this element. - for (Node child : node.getChildren()) { - if (select(viewer, element, child)) - return true; - } - - return matcher.reset(node.getName().toLowerCase()).matches(); - } - } - }); - tree.setCheckStateProvider(checkStateProvider); - } - - Composite bar = new Composite(container, SWT.NONE); - GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(bar); - bar.setLayout(new RowLayout()); - Button selectAll = new Button(bar, SWT.PUSH); - selectAll.setText("Select &All"); - selectAll.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - selectedNodes.addAll(exportModel.nodes.breadthFirstFlatten()); - for (Node root : exportModel.nodes.roots) - tree.setSubtreeChecked(root, true); - validatePage(); - } - }); - Button clearSelection = new Button(bar, SWT.PUSH); - clearSelection.setText("&Clear Selection"); - clearSelection.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - selectedNodes.clear(); - for (Node root : exportModel.nodes.roots) - tree.setSubtreeChecked(root, false); - validatePage(); - } - }); - Button selectVisible = new Button(bar, SWT.PUSH); - selectVisible.setText("&Select Visible"); - selectVisible.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - selectedNodes.addAll(getVisibleNodes()); - refreshAndExpandTree(); - validatePage(); - } - }); - Button deselectVisible = new Button(bar, SWT.PUSH); - deselectVisible.setText("&Deselect Visible"); - deselectVisible.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - selectedNodes.removeAll(getVisibleNodes()); - refreshAndExpandTree(); - validatePage(); - } - }); + nodeTree = new NodeTree(container, selectedNodes); + GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(nodeTree); + nodeTree.setSelectionChangeListener(this::validatePage); toFileLabel = new Label(container, SWT.NONE); toFileLabel.setText("&To file:"); @@ -474,7 +203,7 @@ public class PDFExportPage extends WizardPage { } }); */ - + final Button attachWikiButton = new Button(container, SWT.CHECK); GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo( attachWikiButton ); attachWikiButton.setText("Attach &Wiki page"); @@ -485,7 +214,18 @@ public class PDFExportPage extends WizardPage { exportModel.attachWiki = attachWikiButton.getSelection(); } }); - + + final Button addPageNumbers = new Button(container, SWT.CHECK); + GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo( addPageNumbers ); + addPageNumbers.setText("Add page &numbers"); + addPageNumbers.setSelection(exportModel.addPageNumbers); + addPageNumbers.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + exportModel.addPageNumbers = addPageNumbers.getSelection(); + } + }); + setControl(container); validatePage(); @@ -493,21 +233,14 @@ public class PDFExportPage extends WizardPage { } private void scheduleInitializeData(final NamedResource modelSelection) { - display.asyncExec(new Runnable() { - @Override - public void run() { - if (filter.isDisposed()) - return; - - try { + display.asyncExec(() -> { + try { + if (!nodeTree.isDisposed()) initializeData(modelSelection); - } catch (DatabaseException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.getTargetException().printStackTrace(); - } catch (InterruptedException e) { - e.printStackTrace(); - } + } catch (DatabaseException | InterruptedException e) { + LOGGER.error("Input data initialization failed.", e); + } catch (InvocationTargetException e) { + LOGGER.error("Input data initialization failed.", e.getTargetException()); } }); } @@ -527,43 +260,9 @@ public class PDFExportPage extends WizardPage { exportLocation.addModifyListener(exportLocationListener); } - private Collection getVisibleNodes() { - Collection result = new ArrayList(); - - Deque todo = new ArrayDeque(); - for (TreeItem ti : tree.getTree().getItems()) { - todo.add(ti); - } - - while (!todo.isEmpty()) { - TreeItem item = todo.removeLast(); - Node node = (Node) item.getData(); - result.add(node); - - for (TreeItem child : item.getItems()) { - todo.add(child); - } - } - - return result; - } - - private void resetFilterString(String filterString) { - String patternString = filterStrategy.toPatternString(filterString); - if (patternString == null) { - matcher = null; - } else { - matcher = Pattern.compile(patternString).matcher(""); - } - refreshAndExpandTree(); - } - - private void refreshAndExpandTree() { - tree.refresh(); - tree.expandAll(); - } - private void initializeData(final NamedResource modelSelection) throws DatabaseException, InvocationTargetException, InterruptedException { + Set toBeSelected = new HashSet<>(); + if (modelSelection != null) { // Process input selection to find the model/state selected by default. @@ -573,29 +272,54 @@ public class PDFExportPage extends WizardPage { // !PROFILE long time = System.nanoTime(); - getWizard().getContainer().run(true, true, new IRunnableWithProgress() { - @Override - public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { - try { - final SubMonitor mon = SubMonitor.convert(monitor, "Searching for exportable diagrams...", 100); - exportModel.sessionContext.getSession().syncRequest(new ReadRequest() { - @Override - public void run(ReadGraph graph) throws DatabaseException { - exportModel.nodes = DiagramPrinter.browse(mon.newChild(100), graph, new Resource[] { modelSelection.getResource() }); + getWizard().getContainer().run(true, true, monitor -> { + try { + SubMonitor mon = SubMonitor.convert(monitor, "Searching for exportable diagrams...", 100); + exportModel.sessionContext.getSession().syncRequest(new ReadRequest() { + @Override + public void run(ReadGraph graph) throws DatabaseException { + CollectionResult coll = exportModel.nodes = DiagramPrinter.browse(mon.newChild(100), graph, new Resource[] { modelSelection.getResource() }); + + // Decide initial selection based on exportModel.initialSelection + if (modelSelection.equals(exportModel.initialModelSelection)) { + Set selectedResources = new HashSet<>(); + for (Object o : exportModel.initialSelection.toList()) { + Resource r = ResourceAdaptionUtils.toSingleResource(o); + if (r != null) + selectedResources.add(r); + } + coll.walkTree(node -> { + if (node.getDiagramResource() != null) { + if (Nodes.parentIsInSet(toBeSelected, node)) + toBeSelected.add(node); + else + for (Resource r : node.getDefiningResources()) + if (selectedResources.contains(r)) + toBeSelected.add(node); + } + return true; + }); } - }); - } catch (DatabaseException e) { - throw new InvocationTargetException(e); - } finally { - monitor.done(); - } + + // Filter out any excess nodes from the tree. + exportModel.nodes = coll = coll.withRoots(Nodes.depthFirstFilter(Nodes.DIAGRAM_RESOURCE_PREDICATE, coll.roots)); + + // Select all if initial selection doesn't dictate anything. + if (toBeSelected.isEmpty()) + toBeSelected.addAll(coll.breadthFirstFlatten(CollectionResult.DIAGRAM_RESOURCE_FILTER)); + } + }); + } catch (DatabaseException e) { + throw new InvocationTargetException(e); + } finally { + monitor.done(); } }); // !PROFILE long endTime = System.nanoTime(); if (exportModel.nodes != null) - System.out.println("Found " + exportModel.nodes.diagrams.size() + " diagrams in " + ((endTime - time)*1e-9) + " seconds."); + LOGGER.info("Found " + exportModel.nodes.diagrams.size() + " diagrams in " + ((endTime - time)*1e-9) + " seconds."); } // Browsing was canceled by user. @@ -604,15 +328,10 @@ public class PDFExportPage extends WizardPage { // Setup selected states, select everything by default. selectedNodes.clear(); - selectedNodes.addAll(exportModel.nodes.breadthFirstFlatten()); - - tree.setInput(this); + selectedNodes.addAll(toBeSelected); - for (Node root : exportModel.nodes.roots) { - tree.setSubtreeChecked(root, true); - } - - resetFilterString(filter.getText()); + // Fully refresh node tree + nodeTree.setInput(exportModel.nodes); modelSelector.removeSelectionListener(modelSelectorListener); int selectedIndex = -1; @@ -632,8 +351,16 @@ public class PDFExportPage extends WizardPage { } void validatePage() { + int diagramCount = 0; + Node singleDiagram = null; + for (Node n : selectedNodes) + if (n.getDiagramResource() != null) { + ++diagramCount; + singleDiagram = n; + } + //System.out.println("VALIDATE PAGE: " + exportLocationTouchedByUser); - if (selectedNodes.size() == 0) { + if (diagramCount == 0) { setMessage("Select the diagrams to export."); setErrorMessage(null); setPageComplete(false); @@ -645,8 +372,8 @@ public class PDFExportPage extends WizardPage { // Generate file name automatically if user hasn't touched the name manually. NamedResource nr = getSelectedModel(); if (nr != null) { - if (selectedNodes.size() == 1) { - generatedName = nr.getName() + "-" + selectedNodes.iterator().next().getName(); + if (diagramCount == 1 && singleDiagram != null) { + generatedName = nr.getName() + "-" + singleDiagram.getName(); } else { generatedName = nr.getName(); } @@ -701,11 +428,6 @@ public class PDFExportPage extends WizardPage { } exportModel.exportLocation = file; - int diagramCount = 0; - for (Node n : selectedNodes) - if (n.getDiagramResource() != null) - ++diagramCount; - String msg = diagramCount + " diagrams selected for export."; setMessage(msg);