186 void resourceviewer_new(DavBrowser *browser, const char *path, DavResourceViewType type) { |
187 void resourceviewer_new(DavBrowser *browser, const char *path, DavResourceViewType type) { |
187 const char *name = util_resource_name(path); |
188 const char *name = util_resource_name(path); |
188 UiObject *win = ui_simple_window(name, NULL); |
189 UiObject *win = ui_simple_window(name, NULL); |
189 ui_window_size(win, 600, 600); |
190 ui_window_size(win, 600, 600); |
190 |
191 |
191 // TODO: when properties can be modified, always add the headerbar |
192 ui_headerbar(win, .showtitle = TRUE) { |
192 if(type == DAV_RESOURCE_VIEW_TEXT) { |
193 ui_headerbar_start(win) { |
193 ui_headerbar(win, .showtitle = TRUE) { |
194 ui_button(win, .label = "Save", .onclick = action_resourceviewer_save, .groups = UI_GROUPS(RESOURCEVIEWER_STATE_MODIFIED)); |
194 ui_headerbar_start(win) { |
195 } |
195 ui_button(win, .label = "Save", .style_class = "suggested-action", .onclick = action_resourceviewer_save, .groups = UI_GROUPS(RESOURCEVIEWER_STATE_MODIFIED)); |
196 } |
196 } |
197 |
197 } |
198 DavResourceViewer *doc = dav_resourceviewer_create(win, browser->sn, path, type); |
198 } |
|
199 |
|
200 |
|
201 DavResourceViewer *doc = dav_resourceviewer_create(browser->sn, path, type); |
|
202 ui_attach_document(win->ctx, doc); |
199 ui_attach_document(win->ctx, doc); |
203 ui_context_closefunc(win->ctx, resourceviewer_close, doc); |
200 ui_context_closefunc(win->ctx, resourceviewer_close, doc); |
204 |
201 |
205 ui_tabview(win, .tabview = UI_TABVIEW_INVISIBLE, .varname = "tabview") { |
202 ui_tabview(win, .tabview = UI_TABVIEW_INVISIBLE, .varname = "tabview") { |
206 /* loading / message tab */ |
203 /* loading / message tab */ |
253 } |
250 } |
254 |
251 |
255 ui_tab(win, "Properties") { |
252 ui_tab(win, "Properties") { |
256 UiModel* model = ui_model(win->ctx, UI_STRING, "Namespace", UI_STRING, "Name", UI_STRING, "Value", -1); |
253 UiModel* model = ui_model(win->ctx, UI_STRING, "Namespace", UI_STRING, "Name", UI_STRING, "Value", -1); |
257 model->getvalue = (ui_getvaluefunc) resourceviewer_proplist_getvalue; |
254 model->getvalue = (ui_getvaluefunc) resourceviewer_proplist_getvalue; |
258 ui_table(win, .fill = UI_ON, .model = model, .varname = "properties"); |
255 ui_table(win, .fill = UI_ON, .model = model, .varname = "properties", .onselection = action_resourceviewer_property_select, .onactivate = action_resourceviewer_property_activate); |
|
256 ui_hbox(win, .fill = UI_OFF, .margin = 4, .spacing = 4) { |
|
257 ui_button(win, .label = "Add", .onclick = action_resourceviewer_property_add); |
|
258 ui_button(win, .label = "Edit", .onclick = action_resourceviewer_property_edit, .groups = UI_GROUPS(RESOURCEVIEWER_STATE_PROP_SELECTED)); |
|
259 ui_button(win, .label = "Remove", .onclick = action_resourceviewer_property_remove, .groups = UI_GROUPS(RESOURCEVIEWER_STATE_PROP_SELECTED)); |
|
260 } |
259 } |
261 } |
260 } |
262 } |
261 } |
263 } |
262 } |
264 } |
263 |
265 |
543 |
545 |
544 void action_resourceviewer_save(UiEvent *event, void *data) { |
546 void action_resourceviewer_save(UiEvent *event, void *data) { |
545 DavResourceViewer *doc = event->document; |
547 DavResourceViewer *doc = event->document; |
546 dav_resourceviewer_save(event->obj, doc); |
548 dav_resourceviewer_save(event->obj, doc); |
547 } |
549 } |
|
550 |
|
551 void action_resourceviewer_property_select(UiEvent *event, void *data) { |
|
552 DavResourceViewer *doc = event->document; |
|
553 UiListSelection *selection = event->eventdata; |
|
554 if(selection->count == 1) { |
|
555 ui_set_group(event->obj->ctx, RESOURCEVIEWER_STATE_PROP_SELECTED); |
|
556 doc->selected_property = ui_list_get(doc->properties, selection->rows[0]); |
|
557 } else { |
|
558 ui_unset_group(event->obj->ctx, RESOURCEVIEWER_STATE_PROP_SELECTED); |
|
559 doc->selected_property = NULL; |
|
560 } |
|
561 } |
|
562 |
|
563 void action_resourceviewer_property_activate(UiEvent *event, void *data) { |
|
564 action_resourceviewer_property_select(event, data); |
|
565 action_resourceviewer_property_edit(event, data); |
|
566 } |
|
567 |
|
568 |
|
569 typedef struct PropertyDialog { |
|
570 UiInteger *type; |
|
571 UiString *ns; |
|
572 UiString *name; |
|
573 UiText *value; |
|
574 } PropertyDialog; |
|
575 |
|
576 static void propertydialog_action(UiEvent *event, void *data) { |
|
577 DavResourceViewer *res = data; |
|
578 if(event->intval == 4) { |
|
579 char *ns = ui_get(res->property_ns); |
|
580 char *name = ui_get(res->property_name); |
|
581 int type = ui_get(res->property_type); |
|
582 char *nsdef = ui_get(res->property_nsdef); |
|
583 char *value = ui_get(res->property_value); |
|
584 |
|
585 if(strlen(ns) == 0) { |
|
586 ui_set(res->property_errormsg, "Namespace must not be empty!"); |
|
587 return; |
|
588 } |
|
589 if(strlen(name) == 0) { |
|
590 ui_set(res->property_errormsg, "Name must not be empty!"); |
|
591 return; |
|
592 } |
|
593 |
|
594 char *textvalue = NULL; |
|
595 DavXmlNode *xmlvalue = NULL; |
|
596 if(type == 0) { |
|
597 // text value |
|
598 textvalue = value; |
|
599 } else { |
|
600 // xml value |
|
601 } |
|
602 |
|
603 DavBool add = FALSE; |
|
604 if(res->edit_property) { |
|
605 if(strcmp(res->edit_property->ns, ns) || strcmp(res->edit_property->name, name)) { |
|
606 // name or namespace changed, remove existing and create new property |
|
607 dav_resourceviewer_property_remove(res, res->edit_property); |
|
608 add = TRUE; |
|
609 } |
|
610 } else { |
|
611 add = TRUE; |
|
612 } |
|
613 |
|
614 if(add) { |
|
615 if(textvalue) { |
|
616 dav_resourceviewer_property_add_text(res, ns, name, textvalue); |
|
617 } else { |
|
618 dav_resourceviewer_property_add_xml(res, ns, name, nsdef, xmlvalue); |
|
619 } |
|
620 } else { |
|
621 if(textvalue) { |
|
622 dav_resourceviewer_property_update_text(res, res->edit_property, textvalue); |
|
623 } else { |
|
624 dav_resourceviewer_property_update_xml(res, res->edit_property, xmlvalue); |
|
625 } |
|
626 } |
|
627 } |
|
628 ui_close(event->obj); |
|
629 } |
|
630 |
|
631 static void prop_type_changed(UiEvent *event, void *data) { |
|
632 DavResourceViewer *res = data; |
|
633 switch(ui_get(res->property_type)) { |
|
634 case 0: { |
|
635 ui_unset_group(event->obj->ctx, RESOURCEVIEWER_STATE_PROP_XML); |
|
636 break; |
|
637 } |
|
638 case 1: { |
|
639 ui_set_group(event->obj->ctx, RESOURCEVIEWER_STATE_PROP_XML); |
|
640 char *ns = ui_get(res->property_ns); |
|
641 char *nsdef = ui_get(res->property_nsdef); |
|
642 if(strlen(nsdef) == 0) { |
|
643 cxmutstr def = cx_asprintf("xmlns:x0=\"%s\"", ns); |
|
644 ui_set(res->property_nsdef, def.ptr); |
|
645 free(def.ptr); |
|
646 } |
|
647 |
|
648 break; |
|
649 } |
|
650 } |
|
651 } |
|
652 |
|
653 static void edit_property_dialog(DavResourceViewer *res, const char *title, DavPropertyList *prop) { |
|
654 res->edit_property = prop; |
|
655 |
|
656 UiObject *obj = ui_dialog_window(res->obj, |
|
657 .title = title, |
|
658 .show_closebutton = UI_OFF, |
|
659 .lbutton1 = "Cancel", |
|
660 .rbutton4 = "Save", |
|
661 .default_button = 4, |
|
662 .onclick = propertydialog_action, |
|
663 .onclickdata = res, |
|
664 .width = 600, |
|
665 .height = 500); |
|
666 |
|
667 ui_grid(obj, .margin = 16, .columnspacing = 8, .rowspacing = 12) { |
|
668 ui_llabel(obj, .label = "Namespace"); |
|
669 ui_textfield(obj, .hexpand = TRUE, .value = res->property_ns); |
|
670 ui_newline(obj); |
|
671 |
|
672 ui_llabel(obj, .label = "Property Name"); |
|
673 ui_textfield(obj, .hexpand = TRUE, .value = res->property_name); |
|
674 ui_newline(obj); |
|
675 |
|
676 ui_llabel(obj, .label = "Type"); |
|
677 ui_hbox(obj, .spacing = 8, .colspan = 2) { |
|
678 ui_radiobutton(obj, .label = "Text", .value = res->property_type, .onchange = prop_type_changed, .onchangedata = res); |
|
679 ui_radiobutton(obj, .label = "XML", .value = res->property_type, .onchange = prop_type_changed, .onchangedata = res); |
|
680 } |
|
681 ui_newline(obj); |
|
682 |
|
683 ui_llabel(obj, .label = "Namespace Declarations"); |
|
684 ui_textfield(obj, .hexpand = TRUE, .value = res->property_nsdef, .groups = UI_GROUPS(RESOURCEVIEWER_STATE_PROP_XML)); |
|
685 ui_newline(obj); |
|
686 |
|
687 ui_textarea(obj, .value = res->property_value, .hexpand = TRUE, .vexpand = TRUE, .colspan = 2); |
|
688 ui_newline(obj); |
|
689 |
|
690 ui_llabel(obj, .colspan = 2, .value = res->property_errormsg); |
|
691 } |
|
692 |
|
693 if(prop && prop->ns && prop->name) { |
|
694 ui_set(res->property_ns, prop->ns); |
|
695 ui_set(res->property_name, prop->name); |
|
696 if(prop->value_full) { |
|
697 ui_set(res->property_type, 0); |
|
698 ui_set(res->property_nsdef, ""); |
|
699 ui_set(res->property_value, prop->value_full); |
|
700 ui_unset_group(obj->ctx, RESOURCEVIEWER_STATE_PROP_XML); |
|
701 } else if(prop->xml) { |
|
702 ui_set(res->property_type, 1); |
|
703 cxmutstr xml; |
|
704 cxmutstr nsdef; |
|
705 property_xml2str(prop->xml, prop->ns, &xml, &nsdef); |
|
706 ui_set(res->property_nsdef, nsdef.ptr); |
|
707 ui_set(res->property_value, xml.ptr); |
|
708 free(xml.ptr); |
|
709 free(nsdef.ptr); |
|
710 ui_set_group(obj->ctx, RESOURCEVIEWER_STATE_PROP_XML); |
|
711 } |
|
712 } else { |
|
713 ui_set(res->property_ns, ""); |
|
714 ui_set(res->property_name, ""); |
|
715 ui_set(res->property_nsdef, ""); |
|
716 ui_set(res->property_type, 0); |
|
717 ui_set(res->property_value, ""); |
|
718 } |
|
719 |
|
720 ui_set(res->property_errormsg, ""); |
|
721 |
|
722 ui_show(obj); |
|
723 } |
|
724 |
|
725 void action_resourceviewer_property_add(UiEvent *event, void *data) { |
|
726 DavResourceViewer *doc = event->document; |
|
727 edit_property_dialog(doc, "Add Property", NULL); |
|
728 } |
|
729 |
|
730 void action_resourceviewer_property_edit(UiEvent *event, void *data) { |
|
731 DavResourceViewer *doc = event->document; |
|
732 edit_property_dialog(doc, "Edit Property", doc->selected_property); |
|
733 } |
|
734 |
|
735 void action_resourceviewer_property_remove(UiEvent *event, void *data) { |
|
736 DavResourceViewer *doc = event->document; |
|
737 if(!doc->selected_property) { |
|
738 return; // shouldn't happen |
|
739 } |
|
740 dav_resourceviewer_property_remove(doc, doc->selected_property); |
|
741 } |
|
742 |