001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: * Tom Schindl <tom.schindl@bestsolution.at> - initial API and implementation
011: * - fix in bug: 174355,171126,,195908,198035
012: *******************************************************************************/package org.eclipse.jface.viewers;
013:
014: import java.util.LinkedList;
015:
016: import org.eclipse.core.runtime.Assert;
017: import org.eclipse.swt.graphics.Color;
018: import org.eclipse.swt.graphics.Font;
019: import org.eclipse.swt.graphics.Image;
020: import org.eclipse.swt.graphics.Rectangle;
021: import org.eclipse.swt.widgets.Control;
022: import org.eclipse.swt.widgets.Tree;
023: import org.eclipse.swt.widgets.TreeItem;
024: import org.eclipse.swt.widgets.Widget;
025:
026: /**
027: * TreeViewerRow is the Tree implementation of ViewerRow.
028: *
029: * @since 3.3
030: *
031: */
032: public class TreeViewerRow extends ViewerRow {
033: private TreeItem item;
034:
035: /**
036: * Create a new instance of the receiver.
037: *
038: * @param item
039: */
040: TreeViewerRow(TreeItem item) {
041: this .item = item;
042: }
043:
044: /*
045: * (non-Javadoc)
046: *
047: * @see org.eclipse.jface.viewers.ViewerRow#getBounds(int)
048: */
049: public Rectangle getBounds(int columnIndex) {
050: return item.getBounds(columnIndex);
051: }
052:
053: /*
054: * (non-Javadoc)
055: *
056: * @see org.eclipse.jface.viewers.ViewerRow#getBounds()
057: */
058: public Rectangle getBounds() {
059: return item.getBounds();
060: }
061:
062: /*
063: * (non-Javadoc)
064: *
065: * @see org.eclipse.jface.viewers.ViewerRow#getColumnCount()
066: */
067: public int getColumnCount() {
068: return item.getParent().getColumnCount();
069: }
070:
071: /*
072: * (non-Javadoc)
073: *
074: * @see org.eclipse.jface.viewers.ViewerRow#getItem()
075: */
076: public Widget getItem() {
077: return item;
078: }
079:
080: /*
081: * (non-Javadoc)
082: *
083: * @see org.eclipse.jface.viewers.ViewerRow#getBackground(int)
084: */
085: public Color getBackground(int columnIndex) {
086: return item.getBackground(columnIndex);
087: }
088:
089: /*
090: * (non-Javadoc)
091: *
092: * @see org.eclipse.jface.viewers.ViewerRow#getFont(int)
093: */
094: public Font getFont(int columnIndex) {
095: return item.getFont(columnIndex);
096: }
097:
098: /*
099: * (non-Javadoc)
100: *
101: * @see org.eclipse.jface.viewers.ViewerRow#getForeground(int)
102: */
103: public Color getForeground(int columnIndex) {
104: return item.getForeground(columnIndex);
105: }
106:
107: /*
108: * (non-Javadoc)
109: *
110: * @see org.eclipse.jface.viewers.ViewerRow#getImage(int)
111: */
112: public Image getImage(int columnIndex) {
113: return item.getImage(columnIndex);
114: }
115:
116: /*
117: * (non-Javadoc)
118: *
119: * @see org.eclipse.jface.viewers.ViewerRow#getText(int)
120: */
121: public String getText(int columnIndex) {
122: return item.getText(columnIndex);
123: }
124:
125: /*
126: * (non-Javadoc)
127: *
128: * @see org.eclipse.jface.viewers.ViewerRow#setBackground(int,
129: * org.eclipse.swt.graphics.Color)
130: */
131: public void setBackground(int columnIndex, Color color) {
132: item.setBackground(columnIndex, color);
133: }
134:
135: /*
136: * (non-Javadoc)
137: *
138: * @see org.eclipse.jface.viewers.ViewerRow#setFont(int,
139: * org.eclipse.swt.graphics.Font)
140: */
141: public void setFont(int columnIndex, Font font) {
142: item.setFont(columnIndex, font);
143: }
144:
145: /*
146: * (non-Javadoc)
147: *
148: * @see org.eclipse.jface.viewers.ViewerRow#setForeground(int,
149: * org.eclipse.swt.graphics.Color)
150: */
151: public void setForeground(int columnIndex, Color color) {
152: item.setForeground(columnIndex, color);
153: }
154:
155: /*
156: * (non-Javadoc)
157: *
158: * @see org.eclipse.jface.viewers.ViewerRow#setImage(int,
159: * org.eclipse.swt.graphics.Image)
160: */
161: public void setImage(int columnIndex, Image image) {
162: Image oldImage = item.getImage(columnIndex);
163: if (image != oldImage) {
164: item.setImage(columnIndex, image);
165: }
166: }
167:
168: /*
169: * (non-Javadoc)
170: *
171: * @see org.eclipse.jface.viewers.ViewerRow#setText(int, java.lang.String)
172: */
173: public void setText(int columnIndex, String text) {
174: item.setText(columnIndex, text == null ? "" : text); //$NON-NLS-1$
175: }
176:
177: /*
178: * (non-Javadoc)
179: *
180: * @see org.eclipse.jface.viewers.ViewerRow#getControl()
181: */
182: public Control getControl() {
183: return item.getParent();
184: }
185:
186: public ViewerRow getNeighbor(int direction, boolean sameLevel) {
187: if (direction == ViewerRow.ABOVE) {
188: return getRowAbove(sameLevel);
189: } else if (direction == ViewerRow.BELOW) {
190: return getRowBelow(sameLevel);
191: } else {
192: throw new IllegalArgumentException(
193: "Illegal value of direction argument."); //$NON-NLS-1$
194: }
195: }
196:
197: private ViewerRow getRowBelow(boolean sameLevel) {
198: Tree tree = item.getParent();
199:
200: // This means we have top-level item
201: if (item.getParentItem() == null) {
202: if (sameLevel || !item.getExpanded()) {
203: int index = tree.indexOf(item) + 1;
204:
205: if (index < tree.getItemCount()) {
206: return new TreeViewerRow(tree.getItem(index));
207: }
208: } else if (item.getExpanded() && item.getItemCount() > 0) {
209: return new TreeViewerRow(item.getItem(0));
210: }
211: } else {
212: if (sameLevel || !item.getExpanded()) {
213: TreeItem parentItem = item.getParentItem();
214:
215: int nextIndex = parentItem.indexOf(item) + 1;
216: int totalIndex = parentItem.getItemCount();
217:
218: TreeItem itemAfter;
219:
220: // This would mean that it was the last item
221: if (nextIndex == totalIndex) {
222: itemAfter = findNextItem(parentItem);
223: } else {
224: itemAfter = parentItem.getItem(nextIndex);
225: }
226:
227: if (itemAfter != null) {
228: return new TreeViewerRow(itemAfter);
229: }
230:
231: } else if (item.getExpanded() && item.getItemCount() > 0) {
232: return new TreeViewerRow(item.getItem(0));
233: }
234: }
235:
236: return null;
237: }
238:
239: private ViewerRow getRowAbove(boolean sameLevel) {
240: Tree tree = item.getParent();
241:
242: // This means we have top-level item
243: if (item.getParentItem() == null) {
244: int index = tree.indexOf(item) - 1;
245: TreeItem nextTopItem = null;
246:
247: if (index >= 0) {
248: nextTopItem = tree.getItem(index);
249: }
250:
251: if (nextTopItem != null) {
252: if (sameLevel) {
253: return new TreeViewerRow(nextTopItem);
254: }
255:
256: return new TreeViewerRow(
257: findLastVisibleItem(nextTopItem));
258: }
259: } else {
260: TreeItem parentItem = item.getParentItem();
261: int previousIndex = parentItem.indexOf(item) - 1;
262:
263: TreeItem itemBefore;
264: if (previousIndex >= 0) {
265: if (sameLevel) {
266: itemBefore = parentItem.getItem(previousIndex);
267: } else {
268: itemBefore = findLastVisibleItem(parentItem
269: .getItem(previousIndex));
270: }
271: } else {
272: itemBefore = parentItem;
273: }
274:
275: if (itemBefore != null) {
276: return new TreeViewerRow(itemBefore);
277: }
278: }
279:
280: return null;
281: }
282:
283: private TreeItem findLastVisibleItem(TreeItem parentItem) {
284: TreeItem rv = parentItem;
285:
286: while (rv.getExpanded() && rv.getItemCount() > 0) {
287: rv = rv.getItem(rv.getItemCount() - 1);
288: }
289:
290: return rv;
291: }
292:
293: private TreeItem findNextItem(TreeItem item) {
294: TreeItem rv = null;
295: Tree tree = item.getParent();
296: TreeItem parentItem = item.getParentItem();
297:
298: int nextIndex;
299: int totalItems;
300:
301: if (parentItem == null) {
302: nextIndex = tree.indexOf(item) + 1;
303: totalItems = tree.getItemCount();
304: } else {
305: nextIndex = parentItem.indexOf(item) + 1;
306: totalItems = parentItem.getItemCount();
307: }
308:
309: // This is once more the last item in the tree
310: // Search on
311: if (nextIndex == totalItems) {
312: if (item.getParentItem() != null) {
313: rv = findNextItem(item.getParentItem());
314: }
315: } else {
316: if (parentItem == null) {
317: rv = tree.getItem(nextIndex);
318: } else {
319: rv = parentItem.getItem(nextIndex);
320: }
321: }
322:
323: return rv;
324: }
325:
326: public TreePath getTreePath() {
327: TreeItem tItem = item;
328: LinkedList segments = new LinkedList();
329: while (tItem != null) {
330: Object segment = tItem.getData();
331: Assert.isNotNull(segment);
332: segments.addFirst(segment);
333: tItem = tItem.getParentItem();
334: }
335:
336: return new TreePath(segments.toArray());
337: }
338:
339: void setItem(TreeItem item) {
340: this .item = item;
341: }
342:
343: public Object clone() {
344: return new TreeViewerRow(item);
345: }
346:
347: public Object getElement() {
348: return item.getData();
349: }
350:
351: public int getVisualIndex(int creationIndex) {
352: int[] order = item.getParent().getColumnOrder();
353:
354: for (int i = 0; i < order.length; i++) {
355: if (order[i] == creationIndex) {
356: return i;
357: }
358: }
359:
360: return super .getVisualIndex(creationIndex);
361: }
362:
363: public int getCreationIndex(int visualIndex) {
364: if (item != null && !item.isDisposed() && hasColumns()
365: && isValidOrderIndex(visualIndex)) {
366: return item.getParent().getColumnOrder()[visualIndex];
367: }
368: return super .getCreationIndex(visualIndex);
369: }
370:
371: private boolean hasColumns() {
372: return this .item.getParent().getColumnCount() != 0;
373: }
374:
375: private boolean isValidOrderIndex(int currentIndex) {
376: return currentIndex < this.item.getParent().getColumnOrder().length;
377: }
378: }
|