diff options
Diffstat (limited to 'js/io/ui/file-picker/file-picker-controller.js')
-rwxr-xr-x | js/io/ui/file-picker/file-picker-controller.js | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/js/io/ui/file-picker/file-picker-controller.js b/js/io/ui/file-picker/file-picker-controller.js new file mode 100755 index 00000000..129bebad --- /dev/null +++ b/js/io/ui/file-picker/file-picker-controller.js | |||
@@ -0,0 +1,494 @@ | |||
1 | /* <copyright> | ||
2 | This file contains proprietary software owned by Motorola Mobility, Inc.<br/> | ||
3 | No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> | ||
4 | (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. | ||
5 | </copyright> */ | ||
6 | |||
7 | |||
8 | var Montage = require("montage/core/core").Montage, | ||
9 | pickerNavigatorReel = require("js/io/ui/file-picker/picker-navigator.reel").PickerNavigator, | ||
10 | filePickerModelModule = require("js/io/ui/file-picker/file-picker-model"), | ||
11 | Popup = require("montage/ui/popup/popup.reel").Popup; | ||
12 | |||
13 | //singleton with functions to create a new file picker instance and utilities to format or filter the model data | ||
14 | var FilePickerController = exports.FilePickerController = Montage.create(require("montage/ui/component").Component, { | ||
15 | /** | ||
16 | * Register a listener for file open event | ||
17 | */ | ||
18 | deserializedFromTemplate:{ | ||
19 | writable:false, | ||
20 | enumerable:true, | ||
21 | value:function(){ | ||
22 | var that = this; | ||
23 | |||
24 | this.eventManager.addEventListener("openFilePicker", function(evt){ | ||
25 | var settings; | ||
26 | if(typeof evt._event.settings !== "undefined"){ | ||
27 | settings = evt._event.settings; | ||
28 | } | ||
29 | that.showFilePicker(settings); | ||
30 | }, false); | ||
31 | |||
32 | } | ||
33 | }, | ||
34 | |||
35 | filePickerPopupType:{ | ||
36 | writable: true, | ||
37 | enumerable: false, | ||
38 | value: "filePicker" | ||
39 | }, | ||
40 | |||
41 | /** | ||
42 | *this function is used to create an instance of a file picker | ||
43 | * | ||
44 | * parameters: | ||
45 | * settings is an object containing : | ||
46 | * callback [optional]: the call back function which will be used to send the selected URIs back. If undefined then an event is fired with the selected uri | ||
47 | * callbackScope : required if callback is set | ||
48 | * pickerMode [optional]: ["read", "write"] : specifies if the file picker is opened to read a file/folder or to save a file | ||
49 | * currentFilter [optional]: if a current filter needs to be applied [ex: .psd] | ||
50 | * allFileFilters [optional]: list of filters that user can use to filter the view | ||
51 | * inFileMode [optional]: true => allow file selection , false => allow directory selection | ||
52 | * allowNewFileCreation [optional]: flag to specify whether or not it should return URI(s) to item(s) that do not exist. i.e. a user can type a filename to a new file that doesn't yet exist in the file system. | ||
53 | * allowMultipleSelections [optional]: allowMultipleSelections | ||
54 | * pickerName: name for montage custom popup | ||
55 | * | ||
56 | * return: none | ||
57 | */ | ||
58 | |||
59 | showFilePicker:{ | ||
60 | writable:false, | ||
61 | enumerable:true, | ||
62 | value:function(settings){ | ||
63 | var callback, callbackScope, pickerMode, currentFilter, allFileFilters, inFileMode, allowNewFileCreation, allowMultipleSelections, pickerName; | ||
64 | if(!!settings){ | ||
65 | if(typeof settings.callback !== "undefined"){callback = settings.callback;} | ||
66 | if(typeof settings.pickerMode !== "undefined"){pickerMode = settings.pickerMode;} | ||
67 | if(typeof settings.currentFilter !== "undefined"){currentFilter = settings.currentFilter;} | ||
68 | if(typeof settings.allFileFilters !== "undefined"){allFileFilters = settings.allFileFilters;} | ||
69 | if(typeof settings.inFileMode !== "undefined"){inFileMode = settings.inFileMode;} | ||
70 | if(typeof settings.allowNewFileCreation !== "undefined"){allowNewFileCreation = settings.allowNewFileCreation;} | ||
71 | if(typeof settings.allowMultipleSelections !== "undefined"){allowMultipleSelections = settings.allowMultipleSelections;} | ||
72 | if(typeof settings.pickerName !== "undefined"){this.filePickerPopupType = settings.pickerName;} | ||
73 | } | ||
74 | |||
75 | if(settings.pickerName === "saveAsDirectoryPicker"){//need to set the picker mode in a better way | ||
76 | pickerMode = "write"; | ||
77 | }else{ | ||
78 | pickerMode = "read"; | ||
79 | } | ||
80 | |||
81 | var aModel = filePickerModelModule.FilePickerModel.create(); | ||
82 | |||
83 | var topLevelDirectories = null; | ||
84 | var driveData = this.application.ninja.coreIoApi.getDirectoryContents({uri:"", recursive:false, returnType:"all"}); | ||
85 | if(driveData.success){ | ||
86 | topLevelDirectories = (JSON.parse(driveData.content)).children; | ||
87 | }else{ | ||
88 | var errorCause = ""; | ||
89 | if(driveData.status === null){ | ||
90 | errorCause = "Service Unavailable" | ||
91 | }else{ | ||
92 | errorCause = driveData.status; | ||
93 | } | ||
94 | aModel.fatalError = " ** Unable to get files [Error: "+ errorCause +"]"; | ||
95 | } | ||
96 | |||
97 | //dummy data - TODO:remove after testing | ||
98 | //aModel.currentFilter = "*.html, *.png"; | ||
99 | //aModel.currentFilter = "*.jpg"; | ||
100 | aModel.currentFilter = "*.*"; | ||
101 | aModel.inFileMode = true; | ||
102 | aModel.fileFilters = [".html, .htm", ".jpg, .jpeg, .png, .gif", ".js, .json", ".css", ".txt, .rtf", ".doc, .docx", ".pdf", ".avi, .mov, .mpeg, .ogg, .webm", "*.*"]; | ||
103 | //-end - dummy data | ||
104 | |||
105 | if(!!currentFilter){aModel.currentFilter = currentFilter;} | ||
106 | if(typeof inFileMode !== "undefined"){aModel.inFileMode = inFileMode;} | ||
107 | |||
108 | aModel.topLevelDirectories = topLevelDirectories; | ||
109 | |||
110 | if(!!topLevelDirectories && !!topLevelDirectories[0]){ | ||
111 | aModel.currentRoot = topLevelDirectories[0].uri; | ||
112 | } | ||
113 | |||
114 | //populate the last opened folder first, if none then populate default root | ||
115 | var storedUri = null; | ||
116 | var sessionStorage = window.sessionStorage; | ||
117 | try{ | ||
118 | if(pickerMode === "write"){ | ||
119 | storedUri = sessionStorage.getItem("lastSavedFolderURI"); | ||
120 | }else if(inFileMode === true){ | ||
121 | storedUri = sessionStorage.getItem("lastOpenedFolderURI_fileSelection"); | ||
122 | }else if(inFileMode === false){ | ||
123 | storedUri = sessionStorage.getItem("lastOpenedFolderURI_folderSelection"); | ||
124 | } | ||
125 | }catch(e){ | ||
126 | if(e.code == 22){ | ||
127 | sessionStorage.clear(); | ||
128 | } | ||
129 | } | ||
130 | |||
131 | if(!!storedUri){ | ||
132 | aModel.currentRoot = unescape(storedUri); | ||
133 | } | ||
134 | |||
135 | if(!!allFileFilters){aModel.fileFilters = allFileFilters;} | ||
136 | if(!!callback){aModel.callback = callback;} | ||
137 | if(!!callbackScope){aModel.callbackScope = callbackScope;} | ||
138 | if(typeof pickerMode !== "undefined"){aModel.pickerMode = pickerMode;} | ||
139 | |||
140 | |||
141 | |||
142 | //logic: get file content data onDemand from the REST api for the default or last opened root. Cache the data in page [in local cache ? dirty fs? ]. Filter on client side to reduce network calls. | ||
143 | this.openFilePickerAsModal(callback, aModel); | ||
144 | |||
145 | |||
146 | //to open this on another modal dialog, make it a popup instead above the modal dialog container layer | ||
147 | |||
148 | } | ||
149 | }, | ||
150 | |||
151 | openFilePickerAsModal:{ | ||
152 | writable:false, | ||
153 | enumerable:true, | ||
154 | value:function(callback, aModel){ | ||
155 | //render modal dialog | ||
156 | var pickerNavContent = document.createElement("div"); | ||
157 | pickerNavContent.id = "filePicker"; | ||
158 | |||
159 | pickerNavContent.style.color = "#fff"; | ||
160 | |||
161 | //hack (elements needs to be on DOM to be drawn) | ||
162 | document.getElementById('modalContainer').appendChild(pickerNavContent); | ||
163 | |||
164 | var pickerNavChoices = Montage.create(pickerNavigatorReel); | ||
165 | var initUri = aModel.currentRoot; | ||
166 | |||
167 | //remove extra / at the end | ||
168 | if((initUri.length > 1) && (initUri.charAt(initUri.length - 1) === "/")){ | ||
169 | initUri = initUri.substring(0, (initUri.length - 1)); | ||
170 | } | ||
171 | |||
172 | pickerNavChoices.mainContentData = this.prepareContentList(initUri, aModel); | ||
173 | pickerNavChoices.pickerModel = aModel; | ||
174 | pickerNavChoices.element = pickerNavContent; | ||
175 | |||
176 | //hack - remove after rendering and add in modal dialog | ||
177 | document.getElementById('modalContainer').removeChild(pickerNavContent); | ||
178 | |||
179 | var popup = Popup.create(); | ||
180 | popup.content = pickerNavChoices; | ||
181 | popup.modal = true; | ||
182 | popup.type = this.filePickerPopupType;//should be set always to not default to the single custom popup layer | ||
183 | popup.show(); | ||
184 | pickerNavChoices.popup = popup;//handle to be used for hiding the popup | ||
185 | } | ||
186 | }, | ||
187 | openFilePickerAsPopup:{ | ||
188 | writable:false, | ||
189 | enumerable:true, | ||
190 | value:function(){} | ||
191 | }, | ||
192 | |||
193 | expandDirectory:{ | ||
194 | writable:false, | ||
195 | enumerable:true, | ||
196 | value: function(root, currentFilter, inFileMode){ | ||
197 | //populate children in dom | ||
198 | } | ||
199 | }, | ||
200 | |||
201 | refreshDirectoryCache:{ | ||
202 | writable:false, | ||
203 | enumerable:true, | ||
204 | value:function(directoryUri){ | ||
205 | if(directoryContentCache[directoryUri] !== null){ | ||
206 | directoryContentCache[directoryUri] = null; //invalidate the cached content | ||
207 | //fetch fresh content | ||
208 | } | ||
209 | } | ||
210 | }, | ||
211 | |||
212 | /** | ||
213 | * queries the cache to build contents array. If not found queries the file system | ||
214 | * | ||
215 | * parameters: | ||
216 | * folderUri | ||
< |