001: /*******************************************************************************
002: * Copyright (c) 2005, 2006 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: *******************************************************************************/package org.eclipse.ui.internal.progress;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: import org.eclipse.jface.dialogs.IDialogConstants;
016: import org.eclipse.jface.resource.JFaceResources;
017: import org.eclipse.jface.viewers.ViewerComparator;
018: import org.eclipse.swt.SWT;
019: import org.eclipse.swt.custom.ScrolledComposite;
020: import org.eclipse.swt.events.ControlEvent;
021: import org.eclipse.swt.events.ControlListener;
022: import org.eclipse.swt.events.FocusAdapter;
023: import org.eclipse.swt.events.FocusEvent;
024: import org.eclipse.swt.graphics.Point;
025: import org.eclipse.swt.layout.GridData;
026: import org.eclipse.swt.layout.GridLayout;
027: import org.eclipse.swt.widgets.Composite;
028: import org.eclipse.swt.widgets.Control;
029: import org.eclipse.swt.widgets.Text;
030: import org.eclipse.swt.widgets.Widget;
031: import org.eclipse.ui.PlatformUI;
032: import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
033:
034: /**
035: * The VirtualProgressViewer is a viewer that shows the details of all in
036: * progress job or jobs that are finished awaiting user input. It only updates
037: * those items that are currently visible.
038: *
039: * @since 3.3
040: *
041: */
042: public class VirtualProgressViewer extends AbstractProgressViewer {
043:
044: Composite control;
045:
046: private ScrolledComposite scrolled;
047:
048: private Composite noEntryArea;
049:
050: /**
051: * Create a new instance of the receiver with a control that is a child of
052: * parent with style style.
053: *
054: * @param parent
055: * @param style
056: */
057: public VirtualProgressViewer(Composite parent, int style) {
058: scrolled = new ScrolledComposite(parent, SWT.V_SCROLL | style);
059: int height = JFaceResources.getDefaultFont().getFontData()[0]
060: .getHeight();
061: scrolled.getVerticalBar().setIncrement(height * 2);
062: scrolled.setExpandHorizontal(true);
063: scrolled.setExpandVertical(true);
064:
065: control = new Composite(scrolled, SWT.NONE);
066:
067: control.addControlListener(new ControlListener() {
068: /*
069: * (non-Javadoc)
070: *
071: * @see org.eclipse.swt.events.ControlListener#controlMoved(org.eclipse.swt.events.ControlEvent)
072: */
073: public void controlMoved(ControlEvent e) {
074: updateVisibleItems();
075:
076: }
077:
078: /*
079: * (non-Javadoc)
080: *
081: * @see org.eclipse.swt.events.ControlListener#controlResized(org.eclipse.swt.events.ControlEvent)
082: */
083: public void controlResized(ControlEvent e) {
084: updateVisibleItems();
085:
086: }
087: });
088: GridLayout layout = new GridLayout();
089: layout.marginHeight = 0;
090: layout.marginWidth = 0;
091: control.setLayout(layout);
092: control.setBackground(parent.getDisplay().getSystemColor(
093: SWT.COLOR_LIST_BACKGROUND));
094:
095: control.addFocusListener(new FocusAdapter() {
096: /*
097: * (non-Javadoc)
098: *
099: * @see org.eclipse.swt.events.FocusAdapter#focusGained(org.eclipse.swt.events.FocusEvent)
100: */
101: public void focusGained(FocusEvent e) {
102: setFocus();
103: }
104: });
105:
106: PlatformUI.getWorkbench().getHelpSystem().setHelp(control,
107: IWorkbenchHelpContextIds.RESPONSIVE_UI);
108:
109: scrolled.setContent(control);
110: hookControl(control);
111:
112: noEntryArea = new Composite(scrolled, SWT.NONE);
113: noEntryArea.setLayout(new GridLayout());
114:
115: Text noEntryLabel = new Text(noEntryArea, SWT.SINGLE);
116: noEntryLabel
117: .setText(ProgressMessages.ProgressView_NoOperations);
118: noEntryLabel.setBackground(noEntryArea.getDisplay()
119: .getSystemColor(SWT.COLOR_WIDGET_BACKGROUND));
120: GridData textData = new GridData(
121: GridData.VERTICAL_ALIGN_BEGINNING);
122: noEntryLabel.setLayoutData(textData);
123: noEntryLabel.setEditable(false);
124:
125: PlatformUI.getWorkbench().getHelpSystem().setHelp(noEntryLabel,
126: IWorkbenchHelpContextIds.RESPONSIVE_UI);
127:
128: }
129:
130: /*
131: * (non-Javadoc)
132: *
133: * @see org.eclipse.ui.internal.progress.AbstractProgressViewer#add(java.lang.Object[])
134: */
135: public void add(Object[] elements) {
136: ViewerComparator sorter = getComparator();
137: ArrayList newItems = new ArrayList(control.getChildren().length
138: + elements.length);
139:
140: Control[] existingChildren = control.getChildren();
141: for (int i = 0; i < existingChildren.length; i++) {
142: newItems.add(existingChildren[i].getData());
143: }
144:
145: for (int i = 0; i < elements.length; i++) {
146: newItems.add(elements[i]);
147: }
148:
149: JobTreeElement[] infos = new JobTreeElement[newItems.size()];
150: newItems.toArray(infos);
151:
152: if (sorter != null) {
153: sorter.sort(this , infos);
154: }
155:
156: // Update with the new elements to prevent flash
157: for (int i = 0; i < existingChildren.length; i++) {
158: ((VirtualInfoItem) existingChildren[i]).dispose();
159: }
160:
161: for (int i = 0; i < newItems.size(); i++) {
162: VirtualInfoItem item = createNewItem(infos[i]);
163: item.setColor(i);
164: }
165:
166: control.layout(true);
167: updateForShowingProgress();
168: }
169:
170: /**
171: * Update for the progress being displayed.
172: */
173: private void updateForShowingProgress() {
174: if (control.getChildren().length > 0) {
175: scrolled.setContent(control);
176: } else {
177: scrolled.setContent(noEntryArea);
178: }
179: }
180:
181: /**
182: * Create a new item for info.
183: *
184: * @param info
185: * @return VirtualInfoItem
186: */
187: private VirtualInfoItem createNewItem(JobTreeElement info) {
188: final VirtualInfoItem item = new VirtualInfoItem(control,
189: SWT.NONE, info);
190:
191: item.setIndexListener(new VirtualInfoItem.IndexListener() {
192: /*
193: * (non-Javadoc)
194: *
195: * @see org.eclipse.ui.internal.progress.VirtualInfoItem.IndexListener#selectNext()
196: */
197: public void selectNext() {
198: VirtualProgressViewer.this .selectNext(item);
199:
200: }
201:
202: /*
203: * (non-Javadoc)
204: *
205: * @see org.eclipse.ui.internal.progress.VirtualInfoItem.IndexListener#selectPrevious()
206: */
207: public void selectPrevious() {
208: VirtualProgressViewer.this .selectPrevious(item);
209:
210: }
211:
212: /*
213: * (non-Javadoc)
214: *
215: * @see org.eclipse.ui.internal.progress.VirtualInfoItem.IndexListener#select()
216: */
217: public void select() {
218:
219: Control[] children = control.getChildren();
220: for (int i = 0; i < children.length; i++) {
221: VirtualInfoItem child = (VirtualInfoItem) children[i];
222: if (!item.equals(child)) {
223: child.selectWidgets(false);
224: }
225: }
226: item.selectWidgets(true);
227:
228: }
229: });
230:
231: // Refresh to populate with the current tasks
232: item.refresh();
233: return item;
234: }
235:
236: /**
237: * Select the previous item in the receiver.
238: *
239: * @param item
240: */
241: protected void selectPrevious(VirtualInfoItem item) {
242: Control[] children = control.getChildren();
243: for (int i = 0; i < children.length; i++) {
244: VirtualInfoItem child = (VirtualInfoItem) children[i];
245: if (item.equals(child)) {
246: VirtualInfoItem previous;
247: if (i == 0) {
248: previous = (VirtualInfoItem) children[children.length - 1];
249: } else {
250: previous = (VirtualInfoItem) children[i - 1];
251: }
252:
253: item.selectWidgets(false);
254: previous.selectWidgets(true);
255: return;
256: }
257: }
258: }
259:
260: /**
261: * Select the next item in the receiver.
262: *
263: * @param item
264: */
265: protected void selectNext(VirtualInfoItem item) {
266: Control[] children = control.getChildren();
267: for (int i = 0; i < children.length; i++) {
268: VirtualInfoItem child = (VirtualInfoItem) children[i];
269: if (item.equals(child)) {
270: VirtualInfoItem next;
271: if (i == children.length - 1) {
272: next = (VirtualInfoItem) children[0];
273: } else {
274: next = (VirtualInfoItem) children[i + 1];
275: }
276: item.selectWidgets(false);
277: next.selectWidgets(true);
278:
279: return;
280: }
281: }
282:
283: }
284:
285: /*
286: * (non-Javadoc)
287: *
288: * @see org.eclipse.jface.viewers.StructuredViewer#doFindInputItem(java.lang.Object)
289: */
290: protected Widget doFindInputItem(Object element) {
291: return null;
292: }
293:
294: /*
295: * (non-Javadoc)
296: *
297: * @see org.eclipse.jface.viewers.StructuredViewer#doFindItem(java.lang.Object)
298: */
299: protected Widget doFindItem(Object element) {
300: Control[] existingChildren = control.getChildren();
301: for (int i = 0; i < existingChildren.length; i++) {
302: if (existingChildren[i].isDisposed()
303: || existingChildren[i].getData() == null) {
304: continue;
305: }
306: if (existingChildren[i].getData().equals(element)) {
307: return existingChildren[i];
308: }
309: }
310: return null;
311: }
312:
313: /*
314: * (non-Javadoc)
315: *
316: * @see org.eclipse.jface.viewers.StructuredViewer#doUpdateItem(org.eclipse.swt.widgets.Widget,
317: * java.lang.Object, boolean)
318: */
319: protected void doUpdateItem(Widget item, Object element,
320: boolean fullMap) {
321: if (usingElementMap()) {
322: unmapElement(item);
323: }
324: item.dispose();
325: add(new Object[] { element });
326: }
327:
328: /*
329: * (non-Javadoc)
330: *
331: * @see org.eclipse.jface.viewers.Viewer#getControl()
332: */
333: public Control getControl() {
334: return scrolled;
335: }
336:
337: /*
338: * (non-Javadoc)
339: *
340: * @see org.eclipse.jface.viewers.StructuredViewer#getSelectionFromWidget()
341: */
342: protected List getSelectionFromWidget() {
343: return new ArrayList(0);
344: }
345:
346: /*
347: * (non-Javadoc)
348: *
349: * @see org.eclipse.jface.viewers.Viewer#inputChanged(java.lang.Object,
350: * java.lang.Object)
351: */
352: protected void inputChanged(Object input, Object oldInput) {
353: super .inputChanged(input, oldInput);
354: refreshAll();
355: updateForShowingProgress();
356: }
357:
358: /*
359: * (non-Javadoc)
360: *
361: * @see org.eclipse.jface.viewers.StructuredViewer#internalRefresh(java.lang.Object)
362: */
363: protected void internalRefresh(Object element) {
364: if (element == null) {
365: return;
366: }
367:
368: if (element.equals(getRoot())) {
369: refreshAll();
370: return;
371: }
372: Widget widget = findItem(element);
373: if (widget == null) {
374: add(new Object[] { element });
375: return;
376: }
377: ((VirtualInfoItem) widget).refresh();
378:
379: // Update the minimum size
380: Point size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
381: size.x += IDialogConstants.HORIZONTAL_SPACING;
382: size.y += IDialogConstants.VERTICAL_SPACING;
383:
384: scrolled.setMinSize(size);
385: }
386:
387: /*
388: * (non-Javadoc)
389: *
390: * @see org.eclipse.ui.internal.progress.AbstractProgressViewer#remove(java.lang.Object[])
391: */
392: public void remove(Object[] elements) {
393:
394: for (int i = 0; i < elements.length; i++) {
395:
396: // Make sure we are not keeping this one
397: if (((JobTreeElement) elements[i]).isJobInfo()
398: && FinishedJobs.getInstance().isFinished(
399: (JobInfo) elements[i])) {
400: Widget item = doFindItem(elements[i]);
401: if (item != null) {
402: ((VirtualInfoItem) item).refresh();
403: }
404:
405: } else {
406: Widget item = doFindItem(elements[i]);
407: if (item != null) {
408: unmapElement(elements[i]);
409: item.dispose();
410: }
411: }
412: }
413:
414: Control[] existingChildren = control.getChildren();
415: for (int i = 0; i < existingChildren.length; i++) {
416: VirtualInfoItem item = (VirtualInfoItem) existingChildren[i];
417: item.setColor(i);
418: }
419: control.layout(true);
420: updateForShowingProgress();
421: }
422:
423: /*
424: * (non-Javadoc)
425: *
426: * @see org.eclipse.jface.viewers.StructuredViewer#reveal(java.lang.Object)
427: */
428: public void reveal(Object element) {
429:
430: }
431:
432: /*
433: * (non-Javadoc)
434: *
435: * @see org.eclipse.jface.viewers.StructuredViewer#setSelectionToWidget(java.util.List,
436: * boolean)
437: */
438: protected void setSelectionToWidget(List l, boolean reveal) {
439:
440: }
441:
442: /**
443: * Cancel the current selection
444: *
445: */
446: public void cancelSelection() {
447:
448: }
449:
450: /**
451: * Set focus on the current selection.
452: *
453: */
454: public void setFocus() {
455: Control[] children = control.getChildren();
456: if (children.length > 0) {
457: for (int i = 0; i < children.length; i++) {
458: VirtualInfoItem item = (VirtualInfoItem) children[i];
459: item.setButtonFocus();
460: return;
461: }
462: } else
463: noEntryArea.setFocus();
464: }
465:
466: /**
467: * Refresh everything as the root is being refreshed.
468: */
469: private void refreshAll() {
470:
471: Object[] infos = getSortedChildren(getRoot());
472: Control[] existingChildren = control.getChildren();
473:
474: for (int i = 0; i < existingChildren.length; i++) {
475: existingChildren[i].dispose();
476:
477: }
478: // Create new ones if required
479: for (int i = 0; i < infos.length; i++) {
480: VirtualInfoItem item = createNewItem((JobTreeElement) infos[i]);
481: item.setColor(i);
482: }
483:
484: control.layout(true);
485: updateForShowingProgress();
486:
487: }
488:
489: /**
490: * Set the virtual items to be visible or not depending on the displayed
491: * area.
492: */
493: private void updateVisibleItems() {
494: Control[] children = control.getChildren();
495: int top = scrolled.getOrigin().y;
496: int bottom = top + scrolled.getParent().getBounds().height;
497: for (int i = 0; i < children.length; i++) {
498: VirtualInfoItem item = (VirtualInfoItem) children[i];
499: item.setDisplayed(top, bottom);
500:
501: }
502: }
503:
504: }
|