39 static UiIcon* file_icon; |
39 static UiIcon* file_icon; |
40 |
40 |
41 static UiPathElm* dav_get_pathelm(const char *full_path, size_t len, size_t *ret_nelm, void* data); |
41 static UiPathElm* dav_get_pathelm(const char *full_path, size_t len, size_t *ret_nelm, void* data); |
42 |
42 |
43 void window_init(void) { |
43 void window_init(void) { |
44 folder_icon = ui_foldericon(16); |
44 folder_icon = ui_foldericon(16); |
45 file_icon = ui_fileicon(16); |
45 file_icon = ui_fileicon(16); |
46 } |
46 } |
47 |
47 |
48 UiObject* window_create(void) { |
48 UiObject* window_create(void) { |
49 UiObject* obj = ui_window("iDAV", NULL); |
49 UiObject* obj = ui_window("iDAV", NULL); |
50 ui_window_size(obj, 900, 700); |
50 ui_window_size(obj, 900, 700); |
51 |
51 |
52 MainWindow* wdata = ui_malloc(obj->ctx, sizeof(MainWindow)); |
52 MainWindow* wdata = ui_malloc(obj->ctx, sizeof (MainWindow)); |
53 memset(wdata, 0, sizeof(MainWindow)); |
53 memset(wdata, 0, sizeof (MainWindow)); |
54 obj->window = wdata; |
54 obj->window = wdata; |
55 |
55 |
56 wdata->progress = ui_int_new(obj->ctx, "progress"); |
56 wdata->progress = ui_int_new(obj->ctx, "progress"); |
57 |
57 |
58 // navigation bar |
58 // navigation bar |
59 ui_hbox(obj, .fill = UI_OFF, .margin = 8) { |
59 |
60 ui_button(obj, .icon = UI_ICON_GO_BACK, .onclick = action_go_back); |
60 ui_hbox(obj, .fill = UI_OFF, .margin = 8) { |
61 ui_button(obj, .icon = UI_ICON_GO_FORWARD, .onclick = action_go_forward); |
61 ui_button(obj, .icon = UI_ICON_GO_BACK, .onclick = action_go_back); |
62 |
62 ui_button(obj, .icon = UI_ICON_GO_FORWARD, .onclick = action_go_forward); |
63 ui_path_textfield(obj, .fill = UI_ON, .getpathelm = dav_get_pathelm, .onactivate = action_path_selected ,.varname = "path"); |
63 |
64 |
64 ui_path_textfield(obj, .fill = UI_ON, .getpathelm = dav_get_pathelm, .onactivate = action_path_selected, .varname = "path"); |
65 ui_progressspinner(obj, .value = wdata->progress); |
65 |
66 } |
66 ui_progressspinner(obj, .value = wdata->progress); |
67 |
67 } |
68 // main content |
68 |
69 UiModel* model = ui_model(obj->ctx, UI_ICON_TEXT, "Name", UI_STRING, "Type", UI_STRING_FREE, "Last Modified", UI_STRING_FREE, "Size", -1); |
69 // main content |
70 model->getvalue = (ui_getvaluefunc)window_resource_table_getvalue; |
70 UiModel* model = ui_model(obj->ctx, UI_ICON_TEXT, "Name", UI_STRING, "Type", UI_STRING_FREE, "Last Modified", UI_STRING_FREE, "Size", -1); |
71 ui_table(obj, .fill = UI_ON, .model = model, .onactivate = action_list_activate, .ondrop = action_dnd_drop,.varname = "reslist"); |
71 model->getvalue = (ui_getvaluefunc) window_resource_table_getvalue; |
72 |
72 ui_table(obj, .fill = UI_ON, .model = model, .onactivate = action_list_activate, .ondrop = action_dnd_drop, .varname = "reslist"); |
73 // status bar |
73 |
74 ui_hbox(obj, .fill = UI_OFF) { |
74 // status bar |
75 ui_label(obj, .label = ""); |
75 |
76 } |
76 ui_hbox(obj, .fill = UI_OFF) { |
77 |
77 ui_label(obj, .label = ""); |
78 return obj; |
78 } |
|
79 |
|
80 return obj; |
79 } |
81 } |
80 |
82 |
81 void* window_resource_table_getvalue(DavResource *res, int col) { |
83 void* window_resource_table_getvalue(DavResource *res, int col) { |
82 switch (col) { |
84 switch (col) { |
83 case 0: { // icon |
85 case 0: |
84 return res->iscollection ? folder_icon : file_icon; |
86 { // icon |
85 } |
87 return res->iscollection ? folder_icon : file_icon; |
86 case 1: { // resource name |
88 } |
87 return res->name; |
89 case 1: |
88 } |
90 { // resource name |
89 case 2: { // type |
91 return res->name; |
90 return res->iscollection ? "Collection" : (res->contenttype ? res->contenttype : "Resource"); |
92 } |
91 } |
93 case 2: |
92 case 3: { // last modified |
94 { // type |
93 return util_date_str(res->lastmodified); |
95 return res->iscollection ? "Collection" : (res->contenttype ? res->contenttype : "Resource"); |
94 } |
96 } |
95 case 4: { // size |
97 case 3: |
96 return util_size_str(res->iscollection, res->contentlength); |
98 { // last modified |
97 } |
99 return util_date_str(res->lastmodified); |
98 } |
100 } |
99 return NULL; |
101 case 4: |
|
102 { // size |
|
103 return util_size_str(res->iscollection, res->contentlength); |
|
104 } |
|
105 } |
|
106 return NULL; |
100 } |
107 } |
101 |
108 |
102 void window_progress(MainWindow *win, int on) { |
109 void window_progress(MainWindow *win, int on) { |
103 ui_set(win->progress, on); |
110 ui_set(win->progress, on); |
104 } |
111 } |
105 |
|
106 |
|
107 |
112 |
108 static UiPathElm* dav_get_pathelm(const char *full_path, size_t len, size_t *ret_nelm, void* data) { |
113 static UiPathElm* dav_get_pathelm(const char *full_path, size_t len, size_t *ret_nelm, void* data) { |
109 cxstring fpath = cx_strn(full_path, len); |
114 cxstring fpath = cx_strn(full_path, len); |
110 int protocol = 0; |
115 int protocol = 0; |
111 if(cx_strcaseprefix(fpath, CX_STR("http://"))) { |
116 if (cx_strcaseprefix(fpath, CX_STR("http://"))) { |
112 protocol = 7; |
117 protocol = 7; |
113 } else if (cx_strcaseprefix(fpath, CX_STR("https://"))) { |
118 } else if (cx_strcaseprefix(fpath, CX_STR("https://"))) { |
114 protocol = 8; |
119 protocol = 8; |
115 } |
120 } |
116 |
121 |
117 size_t start = 0; |
122 size_t start = 0; |
118 size_t end = 0; |
123 size_t end = 0; |
119 for (size_t i = protocol; i < len; i++) { |
124 for (size_t i = protocol; i < len; i++) { |
120 if (full_path[i] == '/') { |
125 if (full_path[i] == '/') { |
121 end = i; |
126 end = i; |
122 break; |
127 break; |
123 } |
128 } |
124 } |
129 } |
125 |
130 |
126 int skip = 0; |
131 int skip = 0; |
127 if (end == 0) { |
132 if (end == 0) { |
128 // no '/' found or first char is '/' |
133 // no '/' found or first char is '/' |
129 end = len > 0 && full_path[0] == '/' ? 1 : len; |
134 end = len > 0 && full_path[0] == '/' ? 1 : len; |
130 } else if (end + 1 <= len) { |
135 } else if (end + 1 <= len) { |
131 skip++; // skip first '/' |
136 skip++; // skip first '/' |
132 } |
137 } |
133 |
138 |
134 |
139 |
135 cxmutstr base = cx_strdup(cx_strn(full_path, end)); |
140 cxmutstr base = cx_strdup(cx_strn(full_path, end)); |
136 cxmutstr base_path = cx_strdup(cx_strcast(base)); |
141 cxmutstr base_path = cx_strdup(cx_strcast(base)); |
137 cxstring path = cx_strsubs(fpath, end+skip); |
142 cxstring path = cx_strsubs(fpath, end + skip); |
138 |
143 |
139 cxstring *pathelms; |
144 cxstring *pathelms; |
140 size_t nelm = 0; |
145 size_t nelm = 0; |
141 |
146 |
142 if(path.length > 0) { |
147 if (path.length > 0) { |
143 nelm = cx_strsplit_a(cxDefaultAllocator, path, CX_STR("/"), 4096, &pathelms); |
148 nelm = cx_strsplit_a(cxDefaultAllocator, path, CX_STR("/"), 4096, &pathelms); |
144 if (nelm == 0) { |
149 if (nelm == 0) { |
145 *ret_nelm = 0; |
150 *ret_nelm = 0; |
146 return NULL; |
151 return NULL; |
|
152 } |
|
153 } |
|
154 |
|
155 UiPathElm* elms = (UiPathElm*) calloc(nelm + 1, sizeof (UiPathElm)); |
|
156 size_t n = nelm + 1; |
|
157 elms[0].name = base.ptr; |
|
158 elms[0].name_len = base.length; |
|
159 elms[0].path = base_path.ptr; |
|
160 elms[0].path_len = base_path.length; |
|
161 |
|
162 int j = 1; |
|
163 for (int i = 0; i < nelm; i++) { |
|
164 cxstring c = pathelms[i]; |
|
165 if (c.length == 0) { |
|
166 if (i == 0) { |
|
167 c.length = 1; |
|
168 } else { |
|
169 n--; |
|
170 continue; |
147 } |
171 } |
148 } |
172 } |
149 |
173 |
150 UiPathElm* elms = (UiPathElm*)calloc(nelm + 1, sizeof(UiPathElm)); |
174 cxmutstr m = cx_strdup(c); |
151 size_t n = nelm + 1; |
175 elms[j].name = m.ptr; |
152 elms[0].name = base.ptr; |
176 elms[j].name_len = m.length; |
153 elms[0].name_len = base.length; |
177 |
154 elms[0].path = base_path.ptr; |
178 size_t elm_path_len = c.ptr + c.length - full_path; |
155 elms[0].path_len = base_path.length; |
179 cxmutstr elm_path = cx_strdup(cx_strn(full_path, elm_path_len)); |
156 |
180 elms[j].path = elm_path.ptr; |
157 int j = 1; |
181 elms[j].path_len = elm_path.length; |
158 for (int i = 0; i < nelm; i++) { |
182 |
159 cxstring c = pathelms[i]; |
183 j++; |
160 if (c.length == 0) { |
184 } |
161 if (i == 0) { |
185 *ret_nelm = n; |
162 c.length = 1; |
186 |
163 } |
187 return elms; |
164 else { |
188 } |
165 n--; |
|
166 continue; |
|
167 } |
|
168 } |
|
169 |
|
170 cxmutstr m = cx_strdup(c); |
|
171 elms[j].name = m.ptr; |
|
172 elms[j].name_len = m.length; |
|
173 |
|
174 size_t elm_path_len = c.ptr + c.length - full_path; |
|
175 cxmutstr elm_path = cx_strdup(cx_strn(full_path, elm_path_len)); |
|
176 elms[j].path = elm_path.ptr; |
|
177 elms[j].path_len = elm_path.length; |
|
178 |
|
179 j++; |
|
180 } |
|
181 *ret_nelm = n; |
|
182 |
|
183 return elms; |
|
184 } |
|
185 |
|
186 |
189 |
187 void action_go_back(UiEvent *event, void *data) { |
190 void action_go_back(UiEvent *event, void *data) { |
188 DavBrowser *browser = event->document; |
191 DavBrowser *browser = event->document; |
189 davbrowser_navigation_back(event->obj, browser); |
192 davbrowser_navigation_back(event->obj, browser); |
190 } |
193 } |
191 |
194 |
192 void action_go_forward(UiEvent *event, void *data) { |
195 void action_go_forward(UiEvent *event, void *data) { |
193 DavBrowser *browser = event->document; |
196 DavBrowser *browser = event->document; |
194 davbrowser_navigation_forward(event->obj, browser); |
197 davbrowser_navigation_forward(event->obj, browser); |
195 } |
198 } |
196 |
199 |
197 void action_path_selected(UiEvent *event, void *data) { |
200 void action_path_selected(UiEvent *event, void *data) { |
198 DavBrowser *browser = event->document; |
201 DavBrowser *browser = event->document; |
199 char *path = event->eventdata; |
202 char *path = event->eventdata; |
200 if (path && strlen(path) > 0) { |
203 if (path && strlen(path) > 0) { |
201 davbrowser_query_url(event->obj, browser, path); |
204 davbrowser_query_url(event->obj, browser, path); |
202 } |
205 } |
203 } |
206 } |
204 |
207 |
205 void action_list_activate(UiEvent *event, void *data) { |
208 void action_list_activate(UiEvent *event, void *data) { |
206 UiListSelection *selection = event->eventdata; |
209 UiListSelection *selection = event->eventdata; |
207 DavBrowser *browser = event->document; |
210 DavBrowser *browser = event->document; |
208 |
211 |
209 if (selection->count == 1) { |
212 if (selection->count == 1) { |
210 DavResource *res = ui_list_get(browser->resources, selection->rows[0]); |
213 DavResource *res = ui_list_get(browser->resources, selection->rows[0]); |
211 if (res) { |
214 if (res) { |
212 if (res->iscollection) { |
215 if (res->iscollection) { |
213 davbrowser_query_path(event->obj, browser, res->path); |
216 davbrowser_query_path(event->obj, browser, res->path); |
214 } else { |
217 } else { |
215 // TODO |
218 // TODO |
216 } |
219 } |
217 } |
220 } |
218 } |
221 } |
219 } |
222 } |
220 |
223 |
221 void action_dnd_drop(UiEvent *event, void *data) { |
224 void action_dnd_drop(UiEvent *event, void *data) { |
222 UiListDnd *listdnd = event->eventdata; |
225 UiListDnd *listdnd = event->eventdata; |
223 UiDnD *dnd = listdnd->dnd; |
226 UiDnD *dnd = listdnd->dnd; |
224 UiFileList files = ui_selection_geturis(dnd); |
227 UiFileList files = ui_selection_geturis(dnd); |
225 |
228 |
226 davbrowser_upload_files(event->obj, event->document, files); |
229 davbrowser_upload_files(event->obj, event->document, files); |
227 } |
230 } |