浏览代码

Fix handling of selection and drag-drop

Steven Silvester 8 年之前
父节点
当前提交
7a6124bae4
共有 1 个文件被更改,包括 28 次插入44 次删除
  1. 28 44
      src/filebrowser/listing.ts

+ 28 - 44
src/filebrowser/listing.ts

@@ -354,14 +354,10 @@ class DirListing extends Widget {
    */
   delete(): Promise<void> {
     let names: string[] = [];
-    if (this._softSelection) {
-      names.push(this._softSelection);
-    } else {
-      let items = this._model.items;
-      for (let item of items) {
-        if (this._selection[item.name]) {
-          names.push(item.name);
-        }
+    let items = this._model.items;
+    for (let item of items) {
+      if (this._selection[item.name]) {
+        names.push(item.name);
       }
     }
     let message = `Permanantly delete these ${names.length} files?`;
@@ -420,9 +416,7 @@ class DirListing extends Widget {
     let paths = items.map(item => item.path);
     for (let session of this._model.sessions) {
       let index = paths.indexOf(session.notebook.path);
-      if (!this._softSelection && this._selection[items[index].name]) {
-        promises.push(this._model.shutdown(session.id));
-      } else if (this._softSelection === items[index].name) {
+      if (this._selection[items[index].name]) {
         promises.push(this._model.shutdown(session.id));
       }
     }
@@ -496,9 +490,6 @@ class DirListing extends Widget {
    * Get whether an item is selected by name.
    */
   isSelected(name: string): boolean {
-    if (this._softSelection) {
-      return name === this._softSelection;
-    }
     return this._selection[name] === true;
   }
 
@@ -670,7 +661,6 @@ class DirListing extends Widget {
    * Handle the `'click'` event for the widget.
    */
   private _evtClick(event: MouseEvent) {
-    this._softSelection = '';
     let target = event.target as HTMLElement;
 
     let header = this.headerNode;
@@ -681,17 +671,6 @@ class DirListing extends Widget {
       }
       return;
     }
-
-    // Bail if editing.
-    if (this._editNode.contains(target)) {
-      return;
-    }
-
-    let content = this.contentNode;
-    if (content.contains(target)) {
-      this._handleFileSelect(event);
-    }
-
   }
 
   /**
@@ -725,12 +704,7 @@ class DirListing extends Widget {
     if (index === -1) {
       return;
     }
-    this._softSelection = '';
-    let items = this.sortedItems;
-    let selected = Object.keys(this._selection);
-    if (selected.indexOf(items[index].name) === -1) {
-      this._softSelection = items[index].name;
-    }
+    this._handleFileSelect(event);
 
     // Left mouse press for drag start.
     if (event.button === 0) {
@@ -749,6 +723,15 @@ class DirListing extends Widget {
    * Handle the `'mouseup'` event for the widget.
    */
   private _evtMouseup(event: MouseEvent): void {
+    if (this._softSelection) {
+      let altered = event.metaKey || event.shiftKey || event.ctrlKey;
+      if (!altered && event.button === 0) {
+        this._selection = Object.create(null);
+        this._selection[this._softSelection] = true;
+        this.update();
+      }
+      this._softSelection = '';
+    }
     if (event.button !== 0 || !this._drag) {
       document.removeEventListener('mousemove', this, true);
       document.removeEventListener('mouseup', this, true);
@@ -861,13 +844,10 @@ class DirListing extends Widget {
         return;
       }
       let item = this.sortedItems[index];
-      let target = this._items[index];
-      if (!target.classList.contains(FOLDER_TYPE_CLASS)) {
-        return;
-      }
-      if (!this._softSelection && this._selection[item.name]) {
+      if (item.type !== 'directory' || this._selection[item.name]) {
         return;
       }
+      let target = event.target as HTMLElement;
       target.classList.add(utils.DROP_TARGET_CLASS);
       event.preventDefault();
       event.stopPropagation();
@@ -1009,6 +989,7 @@ class DirListing extends Widget {
     // Start the drag and remove the mousemove and mouseup listeners.
     document.removeEventListener('mousemove', this, true);
     document.removeEventListener('mouseup', this, true);
+    clearTimeout(this._selectTimer);
     this._drag.start(clientX, clientY).then(action => {
       this._drag = null;
       clearTimeout(this._selectTimer);
@@ -1044,6 +1025,10 @@ class DirListing extends Widget {
     } else if (event.shiftKey) {
       this._handleMultiSelect(selected, index);
 
+    // Handle a 'soft' selection
+    } else if (this._selection[name] === true && Object.keys(this._selection).length > 1) {
+      this._softSelection = name;
+
     // Default to selecting the only the item.
     } else {
       // Handle a rename.
@@ -1103,10 +1088,7 @@ class DirListing extends Widget {
    */
   private _getSelectedItems(): IContents.IModel[] {
     let items = this.sortedItems;
-    if (!this._softSelection) {
-      return items.filter(item => this._selection[item.name]);
-    }
-    return items.filter(item => item.name === this._softSelection);
+    return items.filter(item => this._selection[item.name]);
   }
 
   /**
@@ -1142,7 +1124,7 @@ class DirListing extends Widget {
    */
   private _doRename(): Promise<string> {
     let items = this.sortedItems;
-    let name = this._softSelection || Object.keys(this._selection)[0];
+    let name = Object.keys(this._selection)[0];
     let index = arrays.findIndex(items, (value) => value.name === name);
     let row = this._items[index];
     let item = items[index];
@@ -1239,9 +1221,9 @@ class DirListing extends Widget {
   private _isCut = false;
   private _prevPath = '';
   private _clipboard: string[] = [];
-  private _softSelection = '';
   private _manager: DocumentManager = null;
   private _opener: IWidgetOpener = null;
+  private _softSelection = '';
   private _selection: { [key: string]: boolean; } = Object.create(null);
   private _renderer: DirListing.IRenderer = null;
 }
@@ -1508,8 +1490,10 @@ namespace DirListing {
       let modified = utils.findElement(dragImage, ITEM_MODIFIED_CLASS);
       dragImage.removeChild(modified as HTMLElement);
       if (count > 1) {
-        let nameNode = utils.findElement(node, ITEM_TEXT_CLASS);
+        let nameNode = utils.findElement(dragImage, ITEM_TEXT_CLASS);
         nameNode.textContent = '(' + count + ')';
+        let iconNode = utils.findElement(dragImage, ITEM_ICON_CLASS);
+        iconNode.className = `${ITEM_ICON_CLASS} ${FILE_TYPE_CLASS}`;
       }
       return dragImage;
     }