# HG changeset patch # User Omair Majid # Date 1391795874 18000 # Node ID c3002fd38e27c6995914119052adad8638f989dd # Parent 1c835942f3c2207a081ccd1ba91acdf366f33cea Fix dirty state handling for edit pages diff -r 1c835942f3c2 -r c3002fd38e27 TODO.md --- a/TODO.md Thu Feb 06 17:03:49 2014 -0500 +++ b/TODO.md Fri Feb 07 12:57:54 2014 -0500 @@ -6,7 +6,7 @@ - Add validators for all fields where it makes sense -- Fix up dirty/stale states +- Fix up stale states - Implement support for options/arguments diff -r 1c835942f3c2 -r c3002fd38e27 com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/CommandEditPage.java --- a/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/CommandEditPage.java Thu Feb 06 17:03:49 2014 -0500 +++ b/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/CommandEditPage.java Fri Feb 07 12:57:54 2014 -0500 @@ -4,6 +4,8 @@ import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.UpdateValueStrategy; import org.eclipse.core.databinding.beans.BeanProperties; +import org.eclipse.core.databinding.observable.ChangeEvent; +import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.core.databinding.observable.value.IObservableValue; import org.eclipse.jface.databinding.fieldassist.ControlDecorationSupport; @@ -46,10 +48,12 @@ *

