001: /*
002: * CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
003: * NETSCAPE COMMUNICATIONS CORPORATION
004: *
005: * Copyright (c) 1996 Netscape Communications Corporation.
006: * All Rights Reserved.
007: * Use of this Source Code is subject to the terms of the applicable
008: * license agreement from Netscape Communications Corporation.
009: */
010:
011: package graphical;
012:
013: import netscape.application.Color;
014: import netscape.application.DragDestination;
015: import netscape.application.DragSession;
016: import netscape.application.DragSource;
017: import netscape.application.Image;
018: import netscape.application.ListItem;
019: import netscape.application.MouseEvent;
020: import netscape.application.Point;
021: import netscape.application.Rect;
022: import netscape.application.Target;
023: import netscape.application.View;
024:
025: import graphical.MouseOverGridView;
026:
027: import com.indius.base.IntVector;
028: import com.indius.grid.IGrid;
029: import com.indius.grid.IGridRowEditView;
030: import com.indius.grid.SimpleGrid;
031:
032: public class DragIGREView extends MouseOverGridView implements
033: DragDestination, DragSource, DragPolicy {
034: private DragPolicyContext dpc;
035: private boolean m_editableView = false;
036: private int[] columnWidths;
037: private boolean[] editableColumn;
038: private boolean[] editableRow;
039: private boolean[][] editableCell;
040: private Image dragImage;
041:
042: private Target selectionTarget; // selection target
043: private String singleSelectionCommand; // signleClick command
044: private String doubleSelectionCommand; // doubleClick command
045:
046: private boolean m_pressDeferred = false;
047:
048: private int m_dragRow = -1;
049:
050: /**
051: * Constructs an empty DragIGRSView.
052: */
053: public DragIGREView() {
054: // SGP: will that null be ok?
055: this (0, 0, 0, 0, DRAGFROMDISALLOWED, DRAGTODISALLOWED, null,
056: new SimpleGrid());
057: }
058:
059: /**
060: * Constructs a DragIGRSView with bounds <B>rect</B>.
061: * @param rect rectangle
062: */
063: public DragIGREView(Rect rect) {
064: this (rect.x, rect.y, rect.width, rect.height,
065: DRAGFROMDISALLOWED, DRAGTODISALLOWED, null,
066: new SimpleGrid());
067: }
068:
069: /**
070: * Constructs a DragIGRSView with bounds <B>rect</B>.
071: * @param rect rectangle
072: * @param dragSourcePolicy drag source policy
073: * @param dragDestinationPolicy drag destination policy
074: * @param dragImage drag image
075: * @param IGrid grid
076: */
077: public DragIGREView(Rect rect, int dragSourcePolicy,
078: int dragDestinationPolicy, Image dragImage, IGrid igrid) {
079: this (rect.x, rect.y, rect.width, rect.height, dragSourcePolicy,
080: dragDestinationPolicy, dragImage, igrid);
081: }
082:
083: /**
084: * Constructs an empty DragIGRSView with the given bounds.
085: * @param x x
086: * @param y y
087: * @param width width
088: * @param height height
089: */
090: public DragIGREView(int x, int y, int width, int height) {
091: this (x, y, width, height, DRAGFROMDISALLOWED, DRAGTODISALLOWED,
092: null, new SimpleGrid());
093: }
094:
095: /**
096: * Constructs an empty DragIGRSView with the given bounds.
097: * @param x x
098: * @param y y
099: * @param width width
100: * @param height height
101: * @param dragSourcePolicy drag source policy
102: * @param dragDestinationPolicy drag destination policy
103: * @param dragImage drag image
104: * @param IGrid grid
105: */
106: public DragIGREView(int x, int y, int width, int height,
107: int dragSourcePolicy, int dragDestinationPolicy,
108: Image dragImage, IGrid igrid) {
109: // SGP: you know you'll have image/select image...
110:
111: super (x, y, width, height);
112:
113: dpc = new DragPolicyContext(dragImage);
114:
115: setDragSourcePolicy(dragSourcePolicy);
116: setDragDestinationPolicy(dragDestinationPolicy);
117:
118: this .dragImage = dragImage;
119: setGrid(igrid);
120: setHasRowLabels(false);
121: setHasVertScrollBar();
122: setHasHorizScrollBar();
123: setSelectBackgroundColor(Color.lightGray);
124: setSelectTextColor(Color.black);
125: setBuffered(true);
126: }
127:
128: /**
129: * getEditableView - This class supports both editable and non-editable views.
130: * This method returns the current editable state of the view. (MCW)
131: */
132: public boolean getEditableView() {
133: return m_editableView;
134: }
135:
136: /**
137: * setEditableView - This class supports both editable and non-editable views.
138: * This method sets the current editable state of the view. (MCW)
139: */
140: public void setEditableView(boolean editableView) {
141: m_editableView = editableView;
142: }
143:
144: /**
145: * Can the column be resized?
146: * Sure, if it isn't the icon/0 column.
147: * @param c column
148: */
149: public boolean canResizeColumn(int c) {
150: return (c != 0);
151: }
152:
153: public void setGrid(IGrid g) {
154: super .setGrid(g);
155:
156: columnWidths = new int[g.columns()];
157:
158: if (m_editableView == true) {
159: editableRow = new boolean[g.rows()];
160: editableColumn = new boolean[g.columns()];
161: editableCell = new boolean[g.rows()][g.columns()];
162: }
163:
164: if (dragImage != null) {
165: setColumnWidth(0, dragImage.width() + 2);
166: }
167: }
168:
169: public void setColumnWidth(int c, int w) {
170: super .setColumnWidth(c, w);
171: columnWidths[c] = w;
172: }
173:
174: public int columnWidth(int c) {
175: if (columnWidths == null) {
176: return super .columnWidth(c);
177: }
178: return ((columnWidths[c] == 0) ? super .columnWidth(c)
179: : columnWidths[c]);
180: }
181:
182: public void setEditableRow(int r, boolean b) {
183: editableRow[r] = b;
184: }
185:
186: public void setEditableColumn(int c, boolean b) {
187: editableColumn[c] = b;
188: }
189:
190: public void setEditableCell(int r, int c, boolean b) {
191: editableCell[r][c] = b;
192: }
193:
194: public boolean getEditableRow(int r) {
195: return editableRow[r];
196: }
197:
198: public boolean getEditableColumn(int c) {
199: return editableColumn[c];
200: }
201:
202: public boolean getEditableCell(int r, int c) {
203: return editableCell[r][c];
204: }
205:
206: public boolean editable(int r, int c) {
207: if (m_editableView == false) { // Non-Editable view?
208: return false;
209: }
210:
211: if ((r >= editableRow.length) || // Outside of grid?
212: (c >= editableColumn.length)) {
213: return false;
214: }
215:
216: return ((editableRow[r]) // Check for editable row,column
217: || (editableColumn[c]) || (editableCell[r][c]));
218: }
219:
220: /**************/
221: /* DragPolicy */
222: /**************/
223:
224: public DragPolicyContext getDragPolicyContext() {
225: return dpc;
226: }
227:
228: public Target getDestinationTarget() {
229: return dpc.destinationTarget;
230: }
231:
232: public void setDestinationTarget(Target t) {
233: dpc.destinationTarget = t;
234: }
235:
236: public Target getSourceTarget() {
237: return dpc.sourceTarget;
238: }
239:
240: public void setSourceTarget(Target t) {
241: dpc.sourceTarget = t;
242: }
243:
244: public Image getDragImage() {
245: return dpc.dragImage;
246: }
247:
248: public void setDragImage(Image dragImage) {
249: dpc.dragImage = dragImage;
250: }
251:
252: public void setDragSourcePolicy(int dragSourcePolicy)
253: throws IllegalArgumentException {
254: if (DragPolicyContext
255: .validateDragSourcePolicy(dragSourcePolicy)) {
256: dpc.dragSourcePolicy = dragSourcePolicy;
257: } else {
258: throw new IllegalArgumentException(
259: Messages.UNKNOWNDRAGPOLICY + " " + dragSourcePolicy);
260: }
261: }
262:
263: public void setDragDestinationPolicy(int dragDestinationPolicy)
264: throws IllegalArgumentException {
265: if (DragPolicyContext
266: .validateDragDestinationPolicy(dragDestinationPolicy)) {
267: dpc.dragDestinationPolicy = dragDestinationPolicy;
268: } else {
269: throw new IllegalArgumentException(
270: Messages.UNKNOWNDRAGPOLICY + " "
271: + dragDestinationPolicy);
272: }
273: }
274:
275: /**************/
276: /* MouseEvent */
277: /**************/
278:
279: // SGP: require mouse stuff in interface?
280: public boolean mouseDown(MouseEvent e) {
281: // System.out.println( "mouseDown()" );
282: dpc.mouseDownX = e.x;
283: dpc.mouseDownY = e.y;
284: boolean result = super .mouseDown(e);
285:
286: if (columnLabelsRect().contains(e.x, e.y) == true) {
287: // So as not to interfere with Indius column sizing (MCW)
288: return result;
289: }
290:
291: if (locateColumn(e.x, 0) != 0) {
292: // Must click on icon to drag
293: return result;
294: }
295:
296: if (dpc.dragSourcePolicy != DRAGFROMDISALLOWED) {
297: if (dpc.dragSession == null) {
298: IntVector sr;
299:
300: if (selectedRowCount() == 0) {
301: // No selected row, nothing to drag. Shouldn't happen, just in case.
302: return false;
303: } else {
304: // Save selected row array
305: sr = selectedRows();
306: }
307:
308: dpc.dragSession = new DragSession(this , dpc.dragImage,
309: dpc.mouseDownX - (dpc.dragImage.width() / 2),
310: dpc.mouseDownY - (dpc.dragImage.height() / 2),
311: dpc.mouseDownX, dpc.mouseDownY, "", sr);
312: result = true;
313: }
314: }
315:
316: // I hijacked these tests from IGridRowSelectView(), it always returns
317: // false after shift and control key processing which disables drag of
318: // multiply selected items. mouseDown must return true so that IFC will
319: // call mouseDragged(). (MCW)
320: if (e.isShiftKeyDown() && !m_singleSelect) {
321: return true;
322: } else if (e.isControlKeyDown() && !m_singleSelect) {
323: return true;
324: }
325:
326: return result;
327: }
328:
329: public void mouseDragged(MouseEvent e) {
330: // System.out.println( "mouseDragged()" );
331: super .mouseDragged(e);
332: }
333:
334: /**
335: * onPressCell - Intercept single click on a row,
336: * to refresh propertyWindow if open. (MCW)
337: */
338: public void onPressCell(int r, int c) {
339: super .onPressCell(r, c);
340: selectionTarget.performCommand(singleSelectionCommand,
341: new Integer(r));
342: }
343:
344: /**
345: * onDoubleClickRow - Intercept double click on a row,
346: * to open property window. (MCW)
347: */
348: public void onDoubleClickRow(int r) {
349: selectionTarget.performCommand(doubleSelectionCommand,
350: new Integer(r));
351: }
352:
353: /*
354: * These overrides are to change th default selection behavior to allow
355: * multiple selections to be dragged. By default Indius changes selection on
356: * mouse down so you cannot select a range and then click on it to drag, Indius
357: * will change the selection. To get around the problem if on a mouse down,
358: * the current row is already selected, the reselection is deferred until
359: * the mouse up.
360: */
361:
362: /**
363: * onPressRowLabel - Intercept mouse down on row and defer selection to mouse
364: * up if the row is already selected. Used to support multiple drag.
365: */
366: public void onPressRowLabel(int r) {
367: if (isSelected(r) == true) {
368: m_pressDeferred = true;
369: return;
370: }
371:
372: m_pressDeferred = false;
373: super .onPressRowLabel(r);
374: return;
375: }
376:
377: /**
378: * onReleaseRowLabel - Intercept mouse up on row and if the down was deferred
379: * do it now. Used to support multiple drag.
380: */
381: public void onReleaseRowLabel(int r) {
382: if (m_pressDeferred == true) {
383: super .onPressRowLabel(r);
384: }
385:
386: super .onReleaseRowLabel(r);
387: m_pressDeferred = false;
388: return;
389: }
390:
391: /**
392: * onSlideRowLabel - Intercept mouse drag and if the mouse down was deferred,
393: * skip the drag. Used to support multiple drag.
394: */
395: public void onSlideRowLabel(int r) {
396: if (m_pressDeferred == true) {
397: return;
398: }
399:
400: super .onSlideRowLabel(r);
401: }
402:
403: /**
404: * setSelectionTarget - set SINGLE/doubleclick target. (mcw)
405: */
406: public void setSelectionTarget(Target target) {
407: selectionTarget = target;
408: }
409:
410: /**
411: * setSelectionCommand - set single/doubleclick command. (mcw)
412: */
413: public void setSelectionCommand(String singleCommand,
414: String doubleCommand) {
415: singleSelectionCommand = singleCommand;
416: doubleSelectionCommand = doubleCommand;
417: }
418:
419: /* SGP
420: public void mouseUp( MouseEvent e )
421: {
422: // System.out.println( "mouseUp()" );
423: super.mouseUp( e );
424: }
425:
426: public void mouseEntered( MouseEvent e )
427: {
428: // System.out.println( "mouseEntered()" );
429: super.mouseEntered( e );
430: }
431:
432: public void mouseMoved( MouseEvent e )
433: {
434: // System.out.println( "mouseMoved()" );
435: super.mouseMoved( e );
436: }
437:
438: public void mouseExited( MouseEvent e )
439: {
440: // System.out.println( "mouseExited()" );
441: super.mouseExited( e );
442: }
443: */
444:
445: /*******************/
446: /* DragDestination */
447: /*******************/
448:
449: public boolean dragEntered(DragSession ds) {
450: // System.out.println( "dragEntered()" );
451: if (dpc.dragDestinationPolicy != DRAGTODISALLOWED) {
452: dpc.sourceDragSession = ds;
453: return true;
454: } else {
455: return false;
456: }
457: }
458:
459: public boolean dragMoved(DragSession ds) {
460: // System.out.println( "dragMoved()" );
461:
462: if (dpc.destinationTarget != null) {
463: Point destPoint = ds.destinationMousePoint();
464: int r = locateRow(destPoint.y, 0);
465: int c = locateColumn(destPoint.x, 0);
466:
467: if (r != m_dragRow) { // Dragging over new row?
468: addDirtyRect(cellRect(m_dragRow, // Unselect previous drag row
469: iconColumn()));
470: m_dragRow = r;
471: setDragRow(r); // Setup for drag feedback
472: addDirtyRect(cellRect(r, // Force feedback display
473: iconColumn()));
474: }
475: }
476:
477: return true;
478: }
479:
480: public void dragExited(DragSession ds) {
481: // System.out.println( "dragExited()" );
482: setDragRow(-1); // Cancel drag feedback
483: m_dragRow = -1;
484:
485: if (dpc.dragDestinationPolicy != DRAGTODISALLOWED) {
486: dpc.sourceDragSession = null;
487: draw(); // SGP??
488: }
489: }
490:
491: public boolean dragDropped(DragSession ds) {
492: // System.out.println( "dragDropped()" );
493:
494: setDragRow(-1); // Cancel drag feedback
495: m_dragRow = -1;
496:
497: Point destPoint = ds.destinationMousePoint();
498: if (dpc.destinationTarget != null) {
499: DragArgument da = new DragArgument(
500: DragArgument.DRAGDROPPED, this ,
501: /* can't send cell so send coords */
502: new Point(locateColumn(destPoint.x, 0), locateRow(
503: destPoint.y, 0)), ds.source(), ds.data());
504: dpc.destinationTarget.performCommand("", da);
505: }
506:
507: if (dpc.dragDestinationPolicy == DRAGTOACCEPT) {
508: dpc.sourceDragSession = null;
509: return true;
510: } else if (dpc.dragDestinationPolicy == DRAGTOACCEPTINCLUDE) {
511: // SGP: not implemented
512: } else if (dpc.dragDestinationPolicy == DRAGTOACCEPTDISPLACE) {
513: // SGP: not implemented
514: }
515:
516: return true;
517: }
518:
519: public DragDestination acceptsDrag(DragSession ds, int x, int y) {
520: // System.out.println( "acceptsDrag()" );
521:
522: // System.out.println(
523: // "source [" + ds.source().toString() + "]"
524: // );
525: // System.out.println(
526: // "data [" + ds.data().toString() + "]"
527: // );
528:
529: // must be open for business
530: if (dpc.dragDestinationPolicy == DRAGTODISALLOWED) {
531: return null;
532: }
533:
534: // don't drag into the void
535: if (grid() == null) {
536: return null;
537: }
538: if (grid().rows() == 0) {
539: return null;
540: }
541:
542: // SGP:
543: // don't drag onto yourself
544:
545: return this ;
546: }
547:
548: /**************/
549: /* DragSource */
550: /**************/
551:
552: public View sourceView(DragSession ds) {
553: // System.out.println( "sourceView()" );
554: return this ;
555: }
556:
557: public void dragWasAccepted(DragSession ds) {
558: // System.out.println( "dragWasAccepted()" );
559:
560: if (dpc.dragSourcePolicy == DRAGFROMMOVE) {
561: }
562:
563: dpc.dragSession = null;
564: setDirty(true);
565: }
566:
567: public boolean dragWasRejected(DragSession ds) {
568: // System.out.println( "dragWasRejected()" );
569:
570: dpc.dragSession = null;
571: setDirty(true);
572: return true;
573: }
574: }
|