Update called vala api.
[stuffkeeper.git] / src / stuffkeeper-multiple-item-view.vala
blob486da50761ad416676300c0563b80437edc72f4a
1 using GLib;
2 using Gtk;
3 using Stuffkeeper;
4 public class MultipleItemTag : Gtk.CheckButton
6 private weak Stuffkeeper.DataBackend backend = null;
7 private weak List <weak Stuffkeeper.DataItem> items = null;
8 private DataTag tag = null;
9 private bool updating = false;
10 private void update_check_state()
12 int check = 0;
13 foreach (DataItem item in this.items) {
14 if(item.has_tag(tag)) check++;
16 this.set_active(false);
17 this.set_inconsistent(false);
18 if(check == this.items.length()) this.set_active(true);
19 else if (check > 0) this.set_inconsistent(true);
21 /* The following callbacks where lambda's but because of vala bug, it are actual callbacks now */
22 private void toggled_callback()
24 if(this.updating) return;
25 if(this.active) {
26 foreach(DataItem item in this.items) {
27 if(item.has_tag(this.tag) == false)
28 item.add_tag(this.tag);
30 }else{
31 foreach(DataItem item in this.items) {
32 if(item.has_tag(this.tag) == true)
33 item.remove_tag(this.tag);
37 private void item_tags_changed_callback(DataItem item)
39 if(this.updating) return;
40 this.updating = true;
41 update_check_state();
42 this.updating = false;
44 private void database_locked(ParamSpec arg1)
46 this.set_sensitive(!this.backend.get_locked());
48 public MultipleItemTag (Stuffkeeper.DataBackend backend, DataTag tag, List<weak Stuffkeeper.DataItem> items)
50 this.items = items;
51 this.backend =backend;
52 this.tag = tag;
53 this.update_check_state();
54 foreach (DataItem item in this.items) {
55 item.item_tags_changed.connect(item_tags_changed_callback);
57 this.backend.notify["locked"].connect(database_locked);
58 this.set_sensitive(!this.backend.get_locked());
59 this.toggled.connect(toggled_callback);
62 public class Stuffkeeper.MultipleItemView : Gtk.VBox
64 private List <weak Stuffkeeper.DataItem> items = null;
65 private Gtk.EventBox sw_event = null;
66 private Gtk.EventBox header =null;
67 private weak Stuffkeeper.DataBackend backend = null;
68 private Gtk.VBox sw_vbox = null;
69 private Gtk.Table tag_vbox = null;
70 private Gtk.VBox items_vbox = null;
71 public MultipleItemView (Stuffkeeper.DataBackend skdb, List<weak Stuffkeeper.DataItem> items, string? custom_title)
73 this.backend = skdb;
74 /* Title box */
75 header = new Gtk.EventBox();
76 /* Color the header */
77 this.style_set.connect((source, style) => {
78 var color = source.style.bg[Gtk.StateType.SELECTED];
79 this.header.modify_bg(Gtk.StateType.NORMAL, color);
80 color = source.style.fg[Gtk.StateType.SELECTED];
81 this.header.get_child().modify_fg(Gtk.StateType.NORMAL, color);
82 color = source.style.text[Gtk.StateType.SELECTED];
83 this.header.get_child().modify_text(Gtk.StateType.NORMAL, color);
84 });
85 if(custom_title != null) {
86 var vbox = new Gtk.VBox(false, 6);
87 var header_label = new Gtk.Label("");
88 header_label.set_markup(GLib.Markup.printf_escaped("<span size='x-large' weight='bold'>%s</span>",custom_title));
89 header_label.set_alignment(0.0f, 0.5f);
90 header_label.set_padding(8,0);
91 vbox.pack_start(header_label, true, true, 0);
92 header_label = new Gtk.Label("");
93 header_label.set_markup(GLib.Markup.printf_escaped("<span size='small'>%u %s</span>", this.items.length(), "Selected items"));
94 header_label.set_alignment(0.0f, 0.5f);
95 header_label.set_padding(8,0);
96 vbox.pack_start(header_label, false, false, 0);
97 header.add(vbox);
98 } else {
99 var header_label = new Gtk.Label("");
100 header_label.set_markup(GLib.Markup.printf_escaped("<span size='x-large' weight='bold'>%u %s</span>", this.items.length(), "Selected items"));
101 header_label.set_alignment(0.0f, 0.5f);
102 header_label.set_padding(8,8);
103 header.add(header_label);
105 this.pack_start(header, false, false, 0);
106 /* The view below */
107 var sw = new Gtk.ScrolledWindow(null, null);
108 sw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC);
109 /* Color background */
110 sw_event = new Gtk.EventBox();
111 this.style_set.connect((source, style) => {
112 Gdk.Color color =source.style.white;//light[Gtk.StateType.NORMAL];
113 this.sw_event.modify_bg(Gtk.StateType.NORMAL, color);
115 sw_vbox = new Gtk.VBox(false, 6);
116 sw_vbox.border_width = 8;
117 sw.add_with_viewport(sw_event);
118 sw_event.add(sw_vbox);
119 this.pack_start(sw, true, true, 0);
120 /* Setup the view */
121 var title_labels = new Gtk.Label("");
122 title_labels.set_markup(GLib.Markup.printf_escaped("<b>%s</b>", "Items:"));
123 title_labels.set_alignment(0.0f, 0.5f);
124 title_labels.modify_fg(Gtk.StateType.NORMAL, this.style.black);
125 sw_vbox.pack_start(title_labels, false, false, 0);
126 items_vbox = new Gtk.VBox(false, 6);
127 this.sw_vbox.pack_start(items_vbox, false, false, 0);
128 /* Tag Setup */
129 var tag_label = new Gtk.Label("");
130 tag_label.set_markup(GLib.Markup.printf_escaped("<b>%s</b>", "Tags:"));
131 tag_label.set_alignment(0.0f, 0.5f);
132 tag_label.modify_fg(Gtk.StateType.NORMAL, this.style.black);
133 sw_vbox.pack_start(tag_label, false, false, 0);
134 tag_vbox = new Gtk.Table(0,0,false);
135 sw_vbox.pack_start(tag_vbox, false, false, 0);
136 reload_items(items);
137 this.backend.tag_added.connect(tag_added);
138 this.backend.tag_removed.connect(reload_tags);
139 this.show_all();
141 private void tag_added(DataTag tag)
143 reload_tags(0);
145 static int compare_func(DataTag tag1, DataTag tag2)
147 return tag1.get_title().collate(tag2.get_title());
149 private void reload_tags(uint id)
151 int column=3;
152 int items = 0;
153 var list = tag_vbox.get_children();
154 foreach(Gtk.Widget child in list) {
155 child.destroy();
157 if(this.items.length() == 0) return;
158 var taglist = this.backend.get_tags();
159 taglist.sort((GLib.CompareFunc)compare_func);
160 foreach ( DataTag tag in taglist)
162 var hbox = new Gtk.HBox (false, 6);
163 var chk = new MultipleItemTag(backend, tag, this.items);
164 hbox.pack_start(chk, false, false, 0);
165 var tlabel = new Stuffkeeper.DataLabel.tag(tag);
166 tlabel.modify_fg(Gtk.StateType.NORMAL, this.style.black);
167 tlabel.set_alignment(0.0f, 0.5f);
168 hbox.pack_start(tlabel, true, true, 0);
169 this.tag_vbox.attach(hbox, items%column, items%column+1, items/column, items/column+1,
170 Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL, Gtk.AttachOptions.EXPAND|Gtk.AttachOptions.FILL,0,0);
171 items++;
173 tag_vbox.show_all();
175 public void reload_items(List<weak Stuffkeeper.DataItem> items)
177 foreach(Gtk.Widget child in items_vbox.get_children()) {
178 child.destroy();
180 /* Copy the list */
181 this.items = items.copy();
182 foreach(DataItem item in items) {
183 var hbox = new Gtk.HBox(false, 6);
184 var button = new Gtk.Button();
185 var arrow = new Gtk.Image.from_pixbuf(item.get_schema().get_pixbuf());
186 button.relief = Gtk.ReliefStyle.NONE;
187 this.style_set.connect((source, style) => {
188 Gdk.Color color =source.style.white;//light[Gtk.StateType.NORMAL];
189 button.modify_bg(Gtk.StateType.NORMAL, color);
191 Gdk.Color color =this.style.white;//light[Gtk.StateType.NORMAL];
192 button.modify_bg(Gtk.StateType.NORMAL, color);
193 /** TODO image needs updating when schema changed it icon! */
194 hbox.pack_start(arrow, false, false,0);
195 var title = new Stuffkeeper.DataEntry(item, null);
196 hbox.pack_start(title, true, true, 0);
197 button.add(hbox);
198 items_vbox.pack_start(button, false, false, 0);
199 button.set_data<weak DataItem>("item", item);
200 button.clicked.connect((source) => {
201 DataItem fitem = button.get_data<weak DataItem>("item");
202 new Stuffkeeper.ItemWindow(fitem.get_backend(), fitem, Stuffkeeper.config_file);
205 items_vbox.show_all();
206 reload_tags(0);