1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "application.h"
30
31 #include <string.h>
32 #include <stdbool.h>
33
34 #include <libidav/webdav.h>
35
36 #include "window.h"
37 #include "config.h"
38 #include "davcontroller.h"
39 #include "settings.h"
40 #include "appsettings.h"
41
42 static DavContext* davctx;
43
44 static DavApp *app;
45
46 void application_init(
void) {
47 davctx = dav_context_new();
48 dav_context_set_mtsafe(davctx, true);
49
50 application_create_menu();
51 }
52
53 DavApp* get_application(
void) {
54 return app;
55 }
56
57 void application_startup(UiEvent* event,
void* data) {
58 if (load_config(davctx)) {
59
60 exit(-
1);
61 }
62
63 appsettings_init();
64 window_init();
65
66
67 app = application_create_app_document();
68 UiContext *global = ui_global_context();
69 ui_attach_document(global, app);
70
71
72 UiObject *win = window_create();
73
74 DavBrowser *doc = davbrowser_create(win);
75 ui_attach_document(win->ctx, doc);
76
77 ui_show(win);
78 }
79
80 static void* davrepo_getname(
void *elm,
int unused) {
81 DavCfgRepository *repo = elm;
82 return repo->name.value.ptr;
83 }
84
85 void application_create_menu(
void) {
86
87 ui_menu(
"File") {
88 ui_menuitem(.label =
"New Window", .onclick = action_window_new);
89 ui_menuseparator();
90 ui_menuitem(.label =
"New Folder", .onclick = action_mkcol, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
91 ui_menuitem(.label =
"New File", .onclick = action_newfile, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
92 ui_menuitem(.label =
"Delete", .onclick = action_delete, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
93 ui_menuseparator();
94 ui_menuitem(.label =
"Upload File", .onclick = action_upload_file, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
95 ui_menuitem(.label =
"Upload Folder", .onclick = action_upload_dir, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
96 ui_menuitem(.label =
"Download", .onclick = action_download, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
97 ui_menuitem(
"Open Properties", .onclick = action_open_properties, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
98 ui_menuitem(
"Open as Text File", .onclick = action_open_properties, .onclickdata =
"text/plain", .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
99 ui_menuseparator();
100 ui_menuitem(.label =
"Close", .onclick = action_window_close);
101 }
102
103 ui_menu(
"Edit") {
104 ui_menuitem(.label =
"Preferences", .onclick = action_open_settings);
105 }
106
107 ui_menu(
"Go") {
108 ui_menuitem(.label =
"Parent", .onclick = action_go_parent, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
109 ui_menuitem(.label =
"Back", .onclick = action_go_back, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
110 ui_menuitem(.label =
"Forward", .onclick = action_go_forward, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
111 ui_menuseparator();
112 ui_menu(
"Repositories") {
113 ui_menu_itemlist(.varname =
"repolist", .getvalue = davrepo_getname, .onselect = action_repo_selected);
114 }
115 }
116
117 ui_menu(
"View") {
118 ui_menu_itemlist(.varname =
"transferlist", .getvalue = transfers_getlabel, .onselect = action_transfer_selected);
119 }
120
121
122 ui_toolbar_item(
"Home", .icon =
UI_ICON_HOME);
123 ui_toolbar_item(
"NewWindow", .icon =
UI_ICON_NEW_WINDOW, .onclick = action_window_new);
124 ui_toolbar_item(
"Refresh", .icon =
UI_ICON_REFRESH, .onclick = action_refresh, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
125 ui_toolbar_menu(
"Repo", .label =
"Repository") {
126 ui_menu_itemlist(.varname =
"repolist", .getvalue = davrepo_getname, .onselect = action_repo_selected);
127 }
128 ui_toolbar_item(
"NewFolder", .icon =
UI_ICON_NEW_FOLDER, .onclick = action_mkcol, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
129 ui_toolbar_item(
"NewFile", .icon =
UI_ICON_ADD, .onclick = action_newfile, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
130 ui_toolbar_item(
"Upload", .label =
"Upload", .icon =
UI_ICON_UPLOAD, .onclick = action_upload_file, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
131 ui_toolbar_item(
"Download", .icon =
UI_ICON_SAVE_LOCAL, .onclick = action_download, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
132 ui_toolbar_item(
"Remove", .icon =
UI_ICON_DELETE, .onclick = action_delete, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
133 ui_toolbar_toggleitem(
"LocalBrowser", .icon =
UI_ICON_DOCK_LEFT, .label =
"Local Browser");
134 ui_toolbar_toggleitem(
"PreviewPane", .icon =
UI_ICON_DOCK_RIGHT);
135
136 ui_toolbar_appmenu() {
137 ui_menuitem(
"New Window", .onclick = action_window_new);
138 ui_menuseparator();
139 ui_menuitem(
"Download", .onclick = action_download, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
140 ui_menuitem(
"Upload Files", .onclick = action_upload_file, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
141 ui_menuitem(
"Upload Directory", .onclick = action_upload_dir, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION));
142 ui_menuitem(
"Open Properties", .onclick = action_open_properties, .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
143 ui_menuitem(
"Open as Text File", .onclick = action_open_properties, .onclickdata =
"text/plain", .groups =
UI_GROUPS(
APP_STATE_BROWSER_SESSION,
APP_STATE_BROWSER_SELECTION));
144 ui_menuseparator();
145 ui_menu(
"Downloads/Uploads") {
146 ui_menu_itemlist(.varname =
"transferlist", .getvalue = transfers_getlabel, .onselect = action_transfer_selected);
147 }
148 ui_menuseparator();
149 ui_menuitem(
"Preferences", .onclick = action_open_settings);
150 }
151
152
153
154
155 ui_toolbar_add_default(
"Repo",
UI_TOOLBAR_LEFT);
156
157 ui_toolbar_add_default(
"NewFolder",
UI_TOOLBAR_CENTER);
158 ui_toolbar_add_default(
"NewFile",
UI_TOOLBAR_CENTER);
159 ui_toolbar_add_default(
"Remove",
UI_TOOLBAR_CENTER);
160 ui_toolbar_add_default(
"Download",
UI_TOOLBAR_CENTER);
161 ui_toolbar_add_default(
"Upload",
UI_TOOLBAR_CENTER);
162
163
164
165 }
166
167
168
169 DavApp* application_create_app_document(
void) {
170 DavApp *doc = ui_document_new(
sizeof(DavApp));
171 UiContext *ctx = ui_document_context(doc);
172 doc->repos = ui_list_new(ctx,
"repolist");
173 doc->transfers = ui_list_new(ctx,
"transferlist");
174 CxList *transfers = doc->transfers->data;
175 transfers->collection.cmpfunc = cx_cmp_ptr;
176
177
178 application_update_repolist(doc);
179
180 return doc;
181 }
182
183 void application_update_repolist(DavApp *app) {
184 DavConfig *config = get_config();
185
186 ui_list_clear(app->repos);
187
188 for (DavCfgRepository *repo = config->repositories; repo; repo = repo->next) {
189 ui_list_append(app->repos, repo);
190 }
191
192 ui_notify(app->repos->observers,
NULL);
193 }
194
195
196 DavContext* application_dav_context(
void) {
197 return davctx;
198 }
199
200 void* transfers_getlabel(
void *data,
int col) {
201 DavTransfer *trans = data;
202 return trans->label;
203 }
204
205 void application_register_transfer(DavTransfer *trans) {
206 DavApp *app = get_application();
207 ui_list_append(app->transfers, trans);
208 application_update_transferlist();
209 }
210
211 void application_remove_transfer(DavTransfer *trans) {
212 DavApp *app = get_application();
213 CxList *transfers = app->transfers->data;
214 cxListFindRemove(transfers, trans);
215 application_update_transferlist();
216 }
217
218
219
220
221
222
223
224 void application_update_transferlist(
void) {
225 DavApp *app = get_application();
226
227
228
229
230
231
232
233
234 ui_list_update(app->transfers);
235 ui_list_notify(app->transfers);
236 }
237
238
239 void action_window_new(UiEvent *event,
void *data) {
240 UiObject *win = window_create();
241
242 DavBrowser *doc = davbrowser_create(win);
243 ui_attach_document(win->ctx, doc);
244
245 ui_show(win);
246 }
247
248 void action_window_close(UiEvent *event,
void *data) {
249 ui_close(event->obj);
250 }
251
252 void action_refresh(UiEvent *event,
void *data) {
253 DavBrowser *browser = event->document;
254 if (browser->current) {
255 davbrowser_query_path(event->obj, browser, browser->current->path);
256 }
257 }
258
259 void action_repo_selected(UiEvent *event,
void *data) {
260 DavCfgRepository *repo = event->eventdata;
261 DavBrowser *browser = event->document;
262 davbrowser_connect2repo(event->obj, browser, repo,
"");
263 }
264
265 static void file_selected(UiEvent *event,
void *data) {
266 UiFileList *files = event->eventdata;
267 if (files && files->nfiles >
0) {
268
269 UiFileList uploadList = ui_filelist_copy(*files);
270 davbrowser_upload_files(event->obj, event->document, uploadList);
271 }
272
273 }
274
275
276
277 static void download_location_selected(UiEvent *event,
void *data) {
278 DavBrowser *browser = event->document;
279 DavResource *reslist = data;
280 UiFileList *flist = event->eventdata;
281
282 if (flist && flist->nfiles >
0) {
283 davbrowser_download(event->obj, browser, reslist, flist->files[
0]);
284 }
else {
285 dav_session_destroy(reslist->session);
286 }
287 }
288
289 void action_download(UiEvent *event,
void *data) {
290 DavBrowser *browser = event->document;
291 UiListSelection sel = ui_list_getselection(browser->resources);
292 if (sel.count >
0) {;
293 const char *initialFileName =
NULL;
294 if (sel.count ==
1) {
295 DavResource *res = ui_list_get(browser->resources, sel.rows[
0]);
296 if (res && !res->iscollection) {
297 initialFileName = res->name;
298 }
299 }
300
301
302 DavSession *sn = dav_session_clone(browser->sn);
303 DavResource *first =
NULL;
304 DavResource *last =
NULL;
305 for (
int i =
0; i < sel.count; i++) {
306
307 DavResource *res = ui_list_get(browser->resources, sel.rows[i]);
308
309 DavResource *res_copy = dav_resource_new(sn, res->path);
310 res_copy->iscollection = res->iscollection;
311 res_copy->contentlength = res->contentlength;
312 res_copy->lastmodified = res->lastmodified;
313 res_copy->creationdate = res->creationdate;
314
315
316 if (!first) {
317 first = res_copy;
318 }
319 if (last) {
320 res_copy->prev = last;
321 last->next = res_copy;
322 }
323 last = res_copy;
324 }
325
326 if (initialFileName) {
327 ui_savefiledialog(event->obj, initialFileName, download_location_selected, first);
328 }
else {
329 ui_openfiledialog(event->obj,
UI_FILEDIALOG_SELECT_FOLDER, download_location_selected, first);
330 }
331
332 ui_listselection_free(sel);
333 }
334 }
335
336 void action_upload_file(UiEvent *event,
void *data) {
337 DavBrowser *browser = event->document;
338 if(!browser->sn) {
339 return;
340 }
341 ui_openfiledialog(event->obj,
UI_FILEDIALOG_SELECT_MULTI, file_selected,
NULL);
342 }
343
344 void action_upload_dir(UiEvent *event,
void *data) {
345 DavBrowser *browser = event->document;
346 if(!browser->sn) {
347 return;
348 }
349 ui_openfiledialog(event->obj,
UI_FILEDIALOG_SELECT_FOLDER|
UI_FILEDIALOG_SELECT_MULTI, file_selected,
NULL);
350 }
351
352 void action_delete(UiEvent *event,
void *data) {
353 DavBrowser *browser = event->document;
354 UiListSelection sel = ui_list_getselection(browser->resources);
355 if (sel.count >
0) {
356 davbrowser_delete(event->obj, browser, sel);
357 }
358 ui_listselection_free(sel);
359 }
360
361 void action_selectall(UiEvent *event,
void *data) {
362 DavBrowser *browser = event->document;
363 int nres = ui_list_count(browser->resources);
364 for(
int i=
0;i<nres;i++) {
365 ui_list_setselection(browser->resources, i);
366 }
367 }
368
369 void action_rename(UiEvent *event,
void *data) {
370 DavBrowser *browser = event->document;
371 UiListSelection sel = ui_list_getselection(browser->resources);
372 if (sel.count ==
1) {
373 davbrowser_rename(event->obj, browser, sel);
374 }
else if(sel.count >
1) {
375 fprintf(stderr,
"Renaming multiple resources is not implemented yet\n");
376 }
377 }
378
379 static void newfiledialog_result(UiEvent *event,
void *data) {
380 DavBrowser *browser = event->document;
381 char *path = event->eventdata;
382 if (event->intval ==
1) {
383 davbrowser_newfile(event->obj, browser, path);
384 }
385 }
386
387 void action_newfile(UiEvent *event,
void *data) {
388 DavBrowser *browser = event->document;
389 if(!browser->sn) {
390 return;
391 }
392
393 ui_dialog(event->obj,
394 .content =
"New File",
395 .input =
TRUE,
396 .button1_label =
"Create File",
397 .button2_label =
"Cancel",
398 .result = newfiledialog_result);
399 }
400
401
402 static void newfolderdialog_result(UiEvent *event,
void *data) {
403 DavBrowser *browser = event->document;
404 char *path = event->eventdata;
405 if (event->intval ==
1) {
406 davbrowser_mkcol(event->obj, browser, path);
407 }
408 }
409
410 void action_mkcol(UiEvent *event,
void *data) {
411 DavBrowser *browser = event->document;
412 if(!browser->sn) {
413 return;
414 }
415
416
417 ui_dialog(event->obj,
418 .content =
"New Folder",
419 .input =
TRUE,
420 .button1_label =
"Create Folder",
421 .button2_label =
"Cancel",
422 .result = newfolderdialog_result);
423 }
424
425 void action_open_settings(UiEvent *event,
void *data) {
426 settings_window_open();
427 }
428
429 void action_open_properties(UiEvent *event,
void *data) {
430 char *type = data;
431 DavBrowser *browser = event->document;
432
433 UiListSelection sel = ui_list_getselection(browser->resources);
434 for(
int i=
0;i<sel.count;i++) {
435 DavResource *res = ui_list_get(browser->resources, sel.rows[i]);
436 if(res) {
437 davbrowser_open_resource(event->obj, browser, res, type);
438 }
439 }
440 ui_listselection_free(sel);
441 }
442
443 void action_transfer_selected(UiEvent *event,
void *data) {
444 DavApp *app = get_application();
445 DavTransfer *trans = ui_list_get(app->transfers, event->intval);
446 if(trans) {
447 ui_show(trans->window);
448 }
449 }
450