1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.ui.pdf;
\r
14 import java.io.File;
\r
15 import java.lang.reflect.InvocationTargetException;
\r
16 import java.util.ArrayDeque;
\r
17 import java.util.ArrayList;
\r
18 import java.util.Collection;
\r
19 import java.util.Deque;
\r
20 import java.util.HashSet;
\r
21 import java.util.List;
\r
22 import java.util.Set;
\r
23 import java.util.regex.Matcher;
\r
24 import java.util.regex.Pattern;
\r
26 import org.eclipse.core.runtime.IPath;
\r
27 import org.eclipse.core.runtime.IProgressMonitor;
\r
28 import org.eclipse.core.runtime.Path;
\r
29 import org.eclipse.core.runtime.SubMonitor;
\r
30 import org.eclipse.jface.layout.GridDataFactory;
\r
31 import org.eclipse.jface.operation.IRunnableWithProgress;
\r
32 import org.eclipse.jface.resource.JFaceResources;
\r
33 import org.eclipse.jface.resource.LocalResourceManager;
\r
34 import org.eclipse.jface.viewers.CellLabelProvider;
\r
35 import org.eclipse.jface.viewers.CheckStateChangedEvent;
\r
36 import org.eclipse.jface.viewers.CheckboxTreeViewer;
\r
37 import org.eclipse.jface.viewers.ICheckStateListener;
\r
38 import org.eclipse.jface.viewers.ICheckStateProvider;
\r
39 import org.eclipse.jface.viewers.ITreeContentProvider;
\r
40 import org.eclipse.jface.viewers.StructuredSelection;
\r
41 import org.eclipse.jface.viewers.TreeViewer;
\r
42 import org.eclipse.jface.viewers.Viewer;
\r
43 import org.eclipse.jface.viewers.ViewerCell;
\r
44 import org.eclipse.jface.viewers.ViewerComparator;
\r
45 import org.eclipse.jface.viewers.ViewerFilter;
\r
46 import org.eclipse.jface.wizard.WizardPage;
\r
47 import org.eclipse.swt.SWT;
\r
48 import org.eclipse.swt.custom.CCombo;
\r
49 import org.eclipse.swt.events.DisposeEvent;
\r
50 import org.eclipse.swt.events.DisposeListener;
\r
51 import org.eclipse.swt.events.ModifyEvent;
\r
52 import org.eclipse.swt.events.ModifyListener;
\r
53 import org.eclipse.swt.events.SelectionAdapter;
\r
54 import org.eclipse.swt.events.SelectionEvent;
\r
55 import org.eclipse.swt.events.SelectionListener;
\r
56 import org.eclipse.swt.graphics.Color;
\r
57 import org.eclipse.swt.layout.GridData;
\r
58 import org.eclipse.swt.layout.GridLayout;
\r
59 import org.eclipse.swt.layout.RowLayout;
\r
60 import org.eclipse.swt.widgets.Button;
\r
61 import org.eclipse.swt.widgets.Combo;
\r
62 import org.eclipse.swt.widgets.Composite;
\r
63 import org.eclipse.swt.widgets.Display;
\r
64 import org.eclipse.swt.widgets.FileDialog;
\r
65 import org.eclipse.swt.widgets.Label;
\r
66 import org.eclipse.swt.widgets.Text;
\r
67 import org.eclipse.swt.widgets.TreeItem;
\r
68 import org.simantics.browsing.ui.common.views.DefaultFilterStrategy;
\r
69 import org.simantics.browsing.ui.common.views.IFilterStrategy;
\r
70 import org.simantics.databoard.Bindings;
\r
71 import org.simantics.db.ReadGraph;
\r
72 import org.simantics.db.Resource;
\r
73 import org.simantics.db.common.NamedResource;
\r
74 import org.simantics.db.common.request.ReadRequest;
\r
75 import org.simantics.db.exception.DatabaseException;
\r
76 import org.simantics.modeling.requests.Node;
\r
77 import org.simantics.utils.FileUtils;
\r
78 import org.simantics.utils.strings.AlphanumComparator;
\r
79 import org.simantics.utils.ui.ISelectionUtils;
\r
81 public class PDFExportPage extends WizardPage {
\r
83 protected Display display;
\r
85 protected PDFExportPlan exportModel;
\r
87 protected IFilterStrategy filterStrategy = new DefaultFilterStrategy();
\r
89 protected Combo modelSelector;
\r
90 protected SelectionListener modelSelectorListener;
\r
92 protected Text filter;
\r
94 protected Matcher matcher = null;
\r
96 protected CheckboxTreeViewer tree;
\r
98 protected CCombo exportLocation;
\r
99 protected ModifyListener exportLocationListener;
\r
101 protected Set<Node> selectedNodes;
\r
103 protected LocalResourceManager resourceManager;
\r
104 protected Color noDiagramColor;
\r
106 protected Label toFileLabel;
\r
108 protected boolean exportLocationTouchedByUser = false;
\r
110 ICheckStateProvider checkStateProvider = new ICheckStateProvider() {
\r
112 public boolean isChecked(Object element) {
\r
113 Node node = (Node) element;
\r
115 // Primarily checked if any children are selected.
\r
116 Collection<Node> children = node.getChildren();
\r
117 if (!children.isEmpty()) {
\r
118 for (Node child : node.getChildren())
\r
119 if (isChecked(child))
\r
122 // No children are checked, not checked.
\r
126 // Otherwise checked only if selected.
\r
127 return selectedNodes.contains(node);
\r
130 public boolean isGrayed(Object element) {
\r
131 Node node = (Node) element;
\r
133 // Grayed if there are children but not all of them are selected.
\r
134 Collection<Node> children = node.getChildren();
\r
135 if (!children.isEmpty()) {
\r
136 for (Node child : children)
\r
137 if (!selectedNodes.contains(child))
\r
141 // Grayed if the node itself contains no diagram.
\r
142 if (node.getDiagramResource() == null)
\r
145 // Otherwise never grayed.
\r
150 protected PDFExportPage(PDFExportPlan model) {
\r
151 super("Export Diagrams to PDF", "Define Exported Items", null);
\r
152 this.exportModel = model;
\r
153 this.selectedNodes = exportModel.selectedNodeSet;
\r
157 public void createControl(Composite parent) {
\r
158 this.display = parent.getDisplay();
\r
160 Composite container = new Composite(parent, SWT.NONE);
\r
162 GridLayout layout = new GridLayout();
\r
163 layout.horizontalSpacing = 20;
\r
164 layout.verticalSpacing = 10;
\r
165 layout.numColumns = 3;
\r
166 container.setLayout(layout);
\r
168 resourceManager = new LocalResourceManager(JFaceResources.getResources());
\r
169 container.addDisposeListener(new DisposeListener() {
\r
171 public void widgetDisposed(DisposeEvent e) {
\r
172 resourceManager.dispose();
\r
175 noDiagramColor = container.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
\r
177 Label modelSelectorLabel = new Label(container, SWT.NONE);
\r
178 modelSelectorLabel.setText("Model Selector:");
\r
179 GridDataFactory.fillDefaults().span(1, 1).applyTo(modelSelectorLabel);
\r
180 modelSelector = new Combo(container, SWT.BORDER | SWT.READ_ONLY);
\r
181 GridDataFactory.fillDefaults().span(2, 1).applyTo(modelSelector);
\r
182 modelSelectorListener = new SelectionAdapter() {
\r
184 public void widgetSelected(SelectionEvent e) {
\r
185 NamedResource data = (NamedResource) modelSelector.getData(String.valueOf(modelSelector.getSelectionIndex()));
\r
186 scheduleInitializeData(data);
\r
190 // Fill model selector combo
\r
191 for (int i = 0; i < exportModel.selectableModels.size(); ++i) {
\r
192 NamedResource nr = exportModel.selectableModels.get(i);
\r
193 modelSelector.add(nr.getName());
\r
194 modelSelector.setData("" + i, nr);
\r
197 modelSelector.addSelectionListener(modelSelectorListener);
\r
199 // Label label = new Label(container, SWT.NONE);
\r
200 // label.setText("Diagrams to Export:");
\r
201 // GridDataFactory.fillDefaults().span(3, 1).applyTo(label);
\r
203 Label filterLabel = new Label(container, SWT.NONE);
\r
204 filterLabel.setText("Fi<er:");
\r
205 GridDataFactory.fillDefaults().span(1, 1).applyTo(filterLabel);
\r
206 filter = new Text(container, SWT.BORDER);
\r
207 GridDataFactory.fillDefaults().span(2, 1).applyTo(filter);
\r
208 filter.addModifyListener(new ModifyListener() {
\r
210 public void modifyText(ModifyEvent e) {
\r
211 resetFilterString(filter.getText());
\r
215 tree = new CheckboxTreeViewer(container, SWT.BORDER | SWT.MULTI | SWT.FULL_SELECTION);
\r
217 tree.setUseHashlookup(true);
\r
218 GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(tree.getControl());
\r
219 tree.getControl().setToolTipText("Selects the diagram to include in the exported document.");
\r
220 tree.setAutoExpandLevel(TreeViewer.ALL_LEVELS);
\r
221 tree.addCheckStateListener(new ICheckStateListener(){
\r
222 void addOrRemoveSelection(Node node, boolean add) {
\r
224 selectedNodes.add(node);
\r
226 selectedNodes.remove(node);
\r
228 void addOrRemoveSelectionRec(Node node, boolean add) {
\r
229 addOrRemoveSelection(node, add);
\r
230 for (Node child : node.getChildren())
\r
231 addOrRemoveSelectionRec(child, add);
\r
234 public void checkStateChanged(CheckStateChangedEvent event) {
\r
235 final boolean checked = event.getChecked();
\r
236 Node checkedNode = (Node) event.getElement();
\r
238 Set<Node> nodes = new HashSet<Node>();
\r
239 Set<Node> selection = ISelectionUtils.filterSetSelection(tree.getSelection(), Node.class);
\r
240 if (selection.contains(checkedNode))
\r
241 nodes.addAll(selection);
\r
243 tree.setSelection(StructuredSelection.EMPTY);
\r
244 nodes.add(checkedNode);
\r
246 for (Node node : nodes) {
\r
247 addOrRemoveSelectionRec(node, checked);
\r
249 // tree.setSubtreeChecked(node, checked);
\r
250 // The checked node is always either checked or not checked, never grayed.
\r
251 // tree.setGrayed(node, checkStateProvider.isGrayed(node));
\r
253 // Node parent = node.getParent();
\r
254 // if (parent != null) {
\r
255 // tree.setChecked(parent, checkStateProvider.isChecked(parent));
\r
256 // tree.setGrayed(parent, checkStateProvider.isGrayed(parent));
\r
260 refreshAndExpandTree();
\r
265 tree.setContentProvider(new ITreeContentProvider(){
\r
267 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
\r
270 public void dispose() {
\r
273 public Object[] getElements(Object inputElement) {
\r
274 return exportModel.nodes.roots.toArray();
\r
277 public boolean hasChildren(Object element) {
\r
278 Node n = (Node) element;
\r
279 if (n.getChildren().isEmpty()) return false;
\r
280 for (Node c : n.getChildren()) if (hasDiagram(c)) return true;
\r
285 public Object getParent(Object element) {
\r
286 Node n = (Node) element;
\r
287 return n.getParent();
\r
290 public Object[] getChildren(Object parentElement) {
\r
291 Node n = (Node) parentElement;
\r
292 List<Object> result = new ArrayList<Object>( n.getChildren().size() );
\r
293 for (Node c : n.getChildren())
\r
294 if (hasDiagram(c))
\r
296 return result.toArray();
\r
299 boolean hasDiagram(Node n)
\r
301 if (n.getDiagramResource()!=null) return true;
\r
302 for (Node c : n.getChildren()) if (hasDiagram(c)) return true;
\r
306 tree.setLabelProvider(new CellLabelProvider() {
\r
308 public void update(ViewerCell cell) {
\r
309 Object e = cell.getElement();
\r
310 if (e instanceof Node) {
\r
312 String name = DiagramPrinter.formDiagramName(n, false);
\r
313 cell.setText(name);
\r
315 if (n.getDiagramResource() == null)
\r
316 cell.setForeground(noDiagramColor);
\r
318 cell.setForeground(null);
\r
320 cell.setText("invalid input: " + e.getClass().getSimpleName());
\r
324 tree.setComparator(new ViewerComparator(AlphanumComparator.CASE_INSENSITIVE_COMPARATOR));
\r
325 tree.setFilters(new ViewerFilter[] {
\r
326 new ViewerFilter() {
\r
328 public boolean select(Viewer viewer, Object parentElement, Object element) {
\r
329 if (matcher == null)
\r
332 Node node = (Node) element;
\r
333 // If any children are in sight, show this element.
\r
334 for (Node child : node.getChildren()) {
\r
335 if (select(viewer, element, child))
\r
339 return matcher.reset(node.getName().toLowerCase()).matches();
\r
343 tree.setCheckStateProvider(checkStateProvider);
\r
346 Composite bar = new Composite(container, SWT.NONE);
\r
347 GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(bar);
\r
348 bar.setLayout(new RowLayout());
\r
349 Button selectAll = new Button(bar, SWT.PUSH);
\r
350 selectAll.setText("Select &All");
\r
351 selectAll.addSelectionListener(new SelectionAdapter() {
\r
353 public void widgetSelected(SelectionEvent e) {
\r
354 selectedNodes.addAll(exportModel.nodes.breadthFirstFlatten());
\r
355 for (Node root : exportModel.nodes.roots)
\r
356 tree.setSubtreeChecked(root, true);
\r
360 Button clearSelection = new Button(bar, SWT.PUSH);
\r
361 clearSelection.setText("&Clear Selection");
\r
362 clearSelection.addSelectionListener(new SelectionAdapter() {
\r
364 public void widgetSelected(SelectionEvent e) {
\r
365 selectedNodes.clear();
\r
366 for (Node root : exportModel.nodes.roots)
\r
367 tree.setSubtreeChecked(root, false);
\r
371 Button selectVisible = new Button(bar, SWT.PUSH);
\r
372 selectVisible.setText("&Select Visible");
\r
373 selectVisible.addSelectionListener(new SelectionAdapter() {
\r
375 public void widgetSelected(SelectionEvent e) {
\r
376 selectedNodes.addAll(getVisibleNodes());
\r
377 refreshAndExpandTree();
\r
381 Button deselectVisible = new Button(bar, SWT.PUSH);
\r
382 deselectVisible.setText("&Deselect Visible");
\r
383 deselectVisible.addSelectionListener(new SelectionAdapter() {
\r
385 public void widgetSelected(SelectionEvent e) {
\r
386 selectedNodes.removeAll(getVisibleNodes());
\r
387 refreshAndExpandTree();
\r
392 toFileLabel = new Label(container, SWT.NONE);
\r
393 toFileLabel.setText("&To file:");
\r
394 exportLocation = new CCombo(container, SWT.BORDER);
\r
396 exportLocation.setText("");
\r
397 GridDataFactory.fillDefaults().grab(true, false).span(1, 1).applyTo(exportLocation);
\r
399 for (String path : exportModel.recentLocations) {
\r
400 exportLocation.add(path);
\r
403 exportLocationListener = new ModifyListener() {
\r
405 public void modifyText(ModifyEvent e) {
\r
406 //System.out.println("export location changed by user");
\r
407 exportLocationTouchedByUser = true;
\r
411 exportLocation.addModifyListener(exportLocationListener);
\r
413 Button browseFileButton = new Button(container, SWT.PUSH);
\r
415 browseFileButton.setText("Browse...");
\r
416 browseFileButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false));
\r
417 browseFileButton.addSelectionListener(new SelectionAdapter() {
\r
419 public void widgetSelected(SelectionEvent e) {
\r
420 FileDialog dialog = new FileDialog(getShell(), SWT.SAVE);
\r
421 dialog.setFilterExtensions(new String[] { "*.pdf" });
\r
422 dialog.setFilterNames(new String[] { "PDF Document" });
\r
423 String loc = exportLocation.getText();
\r
425 IPath p = new Path(loc);
\r
426 File f = p.toFile();
\r
427 if (f.isDirectory()) {
\r
428 dialog.setFilterPath(f.toString());
\r
429 } else if (f.isFile()) {
\r
430 IPath path = p.removeLastSegments(1);
\r
431 String name = p.lastSegment();
\r
432 dialog.setFilterPath(path.toOSString());
\r
433 dialog.setFileName(name);
\r
435 dialog.setFilterPath(f.toString());
\r
436 IPath path = p.removeLastSegments(1);
\r
437 String name = p.lastSegment();
\r
439 if (f.isDirectory()) {
\r
440 dialog.setFilterPath(path.toOSString());
\r
442 dialog.setFileName(name);
\r
445 String file = dialog.open();
\r
448 exportLocation.setText(file);
\r
454 final Button zoomToFitButton = new Button(container, SWT.CHECK);
\r
455 GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo(zoomToFitButton);
\r
456 zoomToFitButton.setText("F&it by content");
\r
457 zoomToFitButton.setSelection(exportModel.fitContentToPageMargins);
\r
458 zoomToFitButton.addSelectionListener(new SelectionAdapter() {
\r
460 public void widgetSelected(SelectionEvent e) {
\r
461 exportModel.fitContentToPageMargins = zoomToFitButton.getSelection();
\r
466 final Button attachTGButton = new Button(container, SWT.CHECK);
\r
467 GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo( attachTGButton );
\r
468 attachTGButton.setText("Attach &TG (Importable diagram)");
\r
469 attachTGButton.setSelection(exportModel.attachTG);
\r
470 attachTGButton.addSelectionListener(new SelectionAdapter() {
\r
472 public void widgetSelected(SelectionEvent e) {
\r
473 exportModel.attachTG = attachTGButton.getSelection();
\r
478 final Button attachWikiButton = new Button(container, SWT.CHECK);
\r
479 GridDataFactory.fillDefaults().grab(true, false).span(3, 1).applyTo( attachWikiButton );
\r
480 attachWikiButton.setText("Attach &Wiki page");
\r
481 attachWikiButton.setSelection(exportModel.attachWiki);
\r
482 attachWikiButton.addSelectionListener(new SelectionAdapter() {
\r
484 public void widgetSelected(SelectionEvent e) {
\r
485 exportModel.attachWiki = attachWikiButton.getSelection();
\r
489 setControl(container);
\r
492 scheduleInitializeData(exportModel.selection);
\r
495 private void scheduleInitializeData(final NamedResource modelSelection) {
\r
496 display.asyncExec(new Runnable() {
\r
498 public void run() {
\r
499 if (filter.isDisposed())
\r
503 initializeData(modelSelection);
\r
504 } catch (DatabaseException e) {
\r
505 e.printStackTrace();
\r
506 } catch (InvocationTargetException e) {
\r
507 e.getTargetException().printStackTrace();
\r
508 } catch (InterruptedException e) {
\r
509 e.printStackTrace();
\r
515 private NamedResource getSelectedModel() {
\r
516 int sel = modelSelector.getSelectionIndex();
\r
518 NamedResource nr = (NamedResource) modelSelector.getData("" + sel);
\r
524 private void setExportLocationWithoutNotification(String text) {
\r
525 exportLocation.removeModifyListener(exportLocationListener);
\r
526 exportLocation.setText(text);
\r
527 exportLocation.addModifyListener(exportLocationListener);
\r
530 private Collection<Node> getVisibleNodes() {
\r
531 Collection<Node> result = new ArrayList<Node>();
\r
533 Deque<TreeItem> todo = new ArrayDeque<TreeItem>();
\r
534 for (TreeItem ti : tree.getTree().getItems()) {
\r
538 while (!todo.isEmpty()) {
\r
539 TreeItem item = todo.removeLast();
\r
540 Node node = (Node) item.getData();
\r
543 for (TreeItem child : item.getItems()) {
\r
551 private void resetFilterString(String filterString) {
\r
552 String patternString = filterStrategy.toPatternString(filterString);
\r
553 if (patternString == null) {
\r
556 matcher = Pattern.compile(patternString).matcher("");
\r
558 refreshAndExpandTree();
\r
561 private void refreshAndExpandTree() {
\r
566 private void initializeData(final NamedResource modelSelection) throws DatabaseException, InvocationTargetException, InterruptedException {
\r
567 if (modelSelection != null) {
\r
568 // Process input selection to find the model/state selected by default.
\r
570 // This may take longer than the user wants to wait without
\r
574 long time = System.nanoTime();
\r
576 getWizard().getContainer().run(true, true, new IRunnableWithProgress() {
\r
578 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
\r
580 final SubMonitor mon = SubMonitor.convert(monitor, "Searching for exportable diagrams...", 100);
\r
581 exportModel.sessionContext.getSession().syncRequest(new ReadRequest() {
\r
583 public void run(ReadGraph graph) throws DatabaseException {
\r
584 exportModel.nodes = DiagramPrinter.browse(mon.newChild(100), graph, new Resource[] { modelSelection.getResource() });
\r
587 } catch (DatabaseException e) {
\r
588 throw new InvocationTargetException(e);
\r
596 long endTime = System.nanoTime();
\r
597 if (exportModel.nodes != null)
\r
598 System.out.println("Found " + exportModel.nodes.diagrams.size() + " diagrams in " + ((endTime - time)*1e-9) + " seconds.");
\r
601 // Browsing was canceled by user.
\r
602 if (exportModel.nodes == null)
\r
605 // Setup selected states, select everything by default.
\r
606 selectedNodes.clear();
\r
607 selectedNodes.addAll(exportModel.nodes.breadthFirstFlatten());
\r
609 tree.setInput(this);
\r
611 for (Node root : exportModel.nodes.roots) {
\r
612 tree.setSubtreeChecked(root, true);
\r
615 resetFilterString(filter.getText());
\r
617 modelSelector.removeSelectionListener(modelSelectorListener);
\r
618 int selectedIndex = -1;
\r
619 for (int i = 0; i < modelSelector.getItemCount(); ++i) {
\r
620 Object obj = modelSelector.getData("" + i);
\r
621 if (org.simantics.utils.ObjectUtils.objectEquals(obj, modelSelection)) {
\r
625 if (selectedIndex == -1 && modelSelector.getItemCount() > 0)
\r
627 if (selectedIndex != -1)
\r
628 modelSelector.select(selectedIndex);
\r
629 modelSelector.addSelectionListener(modelSelectorListener);
\r
634 void validatePage() {
\r
635 //System.out.println("VALIDATE PAGE: " + exportLocationTouchedByUser);
\r
636 if (selectedNodes.size() == 0) {
\r
637 setMessage("Select the diagrams to export.");
\r
638 setErrorMessage(null);
\r
639 setPageComplete(false);
\r
643 if (!exportLocationTouchedByUser) {
\r
644 String generatedName = null;
\r
645 // Generate file name automatically if user hasn't touched the name manually.
\r
646 NamedResource nr = getSelectedModel();
\r
648 if (selectedNodes.size() == 1) {
\r
649 generatedName = nr.getName() + "-" + selectedNodes.iterator().next().getName();
\r
651 generatedName = nr.getName();
\r
654 //System.out.println("generate name: " + generatedName);
\r
655 if (generatedName != null) {
\r
656 if (!FileUtils.isValidFileName(generatedName))
\r
657 generatedName = (String) Bindings.STR_VARIANT.createUnchecked(Bindings.STRING, generatedName);
\r
658 String name = generatedName + ".pdf";
\r
661 if ( !exportModel.recentLocations.isEmpty() ) {
\r
663 for ( String loc : exportModel.recentLocations )
\r
665 if ( loc.endsWith(name) && !loc.equals(name) ) {
\r
671 String firstLine = exportModel.recentLocations.iterator().next();
\r
672 File f = new File(firstLine);
\r
673 File parentFile = f.getParentFile();
\r
674 if ( parentFile!=null ) {
\r
675 name = new File( f.getParentFile(), name ).getAbsolutePath();
\r
678 setExportLocationWithoutNotification(name);
\r
682 String exportLoc = exportLocation.getText();
\r
683 if (exportLoc.isEmpty()) {
\r
684 setMessage("Select an export target file.");
\r
685 setErrorMessage(null);
\r
686 setPageComplete(false);
\r
689 File file = new File(exportLoc);
\r
690 if (file.exists()) {
\r
691 if (file.isDirectory()) {
\r
692 setErrorMessage("The target already exists and it is a directory.");
\r
693 setPageComplete(false);
\r
696 if (!file.isFile()) {
\r
697 setErrorMessage("The target already exists and it is a not a regular file.");
\r
698 setPageComplete(false);
\r
702 exportModel.exportLocation = file;
\r
704 int diagramCount = 0;
\r
705 for (Node n : selectedNodes)
\r
706 if (n.getDiagramResource() != null)
\r
709 String msg = diagramCount + " diagrams selected for export.";
\r
712 setErrorMessage(null);
\r
713 setPageComplete(true);
\r