plugins/org.symbian.tools.tmw.ui/src/org/symbian/tools/tmw/internal/ui/importwizard/ApplicationImportWizardPage.java
changeset 481 e908ec135fa1
child 483 109da596fa9d
equal deleted inserted replaced
480:b6d992b9b998 481:e908ec135fa1
       
     1 package org.symbian.tools.tmw.internal.ui.importwizard;
       
     2 
       
     3 import java.io.File;
       
     4 import java.net.URI;
       
     5 import java.text.MessageFormat;
       
     6 import java.util.Map;
       
     7 import java.util.Map.Entry;
       
     8 import java.util.TreeMap;
       
     9 
       
    10 import org.eclipse.core.resources.IFile;
       
    11 import org.eclipse.core.resources.IProject;
       
    12 import org.eclipse.core.resources.IResource;
       
    13 import org.eclipse.core.resources.IWorkspace;
       
    14 import org.eclipse.core.resources.ResourcesPlugin;
       
    15 import org.eclipse.core.runtime.IPath;
       
    16 import org.eclipse.core.runtime.IStatus;
       
    17 import org.eclipse.core.runtime.Path;
       
    18 import org.eclipse.jface.dialogs.Dialog;
       
    19 import org.eclipse.jface.layout.GridDataFactory;
       
    20 import org.eclipse.jface.viewers.ComboViewer;
       
    21 import org.eclipse.jface.viewers.ISelection;
       
    22 import org.eclipse.jface.viewers.ISelectionChangedListener;
       
    23 import org.eclipse.jface.viewers.IStructuredContentProvider;
       
    24 import org.eclipse.jface.viewers.IStructuredSelection;
       
    25 import org.eclipse.jface.viewers.LabelProvider;
       
    26 import org.eclipse.jface.viewers.SelectionChangedEvent;
       
    27 import org.eclipse.jface.viewers.StructuredSelection;
       
    28 import org.eclipse.jface.viewers.Viewer;
       
    29 import org.eclipse.jface.wizard.WizardPage;
       
    30 import org.eclipse.swt.SWT;
       
    31 import org.eclipse.swt.events.ModifyEvent;
       
    32 import org.eclipse.swt.events.ModifyListener;
       
    33 import org.eclipse.swt.events.SelectionAdapter;
       
    34 import org.eclipse.swt.events.SelectionEvent;
       
    35 import org.eclipse.swt.layout.GridData;
       
    36 import org.eclipse.swt.layout.GridLayout;
       
    37 import org.eclipse.swt.widgets.Button;
       
    38 import org.eclipse.swt.widgets.Composite;
       
    39 import org.eclipse.swt.widgets.Event;
       
    40 import org.eclipse.swt.widgets.FileDialog;
       
    41 import org.eclipse.swt.widgets.Label;
       
    42 import org.eclipse.swt.widgets.Listener;
       
    43 import org.eclipse.swt.widgets.Text;
       
    44 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
       
    45 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
       
    46 import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea;
       
    47 import org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea.IErrorMessageReporter;
       
    48 import org.symbian.tools.tmw.core.runtimes.IMobileWebRuntime;
       
    49 import org.symbian.tools.tmw.ui.TMWCoreUI;
       
    50 import org.symbian.tools.tmw.ui.project.IApplicationImporter;
       
    51 
       
    52 @SuppressWarnings("restriction")
       
    53 public class ApplicationImportWizardPage extends WizardPage {
       
    54     public class MapContentProvider implements IStructuredContentProvider {
       
    55 
       
    56         public void dispose() {
       
    57             // Do nothing
       
    58         }
       
    59 
       
    60         public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
       
    61             // Do nothing
       
    62         }
       
    63 
       
    64         @SuppressWarnings("unchecked")
       
    65         public Object[] getElements(Object inputElement) {
       
    66             return ((Map<String, IApplicationImporter>) inputElement).entrySet().toArray();
       
    67         }
       
    68 
       
    69     }
       
    70 
       
    71     // constants
       
    72     private static final int SIZING_TEXT_FIELD_WIDTH = 250;
       
    73     private final IFile file;
       
    74     // initial value stores
       
    75     private String initialProjectFieldValue;
       
    76     private ProjectContentsLocationArea locationArea;
       
    77     private final Listener nameModifyListener = new Listener() {
       
    78         public void handleEvent(Event e) {
       
    79             setLocationForSelection();
       
    80             boolean valid = validatePage();
       
    81             setPageComplete(valid);
       
    82 
       
    83         }
       
    84     };
       
    85     // widgets
       
    86     private Text projectNameField;
       
    87     private Text fileName;
       
    88     private ComboViewer runtimes;
       
    89 
       
    90     protected ApplicationImportWizardPage(IFile file) {
       
    91         super("ImportApplication");
       
    92         this.file = file;
       
    93         setTitle("Import Mobile Web Application");
       
    94         setDescription("Create mobile web application project from application package file");
       
    95         setPageComplete(false);
       
    96     }
       
    97 
       
    98     protected void browse() {
       
    99         FileDialog fileDialog = new FileDialog(getShell(), SWT.OPEN);
       
   100         String path = fileName.getText();
       
   101         path = path.trim().length() > 0 ? path.trim() : TMWCoreUI.getDefault().getPreferenceStore()
       
   102                 .getString(ApplicationImportWizard.RECENT_IMPORT_PATH);
       
   103         fileDialog.setFilterPath(path);
       
   104 
       
   105         final Map<String, String> filters = new TreeMap<String, String>();
       
   106         filters.put("*", "All files (*.*)");
       
   107         final IApplicationImporter[] importers = TMWCoreUI.getApplicationImporters();
       
   108         for (IApplicationImporter importer : importers) {
       
   109             filters.putAll(importer.getFileFilters());
       
   110         }
       
   111 
       
   112         final String[] extensions = filters.keySet().toArray(new String[filters.size()]);
       
   113         final String[] names = filters.values().toArray(new String[filters.size()]);
       
   114 
       
   115         fileDialog.setFilterExtensions(extensions);
       
   116         fileDialog.setFilterNames(names);
       
   117         String res = fileDialog.open();
       
   118         if (res != null) {
       
   119             updateWgzName(path.trim(), res);
       
   120             fileName.setText(res);
       
   121             setPageComplete(validatePage());
       
   122         }
       
   123     }
       
   124 
       
   125     public void createControl(Composite parent) {
       
   126         Composite composite = new Composite(parent, SWT.NULL);
       
   127 
       
   128         initializeDialogUnits(parent);
       
   129 
       
   130         composite.setLayout(new GridLayout());
       
   131         composite.setLayoutData(new GridData(GridData.FILL_BOTH));
       
   132 
       
   133         createProjectNameGroup(composite);
       
   134         locationArea = new ProjectContentsLocationArea(getErrorReporter(), composite);
       
   135         if (initialProjectFieldValue != null) {
       
   136             locationArea.updateProjectName(initialProjectFieldValue);
       
   137         }
       
   138 
       
   139         // Scale the button based on the rest of the dialog
       
   140         setButtonLayoutData(locationArea.getBrowseButton());
       
   141         if (file != null) {
       
   142             fileName.setText(file.getLocation().toOSString());
       
   143         }
       
   144         setPageComplete(validatePage());
       
   145         // Show description on opening
       
   146         setErrorMessage(null);
       
   147         setMessage(null);
       
   148         setControl(composite);
       
   149         Dialog.applyDialogFont(composite);
       
   150 
       
   151         setControl(composite);
       
   152     }
       
   153 
       
   154     /**
       
   155      * Creates the project name specification controls.
       
   156      * 
       
   157      * @param parent
       
   158      *            the parent composite
       
   159      */
       
   160     private final void createProjectNameGroup(Composite parent) {
       
   161         // project specification group
       
   162         Composite projectGroup = new Composite(parent, SWT.NONE);
       
   163         GridLayout layout = new GridLayout();
       
   164         layout.numColumns = 2;
       
   165         projectGroup.setLayout(layout);
       
   166         projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
       
   167 
       
   168         Label label = new Label(projectGroup, SWT.NONE);
       
   169         label.setText("WGZ archive:");
       
   170 
       
   171         Composite buttonText = new Composite(projectGroup, SWT.NONE);
       
   172 
       
   173         buttonText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
       
   174 
       
   175         GridLayout gridLayout = new GridLayout(2, false);
       
   176         gridLayout.marginWidth = 0;
       
   177         gridLayout.marginHeight = 0;
       
   178         buttonText.setLayout(gridLayout);
       
   179 
       
   180         fileName = new Text(buttonText, SWT.BORDER);
       
   181         fileName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
       
   182         fileName.addModifyListener(new ModifyListener() {
       
   183             public void modifyText(ModifyEvent e) {
       
   184                 String val = fileName.getData() != null ? fileName.getData().toString() : "";
       
   185                 String name = fileName.getText().trim();
       
   186                 updateWgzName(val, name);
       
   187                 fileName.setData(name);
       
   188                 setPageComplete(validatePage());
       
   189             }
       
   190         });
       
   191         Button browse = new Button(buttonText, SWT.NONE);
       
   192         browse.setText("Browse...");
       
   193         browse.addSelectionListener(new SelectionAdapter() {
       
   194             @Override
       
   195             public void widgetSelected(SelectionEvent e) {
       
   196                 browse();
       
   197             }
       
   198         });
       
   199 
       
   200         new Label(projectGroup, SWT.NONE).setText("Targeted runtime:");
       
   201         runtimes = new ComboViewer(projectGroup, SWT.BORDER | SWT.READ_ONLY);
       
   202         runtimes.getCombo().setEnabled(false);
       
   203         runtimes.setContentProvider(new MapContentProvider());
       
   204         runtimes.setLabelProvider(new LabelProvider() {
       
   205             @SuppressWarnings("unchecked")
       
   206             @Override
       
   207             public String getText(Object element) {
       
   208                 return ((Map.Entry<String, IApplicationImporter>) element).getKey().toString();
       
   209             }
       
   210         });
       
   211         runtimes.getControl().setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
       
   212         runtimes.addSelectionChangedListener(new ISelectionChangedListener() {
       
   213             public void selectionChanged(SelectionChangedEvent event) {
       
   214                 setPageComplete(validatePage());
       
   215             }
       
   216         });
       
   217 
       
   218         Label separator = new Label(projectGroup, SWT.NONE);
       
   219         GridDataFactory.generate(separator, 2, 2);
       
   220 
       
   221         // new project label
       
   222         Label projectLabel = new Label(projectGroup, SWT.NONE);
       
   223         projectLabel.setText(IDEWorkbenchMessages.WizardNewProjectCreationPage_nameLabel);
       
   224         projectLabel.setFont(parent.getFont());
       
   225 
       
   226         // new project name entry field
       
   227         projectNameField = new Text(projectGroup, SWT.BORDER);
       
   228         GridData data = new GridData(GridData.FILL_HORIZONTAL);
       
   229         data.widthHint = SIZING_TEXT_FIELD_WIDTH;
       
   230         projectNameField.setLayoutData(data);
       
   231         projectNameField.setFont(parent.getFont());
       
   232 
       
   233         // Set the initial value first before listener
       
   234         // to avoid handling an event during the creation.
       
   235         if (initialProjectFieldValue != null) {
       
   236             projectNameField.setText(initialProjectFieldValue);
       
   237         }
       
   238         projectNameField.addListener(SWT.Modify, nameModifyListener);
       
   239     }
       
   240 
       
   241     public String getArchiveFile() {
       
   242         return fileName.getText().trim();
       
   243     }
       
   244 
       
   245     /**
       
   246      * Get an error reporter for the receiver.
       
   247      * 
       
   248      * @return IErrorMessageReporter
       
   249      */
       
   250     private IErrorMessageReporter getErrorReporter() {
       
   251         return new IErrorMessageReporter() {
       
   252             /*
       
   253              * (non-Javadoc)
       
   254              * 
       
   255              * @see
       
   256              * org.eclipse.ui.internal.ide.dialogs.ProjectContentsLocationArea
       
   257              * .IErrorMessageReporter#reportError(java.lang.String)
       
   258              */
       
   259             public void reportError(String errorMessage, boolean infoOnly) {
       
   260                 if (infoOnly) {
       
   261                     setMessage(errorMessage, IStatus.INFO);
       
   262                     setErrorMessage(null);
       
   263                 } else {
       
   264                     setErrorMessage(errorMessage);
       
   265                 }
       
   266                 boolean valid = errorMessage == null;
       
   267                 if (valid) {
       
   268                     valid = validatePage();
       
   269                 }
       
   270 
       
   271                 setPageComplete(valid);
       
   272             }
       
   273         };
       
   274     }
       
   275 
       
   276     /**
       
   277      * Returns the current project location path as entered by the user, or its
       
   278      * anticipated initial value. Note that if the default has been returned the
       
   279      * path in a project description used to create a project should not be set.
       
   280      * 
       
   281      * @return the project location path or its anticipated initial value.
       
   282      */
       
   283     public IPath getLocationPath() {
       
   284         return new Path(locationArea.getProjectLocation());
       
   285     }
       
   286 
       
   287     /**
       
   288      * /** Returns the current project location URI as entered by the user, or
       
   289      * <code>null</code> if a valid project location has not been entered.
       
   290      * 
       
   291      * @return the project location URI, or <code>null</code>
       
   292      * @since 3.2
       
   293      */
       
   294     public URI getLocationURI() {
       
   295         return locationArea.getProjectLocationURI();
       
   296     }
       
   297 
       
   298     /**
       
   299      * Creates a project resource handle for the current project name field
       
   300      * value. The project handle is created relative to the workspace root.
       
   301      * <p>
       
   302      * This method does not create the project resource; this is the
       
   303      * responsibility of <code>IProject::create</code> invoked by the new
       
   304      * project resource wizard.
       
   305      * </p>
       
   306      * 
       
   307      * @return the new project resource handle
       
   308      */
       
   309     public IProject getProjectHandle() {
       
   310         return ResourcesPlugin.getWorkspace().getRoot().getProject(getProjectName());
       
   311     }
       
   312 
       
   313     /**
       
   314      * Returns the current project name as entered by the user, or its
       
   315      * anticipated initial value.
       
   316      * 
       
   317      * @return the project name, its anticipated initial value, or
       
   318      *         <code>null</code> if no project name is known
       
   319      */
       
   320     public String getProjectName() {
       
   321         if (projectNameField == null) {
       
   322             return initialProjectFieldValue;
       
   323         }
       
   324 
       
   325         return getProjectNameFieldValue();
       
   326     }
       
   327 
       
   328     /**
       
   329      * Returns the value of the project name field with leading and trailing
       
   330      * spaces removed.
       
   331      * 
       
   332      * @return the project name in the field
       
   333      */
       
   334     private String getProjectNameFieldValue() {
       
   335         if (projectNameField == null) {
       
   336             return ""; //$NON-NLS-1$
       
   337         }
       
   338 
       
   339         return projectNameField.getText().trim();
       
   340     }
       
   341 
       
   342     /**
       
   343      * Sets the initial project name that this page will use when created. The
       
   344      * name is ignored if the createControl(Composite) method has already been
       
   345      * called. Leading and trailing spaces in the name are ignored. Providing
       
   346      * the name of an existing project will not necessarily cause the wizard to
       
   347      * warn the user. Callers of this method should first check if the project
       
   348      * name passed already exists in the workspace.
       
   349      * 
       
   350      * @param name
       
   351      *            initial project name for this page
       
   352      * 
       
   353      * @see IWorkspace#validateName(String, int)
       
   354      * 
       
   355      */
       
   356     public void setInitialProjectName(String name) {
       
   357         if (name == null) {
       
   358             initialProjectFieldValue = null;
       
   359         } else {
       
   360             initialProjectFieldValue = name.trim();
       
   361             if (locationArea != null) {
       
   362                 locationArea.updateProjectName(name.trim());
       
   363             }
       
   364         }
       
   365     }
       
   366 
       
   367     /**
       
   368      * Set the location to the default location if we are set to useDefaults.
       
   369      */
       
   370     void setLocationForSelection() {
       
   371         locationArea.updateProjectName(getProjectNameFieldValue());
       
   372     }
       
   373 
       
   374     private void updateWgzName(String oldValue, String newValue) {
       
   375         String project = projectNameField.getText().trim();
       
   376         if (project.length() == 0 || project.equals(new Path(oldValue).removeFileExtension().lastSegment())) {
       
   377             String projectName = new Path(newValue).removeFileExtension().lastSegment();
       
   378             projectNameField.setText(projectName);
       
   379             locationArea.updateProjectName(projectName);
       
   380         }
       
   381     }
       
   382 
       
   383     /**
       
   384      * Returns the useDefaults.
       
   385      * 
       
   386      * @return boolean
       
   387      */
       
   388     public boolean useDefaults() {
       
   389         return locationArea.isDefault();
       
   390     }
       
   391 
       
   392     private boolean validating = false;
       
   393 
       
   394     /**
       
   395      * Returns whether this page's controls currently all contain valid values.
       
   396      * 
       
   397      * @return <code>true</code> if all controls are valid, and
       
   398      *         <code>false</code> if at least one is invalid
       
   399      */
       
   400     protected synchronized boolean validatePage() {
       
   401         if (validating) {
       
   402             return true;
       
   403         }
       
   404         validating = true;
       
   405         try {
       
   406             final IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
       
   407             final String archive = fileName.getText().trim();
       
   408             if (archive.equals("")) {
       
   409                 setErrorMessage(null);
       
   410                 setMessage("Archive name must be specified");
       
   411                 return false;
       
   412             }
       
   413 
       
   414             final File f = new File(archive);
       
   415             if (!isValidArchive(f)) {
       
   416                 setErrorMessage(MessageFormat.format("{0} is not a valid application archive", archive));
       
   417                 return false;
       
   418             }
       
   419 
       
   420             final String projectFieldContents = getProjectNameFieldValue();
       
   421             if (projectFieldContents.equals("")) { //$NON-NLS-1$
       
   422                 setErrorMessage(null);
       
   423                 setMessage(IDEWorkbenchMessages.WizardNewProjectCreationPage_projectNameEmpty);
       
   424                 return false;
       
   425             }
       
   426 
       
   427             final IStatus nameStatus = workspace.validateName(projectFieldContents, IResource.PROJECT);
       
   428             if (!nameStatus.isOK()) {
       
   429                 setErrorMessage(nameStatus.getMessage());
       
   430                 return false;
       
   431             }
       
   432 
       
   433             final IProject handle = getProjectHandle();
       
   434             if (handle.exists()) {
       
   435                 setErrorMessage(IDEWorkbenchMessages.WizardNewProjectCreationPage_projectExistsMessage);
       
   436                 return false;
       
   437             }
       
   438 
       
   439             final IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(getProjectNameFieldValue());
       
   440             locationArea.setExistingProject(project);
       
   441 
       
   442             final String validLocationMessage = locationArea.checkValidLocation();
       
   443             if (validLocationMessage != null) { // there is no destination location given
       
   444                 setErrorMessage(validLocationMessage);
       
   445                 return false;
       
   446             }
       
   447             if (runtimes.getSelection().isEmpty()) {
       
   448                 setErrorMessage("Select target runtime");
       
   449                 return false;
       
   450             }
       
   451 
       
   452             setErrorMessage(null);
       
   453             setMessage(null);
       
   454             return true;
       
   455         } finally {
       
   456             validating = false;
       
   457         }
       
   458     }
       
   459 
       
   460     private boolean isValidArchive(File f) {
       
   461         if (f.isFile()) {
       
   462             final Map<String, IApplicationImporter> importers = new TreeMap<String, IApplicationImporter>();
       
   463             final IApplicationImporter[] applicationImporters = TMWCoreUI.getApplicationImporters();
       
   464             for (IApplicationImporter importer : applicationImporters) {
       
   465                 final IMobileWebRuntime runtime = importer.getApplicationRuntime(f);
       
   466                 if (runtime != null) {
       
   467                     importers.put(runtime.getName(), importer);
       
   468                 }
       
   469             }
       
   470             final ISelection selection = runtimes.getSelection();
       
   471             Object sel = null;
       
   472             if (!selection.isEmpty()) {
       
   473                 @SuppressWarnings("unchecked")
       
   474                 Map.Entry<String, IApplicationImporter> entry = (Entry<String, IApplicationImporter>) ((IStructuredSelection) selection)
       
   475                         .getFirstElement();
       
   476                 for (Entry<String, IApplicationImporter> ent : importers.entrySet()) {
       
   477                     if (ent.getKey().equals(entry.getKey())) {
       
   478                         sel = ent;
       
   479                     }
       
   480                 }
       
   481             }
       
   482             runtimes.setInput(importers);
       
   483             if (sel != null) {
       
   484                 runtimes.setSelection(new StructuredSelection(sel));
       
   485             } else if (importers.size() == 1) {
       
   486                 runtimes.setSelection(new StructuredSelection(importers.entrySet().iterator().next()));
       
   487             }
       
   488             runtimes.getControl().setEnabled(importers.size() > 1);
       
   489             return !runtimes.getSelection().isEmpty();
       
   490         }
       
   491         return false;
       
   492     }
       
   493 
       
   494     public IApplicationImporter getImporter() {
       
   495         if (runtimes == null || runtimes.getControl().isDisposed()) {
       
   496             return null;
       
   497         }
       
   498         @SuppressWarnings("unchecked")
       
   499         final Map.Entry<String, IApplicationImporter> element = (Entry<String, IApplicationImporter>) ((IStructuredSelection) runtimes
       
   500                 .getSelection()).getFirstElement();
       
   501         return element.getValue();
       
   502     }
       
   503 
       
   504 }