RC2 compatibility
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / ui / preferences / OptionsConfigurationBlock.java
index 941b851..2e4ce5d 100644 (file)
  *******************************************************************************/
 package net.sourceforge.phpdt.internal.ui.preferences;
 
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Hashtable;
+import java.util.Iterator;
 import java.util.Map;
 import java.util.StringTokenizer;
+import java.util.Map.Entry;
 
 import net.sourceforge.phpdt.core.IJavaProject;
 import net.sourceforge.phpdt.core.JavaCore;
-import net.sourceforge.phpdt.internal.ui.util.ExceptionHandler;
 import net.sourceforge.phpdt.internal.ui.wizards.IStatusChangeListener;
 import net.sourceforge.phpeclipse.PHPeclipsePlugin;
 
 import org.eclipse.core.resources.IncrementalProjectBuilder;
+import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.SubProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.dialogs.IDialogConstants;
 import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.dialogs.ProgressMonitorDialog;
-import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
@@ -48,7 +51,11 @@ import org.eclipse.swt.widgets.Text;
 import org.eclipse.swt.widgets.Widget;
 
 /**
-  */
+ * Abstract options configuration block providing a general implementation for setting up
+ * an options configuration page.
+ * 
+ * @since 2.1
+ */
 public abstract class OptionsConfigurationBlock {
 
        protected static class ControlData {
@@ -74,12 +81,14 @@ public abstract class OptionsConfigurationBlock {
                }               
                
                public int getSelection(String value) {
-                       for (int i= 0; i < fValues.length; i++) {
-                               if (value.equals(fValues[i])) {
-                                       return i;
+                       if (value != null) {
+                               for (int i= 0; i < fValues.length; i++) {
+                                       if (value.equals(fValues[i])) {
+                                               return i;
+                                       }
                                }
                        }
-                       return 0;
+                       return fValues.length -1; // assume the last option is the least severe
                }
        }
        
@@ -96,14 +105,17 @@ public abstract class OptionsConfigurationBlock {
 
        protected IStatusChangeListener fContext;
        protected IJavaProject fProject; // project or null
+       protected String[] fAllKeys;
        
        private Shell fShell;
 
-       public OptionsConfigurationBlock(IStatusChangeListener context, IJavaProject project) {
+       public OptionsConfigurationBlock(IStatusChangeListener context, IJavaProject project, String[] allKeys) {
                fContext= context;
                fProject= project;
+               fAllKeys= allKeys;
                
                fWorkingValues= getOptions(true);
+               testIfOptionsComplete(fWorkingValues, allKeys);
                
                fCheckBoxes= new ArrayList();
                fComboBoxes= new ArrayList();
@@ -111,8 +123,14 @@ public abstract class OptionsConfigurationBlock {
                fLabels= new HashMap();
        }
        
-       protected abstract String[] getAllKeys();
-       
+       private void testIfOptionsComplete(Map workingValues, String[] allKeys) {
+               for (int i= 0; i < allKeys.length; i++) {
+                       if (workingValues.get(allKeys[i]) == null) {
+                               PHPeclipsePlugin.logErrorMessage("preference option missing: " + allKeys[i] + " (" + this.getClass().getName() +')');  //$NON-NLS-1$//$NON-NLS-2$
+                       }
+               }
+       }
+
        protected Map getOptions(boolean inheritJavaCoreOptions) {
                if (fProject != null) {
                        return fProject.getOptions(inheritJavaCoreOptions);
@@ -128,7 +146,7 @@ public abstract class OptionsConfigurationBlock {
        public final boolean hasProjectSpecificOptions() {
                if (fProject != null) {
                        Map settings= fProject.getOptions(false);
-                       String[] allKeys= getAllKeys();
+                       String[] allKeys= fAllKeys;
                        for (int i= 0; i < allKeys.length; i++) {
                                if (settings.get(allKeys[i]) != null) {
                                        return true;
@@ -140,12 +158,44 @@ public abstract class OptionsConfigurationBlock {
                
        protected void setOptions(Map map) {
                if (fProject != null) {
+                       Map oldOptions= fProject.getOptions(false);
                        fProject.setOptions(map);
+                       firePropertyChangeEvents(oldOptions, map);
                } else {
                        JavaCore.setOptions((Hashtable) map);
                }       
        } 
        
+       /**
+        * Computes the differences between the given old and new options and fires corresponding
+        * property change events on the Java plugin's mockup preference store.
+        * @param oldOptions The old options
+        * @param newOptions The new options
+        */
+       private void firePropertyChangeEvents(Map oldOptions, Map newOptions) {
+               oldOptions= new HashMap(oldOptions);
+               Object source= fProject.getProject();
+               MockupPreferenceStore store= PHPeclipsePlugin.getDefault().getMockupPreferenceStore();
+               Iterator iter= newOptions.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Entry entry= (Entry) iter.next();
+               
+                       String name= (String) entry.getKey();
+                       Object oldValue= oldOptions.get(name);
+                       Object newValue= entry.getValue();
+                       
+                       if ((oldValue != null && !oldValue.equals(newValue)) || (oldValue == null && newValue != null))
+                               store.firePropertyChangeEvent(source, name, oldValue, newValue);
+                       oldOptions.remove(name);
+               }
+               
+               iter= oldOptions.entrySet().iterator();
+               while (iter.hasNext()) {
+                       Entry entry= (Entry) iter.next();
+                       store.firePropertyChangeEvent(source, (String) entry.getKey(), entry.getValue(), null);
+               }
+       }
+
        protected Shell getShell() {
                return fShell;
        }
@@ -169,7 +219,7 @@ public abstract class OptionsConfigurationBlock {
                checkBox.setLayoutData(gd);
                checkBox.addSelectionListener(getSelectionListener());
                
-               String currValue= (String)fWorkingValues.get(key);      
+               String currValue= (String)fWorkingValues.get(key);
                checkBox.setSelection(data.getSelection(currValue) == 0);
                
                fCheckBoxes.add(checkBox);
@@ -250,7 +300,9 @@ public abstract class OptionsConfigurationBlock {
                fLabels.put(textBox, labelControl);
                
                String currValue= (String) fWorkingValues.get(key);     
-               textBox.setText(currValue);
+               if (currValue != null) {
+                       textBox.setText(currValue);
+               }
                textBox.addModifyListener(getTextModifyListener());
 
                GridData data= new GridData(GridData.HORIZONTAL_ALIGN_FILL);
@@ -334,7 +386,7 @@ public abstract class OptionsConfigurationBlock {
 
        
        public boolean performOk(boolean enabled) {
-               String[] allKeys= getAllKeys();
+               String[] allKeys= fAllKeys;
                Map actualOptions= getOptions(false);
                
                // preserve other options
@@ -345,7 +397,7 @@ public abstract class OptionsConfigurationBlock {
                        String val= null;
                        if (enabled) {
                                val= (String) fWorkingValues.get(key);
-                               if (!val.equals(oldVal)) {
+                               if (val != null && !val.equals(oldVal)) {
                                        hasChanges= true;
                                        actualOptions.put(key, val);
                                }
@@ -372,7 +424,10 @@ public abstract class OptionsConfigurationBlock {
                        }
                        setOptions(actualOptions);
                        if (doBuild) {
-                               doFullBuild();
+                               boolean res= doFullBuild();
+                               if (!res) {
+                                       return false;
+                               }
                        }
                }
                return true;
@@ -380,35 +435,41 @@ public abstract class OptionsConfigurationBlock {
        
        protected abstract String[] getFullBuildDialogStrings(boolean workspaceSettings);
                
-       protected void doFullBuild() {
-               ProgressMonitorDialog dialog= new ProgressMonitorDialog(getShell());
-               try {
-                       dialog.run(true, true, new IRunnableWithProgress() { 
-                               public void run(IProgressMonitor monitor) throws InvocationTargetException {
-                                       monitor.beginTask("", 2); //$NON-NLS-1$
-                                       try {
-                                               if (fProject != null) {
-                                                       monitor.setTaskName(PreferencesMessages.getFormattedString("OptionsConfigurationBlock.buildproject.taskname", fProject.getElementName())); //$NON-NLS-1$
-                                                       fProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor,1));
-                                                       PHPeclipsePlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(monitor,1));
-                                               } else {
-                                                       monitor.setTaskName(PreferencesMessages.getString("OptionsConfigurationBlock.buildall.taskname")); //$NON-NLS-1$
-                                                       PHPeclipsePlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor, 2));
-                                               }
-                                       } catch (CoreException e) {
-                                               throw new InvocationTargetException(e);
-                                       } finally {
-                                               monitor.done();
+       protected boolean doFullBuild() {
+               
+               Job buildJob = new Job(PreferencesMessages.getString("OptionsConfigurationBlock.job.title")){  //$NON-NLS-1$
+                       /* (non-Javadoc)
+                        * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
+                        */
+                       protected IStatus run(IProgressMonitor monitor) {
+                               try {
+                                       if (fProject != null) {
+                                               monitor.setTaskName(PreferencesMessages.getFormattedString("OptionsConfigurationBlock.buildproject.taskname", fProject.getElementName())); //$NON-NLS-1$
+                                               fProject.getProject().build(IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor,1));
+                                               PHPeclipsePlugin.getWorkspace().build(IncrementalProjectBuilder.INCREMENTAL_BUILD, new SubProgressMonitor(monitor,1));
+                                       } else {
+                                               monitor.setTaskName(PreferencesMessages.getString("OptionsConfigurationBlock.buildall.taskname")); //$NON-NLS-1$
+                                               PHPeclipsePlugin.getWorkspace().build(IncrementalProjectBuilder.FULL_BUILD, new SubProgressMonitor(monitor, 2));
                                        }
+                               } catch (CoreException e) {
+                                       return e.getStatus();
+                               } catch (OperationCanceledException e) {
+                                       return Status.CANCEL_STATUS;
                                }
-                       });
-               } catch (InterruptedException e) {
-                       // cancelled by user
-               } catch (InvocationTargetException e) {
-                       String title= PreferencesMessages.getString("OptionsConfigurationBlock.builderror.title"); //$NON-NLS-1$
-                       String message= PreferencesMessages.getString("OptionsConfigurationBlock.builderror.message"); //$NON-NLS-1$
-                       ExceptionHandler.handle(e, getShell(), title, message);
-               }
+                               finally {
+                                       monitor.done();
+                               }
+                               return Status.OK_STATUS;
+                       }
+                       public boolean belongsTo(Object family) {
+                               return ResourcesPlugin.FAMILY_MANUAL_BUILD == family;
+                       }
+               };
+               
+               buildJob.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule());
+               buildJob.setUser(true); 
+               buildJob.schedule();
+               return true;
        }               
        
        public void performDefaults() {
@@ -420,24 +481,35 @@ public abstract class OptionsConfigurationBlock {
        protected void updateControls() {
                // update the UI
                for (int i= fCheckBoxes.size() - 1; i >= 0; i--) {
-                       Button curr= (Button) fCheckBoxes.get(i);
-                       ControlData data= (ControlData) curr.getData();
-                                       
-                       String currValue= (String) fWorkingValues.get(data.getKey());   
-                       curr.setSelection(data.getSelection(currValue) == 0);                   
+                       updateCheckBox((Button) fCheckBoxes.get(i));
                }
                for (int i= fComboBoxes.size() - 1; i >= 0; i--) {
-                       Combo curr= (Combo) fComboBoxes.get(i);
-                       ControlData data= (ControlData) curr.getData();
-                                       
-                       String currValue= (String) fWorkingValues.get(data.getKey());   
-                       curr.select(data.getSelection(currValue));                      
+                       updateCombo((Combo) fComboBoxes.get(i));
                }
                for (int i= fTextBoxes.size() - 1; i >= 0; i--) {
-                       Text curr= (Text) fTextBoxes.get(i);
-                       String key= (String) curr.getData();
-                       
-                       String currValue= (String) fWorkingValues.get(key);
+                       updateText((Text) fTextBoxes.get(i));
+               }
+       }
+       
+       protected void updateCombo(Combo curr) {
+               ControlData data= (ControlData) curr.getData();
+               
+               String currValue= (String) fWorkingValues.get(data.getKey());   
+               curr.select(data.getSelection(currValue));                                      
+       }
+       
+       protected void updateCheckBox(Button curr) {
+               ControlData data= (ControlData) curr.getData();
+               
+               String currValue= (String) fWorkingValues.get(data.getKey());   
+               curr.setSelection(data.getSelection(currValue) == 0);                                           
+       }
+       
+       protected void updateText(Text curr) {
+               String key= (String) curr.getData();
+               
+               String currValue= (String) fWorkingValues.get(key);
+               if (currValue != null) {
                        curr.setText(currValue);
                }
        }