Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown2001-06-27 23:45:29 +0000
committerJeff Brown2001-06-27 23:45:29 +0000
commite19f3ee2e5f1fa5577672314ef96ca3ab839cf03 (patch)
tree65e64fadf8fe98af88838977f6335a3f7bd1365d /examples/org.eclipse.swt.examples
parentf49332c775fa13aa2d8bdf58dbda00cc4dbee67f (diff)
downloadeclipse.platform.swt-e19f3ee2e5f1fa5577672314ef96ca3ab839cf03.tar.gz
eclipse.platform.swt-e19f3ee2e5f1fa5577672314ef96ca3ab839cf03.tar.xz
eclipse.platform.swt-e19f3ee2e5f1fa5577672314ef96ca3ab839cf03.zip
*** empty log message ***
Diffstat (limited to 'examples/org.eclipse.swt.examples')
-rwxr-xr-xexamples/org.eclipse.swt.examples/examples_fileviewer.properties3
-rwxr-xr-xexamples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/FileViewer.java100
-rw-r--r--examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java2
-rwxr-xr-xexamples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/FileViewer.java100
-rw-r--r--examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java2
5 files changed, 143 insertions, 64 deletions
diff --git a/examples/org.eclipse.swt.examples/examples_fileviewer.properties b/examples/org.eclipse.swt.examples/examples_fileviewer.properties
index e3073b7d84..7df80bcb1b 100755
--- a/examples/org.eclipse.swt.examples/examples_fileviewer.properties
+++ b/examples/org.eclipse.swt.examples/examples_fileviewer.properties
@@ -46,7 +46,6 @@ dialog.FailedDelete.description = An error occured while trying to delete "{0}".
simulate.CopyFromTo.text = Simulated copy from "{0}" to "{1}".
simulate.DirectoriesCreated.text = Simulated directories created for "{0}".
-simulate.UnknownResource.text = Ignoring unknown resource "{0}".
-simulate.Delete.text = Deleting "{0}".
+simulate.Delete.text = Simulated delete of "{0}".
error.FailedLaunch.message = Could not launch "{0}"
diff --git a/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/FileViewer.java b/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/FileViewer.java
index 20bc41d0da..a2243b5748 100755
--- a/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/FileViewer.java
+++ b/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/FileViewer.java
@@ -33,6 +33,12 @@ public class FileViewer {
private Label diskSpaceLabel;
private File currentDirectory = null;
+
+ /* Drag and drop optimizations -- avoid redundant updates */
+ private File[] deferredRefreshFiles = null;
+ private boolean deferredRefreshRequested = false;
+ private boolean isDragging = false; // don't refresh during drag and drop
+ private boolean isDropping = false; // don't refresh during drag and drop
/* Combo view */
private static final String COMBODATA_ROOTS = "Combo.roots";
@@ -424,11 +430,14 @@ public class FileViewer {
dndSelection = tree.getSelection();
sourceNames = null;
event.doit = dndSelection.length > 0;
+ isDragging = true;
}
public void dragFinished(DragSourceEvent event){
dragSourceHandleDragFinished(event, sourceNames);
dndSelection = null;
sourceNames = null;
+ isDragging = false;
+ handleDeferredRefresh();
}
public void dragSetData(DragSourceEvent event){
if (dndSelection == null || dndSelection.length == 0) return;
@@ -455,6 +464,13 @@ public class FileViewer {
dropTarget.setTransfer(new Transfer[] { FileTransfer.getInstance() });
dropTarget.addDropListener(new TreeDropFeedbackListener(tree));
dropTarget.addDropListener(new DropTargetAdapter() {
+ public void dragEnter(DropTargetEvent event) {
+ isDropping = true;
+ }
+ public void dragLeave(DropTargetEvent event) {
+ isDropping = false;
+ handleDeferredRefresh();
+ }
public void dragOver(DropTargetEvent event) {
dropTargetValidate(event, getTargetFile(event));
}
@@ -625,11 +641,14 @@ public class FileViewer {
dndSelection = table.getSelection();
sourceNames = null;
event.doit = dndSelection.length > 0;
+ isDragging = true;
}
public void dragFinished(DragSourceEvent event){
dragSourceHandleDragFinished(event, sourceNames);
dndSelection = null;
sourceNames = null;
+ isDragging = false;
+ handleDeferredRefresh();
}
public void dragSetData(DragSourceEvent event){
if (dndSelection == null || dndSelection.length == 0) return;
@@ -655,6 +674,13 @@ public class FileViewer {
DropTarget dropTarget = new DropTarget(table, DND.DROP_MOVE | DND.DROP_COPY);
dropTarget.setTransfer(new Transfer[] { FileTransfer.getInstance() });
dropTarget.addDropListener(new DropTargetAdapter() {
+ public void dragEnter(DropTargetEvent event) {
+ isDropping = true;
+ }
+ public void dragLeave(DropTargetEvent event) {
+ isDropping = false;
+ handleDeferredRefresh();
+ }
public void dragOver(DropTargetEvent event) {
dropTargetValidate(event, getTargetFile(event));
}
@@ -794,6 +820,30 @@ public class FileViewer {
void notifyRefreshFiles(File[] files) {
if (files != null && files.length == 0) return;
+ if ((deferredRefreshRequested) && (deferredRefreshFiles != null) && (files != null)) {
+ // merge requests
+ File[] newRequest = new File[deferredRefreshFiles.length + files.length];
+ System.arraycopy(deferredRefreshFiles, 0, newRequest, 0, deferredRefreshFiles.length);
+ System.arraycopy(files, 0, newRequest, deferredRefreshFiles.length, files.length);
+ deferredRefreshFiles = newRequest;
+ } else {
+ deferredRefreshFiles = files;
+ deferredRefreshRequested = true;
+ }
+ handleDeferredRefresh();
+ }
+
+ /**
+ * Handles deferred Refresh notifications (due to Drag & Drop)
+ */
+ void handleDeferredRefresh() {
+ if (isDragging || isDropping || ! deferredRefreshRequested) return;
+ deferredRefreshRequested = false;
+ File[] files = deferredRefreshFiles;
+ deferredRefreshFiles = null;
+
+ // Does not refresh very intelligently at the moment.
+
/* Table view:
* Refreshes information about any files in the list and their children.
*/
@@ -1019,7 +1069,25 @@ public class FileViewer {
searchFile = searchFile.getParentFile();
} while (searchFile != null);
- if (oldFile.isFile()) {
+ if (oldFile.isDirectory()) {
+ /*
+ * Copy a directory
+ */
+ if (simulateOnly) {
+ System.out.println(getResourceString("simulate.DirectoriesCreated.text",
+ new Object[] { newFile.getPath() }));
+ } else {
+ if (! newFile.mkdirs()) return false;
+ }
+ File[] subFiles = oldFile.listFiles();
+ if (subFiles != null) {
+ for (int i = 0; i < subFiles.length; i++) {
+ File oldSubFile = subFiles[i];
+ File newSubFile = new File(newFile, oldSubFile.getName());
+ if (! copyFileStructure(oldSubFile, newSubFile)) return false;
+ }
+ }
+ } else {
/*
* Copy a file
*/
@@ -1048,36 +1116,8 @@ public class FileViewer {
}
}
}
- return true;
- } else if (oldFile.isDirectory()) {
- /*
- * Copy a directory
- */
- if (simulateOnly) {
- System.out.println(getResourceString("simulate.DirectoriesCreated.text",
- new Object[] { newFile.getPath() }));
- } else {
- if (! newFile.mkdirs()) return false;
- }
- File[] subFiles = oldFile.listFiles();
- if (subFiles != null) {
- for (int i = 0; i < subFiles.length; i++) {
- File oldSubFile = subFiles[i];
- File newSubFile = new File(newFile, oldSubFile.getName());
- if (! copyFileStructure(oldSubFile, newSubFile)) return false;
- }
- }
- return true;
- } else {
- /*
- * Unknown type
- */
- if (simulateOnly) {
- System.out.println(getResourceString("simulate.UnknownResource.text",
- new Object[] { oldFile.getPath() }));
- }
- return false; // error we don't know how to copy this
}
+ return true;
}
/**
diff --git a/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java b/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java
index c40fa9b5ba..262eff01b4 100644
--- a/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java
+++ b/examples/org.eclipse.swt.examples/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java
@@ -1 +1 @@
-package org.eclipse.swt.examples.fileviewer; /* * (c) Copyright IBM Corp. 2000, 2001. * All Rights Reserved */ import org.eclipse.swt.*; import org.eclipse.swt.dnd.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; /** * TreeDropFeedbackListener provides the following feedback mechanisms for Trees * during drag and drop operations: * <ul> * <li>Automatic Tree scrolling. * <p>If the pointer drags over an item in the Tree near its upper or * lower edges, the Tree will scroll so as to make previous or successive items visible * onscreen. This behaviour is consistent with that of popular GUI systems. * </p> * <li>Automatic TreeItem expansion. * <p>If the pointer hovers for a time over an item in the Tree that has not yet been * expanded, the item is expanded automatically. This behaviour is consistent with * that of popular GUI systems. * </p> * </ul> * <p> * To use it send addDropListener(new TreeDropFeedbackListener(tree)) to the DropTarget * object attached to the Tree. * </p> */ public class TreeDropFeedbackListener extends DropTargetAdapter { public static final long DEFAULT_EXPAND_DELAY = 1000; // millis private Tree tree; private long hoverThreshhold = DEFAULT_EXPAND_DELAY; private long hoverBegin = 0; private TreeItem hoverItem = null; /** * Constructs a Tree scrolling Drop Listener * * @param tree the Tree that the DropTarget is attached to */ public TreeDropFeedbackListener(Tree tree) { this.tree = tree; } /** * Handles dragEnter events. */ public void dragEnter(DropTargetEvent event) { hoverItem = null; } /** * Handles dragExit events. */ public void dragExit(DropTargetEvent event) { hoverItem = null; } /** * Handles dragOver events. */ public void dragOver(DropTargetEvent event) { Point point = tree.toControl(new Point(event.x, event.y)); // Get the item directly under the point TreeItem item = tree.getItem(point); if (item == null) return; // Expand the item if we've been hovering over it for some time if (item != hoverItem) { // We just started hovering, remember this item if ((item != null) && (! item.getExpanded())) { hoverBegin = System.currentTimeMillis(); hoverItem = item; } else { hoverItem = null; } } else if (hoverItem != null) { // We've been hovering for a while, expand if our timer elapsed long hoverCurrent = System.currentTimeMillis(); if (hoverCurrent - hoverBegin >= hoverThreshhold) { // Fake as if the user expanded the item manually Event hoverEvent = new Event(); hoverEvent.x = event.x; hoverEvent.y = event.y; hoverEvent.item = hoverItem; hoverEvent.time = (int) hoverCurrent; hoverItem.setExpanded(true); hoverItem = null; tree.notifyListeners(SWT.Expand, hoverEvent); return; } } // Determine scroll direction according to whether we're nearer the top, middle, or bottom Rectangle clientArea = tree.getClientArea(); int scrollRegionSize = Math.min(clientArea.height / 3, 24); // cut region into 3 parts if (scrollRegionSize < 8) return; // don't scroll if the control is too small to make sense TreeItem showItem = item; for(;;) { if (point.y < clientArea.y + scrollRegionSize) { // in upper region showItem = getPreviousVisibleItem(tree, showItem); } else if (point.y > clientArea.height + clientArea.y - scrollRegionSize) { // in lower region showItem = getNextVisibleItem(tree, showItem, false); } else { // in middle region break; } // Show the item (causes a scroll if it is outside of the visible region) if (showItem == null) break; tree.showItem(showItem); // Test that we actually scrolled, if we didn't try again with the next item if (item != tree.getItem(point)) break; } } /** * Given a TreeItem, locates the previous (above the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose previous visible neighbour is to be found * @return the previous visible item, or null if none. */ private TreeItem getPreviousVisibleItem(Tree tree, TreeItem item) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = items.length - 1; i > 0; --i) { if (items[i] == item) return getLastVisibleChild(items[i - 1]); } } return parent; } /** * Given a TreeItem, locates the following (below the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose next visible neighbour is to be found * @return the next visible item, or null if none. */ private TreeItem getNextVisibleItem(Tree tree, TreeItem item, boolean ignoreChildren) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = 0; i < items.length; ++i) { if (items[i] == item) { if (! ignoreChildren && items[i].getExpanded()) { items = items[i].getItems(); if (items != null && items.length > 0) return items[0]; } if (i + 1 < items.length) return items[i + 1]; break; } } if (parent != null) return getNextVisibleItem(tree, parent, true); } return null; } /** * Given a TreeItem, locates its last (lowest) visible item * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param item the TreeItem whose last visible child is to be found * @return the last visible child, or <code>item</code> if no visible children. */ private TreeItem getLastVisibleChild(TreeItem item) { if (! item.getExpanded()) return item; TreeItem[] items = item.getItems(); if (items == null || items.length == 0) return item; return getLastVisibleChild(items[items.length - 1]); } } \ No newline at end of file
+package org.eclipse.swt.examples.fileviewer; /* * (c) Copyright IBM Corp. 2000, 2001. * All Rights Reserved */ import org.eclipse.swt.*; import org.eclipse.swt.dnd.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; /** * TreeDropFeedbackListener provides the following feedback mechanisms for Trees * during drag and drop operations: * <ul> * <li>Automatic Tree scrolling. * <p>If the pointer drags over an item in the Tree near its upper or * lower edges, the Tree will scroll so as to make previous or successive items visible * onscreen. This behaviour is consistent with that of popular GUI systems. * </p> * <li>Automatic TreeItem expansion. * <p>If the pointer hovers for a time over an item in the Tree that has not yet been * expanded, the item is expanded automatically. This behaviour is consistent with * that of popular GUI systems. * </p> * </ul> * <p> * To use it send addDropListener(new TreeDropFeedbackListener(tree)) to the DropTarget * object attached to the Tree. * </p> */ public class TreeDropFeedbackListener extends DropTargetAdapter { protected static final int EXPAND_DELAY = 750; // millis protected static final int SCROLL_DELAY = 50; // millis protected static final int MAX_SCROLL_TRIES = 3; protected Tree tree; protected TreeItem hoverItem = null; protected Point hoverPoint = null; protected Runnable hoverRunnable = null; protected long hoverResumeTime = 0; /** * Constructs a Tree scrolling Drop Listener * * @param tree the Tree that the DropTarget is attached to */ public TreeDropFeedbackListener(Tree tree) { this.tree = tree; } /** * Handles dragEnter events. */ public void dragEnter(DropTargetEvent event) { hoverItem = null; hoverRunnable = null; } /** * Handles dragExit events. */ public void dragExit(DropTargetEvent event) { hoverItem = null; hoverRunnable = null; } /** * Handles dragOver events. * <p> * On Windows, we receive multiple dragOver()'s even if the mouse has not moved. * But we can't get timerExec()'s.<br> * <br> * On Motif, we only get dragOver()'s when the mouse has actually moved. * But timerExec()'s are processed as usual.<br> * <br> * So to ensure cross-platform UI consistency we must handle both cases! * </p> */ public void dragOver(DropTargetEvent event) { Point point = tree.toControl(new Point(event.x, event.y)); // Fetch the item we're hovering over TreeItem item = tree.getItem(point); if ((hoverRunnable != null) && (item == hoverItem)) { if (System.currentTimeMillis() >= hoverResumeTime) hoverRunnable.run(); return; } hoverItem = item; hoverPoint = point; /* * Determine the candidate action for this position: nothing, scroll or expand */ hoverRunnable = null; if (hoverItem == null) return; // Nothing to do // Consider scrolling Rectangle clientArea = tree.getClientArea(); int scrollRegionSize = Math.min(clientArea.height / 3, 24); // cut region into 3 parts if (scrollRegionSize >= 8) { // Decide scroll direction according to whether we're nearer the top, middle, or bottom if (point.y < clientArea.y + scrollRegionSize) { // in upper region setTimer(SCROLL_DELAY, new ScrollRunnable(true)); return; } else if (point.y > clientArea.height + clientArea.y - scrollRegionSize) { // in lower region setTimer(SCROLL_DELAY, new ScrollRunnable(false)); return; } // else we are in middle region } // else the region is too small for scrolling tryExpand(0); } private void tryExpand(int recoverTime) { // Expand the item if it hasn't already been expanded if (! hoverItem.getExpanded()) { setTimer(EXPAND_DELAY - recoverTime, new ExpandRunnable()); } } private void setTimer(int delay, Runnable runnable) { hoverRunnable = runnable; hoverResumeTime = System.currentTimeMillis() + delay; tree.getDisplay().timerExec(delay, hoverRunnable); } /** * Implements scrolling on a timer */ private class ScrollRunnable implements Runnable { boolean isScrollUp; public ScrollRunnable(boolean isScrollUp) { this.isScrollUp = isScrollUp; } public void run() { if (hoverRunnable != this) return; hoverRunnable = null; if (hoverItem.isDisposed()) return; // this can happen due to other events System.out.println("Scroll"); // Loop until we see a different item (abort after a few tries, just in case) TreeItem showItem = hoverItem; for (int i = MAX_SCROLL_TRIES; i > 0; --i) { showItem = (isScrollUp) ? getPreviousVisibleItem(tree, showItem) : getNextVisibleItem(tree, showItem, false); // Show the item (causes a scroll if it is outside of the visible region) if (showItem == null) break; tree.showItem(showItem); if (hoverItem != tree.getItem(hoverPoint)) return; // stop if we actually scrolled } // We get here if we failed to scroll tryExpand(SCROLL_DELAY); // try auto-expand if auto-scroll failed } } /** * Implements expanding on a timer */ private class ExpandRunnable implements Runnable { public void run() { if (hoverRunnable != this) return; hoverRunnable = null; if (hoverItem.isDisposed()) return; // this can happen due to other events System.out.println("Expand"); // Fake as if the user expanded the item manually Event hoverEvent = new Event(); hoverEvent.x = hoverPoint.x; hoverEvent.y = hoverPoint.y; hoverEvent.item = hoverItem; hoverEvent.time = (int) System.currentTimeMillis(); hoverItem.setExpanded(true); tree.notifyListeners(SWT.Expand, hoverEvent); } } /** * Given a TreeItem, locates the previous (above the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose previous visible neighbour is to be found * @return the previous visible item, or null if none. */ private TreeItem getPreviousVisibleItem(Tree tree, TreeItem item) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = items.length - 1; i > 0; --i) { if (items[i] == item) return getLastVisibleChild(items[i - 1]); } } return parent; } /** * Given a TreeItem, locates the following (below the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose next visible neighbour is to be found * @return the next visible item, or null if none. */ private TreeItem getNextVisibleItem(Tree tree, TreeItem item, boolean ignoreChildren) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = 0; i < items.length; ++i) { if (items[i] == item) { if (! ignoreChildren && items[i].getExpanded()) { items = items[i].getItems(); if (items != null && items.length > 0) return items[0]; } if (i + 1 < items.length) return items[i + 1]; break; } } if (parent != null) return getNextVisibleItem(tree, parent, true); } return null; } /** * Given a TreeItem, locates its last (lowest) visible item * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param item the TreeItem whose last visible child is to be found * @return the last visible child, or <code>item</code> if no visible children. */ private TreeItem getLastVisibleChild(TreeItem item) { if (! item.getExpanded()) return item; TreeItem[] items = item.getItems(); if (items == null || items.length == 0) return item; return getLastVisibleChild(items[items.length - 1]); } } \ No newline at end of file
diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/FileViewer.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/FileViewer.java
index 20bc41d0da..a2243b5748 100755
--- a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/FileViewer.java
+++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/FileViewer.java
@@ -33,6 +33,12 @@ public class FileViewer {
private Label diskSpaceLabel;
private File currentDirectory = null;
+
+ /* Drag and drop optimizations -- avoid redundant updates */
+ private File[] deferredRefreshFiles = null;
+ private boolean deferredRefreshRequested = false;
+ private boolean isDragging = false; // don't refresh during drag and drop
+ private boolean isDropping = false; // don't refresh during drag and drop
/* Combo view */
private static final String COMBODATA_ROOTS = "Combo.roots";
@@ -424,11 +430,14 @@ public class FileViewer {
dndSelection = tree.getSelection();
sourceNames = null;
event.doit = dndSelection.length > 0;
+ isDragging = true;
}
public void dragFinished(DragSourceEvent event){
dragSourceHandleDragFinished(event, sourceNames);
dndSelection = null;
sourceNames = null;
+ isDragging = false;
+ handleDeferredRefresh();
}
public void dragSetData(DragSourceEvent event){
if (dndSelection == null || dndSelection.length == 0) return;
@@ -455,6 +464,13 @@ public class FileViewer {
dropTarget.setTransfer(new Transfer[] { FileTransfer.getInstance() });
dropTarget.addDropListener(new TreeDropFeedbackListener(tree));
dropTarget.addDropListener(new DropTargetAdapter() {
+ public void dragEnter(DropTargetEvent event) {
+ isDropping = true;
+ }
+ public void dragLeave(DropTargetEvent event) {
+ isDropping = false;
+ handleDeferredRefresh();
+ }
public void dragOver(DropTargetEvent event) {
dropTargetValidate(event, getTargetFile(event));
}
@@ -625,11 +641,14 @@ public class FileViewer {
dndSelection = table.getSelection();
sourceNames = null;
event.doit = dndSelection.length > 0;
+ isDragging = true;
}
public void dragFinished(DragSourceEvent event){
dragSourceHandleDragFinished(event, sourceNames);
dndSelection = null;
sourceNames = null;
+ isDragging = false;
+ handleDeferredRefresh();
}
public void dragSetData(DragSourceEvent event){
if (dndSelection == null || dndSelection.length == 0) return;
@@ -655,6 +674,13 @@ public class FileViewer {
DropTarget dropTarget = new DropTarget(table, DND.DROP_MOVE | DND.DROP_COPY);
dropTarget.setTransfer(new Transfer[] { FileTransfer.getInstance() });
dropTarget.addDropListener(new DropTargetAdapter() {
+ public void dragEnter(DropTargetEvent event) {
+ isDropping = true;
+ }
+ public void dragLeave(DropTargetEvent event) {
+ isDropping = false;
+ handleDeferredRefresh();
+ }
public void dragOver(DropTargetEvent event) {
dropTargetValidate(event, getTargetFile(event));
}
@@ -794,6 +820,30 @@ public class FileViewer {
void notifyRefreshFiles(File[] files) {
if (files != null && files.length == 0) return;
+ if ((deferredRefreshRequested) && (deferredRefreshFiles != null) && (files != null)) {
+ // merge requests
+ File[] newRequest = new File[deferredRefreshFiles.length + files.length];
+ System.arraycopy(deferredRefreshFiles, 0, newRequest, 0, deferredRefreshFiles.length);
+ System.arraycopy(files, 0, newRequest, deferredRefreshFiles.length, files.length);
+ deferredRefreshFiles = newRequest;
+ } else {
+ deferredRefreshFiles = files;
+ deferredRefreshRequested = true;
+ }
+ handleDeferredRefresh();
+ }
+
+ /**
+ * Handles deferred Refresh notifications (due to Drag & Drop)
+ */
+ void handleDeferredRefresh() {
+ if (isDragging || isDropping || ! deferredRefreshRequested) return;
+ deferredRefreshRequested = false;
+ File[] files = deferredRefreshFiles;
+ deferredRefreshFiles = null;
+
+ // Does not refresh very intelligently at the moment.
+
/* Table view:
* Refreshes information about any files in the list and their children.
*/
@@ -1019,7 +1069,25 @@ public class FileViewer {
searchFile = searchFile.getParentFile();
} while (searchFile != null);
- if (oldFile.isFile()) {
+ if (oldFile.isDirectory()) {
+ /*
+ * Copy a directory
+ */
+ if (simulateOnly) {
+ System.out.println(getResourceString("simulate.DirectoriesCreated.text",
+ new Object[] { newFile.getPath() }));
+ } else {
+ if (! newFile.mkdirs()) return false;
+ }
+ File[] subFiles = oldFile.listFiles();
+ if (subFiles != null) {
+ for (int i = 0; i < subFiles.length; i++) {
+ File oldSubFile = subFiles[i];
+ File newSubFile = new File(newFile, oldSubFile.getName());
+ if (! copyFileStructure(oldSubFile, newSubFile)) return false;
+ }
+ }
+ } else {
/*
* Copy a file
*/
@@ -1048,36 +1116,8 @@ public class FileViewer {
}
}
}
- return true;
- } else if (oldFile.isDirectory()) {
- /*
- * Copy a directory
- */
- if (simulateOnly) {
- System.out.println(getResourceString("simulate.DirectoriesCreated.text",
- new Object[] { newFile.getPath() }));
- } else {
- if (! newFile.mkdirs()) return false;
- }
- File[] subFiles = oldFile.listFiles();
- if (subFiles != null) {
- for (int i = 0; i < subFiles.length; i++) {
- File oldSubFile = subFiles[i];
- File newSubFile = new File(newFile, oldSubFile.getName());
- if (! copyFileStructure(oldSubFile, newSubFile)) return false;
- }
- }
- return true;
- } else {
- /*
- * Unknown type
- */
- if (simulateOnly) {
- System.out.println(getResourceString("simulate.UnknownResource.text",
- new Object[] { oldFile.getPath() }));
- }
- return false; // error we don't know how to copy this
}
+ return true;
}
/**
diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java
index c40fa9b5ba..262eff01b4 100644
--- a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java
+++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/fileviewer/TreeDropFeedbackListener.java
@@ -1 +1 @@
-package org.eclipse.swt.examples.fileviewer; /* * (c) Copyright IBM Corp. 2000, 2001. * All Rights Reserved */ import org.eclipse.swt.*; import org.eclipse.swt.dnd.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; /** * TreeDropFeedbackListener provides the following feedback mechanisms for Trees * during drag and drop operations: * <ul> * <li>Automatic Tree scrolling. * <p>If the pointer drags over an item in the Tree near its upper or * lower edges, the Tree will scroll so as to make previous or successive items visible * onscreen. This behaviour is consistent with that of popular GUI systems. * </p> * <li>Automatic TreeItem expansion. * <p>If the pointer hovers for a time over an item in the Tree that has not yet been * expanded, the item is expanded automatically. This behaviour is consistent with * that of popular GUI systems. * </p> * </ul> * <p> * To use it send addDropListener(new TreeDropFeedbackListener(tree)) to the DropTarget * object attached to the Tree. * </p> */ public class TreeDropFeedbackListener extends DropTargetAdapter { public static final long DEFAULT_EXPAND_DELAY = 1000; // millis private Tree tree; private long hoverThreshhold = DEFAULT_EXPAND_DELAY; private long hoverBegin = 0; private TreeItem hoverItem = null; /** * Constructs a Tree scrolling Drop Listener * * @param tree the Tree that the DropTarget is attached to */ public TreeDropFeedbackListener(Tree tree) { this.tree = tree; } /** * Handles dragEnter events. */ public void dragEnter(DropTargetEvent event) { hoverItem = null; } /** * Handles dragExit events. */ public void dragExit(DropTargetEvent event) { hoverItem = null; } /** * Handles dragOver events. */ public void dragOver(DropTargetEvent event) { Point point = tree.toControl(new Point(event.x, event.y)); // Get the item directly under the point TreeItem item = tree.getItem(point); if (item == null) return; // Expand the item if we've been hovering over it for some time if (item != hoverItem) { // We just started hovering, remember this item if ((item != null) && (! item.getExpanded())) { hoverBegin = System.currentTimeMillis(); hoverItem = item; } else { hoverItem = null; } } else if (hoverItem != null) { // We've been hovering for a while, expand if our timer elapsed long hoverCurrent = System.currentTimeMillis(); if (hoverCurrent - hoverBegin >= hoverThreshhold) { // Fake as if the user expanded the item manually Event hoverEvent = new Event(); hoverEvent.x = event.x; hoverEvent.y = event.y; hoverEvent.item = hoverItem; hoverEvent.time = (int) hoverCurrent; hoverItem.setExpanded(true); hoverItem = null; tree.notifyListeners(SWT.Expand, hoverEvent); return; } } // Determine scroll direction according to whether we're nearer the top, middle, or bottom Rectangle clientArea = tree.getClientArea(); int scrollRegionSize = Math.min(clientArea.height / 3, 24); // cut region into 3 parts if (scrollRegionSize < 8) return; // don't scroll if the control is too small to make sense TreeItem showItem = item; for(;;) { if (point.y < clientArea.y + scrollRegionSize) { // in upper region showItem = getPreviousVisibleItem(tree, showItem); } else if (point.y > clientArea.height + clientArea.y - scrollRegionSize) { // in lower region showItem = getNextVisibleItem(tree, showItem, false); } else { // in middle region break; } // Show the item (causes a scroll if it is outside of the visible region) if (showItem == null) break; tree.showItem(showItem); // Test that we actually scrolled, if we didn't try again with the next item if (item != tree.getItem(point)) break; } } /** * Given a TreeItem, locates the previous (above the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose previous visible neighbour is to be found * @return the previous visible item, or null if none. */ private TreeItem getPreviousVisibleItem(Tree tree, TreeItem item) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = items.length - 1; i > 0; --i) { if (items[i] == item) return getLastVisibleChild(items[i - 1]); } } return parent; } /** * Given a TreeItem, locates the following (below the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose next visible neighbour is to be found * @return the next visible item, or null if none. */ private TreeItem getNextVisibleItem(Tree tree, TreeItem item, boolean ignoreChildren) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = 0; i < items.length; ++i) { if (items[i] == item) { if (! ignoreChildren && items[i].getExpanded()) { items = items[i].getItems(); if (items != null && items.length > 0) return items[0]; } if (i + 1 < items.length) return items[i + 1]; break; } } if (parent != null) return getNextVisibleItem(tree, parent, true); } return null; } /** * Given a TreeItem, locates its last (lowest) visible item * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param item the TreeItem whose last visible child is to be found * @return the last visible child, or <code>item</code> if no visible children. */ private TreeItem getLastVisibleChild(TreeItem item) { if (! item.getExpanded()) return item; TreeItem[] items = item.getItems(); if (items == null || items.length == 0) return item; return getLastVisibleChild(items[items.length - 1]); } } \ No newline at end of file
+package org.eclipse.swt.examples.fileviewer; /* * (c) Copyright IBM Corp. 2000, 2001. * All Rights Reserved */ import org.eclipse.swt.*; import org.eclipse.swt.dnd.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; /** * TreeDropFeedbackListener provides the following feedback mechanisms for Trees * during drag and drop operations: * <ul> * <li>Automatic Tree scrolling. * <p>If the pointer drags over an item in the Tree near its upper or * lower edges, the Tree will scroll so as to make previous or successive items visible * onscreen. This behaviour is consistent with that of popular GUI systems. * </p> * <li>Automatic TreeItem expansion. * <p>If the pointer hovers for a time over an item in the Tree that has not yet been * expanded, the item is expanded automatically. This behaviour is consistent with * that of popular GUI systems. * </p> * </ul> * <p> * To use it send addDropListener(new TreeDropFeedbackListener(tree)) to the DropTarget * object attached to the Tree. * </p> */ public class TreeDropFeedbackListener extends DropTargetAdapter { protected static final int EXPAND_DELAY = 750; // millis protected static final int SCROLL_DELAY = 50; // millis protected static final int MAX_SCROLL_TRIES = 3; protected Tree tree; protected TreeItem hoverItem = null; protected Point hoverPoint = null; protected Runnable hoverRunnable = null; protected long hoverResumeTime = 0; /** * Constructs a Tree scrolling Drop Listener * * @param tree the Tree that the DropTarget is attached to */ public TreeDropFeedbackListener(Tree tree) { this.tree = tree; } /** * Handles dragEnter events. */ public void dragEnter(DropTargetEvent event) { hoverItem = null; hoverRunnable = null; } /** * Handles dragExit events. */ public void dragExit(DropTargetEvent event) { hoverItem = null; hoverRunnable = null; } /** * Handles dragOver events. * <p> * On Windows, we receive multiple dragOver()'s even if the mouse has not moved. * But we can't get timerExec()'s.<br> * <br> * On Motif, we only get dragOver()'s when the mouse has actually moved. * But timerExec()'s are processed as usual.<br> * <br> * So to ensure cross-platform UI consistency we must handle both cases! * </p> */ public void dragOver(DropTargetEvent event) { Point point = tree.toControl(new Point(event.x, event.y)); // Fetch the item we're hovering over TreeItem item = tree.getItem(point); if ((hoverRunnable != null) && (item == hoverItem)) { if (System.currentTimeMillis() >= hoverResumeTime) hoverRunnable.run(); return; } hoverItem = item; hoverPoint = point; /* * Determine the candidate action for this position: nothing, scroll or expand */ hoverRunnable = null; if (hoverItem == null) return; // Nothing to do // Consider scrolling Rectangle clientArea = tree.getClientArea(); int scrollRegionSize = Math.min(clientArea.height / 3, 24); // cut region into 3 parts if (scrollRegionSize >= 8) { // Decide scroll direction according to whether we're nearer the top, middle, or bottom if (point.y < clientArea.y + scrollRegionSize) { // in upper region setTimer(SCROLL_DELAY, new ScrollRunnable(true)); return; } else if (point.y > clientArea.height + clientArea.y - scrollRegionSize) { // in lower region setTimer(SCROLL_DELAY, new ScrollRunnable(false)); return; } // else we are in middle region } // else the region is too small for scrolling tryExpand(0); } private void tryExpand(int recoverTime) { // Expand the item if it hasn't already been expanded if (! hoverItem.getExpanded()) { setTimer(EXPAND_DELAY - recoverTime, new ExpandRunnable()); } } private void setTimer(int delay, Runnable runnable) { hoverRunnable = runnable; hoverResumeTime = System.currentTimeMillis() + delay; tree.getDisplay().timerExec(delay, hoverRunnable); } /** * Implements scrolling on a timer */ private class ScrollRunnable implements Runnable { boolean isScrollUp; public ScrollRunnable(boolean isScrollUp) { this.isScrollUp = isScrollUp; } public void run() { if (hoverRunnable != this) return; hoverRunnable = null; if (hoverItem.isDisposed()) return; // this can happen due to other events System.out.println("Scroll"); // Loop until we see a different item (abort after a few tries, just in case) TreeItem showItem = hoverItem; for (int i = MAX_SCROLL_TRIES; i > 0; --i) { showItem = (isScrollUp) ? getPreviousVisibleItem(tree, showItem) : getNextVisibleItem(tree, showItem, false); // Show the item (causes a scroll if it is outside of the visible region) if (showItem == null) break; tree.showItem(showItem); if (hoverItem != tree.getItem(hoverPoint)) return; // stop if we actually scrolled } // We get here if we failed to scroll tryExpand(SCROLL_DELAY); // try auto-expand if auto-scroll failed } } /** * Implements expanding on a timer */ private class ExpandRunnable implements Runnable { public void run() { if (hoverRunnable != this) return; hoverRunnable = null; if (hoverItem.isDisposed()) return; // this can happen due to other events System.out.println("Expand"); // Fake as if the user expanded the item manually Event hoverEvent = new Event(); hoverEvent.x = hoverPoint.x; hoverEvent.y = hoverPoint.y; hoverEvent.item = hoverItem; hoverEvent.time = (int) System.currentTimeMillis(); hoverItem.setExpanded(true); tree.notifyListeners(SWT.Expand, hoverEvent); } } /** * Given a TreeItem, locates the previous (above the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose previous visible neighbour is to be found * @return the previous visible item, or null if none. */ private TreeItem getPreviousVisibleItem(Tree tree, TreeItem item) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = items.length - 1; i > 0; --i) { if (items[i] == item) return getLastVisibleChild(items[i - 1]); } } return parent; } /** * Given a TreeItem, locates the following (below the specified item) visible TreeItem in a tree. * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param tree the Tree containing the items * @param item the TreeItem whose next visible neighbour is to be found * @return the next visible item, or null if none. */ private TreeItem getNextVisibleItem(Tree tree, TreeItem item, boolean ignoreChildren) { TreeItem parent = item.getParentItem(); TreeItem[] items = (parent != null) ? parent.getItems() : tree.getItems(); if (items != null) { for (int i = 0; i < items.length; ++i) { if (items[i] == item) { if (! ignoreChildren && items[i].getExpanded()) { items = items[i].getItems(); if (items != null && items.length > 0) return items[0]; } if (i + 1 < items.length) return items[i + 1]; break; } } if (parent != null) return getNextVisibleItem(tree, parent, true); } return null; } /** * Given a TreeItem, locates its last (lowest) visible item * <p> * Note that the item may not be actually rendered onscreen though it would be * visible were the control scrolled appropriately. * </p> * * @param item the TreeItem whose last visible child is to be found * @return the last visible child, or <code>item</code> if no visible children. */ private TreeItem getLastVisibleChild(TreeItem item) { if (! item.getExpanded()) return item; TreeItem[] items = item.getItems(); if (items == null || items.length == 0) return item; return getLastVisibleChild(items[items.length - 1]); } } \ No newline at end of file

Back to the top