0.9.3-1 release
[ubi] / qml / ubi / FilesPage.qml
1 import QtQuick 1.0 // to target S60 5th Edition or Maemo 5
2 import "components"
3 import Qt 4.7
4 import "u1.js" as U1
5 import "bytesconv.js" as Conv
6 import "UIConstants.js" as Const
7
8 Page {
9     id: root
10     title: qsTr("Files")
11
12     property variant secrets
13     property string resource_path: "/~/Ubuntu One";
14     property string content_path: "/content/~/Ubuntu One";
15     property variant properties
16     property string path
17     property string name
18
19     property alias taskMenu: taskMenu
20
21     function init(prop)
22     {
23         if(mask.state!="defocused" && mask.state!="dialog") {
24             mask.state = "busy";
25         }
26         if(root.properties && !prop) {
27             prop = root.properties;
28         }
29
30         secrets = {
31             token: Utils.token(),
32             secret: Utils.tokenSecret(),
33             consumer_key : Utils.customerKey(),
34             consumer_secret: Utils.customerSecret()
35         };
36         if(prop) {
37             root.path = prop.path;
38             root.name = U1.fixFilename(prop.path);
39             U1.getFiles(secrets,prop.resource_path,root);
40             resource_path = prop.resource_path;
41             content_path = prop.content_path;
42         } else {
43             root.path = "/";
44             root.name = "";
45             U1.getFileTree(secrets,root);
46         }
47         root.properties = prop;
48     }
49
50     function onResp(nodes)
51     {
52         createFilesView(nodes);
53     }
54
55     function onErr(status)
56     {
57         mask.state = "idle";
58         if(status==401) {
59             tip.show(qsTr("Ubuntu One authorization has failed. Try once again or check login settings."));
60         } else if(status==0) {
61             tip.show(qsTr("Unable to connect. Check internet connection."));
62         } else {
63             tip.show(qsTr("Unknown error: ")+status);
64         }
65         pageStack.pop();
66         initPage.hide()
67     }
68
69
70     function onRespRename()
71     {
72         pageStack.prevPage().init();
73         mask.state = "idle";
74         tip.show(qsTr("Folder renamed!"));
75     }
76
77     function onErrRename(status)
78     {
79         mask.state = "idle";
80         if(status==401) {
81             tip.show(qsTr("Ubuntu One authorization has failed. Try once again or check login settings."));
82         } else {
83             tip.show(qsTr("Unknown error: ")+status);
84         }
85     }
86
87     function onRespNew()
88     {
89         pageStack.currentPage.init();
90         mask.state = "idle";
91         tip.show(qsTr("New folder created!"));
92     }
93
94     function onErrNew(status)
95     {
96         onErrRename(status);
97     }
98
99     function createFilesView(nodes)
100     {
101         var i,l;
102         if(files.children.length>0) {
103             l = files.children.length;
104             for(i=0;i<l;++i) {
105                 files.children[i].destroy();
106             }
107         }
108         var component = Qt.createComponent("components/File.qml");
109         l = nodes.length;
110         for (i=0; i<l; i++) {
111             var object = component.createObject(files);
112             var ind = nodes[i].path.lastIndexOf("/");
113             if(ind>=0) {
114                 object.name = nodes[i].path.substr(ind+1);
115             }  else {
116                 object.name = nodes[i].path;
117             }
118             object.isDirectory = nodes[i].kind == "directory";
119             object.properties = nodes[i];
120             if(object.isDirectory) {
121                 object.clicked.connect(function(prop) {
122                             pageStack.push("FilesPage.qml");
123                             pageStack.currentPage.init(prop);
124                         });
125             } else {
126                 var txt = "" + Conv.bytesToSize(nodes[i].size);
127                 object.description = txt;
128                 object.isPublic = nodes[i].is_public;
129                 object.clicked.connect(function(prop) {
130                             pageStack.push("PropertiesPage.qml");
131                             pageStack.currentPage.init(prop);
132                         });
133
134                 // extension
135                 ind = object.name.lastIndexOf(".");
136                 var ext = "";
137                 if(ind>=0) ext = object.name.substr(ind+1);
138                 if(ext=="jpg" || ext=="JPG" || ext=="Jpg" ||
139                    ext=="jpeg" || ext=="JPEG" || ext=="Jpeg" ||
140                    ext=="gif" || ext=="GIF" || ext=="Gif" ||
141                    ext=="svg" || ext=="SVG" || ext=="Svg" ||
142                    ext=="png" || ext=="PNG" || ext=="Png") {
143                     object.isPhoto = true;
144                 }
145                 if(ext=="mp3" || ext=="MP3" || ext=="Mp3" ||
146                    ext=="wma" || ext=="WMA" || ext=="Wma" ||
147                    ext=="wav" || ext=="WAV" || ext=="Wav" ||
148                    ext=="ogg" || ext=="OGG" || ext=="Ogg" ||
149                    ext=="acc" || ext=="ACC" || ext=="Acc" ||
150                    ext=="m4a" || ext=="M4A" || ext=="M4a" ||
151                    ext=="flac" || ext=="FLAC" || ext=="Flac") {
152                     object.isMusic = true;
153                 }
154                 if(ext=="avi" || ext=="AVI" || ext=="Avi" ||
155                    ext=="mp4" || ext=="MP4" || ext=="Mp4" ||
156                    ext=="mpg" || ext=="MPG" || ext=="Mpg" ||
157                    ext=="mkv" || ext=="MKV" || ext=="Mkv" ||
158                    ext=="flv" || ext=="FLV" || ext=="Flv" ||
159                    ext=="m4v" || ext=="M4V" || ext=="M4v" ||
160                    ext=="3gp" || ext=="3GP") {
161                     object.isVideo = true;
162                 }
163             }
164         }
165         if(mask.state!="defocused" && mask.state!="dialog") {
166             mask.state = "idle";
167         }
168
169         if(l==0) {
170             empty.visible = true;
171         } else {
172             empty.visible = false;
173         }
174
175         initPage.hide()
176     }
177
178     Connections {
179         target: Utils
180         onFileUploaded: init(root.properties);
181     }
182
183     Flickable {
184         id: flickable
185         width: parent.width
186         height: parent.height
187         contentHeight: files.height+Const.TOP_BAR_HEIGHT+Const.SYSTEM_BAR_HEIGHT+Const.TEXT_MARGIN
188         y: Const.TOP_BAR_HEIGHT
189         contentWidth: parent.width
190
191         Column {
192             id: files
193             add: Transition {
194                 NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad }
195             }
196         }
197     }
198
199     Text {
200         id: empty
201         font.pixelSize: Const.DEFAULT_FONT_PIXEL_SIZE
202         color: Const.DEFAULT_FOREGROUND_COLOR
203         text: qsTr("Empty")
204         anchors.centerIn: parent
205         font.italic: true
206         visible: false
207     }
208
209     FileDialog {
210         id: fileSelector
211         z: 200
212         hidden: true
213         folder: Utils.lastFolder()=="" ? Const.DEFAULT_FOLDER : Utils.lastFolder()
214         folderOnly: false
215         onFileSelected: {
216             mask.state = "idle";
217             fileSelector.close();
218             Utils.setLastFolder(folder);
219             var path = content_path+"/"+file;
220             U1.uploadFile(secrets,root,path,file,folder,Utils);
221         }
222     }
223
224     function getParentPath(path) {
225         var ppath;
226         var ind = path.lastIndexOf("/");
227         if(ind>=0) {
228             ppath = path.substr(0,ind);
229         }
230         if(path=="") ppath = "/";
231         return ppath;
232     }
233
234     function trim(s) {
235         var l=0; var r=s.length -1;
236         while(l < s.length && s[l] == ' ')
237         {       l++; }
238         while(r > l && s[r] == ' ')
239         {       r-=1;   }
240         return s.substring(l, r+1);
241     }
242
243     Connections {
244         target: Utils
245         onFileDeleted: {
246             if(pageStack.currentPage==root) {
247                 mask.state = "idle";
248                 tip.show(qsTr("Folder was deleted!"));
249                 pageStack.pop();
250                 pageStack.currentPage.init();
251             }
252         }
253         onOperationError: {
254             if(pageStack.currentPage==root) {
255                 mask.state = "idle";
256                 if(status==401) {
257                     tip.show(qsTr("Authorization failed!"));
258                 } else {
259                     tip.show(qsTr("Error: ")+status);
260                 }
261             }
262         }
263     }
264
265     DialogYesNo {
266         id: dialogDelete
267         z: 200
268         text: qsTr("Delete folder?")
269         onOpened: mask.state = "dialog"
270         onClosed: {
271             if(ok) {
272                 mask.state = "busy";
273                 U1.deleteFile(secrets,properties.resource_path,root,Utils);
274             }
275         }
276     }
277
278     DialogInput {
279         id: dialogRename
280         z: 200
281         textWidth: root.width - 4*Const.DEFAULT_MARGIN
282         label: qsTr("Enter new folder name:")
283         placeholderText: root.name
284         onOpened: {
285             reset();
286             Utils.setOrientation("auto");
287         }
288         onClosed: {
289             mask.state = "idle";
290             Utils.setOrientation(root.orientation);
291             var r = trim(resp);
292             if(r!="") {
293                 mask.state = "busy";
294                 var currentPath = root.properties.resource_path;
295                 var targetPath = getParentPath(root.properties.path)+"/"+resp;
296                 U1.renameFile(secrets,currentPath,targetPath,root);
297             } else {
298                 tip.show(qsTr("Invalid folder name!"))
299             }
300         }
301         onCanceled: {
302             Utils.setOrientation(root.orientation);
303         }
304     }
305
306     DialogInput {
307         id: dialogNew
308         z: 200
309         textWidth: root.width - 4*Const.DEFAULT_MARGIN
310         label: qsTr("Enter new folder name:")
311         placeholderText: ""
312         onOpened: {
313             reset();
314             Utils.setOrientation("auto");
315         }
316         onClosed: {
317             Utils.setOrientation(root.orientation);
318             var r = trim(resp);
319             if(r!="") {
320                 mask.state = "busy";
321                 var rpath;
322                 if(root.properties)
323                     rpath = root.properties.resource_path;
324                 else
325                     rpath = root.resource_path;
326                 var newPath = rpath+"/"+resp;
327                 U1.newFolder(secrets,newPath,root);
328             } else {
329                 tip.show(qsTr("Invalid folder name!"))
330             }
331         }
332         onCanceled: {
333             Utils.setOrientation(root.orientation);
334         }
335     }
336
337     TaskMenu {
338         z: 200
339         id: taskMenu
340
341         contexMenu: true
342         menuDynamic: _menuDyn
343         menuHeight: menuDynamic.height+menuFixed.height+7*Const.DEFAULT_MARGIN
344
345         Flow {
346             id: _menuDyn
347
348             y: root.height-taskMenu.menuHeight-Const.SYSTEM_BAR_HEIGHT+2*Const.DEFAULT_MARGIN
349             x: Const.DEFAULT_MARGIN
350
351             width: parent.width-2*Const.DEFAULT_MARGIN
352             spacing: Const.DEFAULT_MARGIN
353
354             Button {
355                 label: qsTr("Upload file");
356                 onButtonClicked: {
357                     taskMenu.close();
358                     fileSelector.open();
359                 }
360             }
361
362             Button {
363                 label: qsTr("Rename");
364                 onButtonClicked: {
365                     taskMenu.close();
366                     if(root.path=="/") {
367                         tip.show(qsTr("Root folder cannot be renamed."));
368                     } else {
369                         dialogRename.open();
370                     }
371                 }
372             }
373
374             Button {
375                 label: qsTr("Delete");
376                 onButtonClicked: {
377                     taskMenu.close();
378                     if(root.path=="/") {
379                         tip.show(qsTr("Root folder cannot be deleted."));
380                     } else {
381                         dialogDelete.open();
382                     }
383                 }
384             }
385
386             Button {
387                 label: qsTr("New folder");
388                 onButtonClicked: {
389                     taskMenu.close();
390                     dialogNew.open();
391                 }
392             }
393
394             Button {
395                 label: qsTr("Refresh");
396                 onButtonClicked: {
397                     taskMenu.close();
398                     init(root.properties);
399                 }
400             }
401         }
402     }
403 }