0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.sql.framework.ui.view.graph;
0042:
0043: import java.awt.Color;
0044: import java.awt.Dimension;
0045: import java.awt.Insets;
0046: import java.awt.Point;
0047: import java.awt.Rectangle;
0048: import java.awt.event.ActionEvent;
0049: import java.awt.event.ActionListener;
0050: import java.net.URL;
0051: import java.util.ArrayList;
0052: import java.util.Iterator;
0053: import java.util.List;
0054:
0055: import javax.swing.AbstractAction;
0056: import javax.swing.Action;
0057: import javax.swing.Icon;
0058: import javax.swing.ImageIcon;
0059: import javax.swing.JMenuItem;
0060: import javax.swing.JPopupMenu;
0061: import javax.swing.event.ListDataEvent;
0062: import javax.swing.event.ListDataListener;
0063:
0064: import org.netbeans.modules.sql.framework.model.SQLCaseOperator;
0065: import org.netbeans.modules.sql.framework.model.SQLCondition;
0066: import org.netbeans.modules.sql.framework.model.SQLObject;
0067: import org.netbeans.modules.sql.framework.model.SQLPredicate;
0068: import org.netbeans.modules.sql.framework.model.SQLWhen;
0069: import org.netbeans.modules.sql.framework.ui.graph.ICommand;
0070: import org.netbeans.modules.sql.framework.ui.graph.IGraphNode;
0071: import org.netbeans.modules.sql.framework.ui.graph.IGraphPort;
0072: import org.netbeans.modules.sql.framework.ui.graph.IHighlightConfigurator;
0073: import org.netbeans.modules.sql.framework.ui.graph.IHighlightable;
0074: import org.netbeans.modules.sql.framework.ui.graph.ListAreaCellRenderer;
0075: import org.netbeans.modules.sql.framework.ui.graph.impl.BasicCanvasArea;
0076: import org.netbeans.modules.sql.framework.ui.graph.impl.BasicCellArea;
0077: import org.netbeans.modules.sql.framework.ui.graph.impl.BasicImageArea;
0078: import org.netbeans.modules.sql.framework.ui.graph.impl.BasicListArea;
0079: import org.netbeans.modules.sql.framework.ui.graph.impl.CellArea;
0080: import org.netbeans.modules.sql.framework.ui.graph.impl.DefaultListAreaRenderer;
0081: import org.netbeans.modules.sql.framework.ui.graph.impl.HighlightConfiguratorImpl;
0082: import org.netbeans.modules.sql.framework.ui.graph.impl.ListArea;
0083: import org.netbeans.modules.sql.framework.ui.model.SQLUIModel;
0084: import org.netbeans.modules.sql.framework.ui.view.IGraphViewContainer;
0085: import org.netbeans.modules.sql.framework.ui.view.conditionbuilder.ConditionBuilderUtil;
0086: import org.netbeans.modules.sql.framework.ui.view.conditionbuilder.ConditionBuilderView;
0087: import org.openide.DialogDescriptor;
0088: import org.openide.DialogDisplayer;
0089: import org.openide.NotifyDescriptor;
0090:
0091: import com.nwoods.jgo.JGoBrush;
0092: import com.nwoods.jgo.JGoObject;
0093: import com.nwoods.jgo.JGoPen;
0094: import com.nwoods.jgo.JGoRectangle;
0095: import com.nwoods.jgo.JGoSelection;
0096: import com.nwoods.jgo.JGoText;
0097: import com.nwoods.jgo.JGoView;
0098: import com.sun.sql.framework.exception.BaseException;
0099: import net.java.hulp.i18n.Logger;
0100: import org.netbeans.modules.etl.logger.Localizer;
0101: import org.netbeans.modules.etl.logger.LogUtil;
0102:
0103: /**
0104: * This class represents a case area build on top of list area
0105: *
0106: * @author Ritesh Adval
0107: * @version $Revision$
0108: */
0109: public class SQLCaseArea extends BasicListArea {
0110:
0111: protected static final JGoBrush BRUSH_OUTPUT_REGULAR = JGoBrush
0112: .makeStockBrush(new Color(236, 217, 217)); // pink
0113:
0114: protected static final JGoBrush BRUSH_INPUT_REGULAR = JGoBrush
0115: .makeStockBrush(new Color(240, 240, 240)); // light gray
0116:
0117: protected static final JGoBrush BRUSH_INPUT_HIGHLIGHTED = JGoBrush
0118: .makeStockBrush(new Color(254, 254, 244)); // light beige
0119:
0120: protected static final Color TEXT_COLOR_RESULT = Color.BLACK;
0121:
0122: protected static final Color TEXT_COLOR_INPUT = new Color(100, 100,
0123: 90); // gray
0124:
0125: protected static final Color TEXT_COLOR_LITERAL = new Color(30, 70,
0126: 230); // navy
0127:
0128: private static final JGoPen PEN_DEFAULT = JGoPen
0129: .makeStockPen(Color.WHITE);
0130:
0131: private final String nbBundle1 = mLoc.t("PRSR001: condition");
0132:
0133: String nbBundle2 = mLoc.t("PRSR001: invalid condition");
0134:
0135: private final String VALID_CONDITION = Localizer.parse(nbBundle1);
0136:
0137: private final String INVALID_CONDITION = Localizer.parse(nbBundle2);
0138:
0139: private static final URL caseUrl = SQLCaseArea.class
0140: .getResource("/org/netbeans/modules/sql/framework/ui/resources/images/Case.png");
0141:
0142: private static final URL showSqlUrl = SQLCaseArea.class
0143: .getResource("/org/netbeans/modules/sql/framework/ui/resources/images/Show_Sql.png");
0144:
0145: private static final URL removeUrl = SQLCaseArea.class
0146: .getResource("/org/netbeans/modules/sql/framework/ui/resources/images/remove.png");
0147:
0148: private static final URL editUrl = SQLCaseArea.class
0149: .getResource("/org/netbeans/modules/sql/framework/ui/resources/images/Comparison.png");
0150:
0151: private static final URL invalidIconUrl = SQLCaseArea.class
0152: .getResource("/org/netbeans/modules/sql/framework/ui/resources/images/Error.png");
0153:
0154: private static final URL validIconUrl = SQLCaseArea.class
0155: .getResource("/org/netbeans/modules/sql/framework/ui/resources/images/validateField.png");
0156:
0157: private static ImageIcon titleImage;
0158:
0159: private BasicCellArea.Highlightable defaultArea;
0160: private BasicCellArea resultArea;
0161: private SQLCaseOperator caseObj;
0162:
0163: private Action removeWhenAction;
0164:
0165: private JMenuItem showSqlItem;
0166: private JMenuItem removeItem;
0167:
0168: private JPopupMenu whenPopup;
0169:
0170: private ImageIcon invalidIcon = null;
0171: private ImageIcon validIcon = null;
0172:
0173: private static transient final Logger mLogger = LogUtil
0174: .getLogger(SQLCaseArea.class.getName());
0175: private static transient final Localizer mLoc = Localizer.get();
0176:
0177: /** Creates a new instance of SQLCaseArea */
0178: public SQLCaseArea() {
0179: super ("case");
0180: this .setSelectable(true);
0181:
0182: // This case area is no longer resizable but we may change it in future
0183: this .setResizable(false);
0184:
0185: // Case-when does not grab child selections; this is to allow case areas to be
0186: // selectable
0187:
0188: if (titleImage == null) {
0189: titleImage = new ImageIcon(caseUrl);
0190: }
0191: this .getTitleArea().setTitleImage(titleImage);
0192: titleArea.setPen(PEN_DEFAULT);
0193: titleArea.setBrush(BRUSH_TITLE);
0194:
0195: listArea = new ListArea();
0196: listArea.setDrawLines(false);
0197: listArea.setVerticalSpacing(0);
0198: listArea.setShowScrollBar(false);
0199:
0200: // Set the renderer for the list area
0201: listArea.setCellRenderer(new CaseWhenRenderer());
0202:
0203: CaseListModel listModel = new CaseListModel();
0204: RemoveWhenListener whenlistener = new RemoveWhenListener(
0205: listModel);
0206: whenlistener.update();
0207:
0208: listArea.setModel(listModel);
0209: this .addObjectAtTail(listArea);
0210:
0211: //add the default area for the case
0212: defaultArea = new BasicCellArea.Highlightable(
0213: BasicCellArea.LEFT_PORT_AREA, "default");
0214: defaultArea.setTextAlignment(JGoText.ALIGN_CENTER);
0215: defaultArea.drawBoundingRect(true);
0216:
0217: defaultArea.setBrush(BRUSH_INPUT_REGULAR);
0218: defaultArea.getHighlightConfigurator().setHoverBrush(
0219: BRUSH_INPUT_HIGHLIGHTED);
0220: defaultArea.setLinePen(PEN_DEFAULT);
0221: defaultArea.setTextColor(TEXT_COLOR_INPUT);
0222: this .addObjectAtTail(defaultArea);
0223:
0224: //add the result are for the case
0225: resultArea = new BasicCellArea(BasicCellArea.RIGHT_PORT_AREA,
0226: "result");
0227: resultArea.setTextAlignment(JGoText.ALIGN_CENTER);
0228: resultArea.drawBoundingRect(true);
0229: resultArea.setBrush(BRUSH_OUTPUT_REGULAR);
0230: resultArea.setLinePen(PEN_DEFAULT);
0231: resultArea.setTextColor(TEXT_COLOR_RESULT);
0232: this .addObjectAtTail(resultArea);
0233:
0234: initializePopUpMenus();
0235: }
0236:
0237: /**
0238: * Creates a new instance of SQLCaseArea using the given data array.
0239: *
0240: * @param data array of objects to be represented in ListModel
0241: */
0242: public SQLCaseArea(Object[] data) {
0243: super ("Case", data);
0244:
0245: resultArea = new BasicCellArea(BasicCellArea.RIGHT_PORT_AREA,
0246: "result");
0247: resultArea.setLeftGap(20);
0248: resultArea.drawBoundingRect(true);
0249: resultArea.setResizable(false);
0250: this .addObjectAtTail(resultArea);
0251: }
0252:
0253: /**
0254: * Adds a condition in this area
0255: *
0256: * @param val object representing a condition
0257: */
0258: public void setCondition(Object val) {
0259: SQLPredicate sqlPredicate = (SQLPredicate) val;
0260:
0261: // If no condition is set then return
0262: if (sqlPredicate == null) {
0263: return;
0264: }
0265:
0266: try {
0267: SQLWhen sqlWhen = caseObj.getWhen(sqlPredicate
0268: .getDisplayName());
0269: if (sqlPredicate != null) {
0270: sqlWhen.addInput(SQLWhen.CONDITION, sqlPredicate);
0271: }
0272: } catch (BaseException ex) {
0273: ex.printStackTrace();
0274: }
0275: }
0276:
0277: private void addPredicateToModel(Object val, Point loc) {
0278: CaseListModel model = (CaseListModel) listArea.getModel();
0279:
0280: if (loc != null) {
0281: Object data = listArea.getValueAt(loc);
0282: model.add(model.indexOf(data), val);
0283: } else {
0284: model.add(val);
0285: }
0286: }
0287:
0288: /**
0289: * Gets the input port for the given fieldName
0290: *
0291: * @param fieldName name of the field
0292: * @return port for the fieldName
0293: */
0294: public IGraphPort getInputGraphPort(String fieldName) {
0295: if (caseObj != null
0296: && fieldName.equals(SQLCaseOperator.DEFAULT)) {
0297: return defaultArea.getLeftGraphPort();
0298: }
0299:
0300: return null;
0301: }
0302:
0303: /**
0304: * Gets the output graph port for the given fieldName
0305: *
0306: * @param fieldName the name of this field
0307: * @return port that belongs to fieldName
0308: */
0309: public IGraphPort getOutputGraphPort(String fieldName) {
0310: return resultArea.getRightGraphPort();
0311: }
0312:
0313: /**
0314: * Gets a list of all input and output links
0315: *
0316: * @return list of input links
0317: */
0318: public List getAllLinks() {
0319: ArrayList list = new ArrayList();
0320: IGraphPort port = null;
0321:
0322: // Add the link of default area
0323: port = defaultArea.getLeftGraphPort();
0324: addLinks(port, list);
0325:
0326: // Add the link of the list area
0327: for (int i = 0; i < listArea.getModel().getSize(); i++) {
0328: WhenArea wArea = (WhenArea) listArea
0329: .getCellRendererComponent(i);
0330: list.addAll(wArea.getAllLinks());
0331: }
0332:
0333: // Add the link of the result area
0334: port = resultArea.getRightGraphPort();
0335: addLinks(port, list);
0336:
0337: return list;
0338: }
0339:
0340: /**
0341: * Gets the field name for the given port
0342: *
0343: * @param graphPort port
0344: * @return field which has graphPort
0345: */
0346: public String getFieldName(IGraphPort graphPort) {
0347: if (graphPort.equals(resultArea.getRightGraphPort())) {
0348: return resultArea.getText();
0349: }
0350:
0351: //check if it is connected to default area
0352: IGraphPort port = defaultArea.getLeftGraphPort();
0353: if (graphPort.equals(port) && caseObj != null) {
0354: return SQLCaseOperator.DEFAULT;
0355: }
0356:
0357: return null;
0358: }
0359:
0360: /**
0361: * get the child graphNode
0362: *
0363: * @param obj child data object
0364: * @return graph node
0365: */
0366: public IGraphNode getChildNode(Object obj) {
0367: for (int i = 0; i < listArea.getModel().getSize(); i++) {
0368: Object whenObj = listArea.getModel().getElementAt(i);
0369: if (whenObj.equals(obj)) {
0370: return (IGraphNode) listArea
0371: .getCellRendererComponent(i);
0372: }
0373: }
0374:
0375: return null;
0376: }
0377:
0378: /**
0379: * Remove a child object
0380: *
0381: * @param child child object
0382: */
0383: public void removeChildNode(IGraphNode childNode) throws Exception {
0384: Object dataObj = childNode.getDataObject();
0385: if (dataObj != null) {
0386: CaseListModel model = (CaseListModel) listArea.getModel();
0387: if (model.remove(dataObj)) {
0388: //remove from case also
0389: caseObj.removeSQLWhen((SQLWhen) dataObj);
0390:
0391: //a case is removed so make model dirty
0392: ((SQLUIModel) this .getGraphView().getGraphModel())
0393: .setDirty(true);
0394:
0395: //layout children again
0396: this .setHeight(this .getMaximumHeight());
0397: } else {
0398: String nbBundle3 = mLoc
0399: .t("PRSR001: Cannot remove selected when condition - at least one condition must be defined.");
0400: String msg = Localizer.parse(nbBundle3);
0401: NotifyDescriptor d = new NotifyDescriptor.Message(msg,
0402: NotifyDescriptor.INFORMATION_MESSAGE);
0403: DialogDisplayer.getDefault().notify(d);
0404: }
0405: }
0406: }
0407:
0408: // overridden to get the visible row heights
0409: // this not used as of now as this case area is no longer scrollable
0410: protected int getVisibleRowHeights() {
0411: int visHeight = super .getVisibleRowHeights();
0412: if (defaultArea != null) {
0413: visHeight += defaultArea.getHeight();
0414: }
0415:
0416: if (resultArea != null) {
0417: visHeight += resultArea.getHeight();
0418: }
0419:
0420: return visHeight;
0421: }
0422:
0423: /**
0424: * Sets the layout of this area's children
0425: */
0426: public void layoutChildren() {
0427: Insets insets1 = getInsets();
0428:
0429: //get the bounding rectangle of this table area
0430: int x = getLeft() + insets1.left;
0431: int y = getTop() + insets1.top;
0432: int width = getWidth() - insets1.left - insets1.right;
0433: int height = getHeight() - insets1.top - insets1.bottom;
0434:
0435: titleArea.setBoundingRect(x, y, width, titleArea
0436: .getMinimumHeight());
0437:
0438: if (defaultArea == null || resultArea == null) {
0439: return;
0440: }
0441:
0442: if (height - titleArea.getHeight() - defaultArea.getHeight()
0443: - resultArea.getHeight() > 0) {
0444: listArea.setVisible(true);
0445: listArea.setOutOfScrollCellBounds(titleArea
0446: .getBoundingRect());
0447: listArea.setBoundingRect(x, y + titleArea.getHeight(),
0448: width, height - titleArea.getHeight()
0449: - defaultArea.getHeight()
0450: - resultArea.getHeight());
0451: } else {
0452: listArea.setVisible(false);
0453: listArea.setOutOfScrollCellBounds(titleArea
0454: .getBoundingRect());
0455: listArea.setBoundingRect(titleArea.getLocation(),
0456: new Dimension(titleArea.getWidth(), 0));
0457: }
0458:
0459: if (height - titleArea.getHeight() - listArea.getHeight() > 0) {
0460: defaultArea.setVisible(true);
0461: defaultArea.setBoundingRect(x, y + titleArea.getHeight()
0462: + listArea.getHeight(), width, defaultArea
0463: .getHeight());
0464:
0465: } else {
0466: defaultArea.setVisible(false);
0467: defaultArea.setLocation(titleArea.getLocation());
0468: }
0469:
0470: if (height - titleArea.getHeight() - listArea.getHeight()
0471: - defaultArea.getHeight() > 0) {
0472: resultArea.setVisible(true);
0473: resultArea.setBoundingRect(x, y + titleArea.getHeight()
0474: + listArea.getHeight() + defaultArea.getHeight(),
0475: width, resultArea.getHeight());
0476:
0477: } else {
0478: resultArea.setVisible(false);
0479: resultArea.setLocation(titleArea.getLocation());
0480: }
0481: }
0482:
0483: /**
0484: * Gets the data object from this area.
0485: *
0486: * @return data object
0487: */
0488: public Object getDataObject() {
0489: return caseObj;
0490: }
0491:
0492: /**
0493: * Sets the data object in this area
0494: *
0495: * @param obj data object
0496: */
0497: public void setDataObject(Object obj) {
0498: try {
0499: this .caseObj = (SQLCaseOperator) obj;
0500: //create one when by default
0501: if (caseObj.getWhenCount() == 0) {
0502: SQLWhen when = caseObj.createSQLWhen();
0503: caseObj.addSQLWhen(when);
0504: }
0505:
0506: setWhens(caseObj);
0507: } catch (BaseException ex) {
0508: ex.printStackTrace();
0509: }
0510: }
0511:
0512: private void setWhens(SQLCaseOperator sqlCase) {
0513: List list = sqlCase.getWhenList();
0514: if (list == null) {
0515: return;
0516: }
0517:
0518: Iterator it = list.iterator();
0519:
0520: while (it.hasNext()) {
0521: SQLWhen when = (SQLWhen) it.next();
0522: addPredicateToModel(when, null);
0523: }
0524: }
0525:
0526: /**
0527: * Adds a model object holding the predicate
0528: *
0529: * @param obj the object that represents a predicate
0530: * @param loc location of the new predicate
0531: */
0532: public void addPredicate(Object obj, Point loc) {
0533: //add(obj, loc);
0534: }
0535:
0536: class CaseListArea extends ListArea {
0537: public ListAreaCellRenderer getCellRenderer(int row) {
0538: return new CaseWhenRenderer();
0539: }
0540: }
0541:
0542: class DefaultCaseRenderer extends DefaultListAreaRenderer {
0543: public JGoObject getListAreaCellRenderer(ListArea list,
0544: Object value, int index, boolean isSelected,
0545: boolean cellHasFocus) {
0546:
0547: JGoObject aCellArea = super .getListAreaCellRenderer(list,
0548: value, index, isSelected, cellHasFocus);
0549: aCellArea.setResizable(false);
0550:
0551: return aCellArea;
0552: }
0553: }
0554:
0555: class CaseWhenRenderer implements ListAreaCellRenderer {
0556: public JGoObject getListAreaCellRenderer(JGoObject list,
0557: Object value, int index, boolean isSelected,
0558: boolean cellHasFocus) {
0559: String ret = "return";
0560:
0561: SQLWhen when = (SQLWhen) value;
0562: WhenArea whenArea = new WhenArea(ret);
0563: whenArea.setDataObject(when);
0564: whenArea.setResizable(false);
0565:
0566: return whenArea;
0567: }
0568: }
0569:
0570: class ConditionCellArea extends BasicCellArea {
0571: private BasicImageArea bia;
0572: private CellArea invalidMsg;
0573:
0574: public ConditionCellArea(String text) {
0575: super (text);
0576:
0577: bia = new BasicImageArea();
0578: bia.setSelectable(false);
0579: bia.setResizable(false);
0580:
0581: this .addObjectAtTail(bia);
0582: }
0583:
0584: public void setImageIcon(int iconType, Icon icon, String tooltip) {
0585: if (icon != null) {
0586: if (bia != null) {
0587: bia.setVisible(true);
0588: ImageIcon imgIcon = (ImageIcon) icon;
0589: bia.loadImage(imgIcon.getImage(), false);
0590: bia.setSize(imgIcon.getImage().getWidth(null),
0591: imgIcon.getImage().getHeight(null));
0592: if (tooltip != null) {
0593: bia.setToolTipText(tooltip);
0594: }
0595: }
0596: } else {
0597: if (bia != null) {
0598: bia.setVisible(false);
0599: }
0600: }
0601:
0602: layoutChildren();
0603: }
0604:
0605: public void layoutChildren() {
0606: if (drawBoundingRect) {
0607: rect.setBoundingRect(this .getBoundingRect());
0608: }
0609:
0610: int rectwidth = getWidth();
0611: int rectheight = getHeight();
0612:
0613: int width = rectwidth - insets.left - insets.right;
0614: int height = rectheight - insets.top - insets.bottom;
0615:
0616: if ((bia != null) && (bia.isVisible())) {
0617: bia.setSpotLocation(JGoObject.Left, this ,
0618: JGoObject.Left);
0619:
0620: int topGap = this .getHeight() - bia.getHeight();
0621: if (topGap > 0) {
0622: bia.setTop(this .getTop() + topGap / 2);
0623: }
0624:
0625: bia.setLeft(bia.getLeft() + leftGap);
0626: }
0627:
0628: if (cellArea != null) {
0629: int w = width - leftGap;
0630:
0631: if (bia != null && bia.isVisible()) {
0632: cellArea.setSpotLocation(JGoObject.Left, bia,
0633: JGoObject.Right);
0634: cellArea.setLeft(cellArea.getLeft() + iconTextGap);
0635: w = w - bia.getWidth() - iconTextGap;
0636: } else {
0637: cellArea.setSpotLocation(JGoObject.Left, this ,
0638: JGoObject.Left);
0639: cellArea.setLeft(cellArea.getLeft() + leftGap);
0640: }
0641:
0642: cellArea.setSize(w, height);
0643: }
0644: }
0645:
0646: /**
0647: * get the maximum width
0648: *
0649: * @return max width
0650: */
0651: public int getMaximumWidth() {
0652: int minWidth = getInsets().left + getInsets().right;
0653: minWidth += leftGap;
0654:
0655: if (bia != null) {
0656: minWidth += bia.getWidth() + iconTextGap;
0657: }
0658:
0659: if (cellArea != null) {
0660: minWidth += getInvalidMessageArea().getMaximumWidth();
0661: }
0662:
0663: return minWidth;
0664: }
0665:
0666: /**
0667: * get the minimum width of this cell area
0668: *
0669: * @return min width
0670: */
0671: public int getMinimumWidth() {
0672: int minWidth = getInsets().left + getInsets().right;
0673: minWidth += leftGap;
0674:
0675: if (bia != null) {
0676: minWidth += bia.getWidth() + iconTextGap;
0677: }
0678:
0679: if (cellArea != null) {
0680: minWidth += getInvalidMessageArea().getMinimumWidth();
0681: }
0682:
0683: return minWidth;
0684: }
0685:
0686: public int getMinimumHeight() {
0687: int minHeight = getInsets().top + getInsets().bottom;
0688:
0689: int height = 0;
0690: if (cellArea != null) {
0691: height = cellArea.getHeight();
0692: }
0693:
0694: if (bia != null) {
0695: if ((bia != null) && (height < bia.getHeight())) {
0696: height = bia.getHeight();
0697: }
0698: }
0699:
0700: minHeight += height;
0701: return minHeight;
0702: }
0703:
0704: /* (non-Javadoc)
0705: * @see org.netbeans.modules.sql.framework.ui.graph.impl.BasicCellArea#initImageAreas()
0706: */
0707: protected void initImageAreas() {
0708: }
0709:
0710: private CellArea getInvalidMessageArea() {
0711: if (invalidMsg == null) {
0712: invalidMsg = new CellArea(INVALID_CONDITION);
0713: }
0714: return invalidMsg;
0715: }
0716: }
0717:
0718: class WhenArea extends BasicCanvasArea implements IHighlightable {
0719: private JGoRectangle rect;
0720:
0721: private BasicCellArea conditionArea;
0722: private BasicCellArea returnArea;
0723: private SQLWhen dataObject1;
0724:
0725: private boolean selected = false;
0726:
0727: private IHighlightConfigurator hc;
0728:
0729: private boolean drawBoundingRect = false;
0730:
0731: public WhenArea(String returnName) {
0732: super ();
0733:
0734: //make it selectable so that it can be deleted
0735: this .setSelectable(true);
0736:
0737: rect = new JGoRectangle();
0738: rect.setPen(PEN_DEFAULT);
0739:
0740: rect.setBrush(BRUSH_INPUT_REGULAR);
0741: rect.setSelectable(false);
0742: rect.setResizable(false);
0743: addObjectAtHead(rect);
0744: drawBoundingRect(true);
0745:
0746: conditionArea = new ConditionCellArea(INVALID_CONDITION);
0747: conditionArea.setTextAlignment(JGoText.ALIGN_CENTER);
0748: String nbBundle4 = mLoc.t(
0749: "PRSR001: Double-click to edit condition{0}", "");
0750: conditionArea.setToolTipText(Localizer.parse(nbBundle4));
0751: conditionArea.setLinePen(PEN_DEFAULT);
0752: conditionArea.setTextColor(TEXT_COLOR_INPUT);
0753: conditionArea.setBrush(BRUSH_INPUT_REGULAR);
0754:
0755: SQLCaseArea.this .setDisplayAttributesFor(conditionArea,
0756: null);
0757: conditionArea.setResizable(false);
0758: addObjectAtTail(conditionArea);
0759:
0760: returnArea = new BasicCellArea(
0761: BasicCellArea.LEFT_PORT_AREA, returnName);
0762: returnArea.setBrush(BRUSH_INPUT_REGULAR);
0763: returnArea.setLinePen(PEN_DEFAULT);
0764: returnArea.setTextColor(TEXT_COLOR_INPUT);
0765: returnArea.setTextAlignment(JGoText.ALIGN_CENTER);
0766: returnArea.setResizable(false);
0767: addObjectAtTail(returnArea);
0768:
0769: hc = new HighlightConfiguratorImpl(BRUSH_INPUT_REGULAR,
0770: BRUSH_INPUT_HIGHLIGHTED);
0771:
0772: setSize(conditionArea.getWidth() + 20, conditionArea
0773: .getMinimumHeight()
0774: + returnArea.getMinimumHeight());
0775: }
0776:
0777: public void setBrush(JGoBrush newBrush) {
0778: rect.setBrush(newBrush);
0779: conditionArea.setBrush(newBrush);
0780: returnArea.setBrush(newBrush);
0781: }
0782:
0783: /**
0784: * Set if a bounding rectangle needs to be drawn
0785: *
0786: * @param drawRect boolean
0787: */
0788: public void drawBoundingRect(boolean drawRect) {
0789: this .drawBoundingRect = drawRect;
0790: }
0791:
0792: //when this are gains selection set the flag
0793: //this will be used to delete this are if selected
0794: protected void gainedSelection(JGoSelection selection) {
0795: super .gainedSelection(selection);
0796: selected = true;
0797: }
0798:
0799: protected void lostSelection(JGoSelection selection) {
0800: super .lostSelection(selection);
0801: selected = false;
0802: }
0803:
0804: public boolean isSelected() {
0805: return this .selected;
0806: }
0807:
0808: public boolean doMouseClick(int modifiers, Point dc, Point vc,
0809: JGoView view1) {
0810: int popupMask = java.awt.event.InputEvent.BUTTON3_MASK;
0811: if ((modifiers & popupMask) != 0 && whenPopup != null) {
0812: whenPopup.show(view1, vc.x, vc.y);
0813: return true;
0814: }
0815:
0816: return false;
0817: }
0818:
0819: /**
0820: * Overrides default implementation to display condition builder dialog for this
0821: * when clause's associated condition.
0822: *
0823: * @see com.nwoods.jgo.JGoObject#doMouseDblClick(int, java.awt.Point, java.awt.Point, com.nwoods.jgo.JGoView)
0824: */
0825: public boolean doMouseDblClick(int modifiers, Point dc,
0826: Point vc, JGoView myView) {
0827: editWhen_ActionPerformed(null);
0828: return false;
0829: }
0830:
0831: String getText() {
0832: return SQLWhen.RETURN;
0833: }
0834:
0835: IGraphPort getLeftGraphPort() {
0836: return returnArea.getLeftGraphPort();
0837: }
0838:
0839: BasicCellArea getConditionArea() {
0840: return conditionArea;
0841: }
0842:
0843: /**
0844: * handle geometry change we always want to layout if geometry changes this is to
0845: * make sure we layout this area if location (when we collapse or expand location
0846: * changes)
0847: *
0848: * @param prevRect previous bounds rectangle
0849: */
0850: protected void geometryChange(Rectangle prevRect) {
0851: layoutChildren();
0852: }
0853:
0854: /**
0855: * Lays out the children of this area.
0856: */
0857: public void layoutChildren() {
0858: if (drawBoundingRect) {
0859: rect.setBoundingRect(this .getBoundingRect());
0860: }
0861:
0862: int rectleft = getLeft();
0863: int recttop = getTop();
0864: int rectwidth = getWidth();
0865: int rectheight = getHeight();
0866:
0867: int left = rectleft + insets.left;
0868: int top = recttop + insets.top;
0869: int width = rectwidth - insets.left - insets.right;
0870: int height = rectheight - insets.top - insets.bottom;
0871:
0872: if (height > 0 && this .isVisible()) {
0873: conditionArea.setVisible(true);
0874: conditionArea.setBoundingRect(left, top, width,
0875: conditionArea.getHeight());
0876: } else {
0877: conditionArea.setVisible(false);
0878: conditionArea.setLocation(left, top);
0879: }
0880:
0881: if (height - conditionArea.getHeight() > 0
0882: && this .isVisible()) {
0883: returnArea.setVisible(true);
0884: returnArea.setBoundingRect(left, top
0885: + conditionArea.getHeight(), width, returnArea
0886: .getHeight());
0887: } else {
0888: returnArea.setVisible(false);
0889: returnArea.setLocation(left, top);
0890: }
0891: }
0892:
0893: /**
0894: * Expands this graph node
0895: *
0896: * @param expand whether to expand or collapse this node
0897: */
0898: public void expand(boolean expand) {
0899: }
0900:
0901: /**
0902: * Gets the data object associated with graph node
0903: *
0904: * @return data object
0905: */
0906: public Object getDataObject() {
0907: return dataObject1;
0908: }
0909:
0910: /**
0911: * Sets the data object associated with graph node
0912: *
0913: * @param obj new data object
0914: */
0915: public void setDataObject(Object obj) {
0916: this .dataObject1 = (SQLWhen) obj;
0917: if (dataObject1 != null) {
0918: SQLCondition cond = dataObject1.getCondition();
0919: setDisplayAttributesFor(conditionArea, cond);
0920: }
0921: }
0922:
0923: /**
0924: * Gets field name given a port
0925: *
0926: * @param graphPort graph port
0927: * @return field name
0928: */
0929: public String getFieldName(IGraphPort graphPort) {
0930: if (returnArea.getLeftGraphPort().equals(graphPort)) {
0931: return SQLWhen.RETURN;
0932: }
0933:
0934: return null;
0935: }
0936:
0937: /**
0938: * Gets input graph port, given a field name
0939: *
0940: * @param fieldName field name
0941: * @return graph port
0942: */
0943: public IGraphPort getInputGraphPort(String fieldName) {
0944: if (fieldName.equals(SQLWhen.RETURN)) {
0945: return returnArea.getLeftGraphPort();
0946: }
0947:
0948: return null;
0949: }
0950:
0951: /**
0952: * Gets output graph port , given a field name
0953: *
0954: * @param fieldName field name
0955: * @return graph port
0956: */
0957: public IGraphPort getOutputGraphPort(String fieldName) {
0958: return null;
0959: }
0960:
0961: /**
0962: * Gets List of all input and output links
0963: *
0964: * @return list of input links
0965: */
0966: public List getAllLinks() {
0967: List list = new ArrayList();
0968:
0969: IGraphPort port = returnArea.getLeftGraphPort();
0970: addLinks(port, list);
0971:
0972: return list;
0973: }
0974:
0975: /**
0976: * get the child graphNode
0977: *
0978: * @param obj child data object
0979: * @return graph node
0980: */
0981: public IGraphNode getChildNode(Object obj) {
0982: return null;
0983: }
0984:
0985: /**
0986: * Get the parent node
0987: *
0988: * @return parent
0989: */
0990: public IGraphNode getParentGraphNode() {
0991: return SQLCaseArea.this ;
0992: }
0993:
0994: /**
0995: * @see org.netbeans.modules.sql.framework.ui.graph.IHighlightable#setHighlighted(boolean)
0996: */
0997: public void setHighlighted(boolean shouldHighlight) {
0998: if (shouldHighlight) {
0999: this .setBrush(hc.getHoverBrush());
1000: } else {
1001: this .setBrush(hc.getNormalBrush());
1002: }
1003: }
1004:
1005: /**
1006: * @see org.netbeans.modules.sql.framework.ui.graph.IHighlightable#setHighlightEnabled(boolean)
1007: */
1008: public void setHighlightEnabled(boolean enabled) {
1009: // Do nothing - WhenArea is always highlightable
1010: }
1011:
1012: /**
1013: * @see org.netbeans.modules.sql.framework.ui.graph.IHighlightable#isHighlightEnabled()
1014: */
1015: public boolean isHighlightEnabled() {
1016: return true;
1017: }
1018:
1019: /**
1020: * @see org.netbeans.modules.sql.framework.ui.graph.IHighlightable#getHighlightConfigurator()
1021: */
1022: public IHighlightConfigurator getHighlightConfigurator() {
1023: return hc;
1024: }
1025:
1026: /**
1027: * @see org.netbeans.modules.sql.framework.ui.graph.IHighlightable#setHighlightConfigurator(org.netbeans.modules.sql.framework.ui.graph.IHighlightConfigurator)
1028: */
1029: public void setHighlightConfigurator(IHighlightConfigurator hc) {
1030: throw new UnsupportedOperationException(
1031: "Cannot change HighlightConfigurator for WhenArea.");
1032: }
1033: }
1034:
1035: /**
1036: * get maximum width of this area
1037: *
1038: * @return max width
1039: */
1040: public int getMaximumWidth() {
1041: int maxWidth = getInsets().left + getInsets().right;
1042:
1043: int w = 0;
1044:
1045: w = titleArea.getMaximumWidth();
1046:
1047: if (listArea.getMaximumWidth() > w) {
1048: w = listArea.getMaximumWidth();
1049: }
1050:
1051: if (defaultArea.getMaximumWidth() > w) {
1052: w = defaultArea.getMaximumWidth();
1053: }
1054:
1055: if (resultArea.getMaximumWidth() > w) {
1056: w = resultArea.getMaximumWidth();
1057: }
1058:
1059: maxWidth += w;
1060:
1061: return maxWidth;
1062: }
1063:
1064: /**
1065: * get the maximum height of this area
1066: *
1067: * @return max height
1068: */
1069: public int getMaximumHeight() {
1070: int maxHeight = getInsets().top + getInsets().bottom;
1071:
1072: maxHeight += titleArea.getMaximumHeight();
1073: maxHeight += listArea.getMaximumHeight();
1074: maxHeight += defaultArea.getMaximumHeight();
1075: maxHeight += resultArea.getMaximumHeight();
1076:
1077: return maxHeight;
1078: }
1079:
1080: /**
1081: * get the minimum width of this area
1082: *
1083: * @return minimum width
1084: */
1085: public int getMinimumWidth() {
1086: int insetWidth = getInsets().left + getInsets().right;
1087:
1088: int applicableWidth = 0;
1089:
1090: applicableWidth = Math.max(titleArea.getMinimumWidth(),
1091: listArea.getMaximumWidth());
1092: applicableWidth = Math.max(applicableWidth, defaultArea
1093: .getMaximumWidth());
1094: applicableWidth = Math.max(applicableWidth, resultArea
1095: .getMaximumWidth());
1096:
1097: return insetWidth + Math.max(0, applicableWidth);
1098: }
1099:
1100: private void initializePopUpMenus() {
1101: OperatorActionListener aListener = new OperatorActionListener();
1102: popUpMenu = new JPopupMenu();
1103: whenPopup = new JPopupMenu();
1104:
1105: // Show SQL
1106: String nbBundle5 = mLoc.t("PRSR001: Show SQL");
1107: showSqlItem = new JMenuItem(Localizer.parse(nbBundle5),
1108: new ImageIcon(showSqlUrl));
1109: showSqlItem.addActionListener(aListener);
1110:
1111: // Add new when. Use Action to allow inclusion in multiple menus but control via
1112: // only
1113: // one ActionListener.
1114: String nbBundle6 = mLoc.t("PRSR001: Add New When");
1115: Action addWhenAction = new AbstractAction(Localizer
1116: .parse(nbBundle6), new ImageIcon(caseUrl)) {
1117: public void actionPerformed(ActionEvent e) {
1118: addWhen_ActionPerformed(e);
1119: }
1120: };
1121:
1122: // Remove case-when
1123: String nbBundle7 = mLoc.t("PRSR001: Remove");
1124: removeItem = new JMenuItem(Localizer.parse(nbBundle7),
1125: new ImageIcon(removeUrl));
1126: removeItem.addActionListener(aListener);
1127:
1128: // Remove when
1129: String nbBundle8 = mLoc.t("PRSR001: Remove When");
1130: removeWhenAction = new AbstractAction(Localizer
1131: .parse(nbBundle8), new ImageIcon(removeUrl)) {
1132: public void actionPerformed(ActionEvent e) {
1133: removeWhen_ActionPerformed(e);
1134: }
1135: };
1136:
1137: // Build up main pop up menu.
1138: popUpMenu.add(showSqlItem);
1139: popUpMenu.add(new JMenuItem(addWhenAction));
1140: popUpMenu.addSeparator();
1141: popUpMenu.add(removeItem);
1142:
1143: // Build up when-specific pop up menu.
1144: String nbBundle9 = mLoc.t("PRSR001: Edit Condition...");
1145: Action editWhenAction = new AbstractAction(Localizer
1146: .parse(nbBundle9), new ImageIcon(editUrl)) {
1147: public void actionPerformed(ActionEvent e) {
1148: editWhen_ActionPerformed(e);
1149: }
1150: };
1151: whenPopup.add(new JMenuItem(editWhenAction));
1152: whenPopup.addSeparator();
1153: whenPopup.add(new JMenuItem(addWhenAction));
1154: whenPopup.add(new JMenuItem(removeWhenAction));
1155: }
1156:
1157: private class OperatorActionListener implements ActionListener {
1158: /**
1159: * Invoked when an action occurs.
1160: *
1161: * @param e ActionEvent to handle
1162: */
1163: public void actionPerformed(ActionEvent e) {
1164: Object source = e.getSource();
1165: if (source == showSqlItem) {
1166: showSql_actionPerformed(e);
1167: } else if (source == removeItem) {
1168: remove_ActionPerformed(e);
1169: }
1170: }
1171: }
1172:
1173: private void editWhen_ActionPerformed(ActionEvent e) {
1174: for (int i = 0; i < listArea.getModel().getSize(); i++) {
1175: WhenArea renderer = (WhenArea) listArea
1176: .getCellRendererComponent(i);
1177: if (renderer.isSelected()) {
1178: showConditionBuilderFor(renderer);
1179: break;
1180: }
1181: }
1182: }
1183:
1184: /**
1185: * @param renderer
1186: */
1187: private void showConditionBuilderFor(WhenArea renderer) {
1188: SQLWhen when = (SQLWhen) renderer.getDataObject();
1189: ConditionBuilderView builderView = ConditionBuilderUtil
1190: .getConditionBuilderView(when,
1191: (IGraphViewContainer) this .getGraphView()
1192: .getGraphViewContainer());
1193:
1194: String nbBundle10 = mLoc.t("PRSR001: Edit when condition");
1195: String dlgTitle = Localizer.parse(nbBundle10);
1196: DialogDescriptor dd = new DialogDescriptor(builderView,
1197: dlgTitle, true, NotifyDescriptor.OK_CANCEL_OPTION,
1198: null, null);
1199: builderView.doValidation();
1200:
1201: if (DialogDisplayer.getDefault().notify(dd) == NotifyDescriptor.OK_OPTION) {
1202: SQLCondition cond = (SQLCondition) builderView
1203: .getPropertyValue();
1204: BasicCellArea conditionArea = renderer.getConditionArea();
1205:
1206: if (cond != null) {
1207: when.setCondition(cond);
1208: }
1209:
1210: if (null != conditionArea) {
1211: setDisplayAttributesFor(conditionArea, cond);
1212: conditionArea.layoutChildren();
1213: }
1214: ((SQLUIModel) this .getGraphView().getGraphModel())
1215: .setDirty(true);
1216: }
1217: }
1218:
1219: /**
1220: * @param cellArea TODO
1221: * @return
1222: */
1223: private void setDisplayAttributesFor(BasicCellArea cellArea,
1224: SQLCondition cond) {
1225: String conditionDisplay = "";
1226:
1227: if (cond != null && cond.isConditionDefined() && cond.isValid()) {
1228: if (validIcon == null) {
1229: validIcon = new ImageIcon(validIconUrl);
1230: }
1231:
1232: cellArea.setText(VALID_CONDITION);
1233: cellArea.setImageIcon(BasicCellArea.IMAGE_VALIDATION,
1234: validIcon);
1235: conditionDisplay = ": " + cond.getConditionText();
1236: } else {
1237: if (invalidIcon == null) {
1238: invalidIcon = new ImageIcon(invalidIconUrl);
1239: }
1240:
1241: cellArea.setText(INVALID_CONDITION);
1242: cellArea.setImageIcon(BasicCellArea.IMAGE_VALIDATION,
1243: invalidIcon);
1244: }
1245: String nbBundle11 = mLoc.t(
1246: "PRSR001: Double-click to edit condition{0}",
1247: conditionDisplay);
1248: cellArea.setToolTipText(Localizer.parse(nbBundle11));
1249: }
1250:
1251: private void removeWhen_ActionPerformed(ActionEvent e) {
1252: for (int i = 0; i < listArea.getModel().getSize(); i++) {
1253: WhenArea renderer = (WhenArea) listArea
1254: .getCellRendererComponent(i);
1255: if (renderer.isSelected()) {
1256: try {
1257: removeChildNode(renderer);
1258: ((SQLUIModel) this .getGraphView().getGraphModel())
1259: .setDirty(true);
1260: } catch (Exception ex) {
1261: NotifyDescriptor d = new NotifyDescriptor.Message(
1262: ex.toString(),
1263: NotifyDescriptor.INFORMATION_MESSAGE);
1264: DialogDisplayer.getDefault().notify(d);
1265: }
1266: }
1267: }
1268: }
1269:
1270: private void addWhen_ActionPerformed(ActionEvent e) {
1271: SQLCaseOperator caseObj1 = (SQLCaseOperator) this
1272: .getDataObject();
1273: try {
1274: if (caseObj != null) {
1275: // Condition builder dialog call goes here.
1276:
1277: SQLWhen when = caseObj1.createSQLWhen();
1278: caseObj1.addSQLWhen(when);
1279:
1280: //a case is added so make model dirty
1281: ((SQLUIModel) this .getGraphView().getGraphModel())
1282: .setDirty(true);
1283:
1284: CaseListModel model = (CaseListModel) listArea
1285: .getModel();
1286: model.add(when);
1287: this .setHeight(this .getMaximumHeight());
1288: }
1289: } catch (Exception ex) {
1290: ex.printStackTrace();
1291: }
1292: }
1293:
1294: /**
1295: * Invoked when an action occurs.
1296: *
1297: * @param e ActionEvent to handle
1298: */
1299: private void showSql_actionPerformed(ActionEvent e) {
1300: SQLObject sqlObject = (SQLObject) SQLCaseArea.this
1301: .getDataObject();
1302: this .getGraphView().execute(ICommand.SHOW_SQL_CMD,
1303: new Object[] { sqlObject });
1304: }
1305:
1306: private void remove_ActionPerformed(ActionEvent e) {
1307: this .getGraphView().deleteNode(this );
1308: }
1309:
1310: private class RemoveWhenListener implements ListDataListener {
1311: private CaseListModel model;
1312:
1313: public RemoveWhenListener(CaseListModel aModel) {
1314: model = aModel;
1315: aModel.addListDataListener(this );
1316: }
1317:
1318: protected void finalize() throws Throwable {
1319: if (model != null) {
1320: model.removeListDataListener(this );
1321: }
1322: }
1323:
1324: public void contentsChanged(ListDataEvent e) {
1325: setRemoveActionEnabled(e.getSource());
1326: }
1327:
1328: public void intervalAdded(ListDataEvent e) {
1329: setRemoveActionEnabled(e.getSource());
1330: }
1331:
1332: public void intervalRemoved(ListDataEvent e) {
1333: setRemoveActionEnabled(e.getSource());
1334: }
1335:
1336: public void update() {
1337: setRemoveActionEnabled(model);
1338: }
1339:
1340: private void setRemoveActionEnabled(Object source) {
1341: if (null != model && source == model) {
1342: if (removeWhenAction != null) {
1343: removeWhenAction.setEnabled(model.getSize() > 1);
1344: }
1345: }
1346: }
1347: }
1348:
1349: protected void setExpanded(boolean isExpanded) {
1350: super .setExpanded(isExpanded);
1351: setResizable(false);
1352: }
1353: }
|