/* TMut * Copyright (C) 2006-2007 Philip Van Hoof * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with self library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include "tmut-folder-view.h" #include "tmut-folder-selector.h" #include "tmut-msg-view.h" #include "tmut-ringtone-player.h" #include "tmut-shell-window.h" #include "tmut-shell-child.h" #include #include #include #include #include #include #include static GObjectClass *parent_class = NULL; typedef struct _TMutFolderViewPriv TMutFolderViewPriv; struct _TMutFolderViewPriv { GtkTreeView *headers_treeview; TnyFolderMonitor *monitor; TnyFolder *folder; TnyFolderObserver *ringtone_player; TMutShellWindow *shell; TnyAccountStore *account_store; }; #define TMUT_FOLDER_VIEW_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), TMUT_TYPE_FOLDER_VIEW, TMutFolderViewPriv)) static void status_update (GObject *sender, TnyStatus *status, gpointer user_data) { TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (user_data); if (priv->shell) gtk_progress_set_percentage (tmut_shell_window_get_progress (priv->shell), tny_status_get_fraction (status)); return; } static void on_move_done (TnyFolder *folder, gboolean canceled, GError *err, gpointer user_data) { TMutFolderView *self = TMUT_FOLDER_VIEW (user_data); TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); gchar *msg = ""; if (canceled) msg = _("User canceled the operation"); else if (err) msg = err->message; if (err || canceled) { GtkWidget *dialog = gtk_message_dialog_new ( GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (priv->shell))), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, msg); g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); gtk_widget_show_all (dialog); } g_object_unref (user_data); return; } typedef struct { TMutFolderView *self; gboolean delete_originals; TnyList *items; } OnMoveSelectedInfo; static void on_folder_selected_for_move (GtkWidget *widget, gpointer user_data) { OnMoveSelectedInfo *info = (OnMoveSelectedInfo *) user_data; TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (info->self); TnyFolderStore *into = tmut_folder_selector_get_current (TMUT_FOLDER_SELECTOR (widget)); if (into) { if (into != (TnyFolderStore *) priv->folder && TNY_IS_FOLDER (into)) tny_folder_transfer_msgs_async (priv->folder, info->items, TNY_FOLDER (into), info->delete_originals, on_move_done, status_update, g_object_ref (info->self)); g_object_unref (into); } tmut_shell_window_back (priv->shell); return; } static void on_folder_selected_for_move_destroy (GtkWidget *widget, gpointer user_data) { OnMoveSelectedInfo *info = (OnMoveSelectedInfo *) user_data; g_object_unref (info->self); g_object_unref (info->items); g_slice_free (OnMoveSelectedInfo, info); return; } static void message_movecopy_helper (TMutFolderView *self, gboolean move) { TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->headers_treeview); GtkTreeModel *model; GtkTreeIter iter; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { TnyHeader *header = NULL; gtk_tree_model_get (model, &iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); if (header) { TnyFolder *folder; TMutFolderSelector *view; OnMoveSelectedInfo *info; gboolean del_originals = TRUE; info = g_slice_new0 (OnMoveSelectedInfo); info->self = TMUT_FOLDER_VIEW (g_object_ref (self)); info->items = tny_simple_list_new (); tny_list_prepend (info->items, G_OBJECT (header)); info->delete_originals = move; view = tmut_folder_selector_new (); tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (view), priv->account_store); g_signal_connect (G_OBJECT (view), "folder-selected", G_CALLBACK (on_folder_selected_for_move), info); g_signal_connect (G_OBJECT (view), "destroy", G_CALLBACK (on_folder_selected_for_move_destroy), info); gtk_widget_show (GTK_WIDGET (view)); tmut_shell_window_set_child ( tmut_shell_child_get_window (TMUT_SHELL_CHILD (self)), TMUT_SHELL_CHILD (view), _("Select destination")); g_object_unref (header); } } return; } void tmut_folder_view_on_message_move_activated (GObject *sender, TMutFolderView *self) { message_movecopy_helper (self, TRUE); return; } void tmut_folder_view_on_message_copy_activated (GObject *sender, TMutFolderView *self) { message_movecopy_helper (self, FALSE); return; } void tmut_folder_view_on_message_delete_activated (GObject *sender, TMutFolderView *self) { TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); GtkTreeSelection *selection = gtk_tree_view_get_selection (priv->headers_treeview); GtkTreeModel *model; GtkTreeIter iter; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { TnyHeader *header = NULL; gtk_tree_model_get (model, &iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); if (header) { gchar *hstr = tny_header_dup_subject (header); GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (priv->shell), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("This will remove the message with subject \"%s\""), hstr); g_free (hstr); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) { TnyFolder *folder = tny_header_get_folder (header); tny_folder_remove_msg (folder, header, NULL); tny_folder_sync (folder, TRUE, NULL); g_object_unref (folder); } gtk_widget_destroy (dialog); g_object_unref (header); } } return; } static void popup_the_actions_menu (GtkButton *button, gpointer user_data) { GtkMenu *menu = (GtkMenu *) user_data; gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time ()); return; } static void tmut_folder_view_create_menu_default (TMutFolderView *self) { GtkMenu *menu; GtkWidget *mdel_menuitem, *mmove_menuitem, *mcopy_menuitem; GtkButton *menu_button; menu_button = GTK_BUTTON (gtk_button_new_with_label (_("Actions"))); menu = GTK_MENU (gtk_menu_new ()); mdel_menuitem = gtk_menu_item_new_with_label (_("Delete a message")); mmove_menuitem = gtk_menu_item_new_with_label (_("Move a message")); mcopy_menuitem = gtk_menu_item_new_with_label (_("Copy a message")); gtk_widget_show (mdel_menuitem); gtk_widget_show (mmove_menuitem); gtk_widget_show (mcopy_menuitem); gtk_widget_show (GTK_WIDGET (menu)); gtk_widget_show (GTK_WIDGET (menu_button)); gtk_menu_prepend (menu, mdel_menuitem); gtk_menu_prepend (menu, mmove_menuitem); gtk_menu_prepend (menu, mcopy_menuitem); gtk_menu_attach_to_widget (menu, GTK_WIDGET (menu_button), NULL); g_signal_connect (G_OBJECT (menu_button), "clicked", G_CALLBACK (popup_the_actions_menu), menu); g_signal_connect (G_OBJECT (mdel_menuitem), "activate", G_CALLBACK (tmut_folder_view_on_message_delete_activated), self); g_signal_connect (G_OBJECT (mmove_menuitem), "activate", G_CALLBACK (tmut_folder_view_on_message_move_activated), self); g_signal_connect (G_OBJECT (mcopy_menuitem), "activate", G_CALLBACK (tmut_folder_view_on_message_copy_activated), self); gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (menu_button), FALSE, TRUE, 0); return; } static void tmut_folder_view_deactivate_folder (TMutFolderViewPriv *priv) { if (priv->folder) { if (priv->ringtone_player) tny_folder_remove_observer (priv->folder, priv->ringtone_player); g_object_unref (priv->folder); } if (priv->monitor) { tny_folder_monitor_stop (priv->monitor); g_object_unref (priv->monitor); } } static void on_active_folder_got_set (TnyFolder *folder, gboolean cancelled, GError *err, gpointer user_data) { g_object_unref (user_data); return; } void tmut_folder_view_set_active_folder (TMutFolderView *self, TnyFolder *folder) { TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); GtkTreeModel *model = NULL; tmut_folder_view_deactivate_folder (priv); priv->folder = TNY_FOLDER (g_object_ref (folder)); if (!priv->ringtone_player) priv->ringtone_player = tmut_ringtone_player_new (); tny_folder_add_observer (priv->folder, priv->ringtone_player); model = tny_gtk_header_list_model_new (); tny_gtk_header_list_model_set_folder (TNY_GTK_HEADER_LIST_MODEL (model), folder, FALSE, NULL, status_update, self); /* The folder monitor makes Push E-mail work */ priv->monitor = TNY_FOLDER_MONITOR (tny_folder_monitor_new (folder)); tny_folder_monitor_add_list (priv->monitor, TNY_LIST (model)); tny_folder_monitor_start (priv->monitor); tny_folder_refresh_async (folder, on_active_folder_got_set, status_update, g_object_ref (self)); gtk_tree_view_set_model (priv->headers_treeview, model); g_object_unref (model); return; } static void tmut_folder_view_on_got_msg (TnyFolder *folder, gboolean canceled, TnyMsg *msg, GError *err, gpointer user_data) { TMutFolderView *self = TMUT_FOLDER_VIEW (user_data); TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); if (!canceled && !err) { TnyHeader *header; TnyMsgView *view = tmut_msg_view_new (priv->account_store); tny_msg_view_set_msg (view, msg); header = tny_msg_get_header (msg); tny_header_set_flag (header, TNY_HEADER_FLAG_SEEN); g_object_unref (header); gtk_widget_show (GTK_WIDGET (view)); tmut_shell_window_set_child ( tmut_shell_child_get_window (TMUT_SHELL_CHILD (self)), TMUT_SHELL_CHILD (view), NULL); } else { gchar *msg = err?err->message:"User canceled the operation"; GtkWidget *dialog = gtk_message_dialog_new ( GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (priv->shell))), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, msg); g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); gtk_widget_show_all (dialog); } g_object_unref (user_data); return; } typedef struct { TMutFolderView *self; TnyFolder *folder; TnyHeader *header; } OnWentOnlineInfo; static void on_went_online (TnyCamelAccount *account, gboolean canceled, GError *err, gpointer user_data) { OnWentOnlineInfo *info = (OnWentOnlineInfo *) user_data; TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (info->self); if (!canceled && !err && (tny_account_get_connection_status (TNY_ACCOUNT (account)) == TNY_CONNECTION_STATUS_CONNECTED)) { tny_folder_get_msg_async (info->folder, info->header, tmut_folder_view_on_got_msg, status_update, g_object_ref (info->self)); } else { gchar *msg; GtkWidget *dialog; if (err) msg = g_strdup_printf ("Can't get message: %s", err->message); else { if (tny_account_get_connection_status (TNY_ACCOUNT (account)) != TNY_CONNECTION_STATUS_CONNECTED) msg = g_strdup ("Can't get message: account not online"); else msg = g_strdup ("Can't get message: User canceled the operation"); } dialog = gtk_message_dialog_new ( GTK_WINDOW (gtk_widget_get_parent (GTK_WIDGET (priv->shell))), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, msg); g_signal_connect_swapped (dialog, "response", G_CALLBACK (gtk_widget_destroy), dialog); gtk_widget_show_all (dialog); } g_object_unref (info->self); g_object_unref (info->header); g_object_unref (info->folder); g_slice_free (OnWentOnlineInfo, info); } static void on_msg_selected (GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data) { TMutFolderView *self = TMUT_FOLDER_VIEW (user_data); TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview); GtkTreeModel *model; GtkTreeIter iter; if (gtk_tree_selection_get_selected (selection, &model, &iter)) { TnyHeader *header; TnyMsgView *view; gtk_tree_model_get (model, &iter, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &header, -1); if (header) { TnyFolder *folder = tny_header_get_folder (header); if (folder) { TnyDevice *device = tny_account_store_get_device (priv->account_store); if (!tny_device_is_online (device)) { OnWentOnlineInfo *info = g_slice_new0 (OnWentOnlineInfo); TnyAccount *account = tny_folder_get_account (folder); /* If we do this, sometimes the callback tells us the * connecting got canceled. It makes sense why (for me, * Tinymail's developer), perhaps I need to fix this * in Tinymail. For now .. we just don't do it because * it ain't really necessary (the account goes into * online, no matter what state the device is is, when * using tny_camel_account_set_online). * * tny_device_force_online (device); **/ info->folder = g_object_ref (folder); info->header = g_object_ref (header); info->self = g_object_ref (self); tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (account), TRUE, on_went_online, info); g_object_unref (account); } else { tny_folder_get_msg_async (folder, header, tmut_folder_view_on_got_msg, status_update, g_object_ref (self)); } g_object_unref (device); g_object_unref (folder); } g_object_unref (header); } } return; } static void set_common_flags (GtkCellRenderer *renderer, TnyHeaderFlags flags) { g_object_set (G_OBJECT(renderer), "weight", (flags & TNY_HEADER_FLAG_SEEN) ? PANGO_WEIGHT_NORMAL: PANGO_WEIGHT_ULTRABOLD, "strikethrough", (flags & TNY_HEADER_FLAG_DELETED) ? TRUE:FALSE, NULL); } static void header_view_compact_header_cell_data (GtkTreeViewColumn *column, GtkCellRenderer *renderer, GtkTreeModel *tree_model, GtkTreeIter *iter, gpointer user_data) { TnyHeaderFlags flags = 0; gchar *address = NULL; gchar *subject = NULL; gchar *header = NULL; time_t date; GtkCellRenderer *address_cell, *date_or_status_cell, *subject_cell, *address_box, *subject_box = NULL; TnyHeader *msg_header = NULL; gchar *display_date = NULL, *tmp_date = NULL; TnyHeaderFlags prio = 0; address_box = GTK_CELL_RENDERER (g_object_get_data (G_OBJECT (renderer), "address-box-renderer")); subject_box = GTK_CELL_RENDERER (g_object_get_data (G_OBJECT (renderer), "subject-box-renderer")); subject_cell = GTK_CELL_RENDERER (g_object_get_data (G_OBJECT (subject_box), "subject-renderer")); address_cell = GTK_CELL_RENDERER (g_object_get_data (G_OBJECT (address_box), "address-renderer")); date_or_status_cell = GTK_CELL_RENDERER (g_object_get_data (G_OBJECT (address_box), "date-renderer")); gtk_tree_model_get (tree_model, iter, TNY_GTK_HEADER_LIST_MODEL_FLAGS_COLUMN, &flags, TNY_GTK_HEADER_LIST_MODEL_FROM_COLUMN, &address, TNY_GTK_HEADER_LIST_MODEL_SUBJECT_COLUMN, &subject, TNY_GTK_HEADER_LIST_MODEL_DATE_SENT_TIME_T_COLUMN, &date, TNY_GTK_HEADER_LIST_MODEL_INSTANCE_COLUMN, &msg_header, -1); if (subject && strlen (subject)) { gchar* escaped_subject = g_markup_escape_text (subject, -1); g_object_set (G_OBJECT (subject_cell), "markup", escaped_subject, NULL); g_free (escaped_subject); } else g_object_set (G_OBJECT (subject_cell), "markup", _("No subject"), NULL); g_free (subject); set_common_flags (subject_cell, flags); header = g_markup_printf_escaped ("%s", address); g_free (address); g_object_set (G_OBJECT (address_cell), "markup", header, NULL); g_free (header); header = NULL; display_date = g_strdup_printf ("%s", date ? _get_readable_date (date) : ""); g_object_set (G_OBJECT (date_or_status_cell), "markup", display_date, NULL); g_free (tmp_date); tmp_date = NULL; g_free (display_date); display_date = NULL; if (msg_header != NULL) g_object_unref (msg_header); } static void tmut_folder_view_instance_init (GTypeInstance *instance, gpointer g_class) { TMutFolderView *self = (TMutFolderView *) instance; TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); GtkCellRenderer *renderer; GtkTreeViewColumn *column; GtkTreeSelection *select; GtkWidget *widget, *sw; GtkCellRenderer *renderer_compact_header, *renderer_addr_box, *renderer_subject, *renderer_subject_box, *renderer_addr, *renderer_compact_date_or_status; priv->account_store = NULL; priv->monitor = NULL; priv->ringtone_player = NULL; sw = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_NONE); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (sw), TRUE, TRUE, 0); gtk_widget_show (sw); priv->headers_treeview = GTK_TREE_VIEW (gtk_tree_view_new ()); gtk_tree_view_set_headers_visible (priv->headers_treeview, FALSE); #if GTK_CHECK_VERSION (2,12,0) gtk_tree_view_set_show_expanders (priv->headers_treeview, FALSE); #endif gtk_tree_view_set_rules_hint (priv->headers_treeview, TRUE); gtk_tree_view_set_fixed_height_mode (priv->headers_treeview, TRUE); gtk_widget_show (GTK_WIDGET (priv->headers_treeview)); gtk_container_add (GTK_CONTAINER (sw), GTK_WIDGET (priv->headers_treeview)); renderer_compact_header = modest_vbox_cell_renderer_new (); renderer_subject_box = modest_hbox_cell_renderer_new (); renderer_addr_box = modest_hbox_cell_renderer_new (); renderer_addr = gtk_cell_renderer_text_new (); renderer_subject = gtk_cell_renderer_text_new (); renderer_compact_date_or_status = gtk_cell_renderer_text_new (); modest_vbox_cell_renderer_append (MODEST_VBOX_CELL_RENDERER (renderer_compact_header), renderer_subject_box, FALSE); modest_vbox_cell_renderer_append (MODEST_VBOX_CELL_RENDERER (renderer_compact_header), renderer_addr_box, FALSE); modest_hbox_cell_renderer_append (MODEST_HBOX_CELL_RENDERER (renderer_subject_box), renderer_subject, TRUE); modest_hbox_cell_renderer_append (MODEST_HBOX_CELL_RENDERER (renderer_addr_box), renderer_addr, TRUE); modest_hbox_cell_renderer_append (MODEST_HBOX_CELL_RENDERER (renderer_addr_box), renderer_compact_date_or_status, FALSE); g_object_set_data (G_OBJECT (renderer_compact_header), "subject-box-renderer", renderer_subject_box); g_object_set_data (G_OBJECT (renderer_compact_header), "address-box-renderer", renderer_addr_box); g_object_set_data (G_OBJECT (renderer_subject_box), "subject-renderer", renderer_subject); g_object_set_data (G_OBJECT (renderer_addr_box), "address-renderer", renderer_addr); g_object_set_data (G_OBJECT (renderer_addr_box), "date-renderer", renderer_compact_date_or_status); g_object_set (G_OBJECT (renderer_subject_box), "yalign", 0.0, NULL); gtk_cell_renderer_set_fixed_size (renderer_subject_box, -1, 15); gtk_cell_renderer_set_fixed_size (renderer_addr_box, -1, 15); g_object_set (G_OBJECT (renderer_addr_box), "yalign", 0.0, NULL); g_object_set (G_OBJECT (renderer_subject), "ellipsize", PANGO_ELLIPSIZE_END, "yalign", 0.0, NULL); g_object_set (G_OBJECT (renderer_addr), "ellipsize", PANGO_ELLIPSIZE_END, "yalign", 0.0, NULL); g_object_set(G_OBJECT(renderer_compact_date_or_status), "xalign", 0.0, "yalign", 0.0, NULL); renderer = renderer_compact_header; column = gtk_tree_view_column_new_with_attributes (_("Subject"), renderer, NULL); gtk_tree_view_column_set_cell_data_func(column, renderer, header_view_compact_header_cell_data, NULL, NULL); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_resizable (column, FALSE); gtk_tree_view_append_column (GTK_TREE_VIEW(priv->headers_treeview), column); select = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->headers_treeview)); gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE); g_signal_connect (G_OBJECT (priv->headers_treeview), "row-activated", G_CALLBACK (on_msg_selected), self); TMUT_FOLDER_VIEW_GET_CLASS (self)->create_menu (self); return; } static void tmut_folder_view_finalize (GObject *object) { TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (object); tmut_folder_view_deactivate_folder (priv); if (priv->account_store) g_object_unref (priv->account_store); if (priv->ringtone_player) g_object_unref (priv->ringtone_player); (*parent_class->finalize) (object); return; } static void tmut_folder_view_class_init (TMutFolderViewClass *class) { GObjectClass *object_class; parent_class = g_type_class_peek_parent (class); object_class = (GObjectClass*) class; object_class->finalize = tmut_folder_view_finalize; class->create_menu= tmut_folder_view_create_menu_default; g_type_class_add_private (object_class, sizeof (TMutFolderViewPriv)); return; } /** * tmut_folder_view_new: * * * Return value: A new #TnySummaryView instance implemented for TMUT **/ TMutFolderView* tmut_folder_view_new (TnyAccountStore *account_store) { TMutFolderView *self = g_object_new (TMUT_TYPE_FOLDER_VIEW, NULL); TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); priv->account_store = TNY_ACCOUNT_STORE (g_object_ref (account_store)); return TMUT_FOLDER_VIEW (self); } TMutShellWindow* tmut_folder_view_get_window (TMutShellChild *self) { TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); return priv->shell; } void tmut_folder_view_set_window (TMutShellChild *self, TMutShellWindow *window) { TMutFolderViewPriv *priv = TMUT_FOLDER_VIEW_GET_PRIVATE (self); priv->shell = window; } static void tmut_shell_child_init (gpointer g, gpointer iface_data) { TMutShellChildIface *klass = (TMutShellChildIface *)g; klass->get_window= tmut_folder_view_get_window; klass->set_window= tmut_folder_view_set_window; return; } GType tmut_folder_view_get_type (void) { static GType type = 0; if (G_UNLIKELY(type == 0)) { static const GTypeInfo info = { sizeof (TMutFolderViewClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc) tmut_folder_view_class_init, /* class_init */ NULL, /* class_finalize */ NULL, /* class_data */ sizeof (TMutFolderView), 0, /* n_preallocs */ tmut_folder_view_instance_init /* instance_init */ }; static const GInterfaceInfo tmut_shell_child_info = { (GInterfaceInitFunc) tmut_shell_child_init, /* interface_init */ NULL, /* interface_finalize */ NULL /* interface_data */ }; type = g_type_register_static (GTK_TYPE_VBOX, "TMutFolderView", &info, 0); g_type_add_interface_static (type, TMUT_TYPE_SHELL_CHILD, &tmut_shell_child_info); } return type; }