Revision: 3538
Author: [email protected]
Date: Fri May 14 11:58:04 2010
Log: The ColumnEditPanel now allows selection of domains, not just data
types. Refactored a Popup creator from Wabit into the library. This popup
was used in Wabit to choose cubes in an OLAP query. It has been moved into
the library to allow the ColumnEditPanel in Architect to use a popup for
choosing domains and data types.
A new TreeCellRenderer has been created to render domains and data types in
the tree displayed in the Popup, as well as the Domain Editor Panel. Each
cell of the tree is rendered to display user friendly text, icons, and
tooltips.
If two or more users are modifying the same column type and one user
commits the change, the users who have not committed the change will see
that their domain/type tree will be highlighted in red or yellow, just like
the other components in the panel do.
http://code.google.com/p/power-architect/source/detail?r=3538
Added:
/trunk/src/main/java/ca/sqlpower/architect/swingui/SQLTypeTreeCellRenderer.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/SQLTypeTreeModel.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/SQLTypeTreePopupAction.java
/trunk/src/main/resources/ca/sqlpower/architect/swingui/icons
/trunk/src/main/resources/ca/sqlpower/architect/swingui/icons/category.png
/trunk/src/main/resources/ca/sqlpower/architect/swingui/icons/domain.png
/trunk/src/main/resources/ca/sqlpower/architect/swingui/icons/type.png
Modified:
/trunk/regress/ca/sqlpower/architect/StubArchitectSession.java
/trunk/regress/ca/sqlpower/architect/TestingArchitectSession.java
/trunk/regress/ca/sqlpower/architect/swingui/TestColumnEditPanel.java
/trunk/regress/ca/sqlpower/architect/swingui/TestingArchitectSwingSession.java
/trunk/src/main/java/ca/sqlpower/architect/ArchitectProject.java
/trunk/src/main/java/ca/sqlpower/architect/ArchitectSession.java
/trunk/src/main/java/ca/sqlpower/architect/ArchitectSessionImpl.java
/trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
/trunk/src/main/java/ca/sqlpower/architect/enterprise/DomainCategory.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/ColumnEditPanel.java
/trunk/src/main/resources/ca/sqlpower/architect/swingui/messages.properties
=======================================
--- /dev/null
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/SQLTypeTreeCellRenderer.java
Fri May 14 11:58:04 2010
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2010, SQL Power Group Inc.
+ *
+ * This file is part of Power*Architect.
+ *
+ * Power*Architect is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Power*Architect is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package ca.sqlpower.architect.swingui;
+
+import java.awt.Component;
+
+import javax.swing.ImageIcon;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeCellRenderer;
+
+import org.apache.log4j.Logger;
+
+import ca.sqlpower.architect.ArchitectProject;
+import ca.sqlpower.architect.enterprise.DomainCategory;
+import ca.sqlpower.sqlobject.UserDefinedSQLType;
+
+/**
+ * This {...@link TreeCellRenderer} is used for rendering {...@link JTree}s that
used
+ * the {...@link SQLTypeTreeModel}.
+ */
+public class SQLTypeTreeCellRenderer extends DefaultTreeCellRenderer {
+
+ private static final Logger logger =
Logger.getLogger(SQLTypeTreeCellRenderer.class);
+
+ public static final ImageIcon CATEGORY_ICON = new
ImageIcon(SQLTypeTreeCellRenderer.class.getResource("icons/category.png"));
+ public static final ImageIcon DOMAIN_ICON = new
ImageIcon(SQLTypeTreeCellRenderer.class.getResource("icons/domain.png"));
+ public static final ImageIcon TYPE_ICON = new
ImageIcon(SQLTypeTreeCellRenderer.class.getResource("icons/type.png"));
+
+ public SQLTypeTreeCellRenderer() {
+ super();
+ }
+
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree, Object
value, boolean sel, boolean expanded,
+ boolean leaf, int row, boolean hasFocus) {
+ if (value instanceof ArchitectProject) {
+ setIcon(null);
+
+ if (((ArchitectProject)
value).getSession().isEnterpriseSession()) {
+ setText("Domains & Data Types");
+ } else {
+ setText("Data Types");
+ }
+ } else if (value instanceof UserDefinedSQLType) {
+ UserDefinedSQLType type = (UserDefinedSQLType) value;
+
+ if (type.getParent() instanceof DomainCategory) {
+ setIcon(DOMAIN_ICON);
+ } else {
+ setIcon(TYPE_ICON);
+ }
+ setText(type.getName());
+ } else if (value instanceof DomainCategory) {
+ setIcon(CATEGORY_ICON);
+ setText(((DomainCategory) value).getName());
+ }
+ setToolTipText(getText());
+ return this;
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/SQLTypeTreeModel.java
Fri May 14 11:58:04 2010
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2010, SQL Power Group Inc.
+ *
+ * This file is part of Power*Architect.
+ *
+ * Power*Architect is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Power*Architect is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package ca.sqlpower.architect.swingui;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+
+import org.apache.log4j.Logger;
+
+import ca.sqlpower.architect.ArchitectProject;
+import ca.sqlpower.architect.ArchitectSession;
+import ca.sqlpower.architect.enterprise.DomainCategory;
+import ca.sqlpower.object.SPObject;
+import ca.sqlpower.sqlobject.UserDefinedSQLType;
+
+/**
+ * This {...@link TreeModel} defines the hierarchy of {...@link
UserDefinedSQLType}s
+ * and {...@link DomainCategory}s under an {...@link ArchitectProject}.
+ *
+ */
+public class SQLTypeTreeModel implements TreeModel {
+
+ private static final Logger logger =
Logger.getLogger(SQLTypeTreeModel.class);
+
+ private final ArchitectSession session;
+
+ /**
+ * This {...@link Comparator} can compare {...@link UserDefinedSQLType} and
+ * {...@link DomainCategory} objects. {...@link UserDefinedSQLType}s always
come
+ * after {...@link DomainCategory}s. Comparison between objects with
different
+ * parents should never occur.
+ */
+ private final Comparator<SPObject> typeComparator = new
Comparator<SPObject>() {
+
+ public int compare(SPObject spo1, SPObject spo2) {
+ if (spo1.getParent() != spo2.getParent()) {
+ throw new ClassCastException("Cannot compare " +
+ spo1.getClass().getSimpleName() + " and " +
+ DomainCategory.class.getSimpleName() + " objects
with " +
+ "different parents.");
+ }
+
+ if (spo1 instanceof UserDefinedSQLType && spo2 instanceof
UserDefinedSQLType) {
+ return
Integer.signum(spo1.getName().compareTo(spo2.getName()));
+ } else if (spo1 instanceof DomainCategory && spo2 instanceof
DomainCategory) {
+ return
Integer.signum(spo1.getName().compareTo(spo2.getName()));
+ } else if (spo1 instanceof DomainCategory) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ };
+
+ public SQLTypeTreeModel(ArchitectSession session) {
+ this.session = session;
+ }
+
+ public SPObject getChild(Object parent, int index) {
+ // If the parent is the delegate ArchitectProject, get the child at
+ // the specified index which should be of type UserDefinedSQLType
+ // or DomainCategory.
+ if (session.getWorkspace() == parent) {
+ return getChildren().get(index);
+
+ // If the parent is DomainCategory, get the child at the specified
+ // index which should be of type UserDefinedSQLType.
+ } else if (parent instanceof DomainCategory &&
+ session.getDomainCategories().contains(parent)) {
+ return getDomainTypes((DomainCategory) parent).get(index);
+ }
+
+ return null;
+ }
+
+ public int getChildCount(Object parent) {
+ if (session.getWorkspace() == parent) {
+ return getChildren().size();
+ } else if (parent instanceof DomainCategory &&
+ session.getDomainCategories().contains(parent)) {
+ return getDomainTypes((DomainCategory) parent).size();
+ }
+ return 0;
+ }
+
+ /**
+ * Returns the sorted {...@link List} of {...@link UserDefinedSQLType}s and
+ * {...@link DomainCategory}s that are children of a given project.
+ */
+ private List<? extends SPObject> getChildren() {
+ List<SPObject> children = new ArrayList<SPObject>();
+ children.addAll(session.getDomainCategories());
+ children.addAll(session.getSQLTypes());
+ Collections.sort(children, typeComparator);
+ return Collections.unmodifiableList(children);
+ }
+
+ /**
+ * Creates the sorted {...@link List} of {...@link UserDefinedSQLType}s
under a
+ * given {...@link DomainCategory}.
+ *
+ * @param category
+ * The {...@link DomainCategory} to get the children from.
+ * @return The {...@link List} of {...@link UserDefinedSQLType}s that are
+ * contained under the given {...@link DomainCategory}.
+ */
+ private List<UserDefinedSQLType> getDomainTypes(DomainCategory
category) {
+ List<UserDefinedSQLType> children = new
ArrayList<UserDefinedSQLType>();
+ children.addAll(category.getChildren(UserDefinedSQLType.class));
+ Collections.sort(children, typeComparator);
+ return children;
+ }
+
+ public int getIndexOfChild(Object parent, Object child) {
+ if (parent == null || child == null) {
+ return -1;
+ } else if (session.getWorkspace() == parent) {
+ return getChildren().indexOf(child);
+ } else if (parent instanceof DomainCategory &&
+ session.getDomainCategories().contains(parent)) {
+ if (child instanceof UserDefinedSQLType) {
+ return getDomainTypes((DomainCategory)
parent).indexOf(child);
+ }
+ }
+ return -1;
+ }
+
+ public ArchitectProject getRoot() {
+ return session.getWorkspace();
+ }
+
+ public boolean isLeaf(Object node) {
+ return (node instanceof UserDefinedSQLType);
+ }
+
+ public void addTreeModelListener(TreeModelListener l) {
+ // no-op
+ }
+
+ public void removeTreeModelListener(TreeModelListener l) {
+ // no-op
+ }
+
+ public void valueForPathChanged(TreePath path, Object newValue) {
+ // no-op
+ }
+
+}
+
=======================================
--- /dev/null
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/SQLTypeTreePopupAction.java
Fri May 14 11:58:04 2010
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2010, SQL Power Group Inc.
+ *
+ * This file is part of Power*Architect.
+ *
+ * Power*Architect is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Power*Architect is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package ca.sqlpower.architect.swingui;
+
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+import javax.swing.JTree;
+import javax.swing.Popup;
+import javax.swing.SwingUtilities;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+
+import ca.sqlpower.sqlobject.UserDefinedSQLType;
+import ca.sqlpower.swingui.PopupListenerHandler;
+import ca.sqlpower.swingui.SPSUtils;
+
+/**
+ * This {...@link Action} creates a {...@link Popup} for choosing domains and
data
+ * types in the {...@link ColumnEditPanel}.
+ */
+public class SQLTypeTreePopupAction extends AbstractAction {
+
+ private final JPanel panel;
+ private final JTree colType;
+ private final JButton typeChooserButton;
+ private PopupListenerHandler popupListenerHandler;
+
+ /**
+ * Creates a new {...@link SQLTypeTreePopupAction} given the {...@link
JPanel} the
+ * created {...@link Popup} should appear on, the {...@link JTree} the
+ * {...@link Popup} should embed, and the {...@link JButton} that performs
this
+ * action.
+ *
+ * @param panel
+ * The {...@link JPanel} this {...@link Popup} should appear on.
+ * @param colType
+ * The {...@link JTree} the {...@link Popup} should embed.
+ * @param typeChooserButton
+ * The {...@link JButton} that should perform this action.
+ */
+ public SQLTypeTreePopupAction(JPanel panel, JTree colType, JButton
typeChooserButton) {
+ super();
+
+ this.panel = panel;
+ this.colType = colType;
+ this.typeChooserButton = typeChooserButton;
+ }
+
+ /**
+ * Creates a {...@link Popup} if it is not visible, and connects the
+ * appropriate listeners to check for when to hide the {...@link Popup}.
+ * Otherwise, it hides the {...@link Popup} and disconnects the listeners.
+ */
+ public void actionPerformed(ActionEvent e) {
+ if (popupListenerHandler != null &&
popupListenerHandler.isPopupVisible()) {
+ popupListenerHandler.cleanup();
+ } else {
+ Point windowLocation = new Point(0, 0);
+ SwingUtilities.convertPointToScreen(windowLocation,
typeChooserButton);
+ windowLocation.y += typeChooserButton.getHeight();
+
+ // Popup the type choosing tree and attach the
+ // popup listener handler to the tree
+ popupListenerHandler =
+ SPSUtils.popupComponent(panel, colType, windowLocation);
+ popupListenerHandler.connect();
+ colType.addTreeSelectionListener(new TreeSelectionListener() {
+ public void valueChanged(TreeSelectionEvent e) {
+ TreePath path = e.getNewLeadSelectionPath();
+ Object node = path.getLastPathComponent();
+ if (node instanceof UserDefinedSQLType) {
+ popupListenerHandler.cleanup();
+ }
+ }
+ });
+ }
+ }
+
+}
=======================================
--- /dev/null
+++
/trunk/src/main/resources/ca/sqlpower/architect/swingui/icons/category.png
Fri May 14 11:58:04 2010
Binary file, no diff available.
=======================================
--- /dev/null
+++
/trunk/src/main/resources/ca/sqlpower/architect/swingui/icons/domain.png
Fri May 14 11:58:04 2010
Binary file, no diff available.
=======================================
--- /dev/null
+++ /trunk/src/main/resources/ca/sqlpower/architect/swingui/icons/type.png
Fri May 14 11:58:04 2010
Binary file, no diff available.
=======================================
--- /trunk/regress/ca/sqlpower/architect/StubArchitectSession.java Mon May
10 11:20:07 2010
+++ /trunk/regress/ca/sqlpower/architect/StubArchitectSession.java Fri May
14 11:58:04 2010
@@ -23,6 +23,7 @@
import java.util.List;
import ca.sqlpower.architect.ddl.DDLGenerator;
+import ca.sqlpower.architect.enterprise.DomainCategory;
import ca.sqlpower.architect.profile.ProfileManager;
import ca.sqlpower.sql.DataSourceCollection;
import ca.sqlpower.sql.JDBCDataSource;
@@ -184,4 +185,9 @@
// TODO Auto-generated method stub
return null;
}
-}
+
+ public List<DomainCategory> getDomainCategories() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
=======================================
--- /trunk/regress/ca/sqlpower/architect/TestingArchitectSession.java Mon
May 10 11:20:07 2010
+++ /trunk/regress/ca/sqlpower/architect/TestingArchitectSession.java Fri
May 14 11:58:04 2010
@@ -36,6 +36,7 @@
import java.util.List;
import ca.sqlpower.architect.ddl.DDLGenerator;
+import ca.sqlpower.architect.enterprise.DomainCategory;
import ca.sqlpower.architect.olap.OLAPRootObject;
import ca.sqlpower.architect.profile.ProfileManager;
import ca.sqlpower.sql.DataSourceCollection;
@@ -219,4 +220,9 @@
public <T> UserPrompter createListUserPrompter(String question,
List<T> responses, T defaultResponse) {
return defaultUPF.createListUserPrompter(question, responses,
defaultResponse);
}
-}
+
+ public List<DomainCategory> getDomainCategories() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
=======================================
--- /trunk/regress/ca/sqlpower/architect/swingui/TestColumnEditPanel.java
Tue May 4 14:48:14 2010
+++ /trunk/regress/ca/sqlpower/architect/swingui/TestColumnEditPanel.java
Fri May 14 11:58:04 2010
@@ -86,7 +86,7 @@
assertEquals("Wrong column logical
name",col3.getName(),panel.getColLogicalName().getText());
assertEquals("Wrong Precision",col3.getPrecision(),((Integer)
panel.getColPrec().getValue()).intValue());
- assertEquals("Wrong
type",col3.getType(),((UserDefinedSQLType)panel.getColType().getSelectedItem()).getType().intValue());
+ assertEquals("Wrong
type",col3.getType(),((UserDefinedSQLType)panel.getColType().getLastSelectedPathComponent()).getType().intValue());
assertEquals("Wrong Scale",col3.getScale(),((Integer)
(panel.getColScale().getValue())).intValue());
assertEquals(col3.isAutoIncrement(), ((YesNoEnum)
panel.getColAutoInc().getSelectedItem()).getValue());
assertEquals(col3.isPrimaryKey(),
panel.getColInPK().getModel().isSelected());
@@ -98,7 +98,7 @@
assertEquals("Wrong column logical
name",col2.getName(),panel.getColLogicalName().getText());
assertEquals("Wrong Precision",col2.getPrecision(),((Integer)
panel.getColPrec().getValue()).intValue());
- assertEquals("Wrong
type",col2.getType(),((UserDefinedSQLType)panel.getColType().getSelectedItem()).getType().intValue());
+ assertEquals("Wrong
type",col2.getType(),((UserDefinedSQLType)panel.getColType().getLastSelectedPathComponent()).getType().intValue());
assertEquals("Wrong Scale",col2.getScale(),((Integer)
(panel.getColScale().getValue())).intValue());
assertEquals(col2.isAutoIncrement(), ((YesNoEnum)
panel.getColAutoInc().getSelectedItem()).getValue());
assertEquals(col2.isPrimaryKey(),
panel.getColInPK().getModel().isSelected());
@@ -110,7 +110,7 @@
panel.getColPhysicalName().setText("CHANGED");
panel.getColLogicalName().setText("Easier Use Column Name");
- panel.getColType().setSelectedIndex(1);
+ panel.getColType().setSelectionRow(1);
panel.getColPrec().setValue(new Integer(1234));
panel.getTypeOverrideMap().get(panel.getColPrec()).setSelected(true);
panel.getColScale().setValue(new Integer(5432));
@@ -128,7 +128,7 @@
assertEquals("Wrong column physical
name","CHANGED",col2.getPhysicalName());
assertEquals("Wrong column logical name","Easier Use Column
Name",col2.getName());
assertEquals("Wrong Precision",1234,col2.getPrecision());
- assertEquals("Wrong type",2,col2.getType());
+ assertEquals("Wrong type",1,col2.getType());
assertEquals("Wrong Scale",5432,col2.getScale());
assertTrue(col2.isAutoIncrement());
assertTrue(col2.isPrimaryKey());
@@ -141,6 +141,7 @@
panel.getColPhysicalName().setText("CHANGED");
panel.getColLogicalName().setText("Easier Use Column Name");
+ panel.getColType().setSelectionRow(1);
panel.getColPrec().setValue(new Integer(1234));
panel.getColScale().setValue(new Integer(5432));
panel.getColAutoInc().setSelectedItem(YesNoEnum.YES);
@@ -150,6 +151,7 @@
assertEquals("Wrong column physical name","Physical Name
2",col2.getPhysicalName());
assertEquals("Wrong column logical name","Column
2",col2.getName());
+ assertEquals("Wrong column data type", 2, col2.getType());
assertEquals("Wrong Precision",3,col2.getPrecision());
assertEquals("Wrong Scale",4,col2.getScale());
assertFalse(col2.isAutoIncrement());
=======================================
---
/trunk/regress/ca/sqlpower/architect/swingui/TestingArchitectSwingSession.java
Mon May 10 11:20:07 2010
+++
/trunk/regress/ca/sqlpower/architect/swingui/TestingArchitectSwingSession.java
Fri May 14 11:58:04 2010
@@ -41,6 +41,7 @@
import ca.sqlpower.architect.ddl.DDLGenerator;
import ca.sqlpower.architect.ddl.GenericDDLGenerator;
import ca.sqlpower.architect.enterprise.ArchitectClientSideSession;
+import ca.sqlpower.architect.enterprise.DomainCategory;
import ca.sqlpower.architect.etl.kettle.KettleJob;
import ca.sqlpower.architect.olap.OLAPRootObject;
import ca.sqlpower.architect.olap.OLAPSession;
@@ -496,4 +497,8 @@
public <T> UserPrompter createListUserPrompter(String question,
List<T> responses, T defaultResponse) {
return new
DefaultUserPrompterFactory().createListUserPrompter(question, responses,
defaultResponse);
}
-}
+
+ public List<DomainCategory> getDomainCategories() {
+ return Collections.emptyList();
+ }
+}
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/ArchitectProject.java Mon
May 10 12:30:08 2010
+++ /trunk/src/main/java/ca/sqlpower/architect/ArchitectProject.java Fri
May 14 11:58:04 2010
@@ -412,8 +412,8 @@
allChildren.add(kettleSettings);
allChildren.addAll(users);
allChildren.addAll(groups);
- allChildren.addAll(domainCategories);
allChildren.addAll(sqlTypes);
+ allChildren.addAll(domainCategories);
return allChildren;
}
@@ -574,15 +574,6 @@
return true;
}
- /**
- * Returns the list of all child {...@link UserDefinedSQLType} for this
- * {...@link ArchitectProject}
- */
- @NonProperty
- public List<UserDefinedSQLType> getSqlTypes() {
- return sqlTypes;
- }
-
@NonBound
public SPObject getObjectInTree(String uuid) {
return projectMap.get(uuid);
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/ArchitectSession.java Mon
May 3 16:11:03 2010
+++ /trunk/src/main/java/ca/sqlpower/architect/ArchitectSession.java Fri
May 14 11:58:04 2010
@@ -23,6 +23,7 @@
import java.util.List;
import ca.sqlpower.architect.ddl.DDLGenerator;
+import ca.sqlpower.architect.enterprise.DomainCategory;
import ca.sqlpower.architect.profile.ProfileManager;
import ca.sqlpower.sql.DataSourceCollection;
import ca.sqlpower.sql.JDBCDataSource;
@@ -140,6 +141,12 @@
* Returns a list of {...@link UserDefinedSQLType} defined in this
session.
*/
public List<UserDefinedSQLType> getSQLTypes();
+
+ /**
+ * Returns a list of {...@link DomainCategory}s defined in this session.
Only
+ * enterprise sessions should contain domains.
+ */
+ public List<DomainCategory> getDomainCategories();
/**
* Searches the session for a {...@link UserDefinedSQLType} with the given
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/ArchitectSessionImpl.java
Mon May 10 11:20:07 2010
+++ /trunk/src/main/java/ca/sqlpower/architect/ArchitectSessionImpl.java
Fri May 14 11:58:04 2010
@@ -23,10 +23,12 @@
import java.beans.PropertyChangeSupport;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import ca.sqlpower.architect.ddl.DDLGenerator;
import ca.sqlpower.architect.ddl.GenericDDLGenerator;
+import ca.sqlpower.architect.enterprise.DomainCategory;
import ca.sqlpower.architect.profile.ProfileManager;
import ca.sqlpower.architect.profile.ProfileManagerImpl;
import ca.sqlpower.sql.DataSourceCollection;
@@ -279,5 +281,9 @@
public <T> UserPrompter createListUserPrompter(String question,
List<T> responses, T defaultResponse) {
return userPrompterFactory.createListUserPrompter(question,
responses, defaultResponse);
}
+
+ public List<DomainCategory> getDomainCategories() {
+ return Collections.emptyList();
+ }
}
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Mon May 10 22:46:35 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/enterprise/ArchitectClientSideSession.java
Fri May 14 11:58:04 2010
@@ -8,6 +8,7 @@
import java.net.URISyntaxException;
import java.text.ParseException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -254,7 +255,12 @@
@Override
public List<UserDefinedSQLType>
getSQLTypes() {
- return
ArchitectClientSideSession.this.getSQLTypes();
+ List<UserDefinedSQLType> types = new
ArrayList<UserDefinedSQLType>();
+
types.addAll(ArchitectClientSideSession.this.getSQLTypes());
+ for (DomainCategory dc :
ArchitectClientSideSession.this.getDomainCategories()) {
+
types.addAll(dc.getChildren(UserDefinedSQLType.class));
+ }
+ return types;
}
@Override
@@ -954,7 +960,17 @@
*/
@Override
public List<UserDefinedSQLType> getSQLTypes() {
- final List<UserDefinedSQLType> sqlTypes =
getSystemWorkspace().getSqlTypes();
- return sqlTypes;
+ return Collections.unmodifiableList(
+
getSystemWorkspace().getChildren(UserDefinedSQLType.class));
+ }
+
+ /**
+ * Returns the {...@link List} of {...@link DomainCategory}s in this
session's
+ * system workspace.
+ */
+ @Override
+ public List<DomainCategory> getDomainCategories() {
+ return Collections.unmodifiableList(
+ getSystemWorkspace().getChildren(DomainCategory.class));
}
}
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/enterprise/DomainCategory.java
Mon Apr 19 14:18:19 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/enterprise/DomainCategory.java
Fri May 14 11:58:04 2010
@@ -86,6 +86,7 @@
@Override
protected void addChildImpl(SPObject child, int index) {
children.add(index, (UserDefinedSQLType) child);
+ child.setParent(this);
fireChildAdded(UserDefinedSQLType.class, child, index);
}
=======================================
---
/trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
Mon May 10 22:46:35 2010
+++
/trunk/src/main/java/ca/sqlpower/architect/swingui/ArchitectSwingSessionImpl.java
Fri May 14 11:58:04 2010
@@ -61,6 +61,7 @@
import ca.sqlpower.architect.ProjectSettings.ColumnVisibility;
import ca.sqlpower.architect.ddl.DDLGenerator;
import ca.sqlpower.architect.enterprise.ArchitectClientSideSession;
+import ca.sqlpower.architect.enterprise.DomainCategory;
import ca.sqlpower.architect.enterprise.NetworkConflictResolver;
import ca.sqlpower.architect.etl.kettle.KettleJob;
import ca.sqlpower.architect.olap.OLAPRootObject;
@@ -1229,4 +1230,8 @@
public <T> UserPrompter createListUserPrompter(String question,
List<T> responses, T defaultResponse) {
return swinguiUserPrompterFactory.createListUserPrompter(question,
responses, defaultResponse);
}
-}
+
+ public List<DomainCategory> getDomainCategories() {
+ return delegateSession.getDomainCategories();
+ }
+}
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/ColumnEditPanel.java
Mon May 10 19:46:07 2010
+++ /trunk/src/main/java/ca/sqlpower/architect/swingui/ColumnEditPanel.java
Fri May 14 11:58:04 2010
@@ -27,20 +27,17 @@
import java.awt.event.ComponentEvent;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.sql.DatabaseMetaData;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
@@ -51,6 +48,7 @@
import javax.swing.JSpinner;
import javax.swing.JTextArea;
import javax.swing.JTextField;
+import javax.swing.JTree;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
@@ -60,7 +58,11 @@
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
import javax.swing.text.JTextComponent;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
import org.apache.log4j.Logger;
@@ -166,7 +168,9 @@
private final JTextField colPhysicalName;
- private final JComboBox colType;
+ private final JButton typeChooserButton;
+
+ private final JTree colType;
private final JSpinner colScale;
@@ -181,7 +185,7 @@
private final JCheckBox colInPK;
private final JComboBox colAutoInc;
-
+
/**
* Text field for the name of the sequence that will generate this
column's
* default values. In multi-edit mode, this component will be null.
@@ -210,7 +214,7 @@
this(Collections.singleton(col), session);
}
- public ColumnEditPanel(Collection<SQLColumn> cols,
ArchitectSwingSession session) throws SQLObjectException {
+ public ColumnEditPanel(Collection<SQLColumn> cols, final
ArchitectSwingSession session) throws SQLObjectException {
logger.debug("ColumnEditPanel called"); //$NON-NLS-1$
if (session == null) {
@@ -324,19 +328,29 @@
if (cols.size() > 1) {
panel.add(cb, cc.xy(1, row));
}
- List<UserDefinedSQLType> typeList = session.getSQLTypes();
- UserDefinedSQLType[] types = new
UserDefinedSQLType[typeList.size()];
- types = typeList.toArray(types);
- Arrays.sort(types, new Comparator<UserDefinedSQLType>() {
- public int compare(UserDefinedSQLType a, UserDefinedSQLType b)
{
- return a.getName().compareTo(b.getName());
- }
- });
- panel.add(colType = new JComboBox(types), cc.xyw(2, row++, width));
- componentEnabledMap.put(colType, cb);
- colType.setSelectedItem(null);
- colType.addActionListener(this);
-
+
+ typeChooserButton = new
JButton(Messages.getString("ColumnEditPanel.chooseType"));
+
+ if (session.isEnterpriseSession()) {
+ colType = new JTree(new SQLTypeTreeModel(
+ session.getEnterpriseSession()));
+ } else {
+ colType = new JTree(new SQLTypeTreeModel(session));
+ }
+
+ colType.setCellRenderer(new SQLTypeTreeCellRenderer());
+ for (int i = 0; i < colType.getRowCount(); i++) {
+ colType.expandRow(i);
+ }
+ colType.setRootVisible(true);
+ colType.getSelectionModel().setSelectionMode(
+ TreeSelectionModel.SINGLE_TREE_SELECTION);
+
+ typeChooserButton.addActionListener(new
SQLTypeTreePopupAction(panel, colType, typeChooserButton));
+
+ componentEnabledMap.put(colType, cb);
+ panel.add(typeChooserButton, cc.xyw(2, row++, 2));
+
layout.appendRow(RowSpec.decode("5dlu"));
row++;
@@ -357,8 +371,9 @@
colPrec.setEnabled(true);
} else {
colPrec.setEnabled(false);
- if (colType.getSelectedItem() != null) {
- colPrec.setValue(((UserDefinedSQLType)
colType.getSelectedItem()).getPrecision(
+ if (colType.getLastSelectedPathComponent() instanceof
UserDefinedSQLType) {
+ colPrec.setValue(
+ ((UserDefinedSQLType)
colType.getLastSelectedPathComponent()).getPrecision(
SQLTypePhysicalPropertiesProvider.GENERIC_PLATFORM));
}
}
@@ -378,8 +393,8 @@
colScale.setEnabled(true);
} else {
colScale.setEnabled(false);
- if (colType.getSelectedItem() != null) {
- colScale.setValue(((UserDefinedSQLType)
colType.getSelectedItem()).getScale(
+ if (colType.getLastSelectedPathComponent() instanceof
UserDefinedSQLType) {
+ colScale.setValue(((UserDefinedSQLType)
colType.getLastSelectedPathComponent()).getScale(
SQLTypePhysicalPropertiesProvider.GENERIC_PLATFORM));
}
}
@@ -406,9 +421,9 @@
colNullable.setEnabled(true);
} else {
colNullable.setEnabled(false);
- if (colType.getSelectedItem() != null) {
+ if (colType.getLastSelectedPathComponent() instanceof
UserDefinedSQLType) {
colNullable.setSelectedItem(YesNoEnum.valueOf(
- ((UserDefinedSQLType)
colType.getSelectedItem()).getNullability() ==
DatabaseMetaData.columnNullable));
+ ((UserDefinedSQLType)
colType.getLastSelectedPathComponent()).getNullability() ==
DatabaseMetaData.columnNullable));
}
}
updateComponents();
@@ -435,9 +450,9 @@
colAutoInc.setEnabled(true);
} else {
colAutoInc.setEnabled(false);
- if (colType.getSelectedItem() != null) {
+ if (colType.getLastSelectedPathComponent() instanceof
UserDefinedSQLType) {
colAutoInc.setSelectedItem(YesNoEnum.valueOf(
- ((UserDefinedSQLType)
colType.getSelectedItem()).getAutoIncrement()));
+ ((UserDefinedSQLType)
colType.getLastSelectedPathComponent()).getAutoIncrement()));
}
}
}
@@ -463,8 +478,8 @@
colDefaultValue.setEnabled(true);
} else {
colDefaultValue.setEnabled(false);
- if (colType.getSelectedItem() != null) {
- colDefaultValue.setText(((UserDefinedSQLType)
colType.getSelectedItem()).getDefaultValue(
+ if (colType.getLastSelectedPathComponent() instanceof
UserDefinedSQLType) {
+ colDefaultValue.setText(((UserDefinedSQLType)
colType.getLastSelectedPathComponent()).getDefaultValue(
SQLTypePhysicalPropertiesProvider.GENERIC_PLATFORM));
}
}
@@ -586,11 +601,14 @@
SQLPowerUtils.listenToHierarchy(session.getRootObject(),
obsolesenceListener);
SQLPowerUtils.listenToHierarchy(session.getRootObject(), this);
panel.addAncestorListener(cleanupListener);
- colType.addItemListener(new ItemListener() {
- public void itemStateChanged(ItemEvent e) {
- if (e.getItem() instanceof UserDefinedSQLType &&
e.getStateChange() == ItemEvent.SELECTED) {
- UserDefinedSQLType sqlType = (UserDefinedSQLType)
e.getItem();
- updateSQLTypeComponents(sqlType, false);
+
+ colType.addTreeSelectionListener(new TreeSelectionListener() {
+ public void valueChanged(TreeSelectionEvent e) {
+ TreePath path = e.getNewLeadSelectionPath();
+ Object selection = path.getLastPathComponent();
+ if (selection instanceof UserDefinedSQLType) {
+ typeChooserButton.setText(((UserDefinedSQLType)
selection).getName());
+ updateSQLTypeComponents((UserDefinedSQLType)
selection, false);
}
}
});
@@ -610,7 +628,7 @@
return createScaleEditor(); // looks better if both spinners are
same
// size
}
-
+
/**
* Updates all the UI components to reflect the given column's
properties.
* <p>
@@ -667,6 +685,22 @@
}
}
+ private void updateComponent(JTree comp, Object expectedValue) {
+ if (componentEnabledMap.get(comp).isSelected() &&
+ (comp.isSelectionEmpty() ||
comp.getLastSelectedPathComponent() == expectedValue)) {
+ for (int i = 0; i < comp.getRowCount(); i++) {
+ if (comp.getPathForRow(i).getLastPathComponent() ==
expectedValue) {
+ comp.setSelectionRow(i);
+ typeChooserButton.setText(
+ ((UserDefinedSQLType)
expectedValue).getName());
+ }
+ }
+ } else {
+ comp.clearSelection();
+ componentEnabledMap.get(comp).setSelected(false);
+ }
+ }
+
/** Subroutine of {...@link #updateComponents(SQLColumn)}. */
private void updateComponent(JTextComponent comp, String
expectedValue) {
boolean unvisited = comp.getText().equals("");
@@ -678,18 +712,6 @@
}
}
- /** Subroutine of {...@link #updateComponents(SQLColumn)}. */
- private void updateComponent(JComboBox comp, Object expectedValue) {
- boolean unvisited = comp.getSelectedItem() == null;
- if (componentEnabledMap.get(comp).isSelected() &&
- (unvisited ||
comp.getSelectedItem().equals(expectedValue))) {
- comp.setSelectedItem(expectedValue);
- } else {
- comp.setSelectedItem(null);
- componentEnabledMap.get(comp).setSelected(false);
- }
- }
-
/** Subroutine of {...@link #updateComponents(SQLColumn)}. */
private void updateComponent(JCheckBox comp, boolean expectedValue) {
// Checking if a checkbox was visited is not possible just by
examining its value,
@@ -809,7 +831,7 @@
column.setPhysicalName(colPhysicalName.getText());
}
if (componentEnabledMap.get(colType).isSelected()) {
-
column.getUserDefinedSQLType().setUpstreamType((UserDefinedSQLType)
colType.getSelectedItem());
+
column.getUserDefinedSQLType().setUpstreamType((UserDefinedSQLType)
colType.getLastSelectedPathComponent());
}
if (componentEnabledMap.get(colType).isSelected()) {
@@ -959,7 +981,7 @@
}
/** Only for testing. Normal client code should not need to call this.
*/
- public JComboBox getColType() {
+ public JTree getColType() {
return colType;
}
@@ -1072,8 +1094,8 @@
}
public void propertyChanged(PropertyChangeEvent e) {
+ String property = e.getPropertyName();
if (columns.contains(e.getSource())) {
- String property = e.getPropertyName();
if (property.equals("name")) {
DataEntryPanelChangeUtil.incomingChange(colLogicalName, e);
} else if (property.equals("physicalName")) {
@@ -1096,9 +1118,18 @@
DataEntryPanelChangeUtil.incomingChange(colRemarks, e);
} else if (property.equals("defaultValue")) {
DataEntryPanelChangeUtil.incomingChange(colDefaultValue,
e);
- } else return;
+ } else {
+ return;
+ }
setErrorText(DataEntryPanelChangeUtil.ERROR_MESSAGE);
- }
+ } else if (e.getSource() instanceof UserDefinedSQLType &&
columns.contains(((UserDefinedSQLType) e.getSource()).getParent())) {
+ if (property.equals("type")) {
+ DataEntryPanelChangeUtil.incomingChange(colType, e);
+ } else {
+ return;
+ }
+ setErrorText(DataEntryPanelChangeUtil.ERROR_MESSAGE);
+ }
}
public void transactionEnded(TransactionEvent e) {
=======================================
---
/trunk/src/main/resources/ca/sqlpower/architect/swingui/messages.properties
Thu May 6 09:31:10 2010
+++
/trunk/src/main/resources/ca/sqlpower/architect/swingui/messages.properties
Fri May 14 11:58:04 2010
@@ -73,6 +73,7 @@
ASUtils.targetDatabase=(Target Database)
ColumnEditPanel.allowsNulls=Allows Nulls
ColumnEditPanel.autoIncrement=Auto Increment
+ColumnEditPanel.chooseType=Choose Type...
ColumnEditPanel.columnNameRequired=Column name is required
ColumnEditPanel.compoundEditName=Modify Column Properties
ColumnEditPanel.defaultValue=Default Value