瀏覽代碼

HUE-160. Improving FileChooser and FileSaver

Marcus McLaughlin 15 年之前
父節點
當前提交
186515f78c

+ 107 - 69
apps/filebrowser/src/filebrowser/static/js/Source/FileBrowser/CCS.FileBrowser.js

@@ -76,11 +76,6 @@ ART.Sheet.define('window.filechooser.browser', {
 		initialize: function(path, options) {
 			this.parent(path, options);
 			this.addEvent('load', this.setup.bind(this));
-			this.setupHistory();
-			this.addLinkers();
-			this.removeOkEvents();
-			this.addSaverInfo();
-			this.addItemClickEvents();
 			//when an alert is visible, hide the upload swiff
 			//as it sometimes gets "stuck" to the mouse
 			this.addEvents({
@@ -116,7 +111,7 @@ ART.Sheet.define('window.filechooser.browser', {
 		},
 
 		//adds item click events
-		addItemClickEvents: function(){
+		addRowFocusEvents: function(){
 			//do nothing by default
 			//filechooser adds delegated events
 		},
@@ -174,7 +169,7 @@ ART.Sheet.define('window.filechooser.browser', {
 					keys: 'keydown:backspace',
 					shortcut: 'backspace',
 					handler: function(e){
-	    			if ($(e.target).match('input, textarea')) return;
+                                                if ($(e.target).match('input, textarea')) return;
 						e.stop();
 						var table = this.getDirList().retrieve('HtmlTable');
 						//the view only allows one item to be selected at a time currently
@@ -206,17 +201,23 @@ ART.Sheet.define('window.filechooser.browser', {
 
 		//when jframe loads, set up the content
 		setup: function(view){
-			if (!this._shortcutsAdded) {
-				this.addFBShortcuts();
-				this._shortcutsAdded = true;
+                        if (!this._shortcutsAdded) {
+			        this.addFBShortcuts();
+			        this._shortcutsAdded = true;
 			}
-			//make the uploader
+			this.setupHistory();
+			this.addLinkers();
+			this.removeOkEvents();
+			this.addSaverInfo();
+			this.addRowFocusEvents();
+                        			//make the uploader
 			(function(){
 				//note we have a very short delay here; the DOM needs a moment to be there or else you sometimes
 				//get the error "obj.CallFunction is not a function" which means that the JS can't communicate with
 				//the swf file
 				this.makeUploader($(this).getElement('.fb-upload').get('href').toURI().get('data').dest);
 			}).delay(10, this);
+
 		},
 
 		//returns the file list element
@@ -227,7 +228,15 @@ ART.Sheet.define('window.filechooser.browser', {
 		//returns the path relative to the current file system
 		getDirPath: function(){
 			return this.jframe.currentPath.split("?")[0].replace('/' + this.options.filesystem + '/' + this.options.view, '');
-		}
+		},
+
+                getClickPath: function(selected){
+                        var dblclickdelegate = selected.get('data', 'dblclick-delegate', true);
+                        if (dblclickdelegate) var dblclick_loads = dblclickdelegate.dblclick_loads;
+                        if (dblclick_loads) var elemLoad = selected.getElement(dblclick_loads);
+                        if (elemLoad) return elemLoad.href; 
+                }
+
 
 
 	};
@@ -348,6 +357,7 @@ ART.Sheet.define('window.filechooser.browser', {
 				return this.caption || "Choose Where To Save This File";
 			}.bind(this)
 		},
+                //append an input to the alert, allowing the user to view/enter the path where the file will be saved
 		addSaverInfo: function() {
 			var locationInput = new Element("input", {
 				'type' : 'text',
@@ -362,20 +372,29 @@ ART.Sheet.define('window.filechooser.browser', {
 			locationDiv.inject($(this.footer), 'top');
 			this.locationInput = locationInput;
 		},
-		addItemClickEvents: function(){
-			$(this).addEvent('click:relay(.fb-item-row)', function(event, clicked) {
-				var targetData = clicked.get('data', 'filedata', true);
-				var locationInput = $(this).getElement('.fs-locationInput');
-				if (targetData.type === 'file') {
-					locationInput.set('value', targetData.path.split('/').getLast());
-				} else if (targetData.type === 'dir') {
-					locationInput.set('value', this.options.fileToMove);
-				}
+                //add events which will occur when rows of filebrowser table are focused 
+		addRowFocusEvents: function(){
+                        var table = $(this).getElement('[data-filters*=HtmlTable]');
+                        if(!table) return;
+                        var hTable = table.retrieve('HtmlTable');
+                        var locationInput = $(this).getElement('.fs-locationInput');
+                        hTable.addEvent('rowFocus', function(row) {
+                                var selectData = row.get('data', 'filedata', true);
+                                if (selectData.type == 'file') {
+                                        //Doesn't make sense to do this if overwriting files is not possible.
+                                        //locationInput.set('value', targetData.path.split('/').getLast());
+                                        this.getOk().setText("Save");
+                                }
+                                if (selectData.type =='dir') {
+                                        locationInput.set('value', this.options.fileToMove);
+                                        this.getOk().setText("Open");
+                                }
+                        }.bind(this));
 
-			}.bind(this));
 		},
+                //add keyboard shortcuts for filebrowser
 		addFBShortcuts: function(){
-			this.jframe.addShortcuts({
+                        this.jframe.addShortcuts({
 			'Select Highlighted': {
 				keys: 'enter',
 				shortcut: 'enter',
@@ -396,15 +415,14 @@ ART.Sheet.define('window.filechooser.browser', {
 						}.bind(this), {});
 							confirmDialog.show();
 						}*/
-						} else {
-							this.getOk().fireEvent('press');
-						}
-					}.bind(this),
+					} else {
+						this.getOk().fireEvent('press');
+					}
+                                }.bind(this),
 				description: 'Select the highlighted row or folder.'
-				}
+			}
 			});
-
-		}
+                }
 	});
 
 	/*
@@ -425,10 +443,10 @@ ART.Sheet.define('window.filechooser.browser', {
 				resizable: true
 			});
 			var chooser = new CCS.FileChooser("/filebrowser/view" + fsPath, options);
+                        //set caption when jframe is done loading
 			chooser.jframe.addEvent('loadComplete', function() {
 				this.setCaption(chooser.getDirPath() + " :: " + caption);
-			}.bind(chooser));
-			chooser.getOk().addEvent('press', function(){
+                                chooser.getOk().addEvent('press', function(){
 				var selected = $(chooser).getElement('.table-tr-selected');
 				var error = function(){
 					var msg = "Please choose a directory.";
@@ -437,24 +455,38 @@ ART.Sheet.define('window.filechooser.browser', {
 					chooser.fireEvent('badSelection', selected);
 				};
 				if (selected) {
+                                        //If file_filter was part of query, the filtered rows will have a "not-selectable" class.
 					if (selected.hasClass('not-selectable')) {
 						error();
 						return;
 					}
-					callback($(chooser).getElement('.table-tr-selected').get('data', 'filedata', true));
-					chooser.hide();
+                                        var selectedData = selected.get('data', 'filedata', true);
+                                        //Otherwise, use options.filter and the selected row's filedata object to determine whether or not the row should be filtered.
+					if(selectedData) {
+                                                //Ensure that the two values don't conflict.  (Other possible value is 'any', which allows any selection.) If they don't, fire callback.  Otherwise, show error.
+                                                if(selectedData.type == 'file' && options.filter != 'dir' || selectedData.type == 'dir' && options.filter != 'file'){
+                                                        callback(selectedData);
+                                                        chooser.hide();
+                                                } else {
+                                                        error();
+                                                }
+                                        }
 				} else if (options.filter == "file") {
+                                        //If nothing is selected, and filter is 'file', show error.
 					error();
 				} else {
+                                        //If nothing is selected, and filter is 'dir or any', call callback using chooser's current directory as path.
 					callback({
 						path: chooser.getDirPath(),
 						type: 'dir'
 					});
 					chooser.hide();
 				}
-				
 			});
-			return chooser;
+
+			}.bind(chooser));
+                        //add event on click of ok button which handles filtering and passing of file data to callback 
+						return chooser;
 		});
 	};
 	CCS.saveFile = function(jbrowser, toMove, fsPath, cap, fn, opt){
@@ -466,42 +498,48 @@ ART.Sheet.define('window.filechooser.browser', {
 					fileToMove: toMove
 				});
 				var saver = new CCS.FileSaver("/filebrowser/view" + fsPath + "?show_upload=false", options);
+                                //Set caption on loadComplete
 				saver.jframe.addEvent('loadComplete', function() {
 					this.setCaption(saver.getDirPath() + " :: " + caption);
+                                        var locationInput = $(saver).getElement('.fs-locationInput');
+                                        saver.getOk().addEvent('press', function(){
+                                                //Get selected row of filebrowser table
+                                                var selected = $(saver).getElement('.table-tr-selected');
+                                                var selectedPath, isDirSelected = false;
+                                                // If there is a row selected, navigate to that directory 
+                                                // If not create a selected path based on the current displayed directory
+                                                if(selected) {
+                                                        var selectedData = selected.get('data', 'filedata', true);
+                                                        isDirSelected = selectedData.type == 'dir';
+                                                } else {
+                                                        selectedPath = saver.getDirPath();
+                                                }
+                                                var error = function(){
+                                                        var msg = "Please choose a directory.";
+                                                        if (options.filter == "file") msg = "Please choose a file.";
+                                                        saver.alert(caption || "Choose a File", msg);
+                                                        saver.fireEvent('badSelection', selected);
+                                                };
+                                                //if a directory is selected, naviagte to the selected directory
+                                                if (isDirSelected) {
+                                                        saver.jframe.load({
+                                                                requestPath: saver.getClickPath(selected) 
+                                                        });
+                                                } else {
+                                                        var inputPath = locationInput.get('value');
+                                                        var returnPath; 
+                                                        //An input path belonging with a slash is assumed to be an absolute path.
+                                                        if (inputPath[0] == '/') returnPath = inputPath;
+                                                        else returnPath = saver.getDirPath() + '/' + inputPath;
+                                                        callback({
+                                                                path: returnPath,
+                                                                type: 'dir'
+                                                        });
+                                                        saver.hide();
+                                                }
+                                        });
 				}.bind(saver));
-				var locationInput = $(saver).getElement('.fs-locationInput');
-				saver.getOk().addEvent('press', function(){
-				//Get selected row of filebrowser table
-				var selected = $(saver).getElement('.table-tr-selected');
-				var selectedPath, isDirSelected = false;
-				// If there is a row selected create a selected path based on that row
-				// If not create a selected path based on the current displayed directory
-				if(selected) {
-					var selectedData = selected.get('data', 'filedata', true);
-					isDirSelected = selectedData.type == 'dir';
-					selectedPath = selectedData.path;
-				} else {
-					selectedPath = saver.getDirPath();
-				}
-				var error = function(){
-					var msg = "Please choose a directory.";
-					if (options.filter == "file") msg = "Please choose a file.";
-					saver.alert(caption || "Choose a File", msg);
-					saver.fireEvent('badSelection', selected);
-				};
-				//if a directory is selected, move to the selected directory
-				var inputPath = (isDirSelected ? selectedPath + "/" : "") + locationInput.get('value');
-				var returnPath; 
-				//An input path belonging with a slash is assumed to be an absolute path.
-				if (inputPath[0] == '/') returnPath = inputPath;
-				else returnPath = saver.getDirPath() + '/' + inputPath;
-				callback({
-					path: returnPath,
-					type: 'dir'
-				});
-				saver.hide();
-				});
-			return saver;
+				return saver;
 		});
 	};
 })();

+ 7 - 1
apps/jframegallery/src/jframegallery/templates/chooser.linker.html

@@ -20,6 +20,12 @@ limitations under the License.
   <title>File Chooser Filter</title>
 </head>
 <body>
-  <input type="text" name="path"/><a class="ccs-choose_file" data-filters="ArtButton" data-chooseFor="path">Save As</a>
+  <p>Choose a File (Can't Choose Directory)
+  <input type="text" name="file"/><a class="ccs-choose_file" data-filters="ArtButton" data-chooseFor="file">Save As</a>
+  <p>Choose a Directory (Can't Choose Path)
+  <input type="text" name="dir"/><a class="ccs-choose_dir" data-filters="ArtButton" data-chooseFor="dir">Save As</a>
+  <p>Choose a Path (Can Choose Either Directory or Path)
+  <input type="text" name="path"/><a class="ccs-choose_path" data-filters="ArtButton" data-chooseFor="path">Save As</a>
+
 </body>
 </html>

+ 36 - 24
desktop/core/static/js/Source/JFrameLinkers/CCS.JFrame.Chooser.js

@@ -15,7 +15,7 @@
 // limitations under the License.
 /*
 ---
-description: Opens a CCS.FileChooser for any element with the ccs-choose_file class and places the path of the chosen file in the input field whose "name" attribute is equal to the data stored in  the "chooseFor" attribute of the element.
+description: Opens a CCS.FileChooser for any element with the ccs-choose_file, ccs-choose_dir, or ccs-choose_path  class and places the chosen path in the input field whose "name" attribute is equal to the data stored in  the "chooseFor" attribute of the element.
 provides: [CCS.JFrame.Chooser]
 requires: [/CCS.JFrame]
 script: CCS.JFrame.Chooser.js
@@ -23,29 +23,41 @@ script: CCS.JFrame.Chooser.js
 ...
 */
 
-CCS.JFrame.addGlobalLinkers({
+(function(){
 
-	'.ccs-choose_file': function(e, link){
-		//Stop link from its standard action
-		e.preventDefault();
-		var targetName = link.get('data','chooseFor');
-		var targetInput = $(this.parentWidget).getElement('input[name=' + targetName + ']');
-		var jbrowser = this.parentWidget;
-		//use parent widget to get jbrowser for CCS.chooseFile
-		//CCS.chooseFile creates an ART alert which contains a FileChooser from which teh user can select a file.
+        var caption = {'dir': 'Choose A Directory',
+                        'file' : 'Choose A File',
+                        'any' : 'Choose A Path'
+        };
 
-		//The function argument is the callback which is called after the OK button in the ART alert is clicked.
-		CCS.Desktop.load("FileBrowser", function(){
-			CCS.chooseFile(jbrowser, '/', "Choose a File", function(data) {
-				targetInput.set('value', data.path);
-				targetInput.fireEvent('change');
-				//hide overtext on targetInput 
-				var overtext = targetInput.retrieve('OverText');
-				if(overtext) overtext.hide();
-			}, {
-				filter: 'file'
-			});
-		});
-	}
+        var chooser = function(filter) {
+                return function(e, link) {
+                        //Stop link from its standard action
+                        e.preventDefault();
+                        var targetName = link.get('data','chooseFor');
+                        var targetInput = $(this.parentWidget).getElement('input[name=' + targetName + ']');
+                        var jbrowser = this.parentWidget;
+                        //use parent widget to get jbrowser for CCS.chooseFile
+                        //CCS.chooseFile creates an ART alert which contains a FileChooser from which teh user can select a file.
+                //The function argument is the callback which is called after the OK button in the ART alert is clicked.
+                        CCS.Desktop.load("FileBrowser", function(){
+                                CCS.chooseFile(jbrowser, '/', caption[filter], function(data) {
+                                        targetInput.set('value', data.path);
+                                        targetInput.fireEvent('change');
+                                        //hide overtext on targetInput 
+                                        var overtext = targetInput.retrieve('OverText');
+                                        if(overtext) overtext.hide();
+                                }, {
+                                        filter: filter 
+                                });
+                        });
+                };
+        };
 
-});
+        CCS.JFrame.addGlobalLinkers({
+                '.ccs-choose_file': chooser('file'), 
+                '.ccs-choose_dir': chooser('dir'), 
+                '.ccs-choose_path': chooser('any') 
+        });
+
+})();