/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.internal.dialogs; import java.io.File; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.DirectoryDialog; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IEditorPart; import org.xmind.ui.dialogs.HyperlinkPage; import org.xmind.ui.internal.editor.MME; import org.xmind.ui.internal.protocols.FilePathParser; /** * * @author Frank Shaka */ public class FileHyperlinkPage extends HyperlinkPage implements Listener { private IEditorPart editor; private String basePath; private boolean relative; private File file; private Composite composite; private Text pathInput; private Button relativeButton; private Button absoluteButton; private Button fileChooser; private Button folderChooser; private boolean ignoreModify = false; private boolean warningFileNotExists = false; private boolean warningRelative = false; public FileHyperlinkPage() { } public void init(IEditorPart editor, IStructuredSelection selection) { this.editor = editor; File workbookFile = MME.getFile(editor.getEditorInput()); if (workbookFile != null) { this.basePath = workbookFile.getParent(); } else { this.basePath = null; } } public void createControl(Composite parent) { composite = new Composite(parent, SWT.NONE); composite.setLayout(new GridLayout(1, false)); createLabel(composite); createPathInput(composite); createOptionsArea(composite); createPathChoosers(composite); } private void createLabel(Composite parent) { Label label = new Label(parent, SWT.WRAP); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); ((GridData) label.getLayoutData()).widthHint = 380; label.setText(DialogMessages.FileHyperlinkPage_label); } private void createPathInput(Composite parent) { pathInput = new Text(parent, SWT.SINGLE | SWT.BORDER); pathInput.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); pathInput.addListener(SWT.Modify, this); } private void createOptionsArea(Composite parent) { GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false); Group group = new Group(parent, SWT.NONE); group.setLayoutData(layoutData); GridLayout layout = new GridLayout(2, true); group.setLayout(layout); group.setText(DialogMessages.FileHyperlinkPage_HrefGroup_Text); absoluteButton = new Button(group, SWT.RADIO); absoluteButton.setLayoutData(layoutData); absoluteButton .setText(DialogMessages.FileHyperlinkPage_AbsoluteButton_Text); absoluteButton.setSelection(true); absoluteButton.addListener(SWT.Selection, this); relativeButton = new Button(group, SWT.RADIO); relativeButton.setLayoutData(layoutData); relativeButton .setText(DialogMessages.FileHyperlinkPage_RelativeButton_Text); relativeButton.addListener(SWT.Selection, this); } private void createPathChoosers(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); GridLayout layout = new GridLayout(3, false); layout.marginWidth = 5; layout.marginHeight = 5; layout.verticalSpacing = 0; layout.horizontalSpacing = 5; composite.setLayout(layout); Label label = new Label(composite, SWT.NONE); label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); createFileChooser(composite); createFolderChooser(composite); int maxWidth = 98; for (Control c : composite.getChildren()) { if (c instanceof Button) { maxWidth = Math.max(maxWidth, c.computeSize(SWT.DEFAULT, SWT.DEFAULT).x); } } for (Control c : composite.getChildren()) { if (c instanceof Button && c.getLayoutData() instanceof GridData) { ((GridData) c.getLayoutData()).widthHint = maxWidth; } } } private void createFileChooser(Composite parent) { fileChooser = new Button(parent, SWT.PUSH); fileChooser.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); fileChooser.setText(DialogMessages.FileHyperlinkPage_ChooseFile_text); fileChooser.addListener(SWT.Selection, this); } private void createFolderChooser(Composite parent) { folderChooser = new Button(parent, SWT.PUSH); folderChooser.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); folderChooser .setText(DialogMessages.FileHyperlinkPage_ChooseFolder_text); folderChooser.addListener(SWT.Selection, this); } @Override public void setValue(String value) { super.setValue(value); String path = value == null ? null : FilePathParser.toPath(value); relative = path == null ? false : FilePathParser.isPathRelative(path); file = getFile(path); if (pathInput != null && !pathInput.isDisposed()) { ignoreModify = true; pathInput .setText(file == null ? (path == null ? "" : path) : file.getAbsolutePath()); //$NON-NLS-1$ ignoreModify = false; } if (absoluteButton != null && !absoluteButton.isDisposed()) { absoluteButton.setSelection(!relative); } if (relativeButton != null && !relativeButton.isDisposed()) { relativeButton.setSelection(relative); } } private File getFile(String path) { if (path == null) return null; if (relative) return basePath == null ? new File(System.getProperty("user.home"), //$NON-NLS-1$ path) : new File(FilePathParser.toAbsolutePath(basePath, path)); return new File(path); } @Override public boolean tryFinish() { if (file != null && relative) { if (basePath == null) { editor.doSaveAs(); File newFilePath = MME.getFile(editor.getEditorInput()); if (newFilePath == null) return false; basePath = newFilePath.getParent(); String relativePath = FilePathParser.toRelativePath(basePath, file.getAbsolutePath()); if (relativePath != null) { super.setValue(FilePathParser.toURI(relativePath, relative)); } // String workbookPath = openSaveDialog(); // if (workbookPath == null) // return false; // // basePath = new File(workbookPath).getParent(); // if (basePath == null) // return false; // // String relativePath = FilePathParser.toRelativePath(basePath, // file.getAbsolutePath()); // if (relativePath != null) { // saveWorkbook(workbookPath); // super // .setValue(FilePathParser.toURI(relativePath, // relative)); // } } } return super.tryFinish(); } // private String openSaveDialog() { // IWorkbook workbook = (IWorkbook) editor.getAdapter(IWorkbook.class); // String name = workbook.getPrimarySheet().getRootTopic().getTitleText(); // String proposalName = MindMapUtils.trimFileName(name); // return DialogUtils.save(composite.getShell(), proposalName, // new String[] { "*" + MindMapUI.FILE_EXT_XMIND }, //$NON-NLS-1$ // new String[] { DialogMessages.WorkbookFilterName }, 0, null); // } // // private void saveWorkbook(final String path) { // if (path != null) { // final IWorkbookRef workbookRef = (IWorkbookRef) editor // .getAdapter(IWorkbookRef.class); // if (workbookRef != null && workbookRef instanceof WorkbookRef) { // BusyIndicator.showWhile(Display.getCurrent(), new Runnable() { // public void run() { // final String errorMessage = NLS.bind( // DialogMessages.FailedToSaveWorkbook_message, // path); // SafeRunner.run(new SafeRunnable(errorMessage) { // public void run() throws Exception { // ((WorkbookRef) workbookRef).saveWorkbookAs( // MME.createFileEditorInput(path), // new NullProgressMonitor(), null); // } // }); // } // }); // } // } // } public void handleEvent(Event event) { if (event.widget == pathInput) { if (event.type == SWT.Modify) { if (!ignoreModify) { setFile(pathInput.getText(), false); } } } else if (event.widget == fileChooser) { FileDialog dialog = createFileDialog(); String path = dialog.open(); if (path != null) { setFile(path, true); } } else if (event.widget == folderChooser) { DirectoryDialog dialog = createFolderDialog(); String path = dialog.open(); if (path != null) { setFile(path, true); } } else if (event.widget == relativeButton) { setRelative(true); } else if (event.widget == absoluteButton) { setRelative(false); } } protected DirectoryDialog createFolderDialog() { DirectoryDialog dialog = new DirectoryDialog(composite.getShell(), SWT.OPEN | SWT.SINGLE); dialog.setText(DialogMessages.FileHyperlinkPage_OpenFileDialog_windowTitle); return dialog; } protected FileDialog createFileDialog() { FileDialog dialog = new FileDialog(composite.getShell(), SWT.OPEN | SWT.SINGLE); dialog.setText(DialogMessages.FileHyperlinkPage_OpenFileDialog_windowTitle); return dialog; } protected void setFile(String path, boolean updateWidget) { boolean invalidPath = path == null || "".equals(path); //$NON-NLS-1$ file = invalidPath ? null : new File(path); super.setValue(getURI()); setCanFinish(!invalidPath); warningFileNotExists = !invalidPath && file != null && !file.exists(); updateWarningMessage(); if (updateWidget && pathInput != null && !pathInput.isDisposed()) { ignoreModify = true; pathInput.setText(path); ignoreModify = false; } } protected void setRelative(boolean relative) { this.relative = relative; warningRelative = (relative && basePath == null); super.setValue(getURI()); updateWarningMessage(); } private void updateWarningMessage() { setMessage( warningFileNotExists ? DialogMessages.FileHyperlinkPage_FileNotExists_message : (warningRelative ? DialogMessages.FileHyperlinkPage_RelativeWarning_message : null), WARNING); } private String getURI() { if (file == null) return null; if (relative) { if (basePath != null) return FilePathParser.toURI( FilePathParser.toRelativePath(basePath, file.getAbsolutePath()), relative); } return FilePathParser.toURI(file.getAbsolutePath(), relative); } public void dispose() { } public Control getControl() { return composite; } public void setFocus() { if (pathInput != null && !pathInput.isDisposed()) pathInput.setFocus(); } }