0001: //** Copyright Statement ***************************************************
0002: //The Salmon Open Framework for Internet Applications (SOFIA)
0003: // Copyright (C) 1999 - 2002, Salmon LLC
0004: //
0005: // This program is free software; you can redistribute it and/or
0006: // modify it under the terms of the GNU General Public License version 2
0007: // as published by the Free Software Foundation;
0008: //
0009: // This program is distributed in the hope that it will be useful,
0010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
0011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012: // GNU General Public License for more details.
0013: //
0014: // You should have received a copy of the GNU General Public License
0015: // along with this program; if not, write to the Free Software
0016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
0017: //
0018: // For more information please visit http://www.salmonllc.com
0019: //** End Copyright Statement ***************************************************
0020: package com.salmonllc.html;
0021:
0022: import java.io.PrintWriter;
0023: import java.lang.reflect.Method;
0024: import java.util.Enumeration;
0025: import java.util.Hashtable;
0026: import java.util.Vector;
0027:
0028: import javax.servlet.http.HttpServletRequest;
0029:
0030: import com.salmonllc.html.events.SubmitEvent;
0031: import com.salmonllc.html.events.SubmitListener;
0032: import com.salmonllc.html.events.TreeExpandContractEvent;
0033: import com.salmonllc.html.events.TreeListener;
0034: import com.salmonllc.html.treeControl.TreeBuffer;
0035: import com.salmonllc.html.treeControl.TreeTraversalCallBack;
0036: import com.salmonllc.jsp.JspForm;
0037: import com.salmonllc.properties.Props;
0038: import com.salmonllc.sql.DataStoreBuffer;
0039: import com.salmonllc.sql.DataStoreEvaluator;
0040: import com.salmonllc.sql.DataStoreException;
0041: import com.salmonllc.sql.DataStoreExpression;
0042: import com.salmonllc.util.MessageLog;
0043: import com.salmonllc.util.ThreeObjectContainer;
0044:
0045: /**
0046: * This class is used to place a tree control.
0047: * @see com.salmonllc.html.treeControl
0048: */
0049: public class HtmlTreeControl extends HtmlComponent implements
0050: TreeTraversalCallBack, java.io.Serializable {
0051:
0052: private TreeBuffer _tb;
0053:
0054: private String _fontTagStart = null;
0055: private String _fontTagEnd = null;
0056: private boolean _autoScroll = true;
0057:
0058: /*
0059: * Added by: Henry Tafolla
0060: * Date: Feburary 22 2003
0061: * Description: Properties for the HtmlTreeComponent
0062: */
0063: private String _anchorClass = null;
0064: private int _cellPadding = 0;
0065: private int _cellSpacing = 0;
0066: private boolean _window = false;
0067: private String _windowDirectories;
0068: private int _windowHeight;
0069: private String _windowLocation;
0070: private String _windowMenubar;
0071: private String _windowName;
0072: private String _windowResizable;
0073: private String _windowScrollbars;
0074: private String _windowStatus;
0075: private String _windowToolbar;
0076: private int _windowWidth = -1;
0077: private String _tableCellClass = null;
0078: private String _headerCellClass = null;
0079: private String _tableCellStyle = null;
0080: private String _headerCellStyle = null;
0081: private String _treeTableStyle = null;
0082: private String _treeTableClass = null;
0083: private HtmlComponent _submit = null;
0084: private boolean _clickSort = true;
0085: private int _clickSortColumn = -1;
0086: private int _sortColumn = -1;
0087: private int _sortDir = TreeBuffer.SORT_ASC;
0088: private int _sortPathDir = TreeBuffer.SORT_ANY;
0089:
0090: private String _nodePtSizeSpanStart = "<SPAN STYLE=\"font-size:12;\">";
0091: private String _nodePtSizeSpanEnd = "</SPAN>";
0092:
0093: private String _expandImage, _contractImage, _nullImage;
0094: private Vector _treeListeners = new Vector();
0095: private Vector _submitListeners = new Vector();
0096: private String _targetFrame;
0097: private String _scrollTop, _scrollLeft;
0098: private String _width = null;
0099: private Vector _propertyExpressions;
0100: private String _theme;
0101:
0102: private class TreeNodeParmProcessor implements
0103: TreeTraversalCallBack {
0104: Hashtable _tab;
0105:
0106: public TreeNodeParmProcessor(Hashtable tab) {
0107: _tab = tab;
0108: }
0109:
0110: public void callBack(TreeBuffer t, PrintWriter p) {
0111: Vector nodeComps = t.getNodeComponents();
0112: int compSize = nodeComps.size();
0113: int row = t.getRow();
0114: if (row >= 0) {
0115: for (int i = 0; i < compSize; i++) {
0116: HtmlComponent comp = (HtmlComponent) nodeComps
0117: .elementAt(i);
0118: try {
0119: if (comp.processParms(_tab, row))
0120: _submit = comp;
0121: } catch (Exception e) {
0122: MessageLog.writeErrorMessage(
0123: "TreeBufferProcessParmsCallBack", e,
0124: this );
0125: }
0126: }
0127: }
0128: }
0129: }
0130:
0131: /**
0132: * Constructs a new TreeControl.
0133: */
0134: public HtmlTreeControl(String name, HtmlPage p) {
0135: this (name, null, p);
0136: }
0137:
0138: /**
0139: * Constructs a new TreeControl with a theme.
0140: */
0141: public HtmlTreeControl(String name, String theme, HtmlPage p) {
0142: super (name, p);
0143: setTheme(theme);
0144: _tb = new TreeBuffer();
0145: }
0146:
0147: /**
0148: * Adds a listener that will be notified if the tree is submitted.
0149: */
0150: public void addSubmitListener(SubmitListener t) {
0151: for (int i = 0; i < _submitListeners.size(); i++)
0152: if (t == (SubmitListener) _submitListeners.elementAt(i))
0153: return;
0154: _submitListeners.addElement(t);
0155: }
0156:
0157: /**
0158: * Adds a listener that will be notified if a tree node is expanded or contracted.
0159: */
0160:
0161: public void addTreeListener(TreeListener t) {
0162: for (int i = 0; i < _treeListeners.size(); i++)
0163: if (t == (TreeListener) _treeListeners.elementAt(i))
0164: return;
0165: _treeListeners.addElement(t);
0166: }
0167:
0168: /**
0169: * This method is used internally by the tree control and should not be executed directly.
0170: */
0171: public void callBack(TreeBuffer tb, PrintWriter p) {
0172: //if the tree item is invisible, it's image will be null so skip the whole line
0173: if (tb.getImage() == null)
0174: return;
0175:
0176: //selected node
0177: String bold = "";
0178: String unbold = "";
0179: if (tb.getHandle() == tb.getSelected()) {
0180: bold = "<b>";
0181: unbold = "</b>";
0182: }
0183:
0184: String text = tb.getText();
0185: String handle = new Integer(tb.getHandle()).toString();
0186: String name = getFullName();
0187: int level = tb.getLevel();
0188:
0189: StringBuffer output = new StringBuffer();
0190: output.append("<TR>");
0191:
0192: //select radio buttons or check boxes
0193: if (tb.getSelectMode() != TreeBuffer.SELECT_NONE) {
0194: output.append("<TD WIDTH=\"1%\"");
0195: if (_tableCellStyle != null)
0196: output.append(" style=\"" + _tableCellStyle + "\"");
0197: else if (_tableCellClass != null)
0198: output.append(" class=\"" + _tableCellClass + "\"");
0199: output.append(" valign=\"top\">");
0200: }
0201: if (tb.getSelectable()) {
0202: if (tb.getSelectMode() == TreeBuffer.SELECT_ONE) {
0203: output.append("<INPUT NAME=\"" + getFullName()
0204: + "Select\" TYPE=\"RADIO\"" + " VALUE=\""
0205: + handle + "\"");
0206: if (tb.getHandle() == tb.getSelected())
0207: output.append(" CHECKED ");
0208: output.append("> ");
0209: } else if (tb.getSelectMode() == TreeBuffer.SELECT_MANY) {
0210: output.append("<INPUT NAME=\"" + getFullName() + handle
0211: + "_Select\" TYPE=\"CHECKBOX\" VALUE=\""
0212: + handle + "\"");
0213: if (tb.getSelected(tb.getHandle()))
0214: output.append(" CHECKED ");
0215: output.append(">");
0216: }
0217: }
0218: if (tb.getSelectMode() != TreeBuffer.SELECT_NONE)
0219: output.append("</TD>");
0220:
0221: //write out the first anchor
0222:
0223: if (_tableCellClass != null)
0224: output.append("<TD NOWRAP valign=\"top\" class=\""
0225: + _tableCellClass + "\"><a name=\"" + name + handle
0226: + "\"></a>");
0227: else if (_tableCellStyle != null)
0228: output.append("<TD NOWRAP valign=\"top\" style=\""
0229: + _tableCellStyle + "\"><a name=\"" + name + handle
0230: + "\"></a>");
0231: else
0232: output.append("<TD NOWRAP valign=\"top\"><a name=\"" + name
0233: + handle + "\"></a>");
0234:
0235: //do the indent based on level
0236: if (_tb.getShowRoot() && (level > 0)) {
0237: for (int i = 0; i < level; i++)
0238: output.append(" ");
0239: } else if (!_tb.getShowRoot() && (level > 1)) {
0240: for (int i = 1; i < level; i++)
0241: output.append(" ");
0242: }
0243:
0244: //Expand/Contract image
0245: String img = new String(_nullImage);
0246:
0247: if (tb.hasChildren()) {
0248: String op;
0249: if (tb.isExpanded()) {
0250: op = "C";
0251: img = _contractImage;
0252: } else {
0253: op = "E";
0254: img = _expandImage;
0255: }
0256:
0257: if (_tb.getMode() == TreeBuffer.MODE_LINK) {
0258: output.append("<a href=\"javascript:" + name
0259: + "_expandContract('" + handle + "','" + op
0260: + "')\">");
0261: output.append("<img src=\"" + img
0262: + "\" border=\"0\"></a>");
0263: } else
0264: output
0265: .append("<INPUT TYPE=\"IMAGE\" BORDER=\"0\" NAME = \""
0266: + name
0267: + "_"
0268: + handle
0269: + "_"
0270: + op
0271: + "\" SRC=\"" + img + "\">");
0272: } else
0273: output.append("<img src=\"" + img + "\" border=\"0\">");
0274:
0275: output.append(bold);
0276:
0277: //File/Folder image and text
0278: String link = tb.getURL();
0279: String border = "\"0\"";
0280:
0281: if (tb.getImageURL() != null) {
0282:
0283: if (_window) {
0284:
0285: output
0286: .append("<a href=\"javascript:doNothing();\" onclick=\"javascript:window.open('"
0287: + tb.getImageURL()
0288: + "', '"
0289: + _windowName
0290: + "','toolbars="
0291: + _windowToolbar
0292: + ",directories="
0293: + _windowDirectories
0294: + ",scrollbars="
0295: + _windowScrollbars
0296: + ",location="
0297: + _windowLocation
0298: + ",status="
0299: + _windowStatus
0300: + ",menubar="
0301: + _windowMenubar
0302: + ",resizable="
0303: + _windowResizable
0304: + ",width="
0305: + _windowWidth
0306: + ",height="
0307: + _windowHeight + "');\">");
0308:
0309: } else {
0310: output.append("<a href=\""
0311: + encodeURL(tb.getImageURL()) + "\"");
0312: if (_targetFrame != null)
0313: output.append(" target=\"" + _targetFrame + "\" ");
0314: output.append(">");
0315: }
0316: }
0317:
0318: output.append("<img src=\"" + tb.getImage() + "\" border="
0319: + border + ">");
0320:
0321: if (tb.getImageURL() != null)
0322: output.append("</a>");
0323:
0324: //text for file or folder
0325: if (link != null) {
0326:
0327: if (_window && _anchorClass != null) {
0328:
0329: output
0330: .append("<a class=\""
0331: + _anchorClass
0332: + "\" href=\"javascript:doNothing();\" onclick=\"javascript:window.open('"
0333: + _tb.replaceUno(link) + "', '"
0334: + _windowName + "','toolbars="
0335: + _windowToolbar + ",directories="
0336: + _windowDirectories + ",scrollbars="
0337: + _windowScrollbars + ",location="
0338: + _windowLocation + ",status="
0339: + _windowStatus + ",menubar="
0340: + _windowMenubar + ",resizable="
0341: + _windowResizable + ",width="
0342: + _windowWidth + ",height="
0343: + _windowHeight + "');\">");
0344:
0345: } else if (_window && _anchorClass == null) {
0346:
0347: output
0348: .append("<a href=\"javascript:doNothing();\" onclick=\"javascript:window.open('"
0349: + _tb.replaceUno(link)
0350: + "', '"
0351: + _windowName
0352: + "','toolbars="
0353: + _windowToolbar
0354: + ",directories="
0355: + _windowDirectories
0356: + ",scrollbars="
0357: + _windowScrollbars
0358: + ",location="
0359: + _windowLocation
0360: + ",status="
0361: + _windowStatus
0362: + ",menubar="
0363: + _windowMenubar
0364: + ",resizable="
0365: + _windowResizable
0366: + ",width="
0367: + _windowWidth
0368: + ",height="
0369: + _windowHeight + "');\">");
0370:
0371: } else if (_anchorClass != null) {
0372:
0373: output.append("<a class=\"" + _anchorClass
0374: + "\" href=\""
0375: + encodeURL(_tb.replaceUno(link)) + "\"");
0376: if (_targetFrame != null)
0377: output.append("target=\"" + _targetFrame + "\" ");
0378: output.append(">");
0379: } else {
0380: output.append("<a href=\""
0381: + encodeURL(_tb.replaceUno(link)) + "\"");
0382: if (_targetFrame != null)
0383: output.append("target=\"" + _targetFrame + "\" ");
0384: output.append(">");
0385: }
0386:
0387: }
0388:
0389: //output.append("<font face=\"Helvetica\" SIZE=\"2\"><SPAN STYLE=\"font-size:12;\">" + text + "</SPAN></font>");
0390: if (_tableCellClass == null) {
0391:
0392: if (_fontTagStart != null)
0393: output.append(_fontTagStart + _nodePtSizeSpanStart
0394: + text + _nodePtSizeSpanEnd + _fontTagEnd);
0395: else
0396: output.append("<font face=\"Helvetica\" SIZE=\"2\">"
0397: + _nodePtSizeSpanStart + text
0398: + _nodePtSizeSpanEnd + "</font>");
0399: } else {
0400: output.append(text);
0401: }
0402:
0403: if (link != null)
0404: output.append("</a>");
0405:
0406: //Add any additional images to the line
0407: for (int i = 0; i < _tb.getAdditionalImageCount(); i++) {
0408: String img2 = _tb.getAdditionalImage(i);
0409: String txt = _tb.getAdditionalText(i);
0410: String u = _tb.getAdditionalURL(i);
0411: if (u != null) {
0412: u = _tb.replaceUno(u);
0413: output.append("<a href=\"" + u + "\"");
0414: if (_targetFrame != null)
0415: output.append("target=\"" + _targetFrame + "\" ");
0416: output.append(">");
0417: }
0418:
0419: output.append("<img src=\"" + img2
0420: + "\" border=\"0\" alt=\"" + txt + "\">");
0421: if (u != null)
0422: output.append("</a>");
0423: }
0424:
0425: output.append(unbold);
0426: output.append("</TD>");
0427: p.println(output.toString());
0428: Vector nodeComps = _tb.getNodeComponents();
0429: if (nodeComps != null) {
0430: for (int i = 0; i < nodeComps.size(); i++) {
0431: int row = tb.getRow();
0432: p.print("<TD VALIGN=\"top\"");
0433: if (_tableCellStyle != null)
0434: p.print(" style=\"" + _tableCellStyle + "\"");
0435: else if (_tableCellClass != null)
0436: p.print(" class=\"" + _tableCellClass + "\"");
0437: int headerNo = i + 1;
0438: if (headerNo < tb.getHeaderCount()) {
0439: String align = _tb.getHeaderAlign(headerNo);
0440: if (align != null)
0441: p.print(" align =\"" + align + "\"");
0442: }
0443: p.println(">");
0444: try {
0445: if (row > -1)
0446: processPropertyExpressions(row);
0447: HtmlComponent comp = ((HtmlComponent) nodeComps
0448: .elementAt(i));
0449: if (!comp.getVisible())
0450: p.println(" ");
0451: else
0452: comp.generateHTML(p, row);
0453: } catch (Exception e) {
0454: MessageLog.writeErrorMessage("callback of Tree", e,
0455: this );
0456: }
0457: p.println("</TD>");
0458: }
0459:
0460: }
0461:
0462: //finish it up
0463: p.println("</TR>");
0464:
0465: }
0466:
0467: /**
0468: * This method will remove all elements from the Tree
0469: */
0470: public void clearBuffer() {
0471: _tb = new TreeBuffer();
0472: }
0473:
0474: public boolean executeEvent(int type) throws Exception {
0475:
0476: if (type == HtmlComponent.EVENT_OTHER) {
0477: if (_tb.getNodeComponents() != null) {
0478: HtmlComponent h = null;
0479: for (int i = 0; i < _tb.getNodeComponents().size(); i++) {
0480: h = (HtmlComponent) _tb.getNodeComponents()
0481: .elementAt(i);
0482: if (!h.executeEvent(type))
0483: return false;
0484: }
0485: } else
0486: return true;
0487: } else if (_submit != null
0488: && type == HtmlComponent.EVENT_SUBMIT) {
0489: boolean retVal = _submit.executeEvent(type);
0490: _submit = null;
0491: return retVal;
0492: }
0493:
0494: if (type != EVENT_SUBMIT)
0495: return true;
0496:
0497: if (_treeListeners != null) {
0498: if (_tb.getHandle() != -1) {
0499: for (int i = 0; i < _treeListeners.size(); i++) {
0500: TreeListener l = (TreeListener) _treeListeners
0501: .elementAt(i);
0502: if (_tb.isExpanded())
0503: l.itemExpanded(new TreeExpandContractEvent(
0504: this , _tb.getHandle(), true, _tb));
0505: else
0506: l.itemContracted(new TreeExpandContractEvent(
0507: this , _tb.getHandle(), true, _tb));
0508: }
0509: }
0510: }
0511:
0512: if (_submitListeners != null) {
0513: SubmitEvent e = new SubmitEvent(getPage(), this , getName(),
0514: getFullName(), -1);
0515: for (int i = 0; i < _submitListeners.size(); i++) {
0516: SubmitListener l = (SubmitListener) _submitListeners
0517: .elementAt(i);
0518: e
0519: .setNextListener(_submitListeners.size() > (i + 1) ? _submitListeners
0520: .elementAt(i + 1)
0521: : null);
0522: if (!l.submitPerformed(e))
0523: return false;
0524: }
0525: }
0526:
0527: return true;
0528: }
0529:
0530: public void generateHTML(PrintWriter writer, int rowNo)
0531: throws Exception {
0532: if (!_visible)
0533: return;
0534:
0535: boolean clickSort = _clickSort;
0536:
0537: if (clickSort) {
0538: writer.println("<INPUT TYPE=\"HIDDEN\" NAME=\"SORTITEM"
0539: + getFullName() + "\" VALUE=\"-1\">");
0540: writer.println("<SCRIPT>");
0541: writer.println("function " + getFullName()
0542: + "_clickSort(i) {");
0543: writer.println(getFormString() + "SORTITEM" + getFullName()
0544: + ".value = i;");
0545: JspForm form = JspForm.findParentForm(this );
0546: if (form != null)
0547: writer.println(form.getSubmitScript());
0548: else
0549: writer.println(getFormString() + "submit();");
0550: writer.println("}");
0551: writer.println("</SCRIPT>");
0552: }
0553:
0554: writer.print("<TABLE BORDER=0 CELLPADDING=\"" + _cellPadding
0555: + "\" CELLSPACING=\"" + _cellSpacing + "\"");
0556: if (_width != null)
0557: writer.print(" width=\"" + _width + "\"");
0558: if (_treeTableClass != null)
0559: writer.print(" class=\"" + _treeTableClass + "\"");
0560: else if (_treeTableStyle != null)
0561: writer.print(" style=\"" + _treeTableStyle + "\"");
0562: writer.println(">");
0563:
0564: int count = _tb.getHeaderCount();
0565: if (count != 0) {
0566: writer.println("<TR>");
0567: for (int i = 0; i < count; i++) {
0568: writer.print("<TD");
0569: if (_headerCellClass != null)
0570: writer.print(" class=\"" + _headerCellClass + "\"");
0571: if (_headerCellStyle != null)
0572: writer.print(" style=\"" + _headerCellStyle + "\"");
0573: if (getTreeBuffer().getSelectMode() != TreeBuffer.SELECT_NONE
0574: && i == 0)
0575: writer.print(" colspan=\"2\"");
0576: String align = _tb.getHeaderAlign(i);
0577: if (align != null)
0578: writer.print(" align =\"" + align + "\"");
0579: String width = _tb.getHeaderWidth(i);
0580: if (width != null)
0581: writer.print(" width =\"" + width + "\"");
0582: writer.println(">");
0583: HtmlComponent comp = _tb.getHeaderComponent(i);
0584: boolean underLine = false;
0585: if (clickSort)
0586: underLine = _tb.canSortOnColumn(i);
0587:
0588: if (underLine)
0589: writer.print("<A HREF=\"javascript:"
0590: + getFullName() + "_clickSort(" + i
0591: + ");\">");
0592:
0593: comp.generateHTML(writer, -1);
0594: writer.println("</TD>");
0595: }
0596: writer.println("</TR>");
0597:
0598: }
0599:
0600: if (_tb.getMode() == TreeBuffer.MODE_LINK) {
0601: HtmlPage p = getPage();
0602: HttpServletRequest req = p.getCurrentRequest();
0603:
0604: String param[] = req.getParameterValues(getFullName());
0605: String op[] = req.getParameterValues("op");
0606: String scrollTop[] = req.getParameterValues("scrollTop");
0607: if (scrollTop == null)
0608: _scrollTop = null;
0609: else
0610: _scrollTop = scrollTop[0];
0611:
0612: String scrollLeft[] = req.getParameterValues("scrollLeft");
0613: if (scrollLeft == null)
0614: _scrollLeft = null;
0615: else
0616: _scrollLeft = scrollLeft[0];
0617:
0618: if (param != null) {
0619: try {
0620: int handle = Integer.parseInt(param[0]);
0621: _tb.gotoItem(handle);
0622: //_tb.setScrollTo(handle);
0623:
0624: if (op[0].equals("E"))
0625: _tb.setExpanded(true);
0626: else
0627: _tb.setExpanded(false);
0628:
0629: if (_treeListeners != null) {
0630: for (int i = 0; i < _treeListeners.size(); i++) {
0631: TreeListener l = (TreeListener) _treeListeners
0632: .elementAt(i);
0633: if (_tb.isExpanded())
0634: l
0635: .itemExpanded(new TreeExpandContractEvent(
0636: this , _tb.getHandle(),
0637: true, _tb));
0638: else
0639: l
0640: .itemContracted(new TreeExpandContractEvent(
0641: this , _tb.getHandle(),
0642: true, _tb));
0643: }
0644: }
0645: } catch (Exception e) {
0646: MessageLog.writeErrorMessage("generateHtml()", e,
0647: this );
0648: }
0649: }
0650: }
0651:
0652: if (_tb != null)
0653: _tb.traverse(this , writer);
0654:
0655: writer.println("</TABLE>");
0656:
0657: int scrollTo = _tb.getScrollTo();
0658:
0659: if (_tb.getMode() == TreeBuffer.MODE_SUBMIT && _autoScroll) {
0660: JspForm form = JspForm.findParentForm(this );
0661: if (form != null) {
0662: if (form.isScrollPositionSet()) {
0663: form.scrollToLastPosition();
0664: scrollTo = 0;
0665: }
0666: }
0667: } else if (_tb.getMode() == TreeBuffer.MODE_LINK) {
0668: HtmlPage p = getPage();
0669: HttpServletRequest req = p.getCurrentRequest();
0670: String url = encodeURL(req.getRequestURI());
0671: writer.println("<SCRIPT>");
0672: writer.println("function " + getFullName()
0673: + "_expandContract(handle_parm,op) {");
0674: if (getPage().getBrowserType() == HtmlPage.BROWSER_MICROSOFT)
0675: writer
0676: .println(" u = '"
0677: + url.toString()
0678: + "?c="
0679: + _tb.getCount()
0680: + "&"
0681: + getFullName()
0682: + "=' + handle_parm + '&op=' + op + '&scrollTop=' + document.body.scrollTop + '&scrollLeft=' + document.body.scrollLeft");
0683: else
0684: writer
0685: .println(" u = '"
0686: + url.toString()
0687: + "?c="
0688: + _tb.getCount()
0689: + "&"
0690: + getFullName()
0691: + "=' + handle_parm + '&op=' + op + '&scrollTop=' + window.pageYOffset + '&scrollLeft=' + window.pageXOffset");
0692: writer.println(" location.replace(u);");
0693: writer.println("}");
0694: writer.println("</SCRIPT>");
0695: }
0696:
0697: if (scrollTo > 0 && _autoScroll) {
0698: getPage().scrollToItem(getFullName() + scrollTo);
0699: } else if (_scrollTop != null && _autoScroll) {
0700: if (getPage().getBrowserType() == HtmlPage.BROWSER_MICROSOFT) {
0701: getPage().writeScript(
0702: "document.body.scrollTop=" + _scrollTop + ";");
0703: getPage()
0704: .writeScript(
0705: "document.body.scrollLeft="
0706: + _scrollLeft + ";");
0707: } else {
0708: getPage().writeScript(
0709: "window.scrollTo(" + _scrollLeft + ","
0710: + _scrollTop + ");");
0711: }
0712:
0713: _scrollTop = null;
0714: _scrollLeft = null;
0715: }
0716:
0717: // if (_tb.getMode() == TreeBuffer.MODE_LINK) {
0718: // for (int i = 0; i < 10; i++)
0719: // writer.println("<BR>");
0720: // }
0721: }
0722:
0723: /**
0724: * This method gets the end font tag for the component.
0725: */
0726: public String getFontEndTag() {
0727: return _fontTagEnd;
0728: }
0729:
0730: /**
0731: * This method gets the start font tag for the component.
0732: */
0733: public String getFontStartTag() {
0734: return _fontTagStart;
0735: }
0736:
0737: /**
0738: * This method returns the tree buffer that this component uses.
0739: * The tree buffer is the class that maintains the state of the items on the tree.
0740: */
0741:
0742: public TreeBuffer getTreeBuffer() {
0743: return _tb;
0744: }
0745:
0746: public boolean processParms(Hashtable ht, int rowNo)
0747: throws Exception {
0748:
0749: String param = null;
0750: String op = null;
0751: String selected = null;
0752: boolean retval = false;
0753:
0754: if (_tb.getSelectMode() == TreeBuffer.SELECT_MANY)
0755: _tb.clearVisibleSelections();
0756:
0757: Enumeration en = ht.keys();
0758: while (en.hasMoreElements()) {
0759: String parm = (String) en.nextElement();
0760: if (parm.startsWith(getFullName())
0761: && !parm.equals(getFullName())) {
0762: if (parm.endsWith("Select")) {
0763: String[] sel = (String[]) ht.get(parm);
0764: if (sel != null) {
0765: if (_tb.getSelectMode() == TreeBuffer.SELECT_MANY)
0766: _tb.setSelected(Integer.parseInt(sel[0]),
0767: true);
0768: else
0769: selected = sel[0];
0770: }
0771: } else if (param == null) {
0772: int pos = parm.lastIndexOf(".");
0773: if (pos > 0)
0774: parm = parm.substring(0, pos);
0775: pos = parm.lastIndexOf("_");
0776: if (pos > 0) {
0777: op = parm.substring(pos + 1);
0778: parm = parm.substring(0, pos);
0779: }
0780: pos = parm.lastIndexOf("_");
0781: if (pos > 0) {
0782: param = parm.substring(pos + 1);
0783: parm = parm.substring(0, pos);
0784: }
0785: }
0786: }
0787: }
0788:
0789: if (selected != null) {
0790: int handle = Integer.parseInt(selected);
0791: _tb.setSelected(handle);
0792: }
0793:
0794: _clickSortColumn = -1;
0795: if (_clickSort) {
0796: String clickSort[] = (String[]) ht.get("SORTITEM"
0797: + getFullName());
0798: try {
0799: doSort(Integer.parseInt(clickSort[0]));
0800: } catch (Exception ex) {
0801: }
0802: }
0803:
0804: boolean retVal2 = processNodeParms(_tb, ht);
0805:
0806: if (param != null) {
0807: retval = true;
0808: int handle = Integer.parseInt(param);
0809: _tb.gotoItem(handle);
0810: if (op.equals("E"))
0811: _tb.setExpanded(true);
0812: else
0813: _tb.setExpanded(false);
0814: _tb.setScrollTo(Integer.parseInt(param));
0815: }
0816:
0817: return retval || retVal2;
0818:
0819: }
0820:
0821: private boolean processNodeParms(TreeBuffer tb, Hashtable tab)
0822: throws Exception {
0823: /* String compName = null;
0824: try
0825: {
0826: if (!getVisible())
0827: return false;
0828:
0829: if (tb.getNodeComponents() != null) {
0830: TreeEnumerator enum = (TreeEnumerator) tb.getElements();
0831: Vector nodeComps = tb.getNodeComponents();
0832: int compSize = nodeComps.size();
0833: HtmlComponent comp = null;
0834: while (enum.hasMoreElements()) {
0835: enum.nextElement();
0836: int handle = enum.getHandle();
0837: tb.gotoItem(handle);
0838: int row = tb.getRow();
0839: for (int i = 0; i < compSize; i++) {
0840: comp = (HtmlComponent) nodeComps.elementAt(i);
0841: if (comp.processParms(tab, row))
0842: _submit = comp;
0843: }
0844: }
0845:
0846: }
0847: if (_submit != null)
0848: return true;
0849: else
0850: return false;
0851:
0852: }
0853: catch (Exception e)
0854: {
0855: MessageLog.writeErrorMessage("processParms for " + compName + "\n", e, this);
0856: throw (e);
0857:
0858: }*/
0859:
0860: String compName = null;
0861: if (!getVisible())
0862: return false;
0863:
0864: if (tb.getNodeComponents() != null) {
0865: TreeNodeParmProcessor proc = new TreeNodeParmProcessor(tab);
0866: tb.traverse(proc, null);
0867: }
0868: if (_submit != null)
0869: return true;
0870: else
0871: return false;
0872: }
0873:
0874: /**
0875: * Removes a submit listener.
0876: */
0877:
0878: public void removeSubmitListener(SubmitListener t) {
0879: for (int i = 0; i < _submitListeners.size(); i++)
0880: if (t == (SubmitListener) _submitListeners.elementAt(i)) {
0881: _submitListeners.removeElementAt(i);
0882: return;
0883: }
0884: }
0885:
0886: /**
0887: * Removes a tree listener.
0888: */
0889:
0890: public void removeTreeListener(TreeListener t) {
0891: for (int i = 0; i < _treeListeners.size(); i++)
0892: if (t == (TreeListener) _treeListeners.elementAt(i)) {
0893: _treeListeners.removeElementAt(i);
0894: return;
0895: }
0896: }
0897:
0898: /**
0899: * Adds a listener that will be notified if the tree is submitted.
0900: */
0901: public void reset() {
0902: _tb = new TreeBuffer();
0903: }
0904:
0905: /**
0906: * This method will load the font start and end tags from the page properties object.See the Constants at the top of the class for valid values to pass to this method.
0907: */
0908: public void setFont(String font) {
0909: Props p = getPage().getPageProperties();
0910: _fontTagStart = p.getProperty(font + Props.TAG_START);
0911: _fontTagEnd = p.getProperty(font + Props.TAG_END);
0912: }
0913:
0914: /**
0915: * This method sets the end font tag for the component.
0916: */
0917: public void setFontEndTag(String value) {
0918: _fontTagEnd = value;
0919: }
0920:
0921: /**
0922: * This method sets the start font tag for the component.
0923: */
0924: public void setFontStartTag(String value) {
0925: _fontTagStart = value;
0926: }
0927:
0928: /**
0929: * This method sets the images that will appear on every tree item. It must be called before the tree can be used.
0930: * @param expandImage The image to use to expand a tree item.
0931: * @param contractImage The image to use to contract a tree item.
0932: * @param nullImage The image to use if a tree item can't be expanded or contracted.
0933: */
0934:
0935: public void setSystemImages(String expandImage,
0936: String contractImage, String nullImage) {
0937: _expandImage = translateSiteMapURL(expandImage);
0938: _contractImage = translateSiteMapURL(contractImage);
0939: _nullImage = translateSiteMapURL(nullImage);
0940: }
0941:
0942: /**
0943: * This method sets the frame that will be effected when the user selects an item in the tree.
0944: */
0945: public void setTargetFrame(String f) {
0946: _targetFrame = f;
0947: }
0948:
0949: /**
0950: * This method sets the tree buffer that this component uses.
0951: * The tree buffer is the class that maintains the state of the items on the tree.
0952: */
0953:
0954: public void setTreeBuffer(TreeBuffer tb) {
0955: _tb = tb;
0956: _sortColumn = 0;
0957: _sortDir = TreeBuffer.SORT_ASC;
0958: _clickSortColumn = -1;
0959: if (_sortPathDir != TreeBuffer.SORT_ANY)
0960: _sortPathDir = TreeBuffer.SORT_ASC;
0961: }
0962:
0963: /**
0964: * For a click sort, decide whether or not the first column (tree path) takes precidence to the column being sorted
0965: */
0966: public void setUsePathForClickSort(boolean usePath) {
0967: if (usePath)
0968: _sortPathDir = TreeBuffer.SORT_ASC;
0969: else
0970: _sortPathDir = TreeBuffer.SORT_ANY;
0971: }
0972:
0973: /**
0974: * Sort the tree
0975: * @param column the number of the header column to sort on (0 for path name only sort)
0976: * @param pathDir the sort direction for the tree path (first column) to sort on TreeBuffer.SORT_ASC or TreeBuffer.SORT_DES or TreeBuffer.SORT_ANY to not use a path sort
0977: * @param dir the direction to sort the specified column on SORT_ASC or SORT_DES if column is not zero
0978: */
0979: public void sort(int sortColumn, int sortPathDir, int sortDir) {
0980: _sortColumn = sortColumn;
0981: _sortPathDir = sortPathDir;
0982: _sortDir = sortDir;
0983: _tb.sort(_sortColumn, _sortPathDir, _sortDir);
0984: }
0985:
0986: /**
0987: * Sort the tree on a column
0988: * @param column the number of the header column to sort on (0 for path name only sort)
0989: * @param dir the direction to sort the specified column on SORT_ASC or SORT_DES if column is not zero
0990: */
0991: public void sort(int sortColumn, int sortDir) {
0992: sort(sortColumn, TreeBuffer.SORT_ANY, sortDir);
0993: }
0994:
0995: public void sort() {
0996: sort(_sortColumn, _sortPathDir, _sortDir);
0997: }
0998:
0999: /*
1000: * Added by: Henry Tafolla
1001: * Date: Feburary 22 2003
1002: * Description: Properties for the HtmlTreeComponent
1003: */
1004: /**
1005: * This method sets the property theme for the component.
1006: * @param theme The theme to use.
1007: */
1008: public void setTheme(String theme) {
1009:
1010: Props prop = getPage().getPageProperties();
1011:
1012: _anchorClass = prop.getThemeProperty(theme,
1013: Props.TREE_ANCHOR_CLASS);
1014: _cellPadding = prop.getThemeIntProperty(theme,
1015: Props.TREE_CELLPADDING);
1016: _cellSpacing = prop.getThemeIntProperty(theme,
1017: Props.TREE_CELLSPACING);
1018: _window = prop.getThemeBooleanProperty(theme,
1019: Props.TREE_JAVASCRIPT_WINDOW);
1020: _windowDirectories = prop.getThemeProperty(theme,
1021: Props.TREE_JAVASCRIPT_WINDOW_DIRECTORIES);
1022: _windowHeight = prop.getThemeIntProperty(theme,
1023: Props.TREE_JAVASCRIPT_WINDOW_HEIGHT);
1024: _windowLocation = prop.getThemeProperty(theme,
1025: Props.TREE_JAVASCRIPT_WINDOW_LOCATION);
1026: _windowMenubar = prop.getThemeProperty(theme,
1027: Props.TREE_JAVASCRIPT_WINDOW_MENUBAR);
1028: _windowName = prop.getThemeProperty(theme,
1029: Props.TREE_JAVASCRIPT_WINDOW_NAME);
1030: _windowResizable = prop.getThemeProperty(theme,
1031: Props.TREE_JAVASCRIPT_WINDOW_RESIZABLE);
1032: _windowScrollbars = prop.getThemeProperty(theme,
1033: Props.TREE_JAVASCRIPT_WINDOW_SCROLLBARS);
1034: _windowStatus = prop.getThemeProperty(theme,
1035: Props.TREE_JAVASCRIPT_WINDOW_STATUS);
1036: _windowToolbar = prop.getThemeProperty(theme,
1037: Props.TREE_JAVASCRIPT_WINDOW_TOOLBAR);
1038: _windowWidth = prop.getThemeIntProperty(theme,
1039: Props.TREE_JAVASCRIPT_WINDOW_WIDTH);
1040: _tableCellClass = prop.getThemeProperty(theme,
1041: Props.TREE_TABLE_CELL_CLASS);
1042: _headerCellClass = prop.getThemeProperty(theme,
1043: Props.TREE_TABLE_HEADER_CELL_CLASS);
1044: _tableCellStyle = prop.getThemeProperty(theme,
1045: Props.TREE_TABLE_CELL_STYLE);
1046: _headerCellStyle = prop.getThemeProperty(theme,
1047: Props.TREE_TABLE_HEADER_CELL_STYLE);
1048: _treeTableStyle = prop.getThemeProperty(theme,
1049: Props.TREE_TABLE_STYLE);
1050: _treeTableClass = prop.getThemeProperty(theme,
1051: Props.TREE_TABLE_CLASS);
1052: _fontTagStart = prop.getThemeProperty(theme,
1053: Props.TREE_NODE_FONT + Props.TAG_START);
1054: _fontTagEnd = prop.getThemeProperty(theme, Props.TREE_NODE_FONT
1055: + Props.TAG_END);
1056: if (_fontTagStart != null) {
1057: _nodePtSizeSpanEnd = "";
1058: _nodePtSizeSpanStart = "";
1059: }
1060: _theme = theme;
1061: }
1062:
1063: /**
1064: * Returns the theme the tree is using
1065: */
1066: public String getTheme() {
1067: return _theme;
1068: }
1069:
1070: /**
1071: * @return the width of the tree table
1072: */
1073: public String getWidth() {
1074: return _width;
1075: }
1076:
1077: /**
1078: * sets the width of the table
1079: */
1080: public void setWidth(String string) {
1081: _width = string;
1082: }
1083:
1084: /**
1085: * This method will add a property expression to the HtmlTree.
1086: * The propExpression will be evaluated for each row in the DataStore and the set method for the specified property will be called on the specified object.
1087: * @param comp The component to set the property for
1088: * @param propertyName The name of the property to set. The component must have a corresponding setProperty method or this method will throw a NoSuchMethodException
1089: * @param propExpression com.salmonllc.html.PropertyExpression The instance of PropertyExpression that should do the evaluating.
1090: * @exception java.lang.NoSuchMethodException The exception description.
1091: * @exception com.salmonllc.sql.DataStoreException The exception description.
1092: */
1093: public void addPropertyExpression(Object comp, String propertyName,
1094: DataStoreBuffer dsb, DataStoreExpression propExpression)
1095: throws NoSuchMethodException, DataStoreException {
1096:
1097: DataStoreEvaluator dse = new DataStoreEvaluator(dsb,
1098: propExpression);
1099: addPropertyExpression(comp, propertyName, dse);
1100: }
1101:
1102: /**
1103: * The propExpression will be evaluated for each row in the DataStore and the set method for the specified property will be called on the specified object.
1104: @param comp The component to set the property for
1105: * @param propertyName The name of the property to set. The component must have a corresponding setProperty method or this method will throw a NoSuchMethodException
1106: * @param expression java.lang.String The datastore expression to evaluate
1107: * @exception java.lang.NoSuchMethodException The exception description.
1108: * @exception com.salmonllc.sql.DataStoreException The exception description.
1109: */
1110: public void addPropertyExpression(Object comp, String propertyName,
1111: DataStoreBuffer dsb, String expression)
1112: throws NoSuchMethodException, DataStoreException {
1113: DataStoreEvaluator dse = new DataStoreEvaluator(dsb, expression);
1114: addPropertyExpression(comp, propertyName, dse);
1115: }
1116:
1117: /**
1118: * The propExpression will be evaluated by the evaluated for each row in the DataStore and the set method for the specified property will be called on the specified object.
1119: * @param comp The component to set the property for
1120: * @param propertyName The name of the property to set. The component must have a corresponding setProperty method or this method will throw a NoSuchMethodException
1121: * @param expEval DataStoreEvaluator The datastore evaluator that evaluates the expression
1122: * @exception java.lang.NoSuchMethodException The exception description.
1123: * @exception com.salmonllc.sql.DataStoreException The exception description.
1124: */
1125: public void addPropertyExpression(Object comp, String propertyName,
1126: DataStoreEvaluator expEval) throws NoSuchMethodException,
1127: DataStoreException {
1128: Class c = comp.getClass();
1129: Method m[] = c.getMethods();
1130: Method exe = null;
1131: String name = "set" + propertyName;
1132: Class parms[] = null;
1133: for (int i = 0; i < m.length; i++) {
1134: if (name.equalsIgnoreCase(m[i].getName())) {
1135: parms = m[i].getParameterTypes();
1136: if (parms.length == 1) {
1137: exe = m[i];
1138: break;
1139: }
1140: }
1141: }
1142: if (exe == null)
1143: throw new NoSuchMethodException(
1144: "Couldn't find a set method for property:"
1145: + propertyName);
1146: ThreeObjectContainer t = new ThreeObjectContainer(comp, exe,
1147: expEval);
1148: if (_propertyExpressions == null)
1149: _propertyExpressions = new Vector();
1150: _propertyExpressions.addElement(t);
1151: }
1152:
1153: public void processPropertyExpressions(int row) {
1154: if (_propertyExpressions == null)
1155: return;
1156:
1157: ThreeObjectContainer c = null;
1158: Object comp = null;
1159: Method meth = null;
1160: DataStoreEvaluator eval = null;
1161:
1162: int propertyExpressionsSize = _propertyExpressions.size();
1163: for (int i = 0; i < propertyExpressionsSize; i++) {
1164: c = (ThreeObjectContainer) _propertyExpressions
1165: .elementAt(i);
1166: comp = c.getObject1();
1167: meth = (Method) c.getObject2();
1168: eval = (DataStoreEvaluator) c.getObject3();
1169: HtmlPage.executePropertyMethod(comp, meth, eval, row);
1170: }
1171: }
1172:
1173: /**
1174: * @return true if the tree will automatically scroll to the location of the previous submit
1175: */
1176: public boolean getAutoScroll() {
1177: return _autoScroll;
1178: }
1179:
1180: /**
1181: * set to true for thee tree to automatically scroll page to the location it was on as of the previous submit
1182: */
1183: public void setAutoScroll(boolean b) {
1184: _autoScroll = b;
1185: }
1186:
1187: /**
1188: * Returns whether click sort on the heading components is enabled
1189: */
1190: public boolean getClickSort() {
1191: return _clickSort;
1192: }
1193:
1194: /**
1195: * Set to true to allow heading components to do a click sort
1196: */
1197: public void setClickSort(boolean b) {
1198: _clickSort = b;
1199: }
1200:
1201: private void doSort(int colNo) {
1202: if (_tb.canSortOnColumn(colNo)) {
1203: if (colNo == _sortColumn) {
1204: if (_sortDir == TreeBuffer.SORT_ASC)
1205: _sortDir = TreeBuffer.SORT_DES;
1206: else
1207: _sortDir = TreeBuffer.SORT_ASC;
1208: } else
1209: _sortDir = TreeBuffer.SORT_ASC;
1210:
1211: if (colNo == 0 && _sortPathDir != TreeBuffer.SORT_ANY) {
1212: if (_sortColumn != 0)
1213: _sortPathDir = TreeBuffer.SORT_ASC;
1214: else if (_sortPathDir == TreeBuffer.SORT_ASC)
1215: _sortPathDir = TreeBuffer.SORT_DES;
1216: else
1217: _sortPathDir = TreeBuffer.SORT_ASC;
1218: }
1219:
1220: _sortColumn = colNo;
1221: _tb.sort(_sortColumn, _sortPathDir, _sortDir);
1222: }
1223: }
1224: }
|