001: /*
002: * The contents of this file are subject to the
003: * Mozilla Public License Version 1.1 (the "License");
004: * you may not use this file except in compliance with the License.
005: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
009: * See the License for the specific language governing rights and
010: * limitations under the License.
011: *
012: * The Initial Developer of the Original Code is Simulacra Media Ltd.
013: * Portions created by Simulacra Media Ltd are Copyright (C) Simulacra Media Ltd, 2004.
014: *
015: * All Rights Reserved.
016: *
017: * Contributor(s):
018: */
019:
020: package org.openharmonise.him.displaycomponents.table;
021:
022: import java.awt.*;
023: import java.awt.dnd.*;
024: import java.awt.event.*;
025: import java.util.*;
026: import java.util.List;
027:
028: import javax.swing.*;
029:
030: import org.openharmonise.him.displaycomponents.*;
031: import org.openharmonise.him.dnd.*;
032: import org.openharmonise.him.window.menus.*;
033: import org.openharmonise.vfs.*;
034: import org.openharmonise.vfs.context.*;
035: import org.openharmonise.vfs.event.*;
036:
037: /**
038: * Table view of resources.
039: *
040: * @author Matthew Large
041: * @version $Revision: 1.2 $
042: *
043: */
044: public class TableView extends AbstractTableComponent implements
045: Runnable, VirtualFileListener, MouseListener, ContextListener,
046: KeyListener {
047:
048: /**
049: * Name order type identifier.
050: */
051: public static String ORDER_NAME = "ORDER_NAME";
052:
053: /**
054: * Date order type identifier.
055: */
056: public static String ORDER_DATE = "ORDER_DATE";
057:
058: /**
059: * Server order type identifier.
060: */
061: public static String ORDER_SERVER = "ORDER_SERVER";
062:
063: /**
064: * Order type.
065: */
066: private String m_sOrderType = ORDER_NAME;
067:
068: /**
069: * Full path to collection to be displayed in table.
070: */
071: private String m_sPath = null;
072:
073: /**
074: * Virtual file system for collection to be displayed in table.
075: */
076: private AbstractVirtualFileSystem m_vfs = null;
077:
078: /**
079: * Full path of selected resource.
080: */
081: private String m_sSelectedPath = null;
082:
083: /**
084: * List of ordered full paths to resources in this view.
085: */
086: private ArrayList m_order = new ArrayList();
087:
088: /**
089: * Map of full path to {@link TableEntry} objects.
090: */
091: private HashMap m_entries = new HashMap();
092:
093: protected List m_colRowMap = new ArrayList();
094:
095: /**
096: * Constructs a new table view.
097: *
098: * @param displayComponent Display component
099: */
100: public TableView(AbstractDisplayComponent displayComponent) {
101: super (displayComponent);
102: this
103: .setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
104: TableLayout fl = new TableLayout(this );
105:
106: this .setLayout(fl);
107: this .addMouseListener(this );
108: this .addKeyListener(this );
109: }
110:
111: /**
112: * Clears the table view.
113: *
114: */
115: public void clearTable() {
116: Component[] comps = this .getComponents();
117: for (int i = 0; i < comps.length; i++) {
118: if (comps[i] instanceof TableEntry) {
119: TableEntry comp = (TableEntry) comps[i];
120: comp.clearToDestroy();
121: }
122: }
123: this .m_entries.clear();
124: this .m_order.clear();
125:
126: this .removeAll();
127: }
128:
129: /**
130: * Sets the virtual file system and full path for the collection
131: * that this table is to display.
132: *
133: * @param vfs Virtual file system
134: * @param sPath Full path
135: */
136: public void setPath(AbstractVirtualFileSystem vfs, String sPath) {
137:
138: if (this .m_vfs != null && this .m_sPath != null) {
139: VirtualFile vfFile = m_vfs.getVirtualFile(sPath)
140: .getResource();
141: if (vfFile != null) {
142: vfFile.removeVirtualFileListener(this );
143: }
144: }
145:
146: this .m_sPath = sPath;
147:
148: this .m_vfs = vfs;
149: VirtualFile vfFile = m_vfs.getVirtualFile(sPath).getResource();
150:
151: vfFile.addVirtualFileListener(this );
152:
153: this .setResources(vfs, vfFile.getChildren());
154: }
155:
156: /**
157: * Sets the virtual file system and full paths for the resources.
158: * Used for display components, such as Search, which do not show
159: * collections but lists of resources.
160: *
161: * @param vfs Virtual file system
162: * @param aResources List of full paths
163: */
164: public void setResources(AbstractVirtualFileSystem vfs,
165: List aResources) {
166: this .m_vfs = vfs;
167:
168: this .clearTable();
169:
170: Iterator itor = aResources.iterator();
171: while (itor.hasNext()) {
172: String sChildPath = (String) itor.next();
173: TableEntry entry = new TableEntry(this .m_vfs, sChildPath,
174: this );
175: this .m_order.add(sChildPath);
176: this .m_entries.put(sChildPath, entry);
177: TableDragSource source = new TableDragSource(entry, entry,
178: DnDConstants.ACTION_COPY_OR_MOVE);
179: this .add(entry);
180: }
181:
182: this .setOrderType(this .m_sOrderType);
183:
184: ((TableLayout) this .getLayout()).reflowContainer(this );
185: this .getParent().validate();
186: }
187:
188: /**
189: * Called when a table entry is selected.
190: *
191: * @param entry Table entry
192: */
193: protected void entrySelected(TableEntry entry) {
194: System.out.println(entry.getPath());
195: m_sSelectedPath = entry.getPath();
196: ((AbstractTreeTableDisplayComponent) this .m_displayComponent)
197: .fileSelection(entry);
198: this .deselectOtherEntries(entry);
199: this .requestFocus();
200: }
201:
202: /**
203: * Called when a version entry is selected.
204: *
205: * @param entry Version entry
206: */
207: protected void entrySelected(VersionEntry entry) {
208: m_sSelectedPath = entry.getPath();
209: ((AbstractTreeTableDisplayComponent) this .m_displayComponent)
210: .fileSelection(entry);
211: this .deselectOtherEntries(entry.getParentTableEntry());
212: this .requestFocus();
213: }
214:
215: /**
216: * Deselects all table entries except the given one.
217: *
218: * @param entry Table entry
219: */
220: private void deselectOtherEntries(TableEntry entry) {
221: for (int i = 0; i < this .getComponentCount(); i++) {
222: if (this .getComponent(i) instanceof TableEntry) {
223: TableEntry currentEntry = (TableEntry) this
224: .getComponent(i);
225: if (currentEntry != entry) {
226: currentEntry.deselectEntry();
227: }
228: }
229: }
230: }
231:
232: /**
233: * Called when a table entry is expanded or collapsed.
234: *
235: * @param entry Table entry
236: */
237: protected void entryHeightChange(TableEntry entry) {
238: ((TableLayout) this .getLayout()).reflowColumn(this , entry);
239: this .getParent().validate();
240: }
241:
242: /* (non-Javadoc)
243: * @see java.lang.Runnable#run()
244: */
245: public void run() {
246: this .validate();
247: this .repaint();
248: }
249:
250: public void setSelectedPath(String sSelectedPath) {
251: this .m_sSelectedPath = sSelectedPath;
252: this .grabFocus();
253: }
254:
255: /* (non-Javadoc)
256: * @see com.simulacramedia.vfs.event.VirtualFileListener#virtualFileChanged(com.simulacramedia.vfs.event.VirtualFileEvent)
257: */
258: public void virtualFileChanged(VirtualFileEvent vfe) {
259: String sSelectedPath = this .m_sSelectedPath;
260: if (this .m_vfs != null) {
261: VirtualFile vfFile = this .m_vfs.getVirtualFile(
262: sSelectedPath).getResource();
263: if (vfFile != null && vfFile.isVersionable()) {
264: VersionedVirtualFile vfVersion = (VersionedVirtualFile) vfFile;
265: if (vfVersion.hasPendingVersion()) {
266: this .m_sSelectedPath = vfVersion
267: .getPendingVersionPath();
268: }
269: }
270: }
271: if (vfe.getEventType() == VirtualFileEvent.FILE_MEMBERS_CHANGED) {
272: if (vfe.getSubType() == VirtualFile.EVENT_ADDITION
273: && vfe.getChildPath() != null) {
274: System.out.println("Setting child added path to "
275: + vfe.getChildPath());
276: this .m_sSelectedPath = vfe.getChildPath();
277: }
278:
279: this .setPath(this .m_vfs, this .m_sPath);
280:
281: ContextEvent ce = new ContextEvent(
282: ContextType.CONTEXT_CLEAR_METADATA);
283: ContextHandler.getInstance().fireContextEvent(ce);
284: }
285: SwingUtilities.invokeLater(new Runnable() {
286: public void run() {
287: runSelection();
288: }
289: });
290: }
291:
292: public void runSelection() {
293: String sSelectedPath = this .m_sSelectedPath;
294: boolean bFound = false;
295: if (sSelectedPath != null && sSelectedPath.length() > 0) {
296: for (int i = 0; i < this .getComponentCount(); i++) {
297: Component comp = this .getComponent(i);
298: if (comp instanceof TableEntry) {
299: TableEntry entry = (TableEntry) comp;
300: System.out.println("RunSelection Comparing: ["
301: + sSelectedPath + "] with entry ["
302: + entry.getPath() + "]");
303: if (entry.getPath().equals(sSelectedPath)) {
304: this .entrySelected(entry);
305: entry.selectEntry();
306: bFound = true;
307: }
308: }
309: }
310: }
311: if (!bFound && this .getOrderedList().size() > 0) {
312: TableEntry entry = this .getEntry((String) this
313: .getOrderedList().get(0));
314: this .m_sSelectedPath = entry.getPath();
315: this .entrySelected(entry);
316: entry.selectEntry();
317: ContextEvent ce = new ContextEvent(
318: ContextType.CONTEXT_FILES, null, this .m_vfs,
319: this .m_sSelectedPath);
320: ContextHandler.getInstance().fireContextEvent(ce);
321: }
322:
323: this .validate();
324: }
325:
326: /**
327: * Returns the ordered list of full paths to resources in this
328: * table view.
329: *
330: * @return List of full paths
331: */
332: protected List getOrderedList() {
333: return (List) this .m_order.clone();
334: }
335:
336: /**
337: * Returns the table entry for a given full path.
338: *
339: * @param sPath Full path
340: * @return Table entry
341: */
342: protected TableEntry getEntry(String sPath) {
343: return (TableEntry) this .m_entries.get(sPath);
344: }
345:
346: /**
347: * Returns the order type.
348: *
349: * @return Order type
350: */
351: public String getOrderType() {
352: return m_sOrderType;
353: }
354:
355: /**
356: * Sets the order type and re-orders the table view accordingly.
357: *
358: * @param string Order type
359: */
360: public synchronized void setOrderType(String string) {
361: m_sOrderType = string;
362:
363: this .m_order.clear();
364:
365: if (this .m_sOrderType.equals(TableView.ORDER_DATE)) {
366: TreeMap treeMap = new TreeMap();
367: Iterator itor = this .m_entries.values().iterator();
368: while (itor.hasNext()) {
369: TableEntry element = (TableEntry) itor.next();
370: String sDate = element.getDate();
371: while (treeMap.keySet().contains(sDate)) {
372: sDate = sDate + element.getName();
373: }
374: treeMap.put(sDate, element.getDragVirtualFilePath());
375: }
376:
377: itor = treeMap.values().iterator();
378: while (itor.hasNext()) {
379: String element = (String) itor.next();
380: this .m_order.add(element);
381: }
382: } else if (this .m_sOrderType.equals(TableView.ORDER_NAME)) {
383: TreeMap treeMap = new TreeMap();
384: Iterator itor = this .m_entries.values().iterator();
385: while (itor.hasNext()) {
386: TableEntry element = (TableEntry) itor.next();
387: String sName = element.getName();
388: int nCount = 1;
389: while (treeMap.keySet().contains(sName)) {
390: sName = sName + nCount;
391: nCount++;
392: }
393: treeMap.put(sName, element.getDragVirtualFilePath());
394: }
395:
396: itor = treeMap.values().iterator();
397: while (itor.hasNext()) {
398: String element = (String) itor.next();
399: this .m_order.add(element);
400: }
401: } else if (this .m_sOrderType.equals(TableView.ORDER_SERVER)) {
402:
403: VirtualFile vfDir = this .m_vfs.getVirtualFile(this .m_sPath)
404: .getResource();
405:
406: List children = vfDir.getChildren();
407:
408: for (int i = 0; i < children.size(); i++) {
409: String array_element = (String) children.get(i);
410: this .m_order.add(array_element);
411: }
412: }
413:
414: if (this .getParent() != null) {
415: ((TableLayout) this .getLayout()).reflowContainer(this );
416: this .getParent().validate();
417: }
418: }
419:
420: /* (non-Javadoc)
421: * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
422: */
423: public void mouseClicked(MouseEvent me) {
424: if (me.getButton() == MouseEvent.BUTTON3) {
425: CollectionContextMenu menu = new CollectionContextMenu(
426: this .m_sPath, this .m_vfs);
427: Point pt = me.getPoint();
428: menu.show(this , pt.x, pt.y);
429: } else if (me.getButton() == MouseEvent.BUTTON1) {
430: this .requestFocus();
431: }
432: }
433:
434: /* (non-Javadoc)
435: * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
436: */
437: public void mouseEntered(MouseEvent me) {
438: }
439:
440: /* (non-Javadoc)
441: * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
442: */
443: public void mouseExited(MouseEvent arg0) {
444: }
445:
446: /* (non-Javadoc)
447: * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
448: */
449: public void mousePressed(MouseEvent arg0) {
450: }
451:
452: /* (non-Javadoc)
453: * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
454: */
455: public void mouseReleased(MouseEvent arg0) {
456: }
457:
458: /**
459: * Opens the specified path in the tree view, if the display component
460: * for this table has a tree.
461: *
462: * @param sPath Full path
463: */
464: public void openPathInTree(String sPath) {
465: if (this .m_displayComponent instanceof AbstractTreeTableDisplayComponent) {
466: ((AbstractTreeTableDisplayComponent) this .m_displayComponent)
467: .openPathInTree(sPath);
468: }
469: }
470:
471: /* (non-Javadoc)
472: * @see com.simulacramedia.contentmanager.context.ContextListener#contextMessage(com.simulacramedia.contentmanager.context.ContextEvent)
473: */
474: public void contextMessage(ContextEvent ce) {
475:
476: }
477:
478: /* (non-Javadoc)
479: * @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
480: */
481: public void keyPressed(KeyEvent arg0) {
482: // NO-OP
483: }
484:
485: /* (non-Javadoc)
486: * @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
487: */
488: public void keyReleased(KeyEvent ke) {
489: if (this .m_sSelectedPath != null) {
490: if (ke.getKeyCode() == KeyEvent.VK_UP) {
491: List column = this .getColumn(this .m_sSelectedPath);
492: if (column != null
493: && column.indexOf(this .m_sSelectedPath) > 0) {
494: String sNewPath = (String) column.get(column
495: .indexOf(this .m_sSelectedPath) - 1);
496: TableEntry entry = this .getEntry(sNewPath);
497: entry.selectEntry();
498: this .entrySelected(entry);
499: }
500: } else if (ke.getKeyCode() == KeyEvent.VK_DOWN) {
501: List column = this .getColumn(this .m_sSelectedPath);
502: if (column != null
503: && column.indexOf(this .m_sSelectedPath) < column
504: .size() - 1) {
505: String sNewPath = (String) column.get(column
506: .indexOf(this .m_sSelectedPath) + 1);
507: TableEntry entry = this .getEntry(sNewPath);
508: entry.selectEntry();
509: this .entrySelected(entry);
510: }
511: } else if (ke.getKeyCode() == KeyEvent.VK_LEFT) {
512: List column = this .getColumn(this .m_sSelectedPath);
513: if (column != null
514: && this .m_colRowMap.indexOf(column) > 0) {
515: List newCol = (List) this .m_colRowMap
516: .get(this .m_colRowMap.indexOf(column) - 1);
517: if (newCol.size() >= column
518: .indexOf(this .m_sSelectedPath) + 1) {
519: String sNewPath = (String) newCol.get(column
520: .indexOf(this .m_sSelectedPath));
521: TableEntry entry = this .getEntry(sNewPath);
522: entry.selectEntry();
523: this .entrySelected(entry);
524: }
525: }
526: } else if (ke.getKeyCode() == KeyEvent.VK_RIGHT) {
527: List column = this .getColumn(this .m_sSelectedPath);
528: if (column != null
529: && this .m_colRowMap.indexOf(column) < this .m_colRowMap
530: .size() - 1) {
531: List newCol = (List) this .m_colRowMap
532: .get(this .m_colRowMap.indexOf(column) + 1);
533: if (newCol.size() >= column
534: .indexOf(this .m_sSelectedPath) + 1) {
535: String sNewPath = (String) newCol.get(column
536: .indexOf(this .m_sSelectedPath));
537: TableEntry entry = this .getEntry(sNewPath);
538: entry.selectEntry();
539: this .entrySelected(entry);
540: }
541: }
542: }
543: }
544: }
545:
546: private List getColumn(String sPath) {
547: List retn = null;
548:
549: Iterator itor = this .m_colRowMap.iterator();
550: while (itor.hasNext()) {
551: List column = (List) itor.next();
552: if (column.contains(sPath)) {
553: retn = column;
554: }
555: }
556:
557: return retn;
558: }
559:
560: /* (non-Javadoc)
561: * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
562: */
563: public void keyTyped(KeyEvent arg0) {
564: // NO-OP
565: }
566:
567: protected void setColRowMap(List colRowMap) {
568: this.m_colRowMap = colRowMap;
569: }
570: }
|