New release 0.9.1-1
[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 "UIConstants.js" as Const
6
7 Page {
8     id: root
9     title: qsTr("Files")
10
11     property variant secrets
12     property string resource_path: "/~/Ubuntu One";
13     property string content_path: "/content/~/Ubuntu One";
14     property variant properties
15     property string path
16     property string name
17
18     menu: [
19         [qsTr("Upload file"),false],
20         [qsTr("Rename"),false],
21         [qsTr("Delete"),false],
22         [qsTr("New folder"),false],
23         [qsTr("Refresh"),false]
24     ]
25
26     function menuFun(id) {
27         if(id==qsTr("Upload file")) {
28             mask.state = "dialog";
29             fileSelector.open();
30         }
31         if(id==qsTr("Refresh")) {
32             init(root.properties);
33         }
34         if(id==qsTr("Rename")) {
35             if(root.path=="/") {
36                 tip.show(qsTr("Root folder can't be renamed!"));
37             } else {
38                 dialogRename.open();
39             }
40         }
41         if(id==qsTr("Delete")) {
42             if(root.path=="/") {
43                 tip.show(qsTr("Root folder can't be deleted!"));
44             } else {
45                 dialogDelete.open();
46             }
47         }
48         if(id==qsTr("New folder")) {
49             dialogNew.open();
50         }
51     }
52
53     function init(prop)
54     {
55         if(mask.state!="defocused") {
56             mask.state = "busy";
57         }
58         if(root.properties && !prop) {
59             prop = root.properties;
60         }
61
62         secrets = {
63             token: Utils.token(),
64             secret: Utils.tokenSecret(),
65             consumer_key : Utils.customerKey(),
66             consumer_secret: Utils.customerSecret()
67         };
68         if(prop) {
69             root.path = prop.path;
70             root.name = U1.fixFilename(prop.path);
71             U1.getFiles(secrets,prop.resource_path,root);
72             resource_path = prop.resource_path;
73             content_path = prop.content_path;
74         } else {
75             root.path = "/";
76             root.name = "";
77             U1.getFileTree(secrets,root);
78         }
79         root.properties = prop;
80     }
81
82     function onResp(nodes)
83     {
84         createFilesView(nodes);
85     }
86
87     function onErr(status)
88     {
89         //console.log("onErr");
90         mask.state = "idle";
91         if(status==401) {
92             tip.show(qsTr("Authorization failed!"));
93         } else if(status==0) {
94             tip.show(qsTr("Unable to connect!"));
95         } else {
96             tip.show(qsTr("Error: ")+status);
97         }
98         pageStack.pop();
99     }
100
101
102     function onRespRename()
103     {
104         //console.log("onRespRename");
105         pageStack.prevPage().init();
106         mask.state = "idle";
107         tip.show(qsTr("Folder renamed!"));
108     }
109
110     function onErrRename(status)
111     {
112         //console.log("onErrRenamed");
113         mask.state = "idle";
114         if(status==401) {
115             tip.show(qsTr("Authorization failed!"));
116         } else {
117             tip.show(qsTr("Error: ")+status);
118         }
119     }
120
121     function onRespNew()
122     {
123         //console.log("onRespNew");
124         pageStack.currentPage.init();
125         mask.state = "idle";
126         tip.show(qsTr("New folder created!"));
127     }
128
129     function onErrNew(status)
130     {
131         onErrRename(status);
132     }
133
134     function createFilesView(nodes)
135     {
136         var i,l;
137         if(files.children.length>0) {
138             l = files.children.length;
139             for(i=0;i<l;++i) {
140                 files.children[i].destroy();
141             }
142         }
143         var component = Qt.createComponent("components/File.qml");
144         l = nodes.length;
145         //console.log("l="+l);
146         for (i=0; i<l; i++) {
147             var object = component.createObject(files);
148             var ind = nodes[i].path.lastIndexOf("/");
149             object.textMax = root.width/17;
150             //console.log("ind="+ind);
151             if(ind>=0) {
152                 object.name = nodes[i].path.substr(ind+1);
153             }  else {
154                 object.name = nodes[i].path;
155             }
156             object.isDirectory = nodes[i].kind == "directory";
157             object.properties = nodes[i];
158             object.width = root.width;
159             //object.height = 50;
160             if(object.isDirectory) {
161                 object.clicked.connect(function(prop) {
162                             pageStack.push("FilesPage.qml");
163                             pageStack.currentPage.init(prop);
164                         });
165             } else {
166                 object.clicked.connect(function(prop) {
167                             pageStack.push("PropertiesPage.qml");
168                             pageStack.currentPage.init(prop);
169                         });
170             }
171         }
172         if(mask.state!="defocused") {
173             mask.state = "idle";
174         }
175
176         if(files.children.length==0) {
177             empty.visible = true;
178         }
179     }
180
181     Connections {
182         target: Utils
183         onFileUploaded: init(root.properties);
184     }
185
186     Flickable {
187         id: flickable
188         width: parent.width
189         height: parent.height
190         contentHeight: files.height+Const.SYSTEM_BAR_HEIGHT+2*Const.TEXT_MARGIN
191         //y: Const.SYSTEM_BAR_HEIGHT+Const.TEXT_MARGIN
192         y: Const.SYSTEM_BAR_HEIGHT+Const.DEFAULT_MARGIN
193         contentWidth: parent.width
194
195         Column {
196             id: files
197             //spacing: Const.DEFAULT_MARGIN
198             //x: Const.TEXT_MARGIN
199             add: Transition {
200                 NumberAnimation { properties: "opacity"; easing.type: Easing.InOutQuad }
201             }
202         }
203     }
204
205     Text {
206         id: empty
207         font.pixelSize: Const.DEFAULT_FONT_PIXEL_SIZE
208         color: Const.DEFAULT_FOREGROUND_COLOR
209         text: qsTr("Folder is empty.")
210         anchors.centerIn: parent
211         font.italic: true
212         visible: false
213     }
214
215     FileSelector {
216         id: fileSelector
217         z: 200
218         folder: Utils.lastFolder()=="" ? Const.DEFAULT_FOLDER : Utils.lastFolder()
219         folderOnly: false
220         onFileSelected: {
221             mask.state = "idle";
222             //console.log("selected: "+file+" "+U1.fixFolder(folder));
223             fileSelector.close();
224             Utils.setLastFolder(folder);
225             var path = content_path+"/"+file;
226             //console.log(path);
227             U1.uploadFile(secrets,root,path,file,folder,Utils);
228         }
229
230     }
231
232     function getParentPath(path) {
233         //console.log(path);
234         var ppath;
235         var ind = path.lastIndexOf("/");
236         if(ind>=0) {
237             ppath = path.substr(0,ind);
238         }
239         if(path=="") ppath = "/";
240
241         //console.log(ppath);
242         return ppath;
243     }
244
245     function trim(s) {
246         var l=0; var r=s.length -1;
247         while(l < s.length && s[l] == ' ')
248         {       l++; }
249         while(r > l && s[r] == ' ')
250         {       r-=1;   }
251         return s.substring(l, r+1);
252     }
253
254     Connections {
255         target: Utils
256         onFileDeleted: {
257             if(pageStack.currentPage==root) {
258                 mask.state = "idle";
259                 tip.show(qsTr("Folder was deleted!"));
260                 pageStack.pop();
261                 pageStack.currentPage.init();
262             }
263         }
264         onOperationError: {
265             if(pageStack.currentPage==root) {
266                 mask.state = "idle";
267                 if(status==401) {
268                     tip.show(qsTr("Authorization failed!"));
269                 } else {
270                     tip.show(qsTr("Error: ")+status);
271                 }
272             }
273         }
274     }
275
276     DialogYesNo {
277         id: dialogDelete
278         z: 200
279         text: qsTr("Delete folder?")
280         onOpened: mask.state = "dialog"
281         onClosed: {
282             mask.state = "idle";
283             if(ok) {
284                 mask.state = "busy";
285                 U1.deleteFile(secrets,properties.resource_path,root,Utils);
286             }
287         }
288         onCanceled: mask.state = "idle"
289     }
290
291     DialogInput {
292         id: dialogRename
293         z: 200
294         textWidth: root.width - 4*Const.DEFAULT_MARGIN
295         label: qsTr("Enter new folder name:")
296         placeholderText: root.name
297         onOpened: {
298             reset();
299             Utils.setOrientation("auto");
300             mask.state = "dialog";
301         }
302         onClosed: {
303             mask.state = "idle";
304             Utils.setOrientation(root.orientation);
305             var r = trim(resp);
306             if(r!="") {
307                 mask.state = "busy";
308                 var currentPath = root.properties.resource_path;
309                 var targetPath = getParentPath(root.properties.path)+"/"+resp;
310                 //console.log("targetPath: "+targetPath);
311                 U1.renameFile(secrets,currentPath,targetPath,root);
312             } else {
313                 tip.show(qsTr("Invalid folder name!"))
314             }
315         }
316         onCanceled: {
317             Utils.setOrientation(root.orientation);
318             mask.state = "idle";
319         }
320     }
321
322     DialogInput {
323         id: dialogNew
324         z: 200
325         textWidth: root.width - 4*Const.DEFAULT_MARGIN
326         label: qsTr("Enter new folder name:")
327         placeholderText: ""
328         onOpened: {
329             reset();
330             Utils.setOrientation("auto");
331             mask.state = "dialog";
332         }
333         onClosed: {
334             mask.state = "idle";
335             Utils.setOrientation(root.orientation);
336             var r = trim(resp);
337             if(r!="") {
338                 mask.state = "busy";
339                 var rpath;
340                 if(root.properties)
341                     rpath = root.properties.resource_path;
342                 else
343                     rpath = root.resource_path;
344                 var newPath = rpath+"/"+resp;
345                 //console.log("newPath: "+newPath);
346                 U1.newFolder(secrets,newPath,root);
347             } else {
348                 tip.show(qsTr("Invalid folder name!"))
349             }
350         }
351         onCanceled: {
352             Utils.setOrientation(root.orientation);
353             mask.state = "idle";
354         }
355     }
356 }