Updated application sources
[apps/web/sample/FileManager.git] / project / js / app.model.js
1 /*
2  *      Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  *      Licensed under the Flora License, Version 1.1 (the "License");
5  *      you may not use this file except in compliance with the License.
6  *      You may obtain a copy of the License at
7  *
8  *              http://floralicense.org/license/
9  *
10  *      Unless required by applicable law or agreed to in writing, software
11  *      distributed under the License is distributed on an "AS IS" BASIS,
12  *      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *      See the License for the specific language governing permissions and
14  *      limitations under the License.
15  */
16
17 /*jslint devel: true*/
18 /*global tizen, SystemIO, $, app */
19
20 /**
21  * @class Model
22  */
23 function Model() {
24     'use strict';
25     this.init();
26 }
27
28 (function () { // strict mode wrapper
29     'use strict';
30     Model.prototype = {
31
32         /**
33          * file open unlock flag
34          * @type {boolean}
35          */
36         openFileUnLocked: true,
37
38         /**
39          * @type SystemIO
40          */
41         systemIO: null,
42
43         /**
44          * @type Array
45          */
46         storages: [{label: 'root', type: 'INTERNAL'}],
47
48         /**
49          * @type String
50          */
51         currentPath: '',
52
53         /**
54          * API module initialisation
55          */
56         init: function Model_init() {
57             this.systemIO = new SystemIO();
58         },
59
60         /**
61          * @returns {FileSystemStorage[]} storages
62          */
63         getInternalStorages: function Model_getInternalStorages() {
64             return this.storages;
65         },
66
67         /**
68          * Saves storages
69          * @param {function} onSuccess callback
70          */
71         loadInternalStorages: function Model_loadInternalStorages(onSuccess) {
72             var self = this;
73
74             this.systemIO.getStorages('INTERNAL', function (storages) {
75                 self.storages = storages;
76                 if (typeof onSuccess === 'function') {
77                     onSuccess();
78                 }
79             }, 'internal0');
80         },
81
82         /**
83          * Returns folder data
84          * @param {string} path Node path
85          * @param {function} onSuccess Success callback
86          * @param {function} onError Error callback
87          */
88         getFolderData: function Model_getFolderData(path, onSuccess, onError) {
89             var self = this,
90                 onOpenSuccess = function (dir) {
91                     dir.listFiles(
92                         function (files) {
93                             self.currentPath = dir.fullPath;
94                             onSuccess(dir, files);
95                         },
96                         function (e) {
97                             console.error(
98                                 'Model_getFolderData listFiles error',
99                                 e
100                             );
101                         }
102                     );
103                 },
104                 onOpenError = function (e) {
105                     console.error('Model_getFolderData openDir error', e);
106                 };
107
108             this.systemIO.openDir(path, onOpenSuccess, onOpenError);
109         },
110
111         isStorageExists: function (nodeName, success, error) {
112             tizen.filesystem.resolve(nodeName, success, error);
113         },
114
115         /**
116          * Launch a service to open the file
117          * @param {string} fullUri ext
118          * @param {string} mime uri
119          */
120         openFile: function Model_openFile(fullUri) {
121             if (this.openFileUnLocked) {
122                 var self = this, serviceReplyCB = {
123                     onsuccess: function (reply) {
124                         self.openFileUnLocked = true;
125                     },
126                     onfailure: function () {
127                         self.openFileUnLocked = true;
128                         console.error('Launch service failed');
129                     }
130                 };
131                 this.openFileUnLocked = false;
132                 try {
133                     console.log('Launching view for file "' + fullUri + '"');
134                     tizen.application.launchAppControl(
135                         new tizen.ApplicationControl(
136                             'http://tizen.org/appcontrol/operation/view',
137                             fullUri
138                         ),
139                         null,
140                         function () {
141                             setTimeout(function () {
142                                 self.openFileUnLocked = true;
143                             }, 500);
144                         },
145                         function (e) {
146                             self.openFileUnLocked = true;
147                             console.error(
148                                 'Service launch failed. Exception message:' +
149                                     e.message
150                             );
151                         },
152                         serviceReplyCB
153                     );
154                 } catch (e) {
155                     self.openFileUnLocked = true;
156                     console.error('openFile failed', e);
157                 }
158             }
159         },
160
161         refreshContent: function (path, successCallback, mode) {
162             successCallback = successCallback || null;
163             mode = mode || 'copy';
164             var isDir = true,
165                 onResolveSuccess;
166             onResolveSuccess = function () {};
167
168             tizen.filesystem.resolve(path, function (file) {
169                 if (file.isFile) {
170                     tizen.content.scanFile(path, successCallback);
171                 } else {
172                     successCallback();
173                 }
174             }, null);
175         },
176
177         resolveAndRefresh: function (path, successCallback, mode) {
178             var self = this;
179             tizen.filesystem.resolve(path, function (file) {
180                 self.refreshContent(file.toURI(), successCallback);
181             }, null);
182         },
183
184         /**
185          * @param {File[]} nodes Collection of node objects
186          * @param {File} dir Directory handle
187          * @param {function} onSuccess
188          * @param {function} onError
189          */
190         deleteNodes: function Model_deleteNodes(
191             nodes,
192             dir,
193             onSuccess,
194             onError
195         ) {
196             var len = nodes.length,
197                 self = this,
198                 onDeleteNodeSuccess = function (file) {
199                     try {
200                         app.clipboard.removeRecursively(file.fullPath);
201                         app.ui.refreshPasteActionBtn();
202                         if (onSuccess instanceof Function) {
203                             onSuccess(file.fullPath);
204                         }
205                     } catch (e) {
206                         console.error(e);
207                     }
208                 },
209                 onDeleteNodeError = function (e) {
210                     if (typeof onError === 'function') {
211                         onError();
212                     }
213                 },
214                 i,
215                 remove = function (file, success, failure) {
216                     var parent = file.parent, fullPath = file.fullPath,
217                         removeSuccess = function () {
218                             if (success instanceof Function) {
219                                 success(file);
220                             }
221                         },
222                         removeFailure = function (error) {
223                             if (failure instanceof Function) {
224                                 failure(error, file);
225                             }
226                         };
227
228                     if (file.isFile) {
229                         parent.deleteFile(
230                             fullPath,
231                             function () {
232                                 tizen.content.scanFile(
233                                     file.toURI(),
234                                     removeSuccess,
235                                     removeFailure
236                                 );
237                             },
238                             removeFailure
239                         );
240                     } else {
241                         file.listFiles(
242                             function (files) {
243                                 var len = files.length,
244                                     index = len - 1,
245                                     counter = 0,
246                                     removeEmptyDir = function () {
247                                         parent.deleteDirectory(
248                                             fullPath,
249                                             false,
250                                             removeSuccess,
251                                             removeFailure
252                                         );
253                                     };
254
255                                 if (len > 0) {
256                                     while (index >= 0) {
257                                         remove(
258                                             files[index],
259                                             function () {
260                                                 counter += 1;
261                                                 if (counter === len) {
262                                                     removeEmptyDir();
263                                                 }
264                                             },
265                                             removeFailure
266                                         );
267                                         index -= 1;
268                                     }
269                                 } else {
270                                     removeEmptyDir();
271                                 }
272                             },
273                             removeFailure
274                         );
275                     }
276                 };
277
278             for (i = 0; i < len; i = i + 1) {
279                 tizen.filesystem.resolve(
280                     nodes[i].uri,
281                     function (file) {
282                         remove(file, onDeleteNodeSuccess, onDeleteNodeError);
283                     }.bind(this),
284                     null
285                 );
286             }
287         },
288
289         /**
290          * Copy specified files to destination path
291          * Overwrites existing files
292          *
293          * @param {File} dir Directory handle
294          * @param {string[]} paths Array with absolute virtual file paths
295          * @param {string} destinationPath
296          * @param {function} onSuccess callback
297          */
298         copyNodes: function Model_copyNodes(
299             dir,
300             paths,
301             destinationPath,
302             onSuccess
303         ) {
304             var len = paths.length, self = this,
305                 scaned = 0,
306                 scanSuccess = function () {
307                     scaned += 1;
308                     if (scaned === len) {
309                         onSuccess();
310                     }
311                 },
312                 onCopyNodeSuccess = function (file) {
313                     self.refreshContent(file.toURI(), scanSuccess, 'copy');
314                 },
315                 onCopyNodeFailure = function (e) {
316                     console.error(e);
317                     setTimeout(function () {
318                         app.refreshCurrentPage();
319                         app.ui.alertPopup('Copying error');
320                     }, 200);
321                 },
322                 i,
323                 sourceName,
324                 decision;
325
326             this.systemIO.getFilesList(dir, function (filesList) {
327                 for (i = 0; i < len; i = i + 1) {
328                     if (destinationPath.indexOf(paths[i]) !== -1) {
329                         setTimeout(function () {
330                             app.ui.alertPopup('Copying error');
331                         }, 200);
332                         return;
333                     }
334                 }
335
336                 for (i = 0; i < len; i = i + 1) {
337                     decision = true;
338                     sourceName = paths[i].split('/').pop();
339                     sourceName = app.helpers.getCopyFileName(
340                         sourceName,
341                         filesList
342                     );
343
344                     try {
345                         dir.copyTo(
346                             paths[i],
347                             destinationPath + '/' + sourceName,
348                             true,
349                             onCopyNodeSuccess,
350                             onCopyNodeFailure
351                         );
352                     } catch (e) {
353                         console.error(e);
354                     }
355                 }
356             });
357         },
358
359         /**
360          * Move specified files to destination path
361          * Overwrites existing files
362          *
363          * @param {File} dir Directory handle
364          * @param {string[]} paths Array with absolute virtual file paths
365          * @param {string} destinationPath
366          * @param {function} onSuccess callback
367          */
368         moveNodes: function Model_moveNodes(
369             dir,
370             paths,
371             destinationPath,
372             onSuccess
373         ) {
374             var len = paths.length, self = this,
375                 scaned = 0,
376                 toScan = len * 2,
377                 illegalMove = false,
378                 scanSuccess = function () {
379                     scaned += 1;
380                     if (scaned === toScan) {
381                         onSuccess();
382                     }
383                 },
384                 onMoveNodeSuccess = function (oldfile, file) {
385                     self.refreshContent(oldfile.toURI(), scanSuccess, 'delete');
386                     self.refreshContent(file.toURI(), scanSuccess, 'copy');
387                 },
388                 onMoveNodeFailure = function () {
389                     app.ui.alertPopup('Moving error');
390                 },
391                 i,
392                 sourceName,
393                 decision;
394
395             len -= 1;
396             while (len >= 0) {
397                 if (destinationPath.match(paths[len])) {
398                     illegalMove = true;
399                     break;
400                 }
401                 len -= 1;
402             }
403
404             len = paths.length;
405
406             if (illegalMove) {
407                 setTimeout(function () {
408                     app.ui.alertPopup('Can not move catalog into itself.');
409                 }, 200);
410                 return;
411             }
412
413             this.systemIO.getFilesList(dir, function (filesList) {
414                 var resolveSuccess = function (
415                     path,
416                     destinationPath,
417                     sourceName,
418                     oldfile
419                 ) {
420                     dir.moveTo(
421                         path,
422                         destinationPath + '/' + sourceName,
423                         false,
424                         onMoveNodeSuccess.bind(self, oldfile),
425                         onMoveNodeFailure
426                     );
427                 };
428                 for (i = 0; i < len; i = i + 1) {
429                     if (destinationPath.indexOf(paths[i]) !== -1) {
430                         app.ui.alertPopup('Moving error');
431                         return;
432                     }
433                 }
434
435                 for (i = 0; i < len; i = i + 1) {
436                     decision = true;
437                     sourceName = paths[i].split('/').pop();
438                     try {
439                         tizen.filesystem.resolve(
440                             paths[i],
441                             resolveSuccess.bind(
442                                 self,
443                                 paths[i],
444                                 destinationPath,
445                                 sourceName
446                             ),
447                             onMoveNodeFailure
448                         );
449                     } catch (e) {
450                         console.error(e);
451                     }
452                 }
453             });
454         }
455     };
456 }());