Author: jfuerth
Date: Wed Sep 3 12:52:54 2008
New Revision: 2689
Modified:
trunk/src/ca/sqlpower/architect/olap/undo/OLAPUndoManager.java
trunk/src/ca/sqlpower/architect/swingui/SwingUIProject.java
trunk/src/ca/sqlpower/architect/swingui/olap/OLAPEditSession.java
Log:
Ultra-deluxe "unsaved changes" support for the OLAP edit sessions. This
implementation is exactly what we've been planning to do for the Architect
for years. This proof-of-concept has worked out beautifully, so we'll
likely make the same changes to the relational modeling part soon.
Basically, we hook into the olap session's undo manager, and only consider
the project modified if the undo manager isn't at the
previously "remembered" position, which is set every time the project gets
saved.
Modified: trunk/src/ca/sqlpower/architect/olap/undo/OLAPUndoManager.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/olap/undo/OLAPUndoManager.java
(original)
+++ trunk/src/ca/sqlpower/architect/olap/undo/OLAPUndoManager.java Wed Sep
3 12:52:54 2008
@@ -21,6 +21,7 @@
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -69,9 +70,42 @@
*/
private int compoundEditDepth = 0;
+ private WeakReference<UndoableEdit> rememberedPosition;
+
public OLAPUndoManager(OLAPObject root) {
OLAPUtil.listenToHierarchy(root, eventHandler, eventHandler,
eventHandler);
// TODO need to track the playpen components as well
+ }
+
+ /**
+ * Marks this undo manager's current position.
+ */
+ public void rememberPosition() {
+ // this might be a weak reference to null, for instance if there
are no edits yet
+ // (but that's ok; it will still work)
+ rememberedPosition = new
WeakReference<UndoableEdit>(editToBeUndone());
+ fireChangeEvent();
+ }
+
+ public boolean isAtRememberedPosition() {
+ return rememberedPosition != null && rememberedPosition.get() ==
editToBeUndone();
+ }
+
+ /**
+ * This override is just a hook for the "remembered position" system.
If we
+ * are trimming off the first edit, and our remembered undoable edit
was
+ * null (which only happens when the remembered position is before the
first
+ * edit), we "unremember" the position because it is now impossible to
get
+ * back there. If we didn't do this, if the user undoes back to the
+ * beginning of the undo vector, we would report that we're at the
+ * remembered position, but it would be a lie.
+ */
+ @Override
+ protected void trimEdits(int from, int to) {
+ super.trimEdits(from, to);
+ if (from == 0 && to > 0 && rememberedPosition.get() == null) {
+ rememberedPosition = null;
+ }
}
@Override
Modified: trunk/src/ca/sqlpower/architect/swingui/SwingUIProject.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/SwingUIProject.java (original)
+++ trunk/src/ca/sqlpower/architect/swingui/SwingUIProject.java Wed Sep 3
12:52:54 2008
@@ -140,6 +140,18 @@
this.session = session;
}
+ /**
+ * Override that also considers whether each OLAP edit session has
modifications.
+ */
+ @Override
+ public boolean isModified() {
+ boolean olapModified = false;
+ for (OLAPEditSession oSession :
getSession().getOLAPEditSessions()) {
+ olapModified |= oSession.isModified();
+ }
+ return olapModified || super.isModified();
+ }
+
// ------------- READING THE PROJECT FILE ---------------
public void load(InputStream in, DataSourceCollection dataSources)
throws IOException, ArchitectException {
@@ -649,7 +661,12 @@
ioo.indent--;
ioo.println(out, "</architect-project>"); //$NON-NLS-1$
+
setModified(false);
+ for (OLAPEditSession oSession :
getSession().getOLAPEditSessions()) {
+ oSession.saveNotify();
+ }
+
} finally {
if (out != null) out.close();
}
Modified: trunk/src/ca/sqlpower/architect/swingui/olap/OLAPEditSession.java
==============================================================================
--- trunk/src/ca/sqlpower/architect/swingui/olap/OLAPEditSession.java
(original)
+++ trunk/src/ca/sqlpower/architect/swingui/olap/OLAPEditSession.java Wed
Sep 3 12:52:54 2008
@@ -29,6 +29,8 @@
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import ca.sqlpower.architect.layout.FruchtermanReingoldForceLayout;
import ca.sqlpower.architect.olap.OLAPChildEvent;
@@ -131,6 +133,11 @@
undoManager = new OLAPUndoManager(olapSession);
pp = OLAPPlayPenFactory.createPlayPen(swingSession, this,
undoManager);
+ undoManager.addChangeListener(new ChangeListener() {
+ public void stateChanged(ChangeEvent e) {
+ d.setTitle(generateDialogTitle());
+ }
+ });
// Don't create actions here. PlayPen is currently null.
}
@@ -225,6 +232,8 @@
OLAPPlayPenFactory.setupOLAPMouseWheelActions(pp, this);
OLAPPlayPenFactory.setupOLAPKeyboardActions(pp, this);
+
+ undoManager.rememberPosition();
}
/**
@@ -244,12 +253,37 @@
public JScrollPane getPPScrollPane() {
return ppScrollPane;
}
+
+ /**
+ * This method must be called just after this session has been saved
with
+ * the project. It resets the save state, and might do other stuff that
+ * client code shouldn't care about.
+ */
+ public void saveNotify() {
+ undoManager.rememberPosition();
+ }
/**
- * Returns the schema edit dialog's title that includes the schema's
name.
+ * returns true if any aspect of this session has been modified since
it was
+ * created or since the last time [EMAIL PROTECTED] #saveNotify()} was called,
whichever
+ * is more recent.
+ */
+ public boolean isModified() {
+ return !undoManager.isAtRememberedPosition();
+ }
+
+ /**
+ * Returns the schema edit dialog's title that includes the schema's
name and
+ * an asterisk if the schema has unsaved changes.
*/
private String generateDialogTitle() {
- return olapSession.getSchema().getName() + " - OLAP Schema Editor";
+ StringBuilder title = new StringBuilder();
+ if (!undoManager.isAtRememberedPosition()) {
+ title.append("*");
+ }
+ title.append(olapSession.getSchema().getName());
+ title.append(" - OLAP Schema Editor");
+ return title.toString();
}
/**