1 #include "pluma-file-browser-messages.h"
2 #include "pluma-file-browser-store.h"
3 #include <pluma/pluma-message.h>
4
5 #define MESSAGE_OBJECT_PATH "/plugins/filebrowser"
6 #define WINDOW_DATA_KEY "PlumaFileBrowserMessagesWindowData"
7
8 #define BUS_CONNECT(bus, name, data) pluma_message_bus_connect(bus, MESSAGE_OBJECT_PATH, #name, (PlumaMessageCallback) message_##name##_cb, data, NULL)
9
10 typedef struct
11 {
12 PlumaWindow *window;
13 PlumaMessage *message;
14 } MessageCacheData;
15
16 typedef struct
17 {
18 guint row_inserted_id;
19 guint row_deleted_id;
20 guint root_changed_id;
21 guint begin_loading_id;
22 guint end_loading_id;
23
24 GList *merge_ids;
25 GtkActionGroup *merged_actions;
26
27 PlumaMessageBus *bus;
28 PlumaFileBrowserWidget *widget;
29 GHashTable *row_tracking;
30
31 GHashTable *filters;
32 } WindowData;
33
34 typedef struct
35 {
36 gulong id;
37
38 PlumaWindow *window;
39 PlumaMessage *message;
40 } FilterData;
41
42 static WindowData *
window_data_new(PlumaWindow * window,PlumaFileBrowserWidget * widget)43 window_data_new (PlumaWindow *window,
44 PlumaFileBrowserWidget *widget)
45 {
46 WindowData *data = g_slice_new (WindowData);
47 GtkUIManager *manager;
48 GList *groups;
49
50 data->bus = pluma_window_get_message_bus (window);
51 data->widget = widget;
52 data->row_tracking = g_hash_table_new_full (g_str_hash,
53 g_str_equal,
54 (GDestroyNotify)g_free,
55 (GDestroyNotify)gtk_tree_row_reference_free);
56
57 data->filters = g_hash_table_new_full (g_str_hash,
58 g_str_equal,
59 (GDestroyNotify)g_free,
60 NULL);
61
62 manager = pluma_file_browser_widget_get_ui_manager (widget);
63
64 data->merge_ids = NULL;
65 data->merged_actions = gtk_action_group_new ("MessageMergedActions");
66
67 groups = gtk_ui_manager_get_action_groups (manager);
68 gtk_ui_manager_insert_action_group (manager, data->merged_actions, g_list_length (groups));
69
70 g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, data);
71
72 return data;
73 }
74
75 static WindowData *
get_window_data(PlumaWindow * window)76 get_window_data (PlumaWindow * window)
77 {
78 return (WindowData *) (g_object_get_data (G_OBJECT (window), WINDOW_DATA_KEY));
79 }
80
81 static void
window_data_free(PlumaWindow * window)82 window_data_free (PlumaWindow *window)
83 {
84 WindowData *data = get_window_data (window);
85 GtkUIManager *manager;
86 GList *item;
87
88 g_hash_table_destroy (data->row_tracking);
89 g_hash_table_destroy (data->filters);
90
91 manager = pluma_file_browser_widget_get_ui_manager (data->widget);
92 gtk_ui_manager_remove_action_group (manager, data->merged_actions);
93
94 for (item = data->merge_ids; item; item = item->next)
95 gtk_ui_manager_remove_ui (manager, GPOINTER_TO_INT (item->data));
96
97 g_list_free (data->merge_ids);
98 g_object_unref (data->merged_actions);
99
100 g_slice_free (WindowData, data);
101
102 g_object_set_data (G_OBJECT (window), WINDOW_DATA_KEY, NULL);
103 }
104
105 static FilterData *
filter_data_new(PlumaWindow * window,PlumaMessage * message)106 filter_data_new (PlumaWindow *window,
107 PlumaMessage *message)
108 {
109 FilterData *data = g_slice_new (FilterData);
110 WindowData *wdata;
111
112 data->window = window;
113 data->id = 0;
114 data->message = message;
115
116 wdata = get_window_data (window);
117
118 g_hash_table_insert (wdata->filters,
119 pluma_message_type_identifier (pluma_message_get_object_path (message),
120 pluma_message_get_method (message)),
121 data);
122
123 return data;
124 }
125
126 static void
filter_data_free(FilterData * data)127 filter_data_free (FilterData *data)
128 {
129 WindowData *wdata = get_window_data (data->window);
130 gchar *identifier;
131
132 identifier = pluma_message_type_identifier (pluma_message_get_object_path (data->message),
133 pluma_message_get_method (data->message));
134
135 g_hash_table_remove (wdata->filters, identifier);
136 g_free (identifier);
137
138 g_object_unref (data->message);
139 g_slice_free (FilterData, data);
140 }
141
142 static GtkTreePath *
track_row_lookup(WindowData * data,const gchar * id)143 track_row_lookup (WindowData *data,
144 const gchar *id)
145 {
146 GtkTreeRowReference *ref;
147
148 ref = (GtkTreeRowReference *)g_hash_table_lookup (data->row_tracking, id);
149
150 if (!ref)
151 return NULL;
152
153 return gtk_tree_row_reference_get_path (ref);
154 }
155
156 static void
message_cache_data_free(MessageCacheData * data,GClosure * closure)157 message_cache_data_free (MessageCacheData *data,
158 GClosure *closure)
159 {
160 g_object_unref (data->message);
161 g_slice_free (MessageCacheData, data);
162 }
163
164 static MessageCacheData *
message_cache_data_new(PlumaWindow * window,PlumaMessage * message)165 message_cache_data_new (PlumaWindow *window,
166 PlumaMessage *message)
167 {
168 MessageCacheData *data = g_slice_new (MessageCacheData);
169
170 data->window = window;
171 data->message = message;
172
173 return data;
174 }
175
176 static void
message_get_root_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)177 message_get_root_cb (PlumaMessageBus *bus,
178 PlumaMessage *message,
179 WindowData *data)
180 {
181 PlumaFileBrowserStore *store;
182 gchar *uri;
183
184 store = pluma_file_browser_widget_get_browser_store (data->widget);
185 uri = pluma_file_browser_store_get_virtual_root (store);
186
187 pluma_message_set (message, "uri", uri, NULL);
188 g_free (uri);
189 }
190
191 static void
message_set_root_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)192 message_set_root_cb (PlumaMessageBus *bus,
193 PlumaMessage *message,
194 WindowData *data)
195 {
196 gchar *root = NULL;
197 gchar *virtual = NULL;
198
199 pluma_message_get (message, "uri", &root, NULL);
200
201 if (!root)
202 return;
203
204 if (pluma_message_has_key (message, "virtual"))
205 pluma_message_get (message, "virtual", &virtual, NULL);
206
207 if (virtual)
208 pluma_file_browser_widget_set_root_and_virtual_root (data->widget, root, virtual);
209 else
210 pluma_file_browser_widget_set_root (data->widget, root, TRUE);
211
212 g_free (root);
213 g_free (virtual);
214 }
215
216 static void
message_set_emblem_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)217 message_set_emblem_cb (PlumaMessageBus *bus,
218 PlumaMessage *message,
219 WindowData *data)
220 {
221 gchar *id = NULL;
222 gchar *emblem = NULL;
223 GtkTreePath *path;
224 PlumaFileBrowserStore *store;
225
226 pluma_message_get (message, "id", &id, "emblem", &emblem, NULL);
227
228 if (!id || !emblem)
229 {
230 g_free (id);
231 g_free (emblem);
232
233 return;
234 }
235
236 path = track_row_lookup (data, id);
237
238 if (path != NULL)
239 {
240 GError *error = NULL;
241 GdkPixbuf *pixbuf;
242
243 pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
244 emblem,
245 10,
246 0,
247 &error);
248
249 if (pixbuf)
250 {
251 GValue value = { 0, };
252 GtkTreeIter iter;
253
254 store = pluma_file_browser_widget_get_browser_store (data->widget);
255
256 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
257 {
258 g_value_init (&value, GDK_TYPE_PIXBUF);
259 g_value_set_object (&value, pixbuf);
260
261 pluma_file_browser_store_set_value (store,
262 &iter,
263 PLUMA_FILE_BROWSER_STORE_COLUMN_EMBLEM,
264 &value);
265
266 g_value_unset (&value);
267 }
268
269 g_object_unref (pixbuf);
270 }
271
272 if (error)
273 g_error_free (error);
274 }
275
276 g_free (id);
277 g_free (emblem);
278 }
279
280 static gchar *
item_id(const gchar * path,const gchar * uri)281 item_id (const gchar *path,
282 const gchar *uri)
283 {
284 return g_strconcat (path, "::", uri, NULL);
285 }
286
287 static gchar *
track_row(WindowData * data,PlumaFileBrowserStore * store,GtkTreePath * path,const gchar * uri)288 track_row (WindowData *data,
289 PlumaFileBrowserStore *store,
290 GtkTreePath *path,
291 const gchar *uri)
292 {
293 GtkTreeRowReference *ref;
294 gchar *id;
295 gchar *pathstr;
296
297 pathstr = gtk_tree_path_to_string (path);
298 id = item_id (pathstr, uri);
299
300 ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (store), path);
301 g_hash_table_insert (data->row_tracking, g_strdup (id), ref);
302
303 g_free (pathstr);
304
305 return id;
306 }
307
308 static void
set_item_message(WindowData * data,GtkTreeIter * iter,GtkTreePath * path,PlumaMessage * message)309 set_item_message (WindowData *data,
310 GtkTreeIter *iter,
311 GtkTreePath *path,
312 PlumaMessage *message)
313 {
314 PlumaFileBrowserStore *store;
315 gchar *uri = NULL;
316 guint flags = 0;
317 gchar *track_id;
318
319 store = pluma_file_browser_widget_get_browser_store (data->widget);
320
321 gtk_tree_model_get (GTK_TREE_MODEL (store), iter,
322 PLUMA_FILE_BROWSER_STORE_COLUMN_URI, &uri,
323 PLUMA_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags,
324 -1);
325
326 if (!uri)
327 return;
328
329 if (path && gtk_tree_path_get_depth (path) != 0)
330 track_id = track_row (data, store, path, uri);
331 else
332 track_id = NULL;
333
334 pluma_message_set (message,
335 "id", track_id,
336 "uri", uri,
337 NULL);
338
339 if (pluma_message_has_key (message, "is_directory"))
340 {
341 pluma_message_set (message,
342 "is_directory", FILE_IS_DIR (flags),
343 NULL);
344 }
345
346 g_free (uri);
347 g_free (track_id);
348 }
349
350 static gboolean
custom_message_filter_func(PlumaFileBrowserWidget * widget,PlumaFileBrowserStore * store,GtkTreeIter * iter,FilterData * data)351 custom_message_filter_func (PlumaFileBrowserWidget *widget,
352 PlumaFileBrowserStore *store,
353 GtkTreeIter *iter,
354 FilterData *data)
355 {
356 WindowData *wdata = get_window_data (data->window);
357 gchar *uri = NULL;
358 guint flags = 0;
359 gboolean filter = FALSE;
360 GtkTreePath *path;
361
362 gtk_tree_model_get (GTK_TREE_MODEL (store), iter,
363 PLUMA_FILE_BROWSER_STORE_COLUMN_URI, &uri,
364 PLUMA_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags,
365 -1);
366
367 if (!uri || FILE_IS_DUMMY (flags))
368 {
369 g_free (uri);
370 return FALSE;
371 }
372
373 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
374 set_item_message (wdata, iter, path, data->message);
375 gtk_tree_path_free (path);
376
377 pluma_message_set (data->message, "filter", filter, NULL);
378
379 pluma_message_bus_send_message_sync (wdata->bus, data->message);
380 pluma_message_get (data->message, "filter", &filter, NULL);
381
382 return !filter;
383 }
384
385 static void
message_add_filter_cb(PlumaMessageBus * bus,PlumaMessage * message,PlumaWindow * window)386 message_add_filter_cb (PlumaMessageBus *bus,
387 PlumaMessage *message,
388 PlumaWindow *window)
389 {
390 gchar *object_path = NULL;
391 gchar *method = NULL;
392 gulong id;
393 PlumaMessageType *message_type;
394 PlumaMessage *cbmessage;
395 FilterData *filter_data;
396 WindowData *data = get_window_data (window);
397
398 pluma_message_get (message,
399 "object_path", &object_path,
400 "method", &method,
401 NULL);
402
403 // Check if there exists such a 'callback' message
404 if (!object_path || !method)
405 {
406 g_free (object_path);
407 g_free (method);
408
409 return;
410 }
411
412 message_type = pluma_message_bus_lookup (bus, object_path, method);
413
414 if (!message_type)
415 {
416 g_free (object_path);
417 g_free (method);
418
419 return;
420 }
421
422 // Check if the message type has the correct arguments
423 if (pluma_message_type_lookup (message_type, "id") != G_TYPE_STRING ||
424 pluma_message_type_lookup (message_type, "uri") != G_TYPE_STRING ||
425 pluma_message_type_lookup (message_type, "is_directory") != G_TYPE_BOOLEAN ||
426 pluma_message_type_lookup (message_type, "filter") != G_TYPE_BOOLEAN)
427 {
428 return;
429 }
430
431 cbmessage = pluma_message_type_instantiate (message_type,
432 "id", NULL,
433 "uri", NULL,
434 "is_directory", FALSE,
435 "filter", FALSE,
436 NULL);
437
438 // Register the custom filter on the widget
439 filter_data = filter_data_new (window, cbmessage);
440 id = pluma_file_browser_widget_add_filter (data->widget,
441 (PlumaFileBrowserWidgetFilterFunc)custom_message_filter_func,
442 filter_data,
443 (GDestroyNotify)filter_data_free);
444
445 filter_data->id = id;
446 }
447
448 static void
message_remove_filter_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)449 message_remove_filter_cb (PlumaMessageBus *bus,
450 PlumaMessage *message,
451 WindowData *data)
452 {
453 gulong id = 0;
454
455 pluma_message_get (message, "id", &id, NULL);
456
457 if (!id)
458 return;
459
460 pluma_file_browser_widget_remove_filter (data->widget, id);
461 }
462
463 static void
message_up_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)464 message_up_cb (PlumaMessageBus *bus,
465 PlumaMessage *message,
466 WindowData *data)
467 {
468 PlumaFileBrowserStore *store = pluma_file_browser_widget_get_browser_store (data->widget);
469
470 pluma_file_browser_store_set_virtual_root_up (store);
471 }
472
473 static void
message_history_back_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)474 message_history_back_cb (PlumaMessageBus *bus,
475 PlumaMessage *message,
476 WindowData *data)
477 {
478 pluma_file_browser_widget_history_back (data->widget);
479 }
480
481 static void
message_history_forward_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)482 message_history_forward_cb (PlumaMessageBus *bus,
483 PlumaMessage *message,
484 WindowData *data)
485 {
486 pluma_file_browser_widget_history_forward (data->widget);
487 }
488
489 static void
message_refresh_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)490 message_refresh_cb (PlumaMessageBus *bus,
491 PlumaMessage *message,
492 WindowData *data)
493 {
494 pluma_file_browser_widget_refresh (data->widget);
495 }
496
497 static void
message_set_show_hidden_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)498 message_set_show_hidden_cb (PlumaMessageBus *bus,
499 PlumaMessage *message,
500 WindowData *data)
501 {
502 gboolean active = FALSE;
503 PlumaFileBrowserStore *store;
504 PlumaFileBrowserStoreFilterMode mode;
505
506 pluma_message_get (message, "active", &active, NULL);
507
508 store = pluma_file_browser_widget_get_browser_store (data->widget);
509 mode = pluma_file_browser_store_get_filter_mode (store);
510
511 if (active)
512 mode &= ~PLUMA_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN;
513 else
514 mode |= PLUMA_FILE_BROWSER_STORE_FILTER_MODE_HIDE_HIDDEN;
515
516 pluma_file_browser_store_set_filter_mode (store, mode);
517 }
518
519 static void
message_set_show_binary_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)520 message_set_show_binary_cb (PlumaMessageBus *bus,
521 PlumaMessage *message,
522 WindowData *data)
523 {
524 gboolean active = FALSE;
525 PlumaFileBrowserStore *store;
526 PlumaFileBrowserStoreFilterMode mode;
527
528 pluma_message_get (message, "active", &active, NULL);
529
530 store = pluma_file_browser_widget_get_browser_store (data->widget);
531 mode = pluma_file_browser_store_get_filter_mode (store);
532
533 if (active)
534 mode &= ~PLUMA_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY;
535 else
536 mode |= PLUMA_FILE_BROWSER_STORE_FILTER_MODE_HIDE_BINARY;
537
538 pluma_file_browser_store_set_filter_mode (store, mode);
539 }
540
541 static void
message_show_bookmarks_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)542 message_show_bookmarks_cb (PlumaMessageBus *bus,
543 PlumaMessage *message,
544 WindowData *data)
545 {
546 pluma_file_browser_widget_show_bookmarks (data->widget);
547 }
548
549 static void
message_show_files_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)550 message_show_files_cb (PlumaMessageBus *bus,
551 PlumaMessage *message,
552 WindowData *data)
553 {
554 pluma_file_browser_widget_show_files (data->widget);
555 }
556
557 static void
message_add_context_item_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)558 message_add_context_item_cb (PlumaMessageBus *bus,
559 PlumaMessage *message,
560 WindowData *data)
561 {
562 GtkAction *action = NULL;
563 gchar *path = NULL;
564 gchar *name;
565 GtkUIManager *manager;
566 guint merge_id;
567
568 pluma_message_get (message,
569 "action", &action,
570 "path", &path,
571 NULL);
572
573 if (!action || !path)
574 {
575 if (action)
576 g_object_unref (action);
577
578 g_free (path);
579 return;
580 }
581
582 gtk_action_group_add_action (data->merged_actions, action);
583 manager = pluma_file_browser_widget_get_ui_manager (data->widget);
584 name = g_strconcat (gtk_action_get_name (action), "MenuItem", NULL);
585 merge_id = gtk_ui_manager_new_merge_id (manager);
586
587 gtk_ui_manager_add_ui (manager,
588 merge_id,
589 path,
590 name,
591 gtk_action_get_name (action),
592 GTK_UI_MANAGER_AUTO,
593 FALSE);
594
595 if (gtk_ui_manager_get_widget (manager, path))
596 {
597 data->merge_ids = g_list_prepend (data->merge_ids, GINT_TO_POINTER (merge_id));
598 pluma_message_set (message, "id", merge_id, NULL);
599 }
600 else
601 {
602 pluma_message_set (message, "id", 0, NULL);
603 }
604
605 g_object_unref (action);
606 g_free (path);
607 g_free (name);
608 }
609
610 static void
message_remove_context_item_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)611 message_remove_context_item_cb (PlumaMessageBus *bus,
612 PlumaMessage *message,
613 WindowData *data)
614 {
615 guint merge_id = 0;
616 GtkUIManager *manager;
617
618 pluma_message_get (message, "id", &merge_id, NULL);
619
620 if (merge_id == 0)
621 return;
622
623 manager = pluma_file_browser_widget_get_ui_manager (data->widget);
624
625 data->merge_ids = g_list_remove (data->merge_ids, GINT_TO_POINTER (merge_id));
626 gtk_ui_manager_remove_ui (manager, merge_id);
627 }
628
629 static void
message_get_view_cb(PlumaMessageBus * bus,PlumaMessage * message,WindowData * data)630 message_get_view_cb (PlumaMessageBus *bus,
631 PlumaMessage *message,
632 WindowData *data)
633 {
634 PlumaFileBrowserView *view;
635 view = pluma_file_browser_widget_get_browser_view (data->widget);
636
637 pluma_message_set (message, "view", view, NULL);
638 }
639
640 static void
register_methods(PlumaWindow * window,PlumaFileBrowserWidget * widget)641 register_methods (PlumaWindow *window,
642 PlumaFileBrowserWidget *widget)
643 {
644 PlumaMessageBus *bus = pluma_window_get_message_bus (window);
645 WindowData *data = get_window_data (window);
646
647 /* Register method calls */
648 pluma_message_bus_register (bus,
649 MESSAGE_OBJECT_PATH, "get_root",
650 1,
651 "uri", G_TYPE_STRING,
652 NULL);
653
654 pluma_message_bus_register (bus,
655 MESSAGE_OBJECT_PATH, "set_root",
656 1,
657 "uri", G_TYPE_STRING,
658 "virtual", G_TYPE_STRING,
659 NULL);
660
661 pluma_message_bus_register (bus,
662 MESSAGE_OBJECT_PATH, "set_emblem",
663 0,
664 "id", G_TYPE_STRING,
665 "emblem", G_TYPE_STRING,
666 NULL);
667
668 pluma_message_bus_register (bus,
669 MESSAGE_OBJECT_PATH, "add_filter",
670 1,
671 "object_path", G_TYPE_STRING,
672 "method", G_TYPE_STRING,
673 "id", G_TYPE_ULONG,
674 NULL);
675
676 pluma_message_bus_register (bus,
677 MESSAGE_OBJECT_PATH, "remove_filter",
678 0,
679 "id", G_TYPE_ULONG,
680 NULL);
681
682 pluma_message_bus_register (bus,
683 MESSAGE_OBJECT_PATH, "add_context_item",
684 1,
685 "action", GTK_TYPE_ACTION,
686 "path", G_TYPE_STRING,
687 "id", G_TYPE_UINT,
688 NULL);
689
690 pluma_message_bus_register (bus,
691 MESSAGE_OBJECT_PATH, "remove_context_item",
692 0,
693 "id", G_TYPE_UINT,
694 NULL);
695
696 pluma_message_bus_register (bus, MESSAGE_OBJECT_PATH, "up", 0, NULL);
697
698 pluma_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_back", 0, NULL);
699 pluma_message_bus_register (bus, MESSAGE_OBJECT_PATH, "history_forward", 0, NULL);
700
701 pluma_message_bus_register (bus, MESSAGE_OBJECT_PATH, "refresh", 0, NULL);
702
703 pluma_message_bus_register (bus,
704 MESSAGE_OBJECT_PATH, "set_show_hidden",
705 0,
706 "active", G_TYPE_BOOLEAN,
707 NULL);
708 pluma_message_bus_register (bus,
709 MESSAGE_OBJECT_PATH, "set_show_binary",
710 0,
711 "active", G_TYPE_BOOLEAN,
712 NULL);
713
714 pluma_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_bookmarks", 0, NULL);
715 pluma_message_bus_register (bus, MESSAGE_OBJECT_PATH, "show_files", 0, NULL);
716
717 pluma_message_bus_register (bus,
718 MESSAGE_OBJECT_PATH, "get_view",
719 1,
720 "view", PLUMA_TYPE_FILE_BROWSER_VIEW,
721 NULL);
722
723 BUS_CONNECT (bus, get_root, data);
724 BUS_CONNECT (bus, set_root, data);
725 BUS_CONNECT (bus, set_emblem, data);
726 BUS_CONNECT (bus, add_filter, window);
727 BUS_CONNECT (bus, remove_filter, data);
728
729 BUS_CONNECT (bus, add_context_item, data);
730 BUS_CONNECT (bus, remove_context_item, data);
731
732 BUS_CONNECT (bus, up, data);
733 BUS_CONNECT (bus, history_back, data);
734 BUS_CONNECT (bus, history_forward, data);
735
736 BUS_CONNECT (bus, refresh, data);
737
738 BUS_CONNECT (bus, set_show_hidden, data);
739 BUS_CONNECT (bus, set_show_binary, data);
740
741 BUS_CONNECT (bus, show_bookmarks, data);
742 BUS_CONNECT (bus, show_files, data);
743
744 BUS_CONNECT (bus, get_view, data);
745 }
746
747 static void
store_row_inserted(PlumaFileBrowserStore * store,GtkTreePath * path,GtkTreeIter * iter,MessageCacheData * data)748 store_row_inserted (PlumaFileBrowserStore *store,
749 GtkTreePath *path,
750 GtkTreeIter *iter,
751 MessageCacheData *data)
752 {
753 gchar *uri = NULL;
754 guint flags = 0;
755
756 gtk_tree_model_get (GTK_TREE_MODEL (store), iter,
757 PLUMA_FILE_BROWSER_STORE_COLUMN_URI, &uri,
758 PLUMA_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags,
759 -1);
760
761 if (!FILE_IS_DUMMY (flags) && !FILE_IS_FILTERED (flags))
762 {
763 WindowData *wdata = get_window_data (data->window);
764
765 set_item_message (wdata, iter, path, data->message);
766 pluma_message_bus_send_message_sync (wdata->bus, data->message);
767 }
768
769 g_free (uri);
770 }
771
772 static void
store_row_deleted(PlumaFileBrowserStore * store,GtkTreePath * path,MessageCacheData * data)773 store_row_deleted (PlumaFileBrowserStore *store,
774 GtkTreePath *path,
775 MessageCacheData *data)
776 {
777 GtkTreeIter iter;
778 gchar *uri = NULL;
779 guint flags = 0;
780
781 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
782 return;
783
784 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter,
785 PLUMA_FILE_BROWSER_STORE_COLUMN_URI, &uri,
786 PLUMA_FILE_BROWSER_STORE_COLUMN_FLAGS, &flags,
787 -1);
788
789 if (!FILE_IS_DUMMY (flags) && !FILE_IS_FILTERED (flags))
790 {
791 WindowData *wdata = get_window_data (data->window);
792
793 set_item_message (wdata, &iter, path, data->message);
794 pluma_message_bus_send_message_sync (wdata->bus, data->message);
795 }
796
797 g_free (uri);
798 }
799
800 static void
store_virtual_root_changed(PlumaFileBrowserStore * store,GParamSpec * spec,MessageCacheData * data)801 store_virtual_root_changed (PlumaFileBrowserStore *store,
802 GParamSpec *spec,
803 MessageCacheData *data)
804 {
805 WindowData *wdata = get_window_data (data->window);
806 gchar *uri;
807
808 uri = pluma_file_browser_store_get_virtual_root (store);
809
810 if (!uri)
811 return;
812
813 pluma_message_set (data->message,
814 "uri", uri,
815 NULL);
816
817 pluma_message_bus_send_message_sync (wdata->bus, data->message);
818
819 g_free (uri);
820 }
821
822 static void
store_begin_loading(PlumaFileBrowserStore * store,GtkTreeIter * iter,MessageCacheData * data)823 store_begin_loading (PlumaFileBrowserStore *store,
824 GtkTreeIter *iter,
825 MessageCacheData *data)
826 {
827 GtkTreePath *path;
828 WindowData *wdata = get_window_data (data->window);
829
830 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
831
832 set_item_message (wdata, iter, path, data->message);
833
834 pluma_message_bus_send_message_sync (wdata->bus, data->message);
835 gtk_tree_path_free (path);
836 }
837
838 static void
store_end_loading(PlumaFileBrowserStore * store,GtkTreeIter * iter,MessageCacheData * data)839 store_end_loading (PlumaFileBrowserStore *store,
840 GtkTreeIter *iter,
841 MessageCacheData *data)
842 {
843 GtkTreePath *path;
844 WindowData *wdata = get_window_data (data->window);
845
846 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
847
848 set_item_message (wdata, iter, path, data->message);
849
850 pluma_message_bus_send_message_sync (wdata->bus, data->message);
851 gtk_tree_path_free (path);
852 }
853
854 static void
register_signals(PlumaWindow * window,PlumaFileBrowserWidget * widget)855 register_signals (PlumaWindow *window,
856 PlumaFileBrowserWidget *widget)
857 {
858 PlumaMessageBus *bus = pluma_window_get_message_bus (window);
859 PlumaFileBrowserStore *store;
860 PlumaMessageType *inserted_type;
861 PlumaMessageType *deleted_type;
862 PlumaMessageType *begin_loading_type;
863 PlumaMessageType *end_loading_type;
864 PlumaMessageType *root_changed_type;
865
866 PlumaMessage *message;
867 WindowData *data;
868
869 /* Register signals */
870 root_changed_type = pluma_message_bus_register (bus,
871 MESSAGE_OBJECT_PATH, "root_changed",
872 0,
873 "id", G_TYPE_STRING,
874 "uri", G_TYPE_STRING,
875 NULL);
876
877 begin_loading_type = pluma_message_bus_register (bus,
878 MESSAGE_OBJECT_PATH, "begin_loading",
879 0,
880 "id", G_TYPE_STRING,
881 "uri", G_TYPE_STRING,
882 NULL);
883
884 end_loading_type = pluma_message_bus_register (bus,
885 MESSAGE_OBJECT_PATH, "end_loading",
886 0,
887 "id", G_TYPE_STRING,
888 "uri", G_TYPE_STRING,
889 NULL);
890
891 inserted_type = pluma_message_bus_register (bus,
892 MESSAGE_OBJECT_PATH, "inserted",
893 0,
894 "id", G_TYPE_STRING,
895 "uri", G_TYPE_STRING,
896 "is_directory", G_TYPE_BOOLEAN,
897 NULL);
898
899 deleted_type = pluma_message_bus_register (bus,
900 MESSAGE_OBJECT_PATH, "deleted",
901 0,
902 "id", G_TYPE_STRING,
903 "uri", G_TYPE_STRING,
904 "is_directory", G_TYPE_BOOLEAN,
905 NULL);
906
907 store = pluma_file_browser_widget_get_browser_store (widget);
908
909 message = pluma_message_type_instantiate (inserted_type,
910 "id", NULL,
911 "uri", NULL,
912 "is_directory", FALSE,
913 NULL);
914
915 data = get_window_data (window);
916
917 data->row_inserted_id =
918 g_signal_connect_data (store,
919 "row-inserted",
920 G_CALLBACK (store_row_inserted),
921 message_cache_data_new (window, message),
922 (GClosureNotify)message_cache_data_free,
923 0);
924
925 message = pluma_message_type_instantiate (deleted_type,
926 "id", NULL,
927 "uri", NULL,
928 "is_directory", FALSE,
929 NULL);
930 data->row_deleted_id =
931 g_signal_connect_data (store,
932 "row-deleted",
933 G_CALLBACK (store_row_deleted),
934 message_cache_data_new (window, message),
935 (GClosureNotify)message_cache_data_free,
936 0);
937
938 message = pluma_message_type_instantiate (root_changed_type,
939 "id", NULL,
940 "uri", NULL,
941 NULL);
942 data->root_changed_id =
943 g_signal_connect_data (store,
944 "notify::virtual-root",
945 G_CALLBACK (store_virtual_root_changed),
946 message_cache_data_new (window, message),
947 (GClosureNotify)message_cache_data_free,
948 0);
949
950 message = pluma_message_type_instantiate (begin_loading_type,
951 "id", NULL,
952 "uri", NULL,
953 NULL);
954 data->begin_loading_id =
955 g_signal_connect_data (store,
956 "begin_loading",
957 G_CALLBACK (store_begin_loading),
958 message_cache_data_new (window, message),
959 (GClosureNotify)message_cache_data_free,
960 0);
961
962 message = pluma_message_type_instantiate (end_loading_type,
963 "id", NULL,
964 "uri", NULL,
965 NULL);
966 data->end_loading_id =
967 g_signal_connect_data (store,
968 "end_loading",
969 G_CALLBACK (store_end_loading),
970 message_cache_data_new (window, message),
971 (GClosureNotify)message_cache_data_free,
972 0);
973 }
974
975 static void
message_unregistered(PlumaMessageBus * bus,PlumaMessageType * message_type,PlumaWindow * window)976 message_unregistered (PlumaMessageBus *bus,
977 PlumaMessageType *message_type,
978 PlumaWindow *window)
979 {
980 gchar *identifier = pluma_message_type_identifier (pluma_message_type_get_object_path (message_type),
981 pluma_message_type_get_method (message_type));
982 FilterData *data;
983 WindowData *wdata = get_window_data (window);
984
985 data = g_hash_table_lookup (wdata->filters, identifier);
986
987 if (data)
988 pluma_file_browser_widget_remove_filter (wdata->widget, data->id);
989
990 g_free (identifier);
991 }
992
993 void
pluma_file_browser_messages_register(PlumaWindow * window,PlumaFileBrowserWidget * widget)994 pluma_file_browser_messages_register (PlumaWindow *window,
995 PlumaFileBrowserWidget *widget)
996 {
997 window_data_new (window, widget);
998
999 register_methods (window, widget);
1000 register_signals (window, widget);
1001
1002 g_signal_connect (pluma_window_get_message_bus (window),
1003 "unregistered",
1004 G_CALLBACK (message_unregistered),
1005 window);
1006 }
1007
1008 static void
cleanup_signals(PlumaWindow * window)1009 cleanup_signals (PlumaWindow *window)
1010 {
1011 WindowData *data = get_window_data (window);
1012 PlumaFileBrowserStore *store;
1013
1014 store = pluma_file_browser_widget_get_browser_store (data->widget);
1015
1016 g_signal_handler_disconnect (store, data->row_inserted_id);
1017 g_signal_handler_disconnect (store, data->row_deleted_id);
1018 g_signal_handler_disconnect (store, data->root_changed_id);
1019 g_signal_handler_disconnect (store, data->begin_loading_id);
1020 g_signal_handler_disconnect (store, data->end_loading_id);
1021
1022 g_signal_handlers_disconnect_by_func (data->bus, message_unregistered, window);
1023 }
1024
1025 void
pluma_file_browser_messages_unregister(PlumaWindow * window)1026 pluma_file_browser_messages_unregister (PlumaWindow *window)
1027 {
1028 PlumaMessageBus *bus = pluma_window_get_message_bus (window);
1029
1030 cleanup_signals (window);
1031 pluma_message_bus_unregister_all (bus, MESSAGE_OBJECT_PATH);
1032
1033 window_data_free (window);
1034 }
1035