001: /*
002: * uDig - User Friendly Desktop Internet GIS client
003: * http://udig.refractions.net
004: * (C) 2004, Refractions Research Inc.
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package net.refractions.udig.catalog.ui;
018:
019: import java.io.File;
020: import java.io.IOException;
021: import java.io.Serializable;
022: import java.lang.reflect.InvocationTargetException;
023: import java.net.URL;
024: import java.util.ArrayList;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028:
029: import net.refractions.udig.catalog.CatalogPlugin;
030: import net.refractions.udig.catalog.IService;
031: import net.refractions.udig.catalog.internal.ui.ConnectionPage;
032: import net.refractions.udig.catalog.ui.internal.Messages;
033: import net.refractions.udig.catalog.ui.workflow.ConnectionState;
034: import net.refractions.udig.catalog.ui.workflow.Workflow;
035: import net.refractions.udig.catalog.ui.workflow.WorkflowWizard;
036: import net.refractions.udig.catalog.ui.workflow.WorkflowWizardDialog;
037: import net.refractions.udig.catalog.ui.workflow.WorkflowWizardPage;
038:
039: import org.eclipse.core.runtime.IProgressMonitor;
040: import org.eclipse.core.runtime.Platform;
041: import org.eclipse.core.runtime.SubProgressMonitor;
042: import org.eclipse.jface.dialogs.IDialogConstants;
043: import org.eclipse.jface.dialogs.IPageChangedListener;
044: import org.eclipse.jface.dialogs.PageChangedEvent;
045: import org.eclipse.jface.operation.IRunnableWithProgress;
046: import org.eclipse.jface.wizard.IWizardContainer;
047: import org.eclipse.jface.wizard.WizardDialog;
048: import org.eclipse.swt.SWT;
049: import org.eclipse.swt.widgets.Button;
050: import org.eclipse.swt.widgets.Composite;
051: import org.eclipse.swt.widgets.Control;
052: import org.eclipse.swt.widgets.Display;
053: import org.eclipse.swt.widgets.Event;
054: import org.eclipse.swt.widgets.FileDialog;
055: import org.eclipse.ui.PlatformUI;
056:
057: /**
058: * A wizard page that opens a file dialog and closes the wizard when dialog is closed.
059: *
060: * @author jeichar
061: * @since 0.9.0
062: */
063: public class FileConnectionPage extends WorkflowWizardPage implements
064: UDIGConnectionPage, IPageChangedListener {
065:
066: private boolean canFlipToNextPage = false;
067: private ArrayList<URL> list;
068: private Composite comp;
069:
070: private FileConnectionFactory factory = new FileConnectionFactory();
071: private FileDialog fileDialog;
072:
073: public String getId() {
074: return "net.refractions.udig.catalog.ui.openFilePage"; //$NON-NLS-1$
075: }
076:
077: /**
078: * Construct <code>OpenFilePage</code>.
079: */
080: public FileConnectionPage() {
081: super (Messages.OpenFilePage_pageTitle);
082: }
083:
084: List<IService> process(List<URL> urls, IProgressMonitor monitor) {
085: List<IService> resources = new ArrayList<IService>();
086: monitor.beginTask(Messages.OpenFilePage_1, list.size());
087: int worked = 0;
088: for (URL url : urls) {
089: if (monitor.isCanceled())
090: return null;
091: try {
092: monitor.subTask(url.toExternalForm());
093: List<IService> acquire = CatalogPlugin.getDefault()
094: .getServiceFactory().acquire(url);
095: resources.addAll(acquire);
096: } catch (Throwable e) {
097: CatalogUIPlugin
098: .log(
099: "error obtaining services from service factory", e); //$NON-NLS-1$
100: }
101: monitor.worked(worked++);
102: }
103: return resources;
104: }
105:
106: private void cancelWizard() {
107: try {
108: getShell().getDisplay().asyncExec(new Runnable() {
109: public void run() {
110: findButton(getShell().getChildren(),
111: IDialogConstants.BACK_ID).notifyListeners(
112: SWT.Selection, new Event());
113: }
114:
115: });
116: } catch (Exception e) {
117: CatalogUIPlugin.log("", e); //$NON-NLS-1$
118: }
119: }
120:
121: Button findButton(Control[] children, int id) {
122: if (((Integer) getShell().getDefaultButton().getData())
123: .intValue() == id)
124: return getShell().getDefaultButton();
125:
126: for (Control child : children) {
127: if (child instanceof Button) {
128: Button button = (Button) child;
129: if (button.getData() != null
130: && ((Integer) button.getData()).intValue() == id)
131: return button;
132: }
133: if (child instanceof Composite) {
134: Composite composite = (Composite) child;
135: Button button = findButton(composite.getChildren(), id);
136: if (button != null)
137: return button;
138: }
139: }
140: return null;
141: }
142:
143: Workflow workflow;
144:
145: private void finishWizard() {
146: try {
147: if (getContainer() instanceof WizardDialog) {
148: final IWizardContainer dialog = getContainer();
149: WorkflowWizard wizard = null;
150: if (dialog instanceof WorkflowWizardDialog) {
151: wizard = ((WorkflowWizardDialog) dialog)
152: .getWorkflowWizard();
153: } else if (dialog.getCurrentPage().getWizard() instanceof WorkflowWizard) {
154: wizard = (WorkflowWizard) dialog.getCurrentPage()
155: .getWizard();
156: }
157:
158: if (wizard != null) {
159: //move workflow to next state
160: workflow = wizard.getWorkflow();
161: final ConnectionState currentState = (ConnectionState) workflow
162: .getCurrentState();
163: (currentState).setURLs(getURLs());
164:
165: final boolean[] finished = new boolean[] { false };
166:
167: dialog.run(true, true, new IRunnableWithProgress() {
168: public void run(IProgressMonitor monitor)
169: throws InvocationTargetException,
170: InterruptedException {
171: monitor
172: .beginTask(
173: Messages.FileConnectionPage_taskname,
174: IProgressMonitor.UNKNOWN);
175: try {
176: // if (currentState.run(new SubProgressMonitor(monitor, 4))
177: // && hasOneResource(new SubProgressMonitor(monitor, 4),
178: // currentState.getServices()) ) {
179: finished[0] = workflow
180: .run(new SubProgressMonitor(
181: monitor, 4));
182: // }else{
183: // workflow.next(new SubProgressMonitor(monitor, 8));
184: // }
185: } catch (Exception e) {
186: throw new InvocationTargetException(e);
187: }
188: };
189: });
190: if (finished[0] && dialog != null
191: && dialog.getShell() != null
192: && !dialog.getShell().isDisposed()) {
193: Display.getDefault().asyncExec(new Runnable() {
194: public void run() {
195: dialog.getShell().close();
196: }
197: });
198: }
199: }
200:
201: //one good hack deserves another
202: if (!(dialog instanceof WizardDialog)) {
203: //manually move wizard to next state
204: ((WizardDialog) dialog)
205: .addPageChangedListener(this );
206: }
207:
208: }
209:
210: } catch (Exception e) {
211: CatalogUIPlugin.log("", e); //$NON-NLS-1$
212: }
213: }
214:
215: protected boolean hasOneResource(SubProgressMonitor monitor,
216: List<IService> services) throws IOException {
217: if (services.size() > 1 || services.isEmpty())
218: return false;
219:
220: if (services.get(0).members(monitor).size() == 1)
221: return true;
222: return false;
223: }
224:
225: public void pageChanged(PageChangedEvent event) {
226: if (getContainer().getCurrentPage() instanceof ConnectionPage) {
227: WizardDialog dialog = (WizardDialog) getContainer();
228: dialog.removePageChangedListener(this );
229:
230: final int button = workflow.hasMoreStates() ? IDialogConstants.NEXT_ID
231: : IDialogConstants.FINISH_ID;
232:
233: getShell().getDisplay().asyncExec(new Runnable() {
234: public void run() {
235: findButton(getShell().getChildren(), button)
236: .notifyListeners(SWT.Selection, new Event());
237:
238: }
239: });
240:
241: }
242: }
243:
244: /**
245: * @see org.eclipse.jface.wizard.WizardPage#canFlipToNextPage()
246: */
247: public boolean canFlipToNextPage() {
248: return (list != null && list.size() > 1) || canFlipToNextPage;
249: }
250:
251: /**
252: * @see net.refractions.udig.ui.UDIGImportPage#setCanFlipToNextPage(boolean)
253: */
254: public void setCanFlipToNextPage(boolean value) {
255: canFlipToNextPage = true;
256: }
257:
258: /**
259: * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
260: */
261: public void createControl(Composite parent) {
262: comp = new Composite(parent, SWT.NULL);
263: // comp.setLayout(new GridLayout(1,true));
264: // viewer=new ListViewer(comp);
265: // viewer.getControl().setLayoutData(new GridData(SWT.FILL,SWT.FILL,true, true));
266: // viewer.setContentProvider(new ArrayContentProvider());
267: // viewer.setLabelProvider(new LabelProvider());
268: setControl(comp);
269:
270: Display.getCurrent().asyncExec(new Runnable() {
271: public void run() {
272: boolean open = openFileDialog(comp);
273: if (open) {
274: finishWizard();
275: } else {
276: cancelWizard();
277: }
278: }
279: });
280: }
281:
282: private boolean checkDND(FileDialog fileDialog) {
283: try {
284:
285: Object context = getState().getWorkflow().getContext();
286:
287: // IStructuredSelection selection = ((IDataWizard) getWizard()).getSelection();
288:
289: ArrayList<URL> urlList = new ArrayList<URL>();
290:
291: URL url = factory.createConnectionURL(context);
292: if (url != null) {
293: urlList.add(url);
294: }
295:
296: if (urlList.size() != 0) {
297: list = urlList;
298: String file = urlList.get(0).getFile();
299: String ext = file.substring(file.lastIndexOf('.'));
300: String dir = new File(file).getParent();
301:
302: file = file
303: .substring(file.lastIndexOf(File.separator) + 1);
304: fileDialog.setFilterPath(dir);
305: fileDialog.setFileName(file);
306:
307: String[] filters = fileDialog.getFilterExtensions();
308: if (filters == null || filters.length == 0) {
309: // no filters set, set em up
310: fileDialog.setFilterExtensions(new String[] {
311: "*" + ext, "*.*" }); //$NON-NLS-1$ //$NON-NLS-2$
312: } else {
313: // we have some filters, look for the one in question
314: // in the list
315: int i = 0;
316: for (; i < filters.length; i++) {
317: if (("*" + ext).equals(filters[i]))break; //$NON-NLS-1$
318: }
319:
320: if (i < filters.length) {
321: // we found it, reorganize the array so that
322: // it is first
323: String[] nfilters = new String[filters.length];
324: nfilters[0] = filters[i];
325: System.arraycopy(filters, 0, nfilters, 1, i);
326: System.arraycopy(filters, i + 1, nfilters,
327: i + 1, filters.length - i - 1);
328: fileDialog.setFilterExtensions(nfilters);
329: } else {
330: // no dice, add the filter
331: String[] nfilters = new String[filters.length + 1];
332: nfilters[0] = "*" + ext; //$NON-NLS-1$
333: System.arraycopy(filters, 0, nfilters, 1,
334: filters.length);
335: fileDialog.setFilterExtensions(nfilters);
336: }
337: }
338:
339: return true;
340: }
341: } catch (Exception e) {
342: CatalogUIPlugin.log(e.getLocalizedMessage(), e);
343: }
344:
345: return false;
346:
347: }
348:
349: public FileDialog getFileDialog() {
350: return fileDialog;
351: }
352:
353: private boolean openFileDialog(Composite parent) {
354: String lastOpenedDirectory = PlatformUI.getPreferenceStore()
355: .getString(CatalogUIPlugin.PREF_OPEN_DIALOG_DIRECTORY);
356: fileDialog = new FileDialog(parent.getShell(), SWT.MULTI);
357: List<String> fileTypes = factory.getExtensionList();
358:
359: StringBuffer all = new StringBuffer();
360: for (Iterator<String> i = fileTypes.iterator(); i.hasNext();) {
361: all.append(i.next());
362: if (i.hasNext())
363: all.append(";"); //semicolon is magic in eclipse FileDialog
364: }
365: fileTypes.add(0, all.toString());
366:
367: fileTypes.add("*.*"); //$NON-NLS-1$
368:
369: fileDialog.setFilterExtensions(fileTypes
370: .toArray(new String[fileTypes.size()]));
371:
372: if (lastOpenedDirectory != null && !checkDND(fileDialog)) {
373: fileDialog.setFilterPath(lastOpenedDirectory);
374: }
375:
376: // //this is a HACK to check for headless execution
377: // if (getContainer() instanceof HeadlessWizardDialog) {
378: // if (dnd)
379: // return true; //there was a workbench selection that allowed us select a file
380: // }
381: //
382: String result = fileDialog.open();
383: if (result == null) {
384: return false;
385: }
386: String path = fileDialog.getFilterPath();
387: PlatformUI.getPreferenceStore().setValue(
388: CatalogUIPlugin.PREF_OPEN_DIALOG_DIRECTORY, path);
389: String[] filenames = fileDialog.getFileNames();
390: list = new ArrayList<URL>();
391: for (int i = 0; i < filenames.length; i++) {
392: try {
393: URL url = new File(
394: path
395: + System.getProperty("file.separator") + filenames[i]).toURL(); //$NON-NLS-1$
396: list.add(url);
397: } catch (Throwable e) {
398: CatalogUIPlugin.log("", e); //$NON-NLS-1$
399: }
400: }
401: return true;
402: // viewer.setInput(urls);
403: }
404:
405: public List<URL> getURLs() {
406: if (list == null || list.isEmpty())
407: return null;
408:
409: return list;
410: }
411:
412: public Map<String, Serializable> getParams() {
413: return null; // no specific connection parameters
414: }
415:
416: }
|