* The details area of the master-details block. */ -class CommandEditPage implements IDetailsPage { +class CommandEditPage implements IDetailsPage, IChangeListener { private FormToolkit toolkit; private Plugin model; + + private boolean isDirty = false; private boolean isStale = false; private Command commandModel; @@ -83,28 +87,23 @@ @Override public void dispose() { if (bindingContext != null) { + DataBindingChangeSupport.removeChangeListener(bindingContext, this); bindingContext.dispose(); } } @Override public boolean isDirty() { - if (commandModel == null) { - return false; - } - - Command latestCommandInModel = model.getCommand(commandModel.getName()); - if (latestCommandInModel == null) { - return false; - } - - // TODO convert is-command-different into is-command-dirty operation - return !latestCommandInModel.equals(commandModel); + return isDirty; } @Override public void commit(boolean onSave) { - // no op + // model is always kept in sync + + if (onSave) { + isDirty = false; + } } @Override @@ -126,12 +125,13 @@ @Override public void refresh() { - // no-op + // no-op: model is always kept in sync } @Override public void selectionChanged(IFormPart part, ISelection selection) { if (bindingContext != null) { + DataBindingChangeSupport.removeChangeListener(bindingContext, this); bindingContext.dispose(); } @@ -142,6 +142,7 @@ } bindingContext = initDataBindings(); + DataBindingChangeSupport.addChangeListener(bindingContext, this); } @Override @@ -285,4 +286,11 @@ return bindingContext; } + + @Override + public void handleChange(ChangeEvent event) { + isDirty = true; + + form.getEditor().editorDirtyStateChanged(); + } } diff -r 1c835942f3c2 -r c3002fd38e27 com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/DataBindingChangeSupport.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/DataBindingChangeSupport.java Fri Feb 07 12:57:54 2014 -0500 @@ -0,0 +1,27 @@ +package com.redhat.thermostat.tools.eclipse.plugin.editor; + +import org.eclipse.core.databinding.Binding; +import org.eclipse.core.databinding.DataBindingContext; +import org.eclipse.core.databinding.observable.IChangeListener; +import org.eclipse.core.databinding.observable.list.IObservableList; + +public class DataBindingChangeSupport { + + public static void addChangeListener(DataBindingContext bindingContext, IChangeListener listener) { + + IObservableList providers = bindingContext.getValidationStatusProviders(); + for (Object o : providers) { + Binding b = (Binding) o; + b.getTarget().addChangeListener(listener); + } + } + + public static void removeChangeListener(DataBindingContext bindingContext, IChangeListener listener) { + IObservableList providers = bindingContext.getValidationStatusProviders(); + for (Object o : providers) { + Binding b = (Binding) o; + b.getTarget().removeChangeListener(listener); + } + } + +} diff -r 1c835942f3c2 -r c3002fd38e27 com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/ExtensionEditPage.java --- a/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/ExtensionEditPage.java Thu Feb 06 17:03:49 2014 -0500 +++ b/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/ExtensionEditPage.java Fri Feb 07 12:57:54 2014 -0500 @@ -1,9 +1,9 @@ package com.redhat.thermostat.tools.eclipse.plugin.editor; -import java.util.Objects; - import org.eclipse.core.databinding.DataBindingContext; import org.eclipse.core.databinding.beans.BeanProperties; +import org.eclipse.core.databinding.observable.ChangeEvent; +import org.eclipse.core.databinding.observable.IChangeListener; import org.eclipse.core.databinding.observable.list.IObservableList; import org.eclipse.jface.databinding.viewers.ObservableListContentProvider; import org.eclipse.jface.viewers.ISelection; @@ -36,7 +36,7 @@ /** * Edits aspects of a single extension. */ -public class ExtensionEditPage implements IDetailsPage { +public class ExtensionEditPage implements IDetailsPage, IChangeListener { private FormToolkit toolkit; private Plugin model; @@ -48,6 +48,8 @@ private FormPage formPage; + private boolean isDirty = false; + public ExtensionEditPage(FormPage parent) { this.formPage = parent; } @@ -64,28 +66,23 @@ @Override public void dispose() { if (bindingContext != null) { + DataBindingChangeSupport.removeChangeListener(bindingContext, this); bindingContext.dispose(); } } @Override public boolean isDirty() { - if (extensionModel == null) { - return false; - } - - Extension extensionInMasterModel = model.getExtension(extensionModel.getName()); - if (extensionInMasterModel == null) { - return false; - } - - // TODO change this is-content-different into is-content-dirty - return !extensionInMasterModel.equals(extensionModel); + return isDirty; } @Override public void commit(boolean onSave) { - // nothing to do + // model is always kept in sync + + if (onSave) { + isDirty = false; + } } @Override @@ -114,6 +111,7 @@ @Override public void selectionChanged(IFormPart part, ISelection selection) { if (bindingContext != null) { + DataBindingChangeSupport.removeChangeListener(bindingContext, this); bindingContext.dispose(); } @@ -121,6 +119,7 @@ extensionModel = model.getExtension(extensionName); bindingContext = initDataBindings(); + DataBindingChangeSupport.addChangeListener(bindingContext, this); } @Override @@ -204,4 +203,12 @@ return bindingContext; } + + @Override + public void handleChange(ChangeEvent event) { + isDirty = true; + + formPage.getEditor().editorDirtyStateChanged(); + } + } diff -r 1c835942f3c2 -r c3002fd38e27 com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/MultiPageEditor.java --- a/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/MultiPageEditor.java Thu Feb 06 17:03:49 2014 -0500 +++ b/com.redhat.thermostat.tools.eclipse.plugin/src/com/redhat/thermostat/tools/eclipse/plugin/editor/MultiPageEditor.java Fri Feb 07 12:57:54 2014 -0500 @@ -2,6 +2,7 @@ import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; +import java.util.Iterator; import java.util.Objects; import org.eclipse.core.resources.IFile; @@ -21,6 +22,7 @@ import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.editor.FormEditor; +import org.eclipse.ui.forms.editor.IFormPage; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.wst.sse.ui.StructuredTextEditor; @@ -32,6 +34,11 @@ private static final int INDEX_SOURCE = 3; private StructuredTextEditor editor; + + /** + * Helps synchronizing changes between editor and model. Not related to + * {@code isDirty()}. + */ private boolean editorIsDirty = false; private PluginModelReaderWriter modelHelper; @@ -128,6 +135,19 @@ updateSourceFromModel(); } + // save all the pages. this doesn't really do the saving, but tells each + // page that it is being saved, so they can get a chance to update the + // model and deal with changes + Iterator iter = pages.iterator(); + while (iter.hasNext()) { + Object obj = iter.next(); + + if (obj instanceof IFormPage) { + ((IFormPage) obj).doSave(monitor); + } + } + + // actually save the model editor.doSave(monitor); }