/* * moofileselector-prefs.c * * Copyright (C) 2004-2010 by Yevgen Muntyan * * This file is part of medit. medit 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.1 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public * License along with medit. If not, see . */ #include "moofileselector.h" #include "mooutils/mooprefspage.h" #include "mooutils/mooutils-treeview.h" #include "mooutils/mooutils.h" #include "mooutils/mooi18n.h" #include "mooutils/moostock.h" #include "mooutils/moohelp.h" #include "moo-help-sections.h" #include "plugins/moofileselector-prefs-gxml.h" #include #include enum { COLUMN_LABEL, COLUMN_COMMAND, COLUMN_EXTENSIONS, COLUMN_MIMETYPES, N_COLUMNS }; static void prefs_page_apply (PrefsPageXml *gxml); static void prefs_page_init (PrefsPageXml *gxml); static gboolean helper_new_row (MooTreeHelper *helper, GtkTreeModel *model, GtkTreePath *path); static gboolean helper_delete_row (MooTreeHelper *helper, GtkTreeModel *model, GtkTreePath *path); static gboolean helper_move_row (MooTreeHelper *helper, GtkTreeModel *model, GtkTreePath *old_path, GtkTreePath *new_path); static void helper_update_widgets (PrefsPageXml *gxml, GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter); static void helper_update_model (MooTreeHelper *helper, GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, PrefsPageXml *gxml); GtkWidget * _moo_file_selector_prefs_page (MooPlugin *plugin) { GtkWidget *page; GtkTreeViewColumn *column; GtkCellRenderer *cell; GtkListStore *store; MooTreeHelper *helper; PrefsPageXml *gxml; page = moo_prefs_page_new (_("File Selector"), MOO_STOCK_FILE_SELECTOR); gxml = prefs_page_xml_new_with_root (page); g_signal_connect_swapped (page, "apply", G_CALLBACK (prefs_page_apply), gxml); g_signal_connect_swapped (page, "init", G_CALLBACK (prefs_page_init), gxml); moo_help_set_id (page, HELP_SECTION_PREFS_FILE_SELECTOR); column = gtk_tree_view_column_new (); gtk_tree_view_append_column (gxml->treeview, column); cell = gtk_cell_renderer_text_new (); gtk_tree_view_column_pack_start (column, cell, TRUE); gtk_tree_view_column_set_attributes (column, cell, "text", COLUMN_LABEL, NULL); store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model (gxml->treeview, GTK_TREE_MODEL (store)); g_object_unref (store); helper = _moo_tree_helper_new (GTK_WIDGET (gxml->treeview), GTK_WIDGET (gxml->new_), GTK_WIDGET (gxml->delete_), GTK_WIDGET (gxml->up), GTK_WIDGET (gxml->down)); g_signal_connect (helper, "new-row", G_CALLBACK (helper_new_row), NULL); g_signal_connect (helper, "delete-row", G_CALLBACK (helper_delete_row), NULL); g_signal_connect (helper, "move-row", G_CALLBACK (helper_move_row), NULL); g_signal_connect_swapped (helper, "update-widgets", G_CALLBACK (helper_update_widgets), gxml); g_signal_connect (helper, "update-model", G_CALLBACK (helper_update_model), gxml); g_object_set_data_full (G_OBJECT (gxml->xml), "moo-tree-helper", helper, g_object_unref); g_object_set_data (G_OBJECT (gxml->xml), "moo-file-selector-plugin", plugin); return GTK_WIDGET (page); } static void save_store (MooTreeHelper *helper, GtkTreeModel *model) { MooMarkupNode *doc; MooMarkupNode *root; GtkTreeIter iter; if (!_moo_tree_helper_get_modified (helper)) return; _moo_tree_helper_set_modified (helper, FALSE); doc = moo_prefs_get_markup (MOO_PREFS_RC); g_return_if_fail (doc != NULL); root = moo_markup_get_element (doc, "MooFileView/Tools"); if (root) moo_markup_delete_node (root); if (!gtk_tree_model_get_iter_first (model, &iter)) return; root = moo_markup_create_element (doc, "MooFileView/Tools"); do { MooMarkupNode *node; char *label, *extensions, *mimetypes, *command; gtk_tree_model_get (model, &iter, COLUMN_LABEL, &label, COLUMN_COMMAND, &command, COLUMN_EXTENSIONS, &extensions, COLUMN_MIMETYPES, &mimetypes, -1); if (command) g_strstrip (command); if (extensions) g_strstrip (extensions); if (mimetypes) g_strstrip (mimetypes); if (command && !command[0]) { g_free (command); command = NULL; } if (extensions && !extensions[0]) { g_free (extensions); extensions = NULL; } if (mimetypes && !mimetypes[0]) { g_free (mimetypes); mimetypes = NULL; } if (!label && !command) { g_warning ("neither label nor command given"); g_free (label); g_free (command); g_free (extensions); g_free (mimetypes); continue; } if (command) node = moo_markup_create_text_element (root, "tool", command); else node = moo_markup_create_element (root, "tool"); if (label) moo_markup_set_prop (node, "label", label); if (extensions) moo_markup_set_prop (node, "extensions", extensions); if (mimetypes) moo_markup_set_prop (node, "mimetypes", mimetypes); } while (gtk_tree_model_iter_next (model, &iter)); } static void prefs_page_apply (PrefsPageXml *gxml) { gpointer store = gtk_tree_view_get_model (gxml->treeview); MooTreeHelper *helper = g_object_get_data (G_OBJECT (gxml->xml), "moo-tree-helper"); _moo_tree_helper_update_model (helper, NULL, NULL); save_store (helper, store); _moo_file_selector_update_tools (g_object_get_data (G_OBJECT (gxml->xml), "moo-file-selector-plugin")); } static void populate_store (GtkListStore *store) { MooMarkupNode *doc; MooMarkupNode *root, *child; gtk_list_store_clear (store); doc = moo_prefs_get_markup (MOO_PREFS_RC); g_return_if_fail (doc != NULL); root = moo_markup_get_element (doc, "MooFileView/Tools"); if (!root) return; for (child = root->children; child != NULL; child = child->next) { const char *label, *extensions, *mimetypes; const char *command; GtkTreeIter iter; if (!MOO_MARKUP_IS_ELEMENT (child)) continue; if (strcmp (child->name, "tool")) { g_warning ("unknown node '%s'", child->name); continue; } label = moo_markup_get_prop (child, "label"); extensions = moo_markup_get_prop (child, "extensions"); mimetypes = moo_markup_get_prop (child, "mimetypes"); command = moo_markup_get_content (child); if (!label) { g_warning ("label missing"); continue; } if (!command) { g_warning ("command missing"); continue; } gtk_list_store_append (store, &iter); gtk_list_store_set (store, &iter, COLUMN_LABEL, label, COLUMN_COMMAND, command, COLUMN_EXTENSIONS, extensions, COLUMN_MIMETYPES, mimetypes, -1); } } static void prefs_page_init (PrefsPageXml *gxml) { gpointer store = gtk_tree_view_get_model (gxml->treeview); populate_store (store); _moo_tree_view_select_first (gxml->treeview); _moo_tree_helper_update_widgets (g_object_get_data (G_OBJECT (gxml->xml), "moo-tree-helper")); _moo_tree_helper_set_modified (g_object_get_data (G_OBJECT (gxml->xml), "moo-tree-helper"), FALSE); } static gboolean helper_new_row (MooTreeHelper *helper, GtkTreeModel *model, GtkTreePath *path) { GtkTreeIter iter; int pos; g_return_val_if_fail (helper != NULL, FALSE); g_return_val_if_fail (GTK_IS_LIST_STORE (model), FALSE); g_return_val_if_fail (gtk_tree_path_get_depth (path) == 1, FALSE); pos = gtk_tree_path_get_indices(path)[0]; gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, pos, COLUMN_LABEL, "Program", COLUMN_COMMAND, "program %f", -1); return TRUE; } static gboolean helper_delete_row (MooTreeHelper *helper, GtkTreeModel *model, GtkTreePath *path) { GtkTreeIter iter; g_return_val_if_fail (helper != NULL, FALSE); g_return_val_if_fail (GTK_IS_LIST_STORE (model), FALSE); if (gtk_tree_model_get_iter (model, &iter, path)) { gtk_list_store_remove (GTK_LIST_STORE (model), &iter); return TRUE; } g_return_val_if_reached (FALSE); } static gboolean helper_move_row (MooTreeHelper *helper, GtkTreeModel *model, GtkTreePath *old_path, GtkTreePath *new_path) { GtkTreeIter iter, position; g_return_val_if_fail (helper != NULL, FALSE); g_return_val_if_fail (GTK_IS_LIST_STORE (model), FALSE); gtk_tree_model_get_iter (model, &iter, old_path); gtk_tree_model_get_iter (model, &position, new_path); if (gtk_tree_path_compare (old_path, new_path) > 0) gtk_list_store_move_before (GTK_LIST_STORE (model), &iter, &position); else gtk_list_store_move_after (GTK_LIST_STORE (model), &iter, &position); return TRUE; } static void helper_update_widgets (PrefsPageXml *gxml, GtkTreeModel *model, G_GNUC_UNUSED GtkTreePath *path, GtkTreeIter *iter) { char *label = NULL, *command = NULL, *extensions = NULL, *mimetypes = NULL; gboolean sensitive = FALSE; if (model && iter) { sensitive = TRUE; gtk_tree_model_get (model, iter, COLUMN_LABEL, &label, COLUMN_COMMAND, &command, COLUMN_EXTENSIONS, &extensions, COLUMN_MIMETYPES, &mimetypes, -1); } gtk_entry_set_text (gxml->label, MOO_NZS (label)); gtk_entry_set_text (gxml->command, MOO_NZS (command)); gtk_entry_set_text (gxml->extensions, MOO_NZS (extensions)); gtk_entry_set_text (gxml->mimetypes, MOO_NZS (mimetypes)); gtk_widget_set_sensitive (GTK_WIDGET (gxml->table), sensitive); g_free (label); g_free (command); g_free (extensions); g_free (mimetypes); } static void helper_update_model (MooTreeHelper *helper, G_GNUC_UNUSED GtkTreeModel *model, G_GNUC_UNUSED GtkTreePath *path, GtkTreeIter *iter, PrefsPageXml *gxml) { const char *label, *command, *extensions, *mimetypes; label = gtk_entry_get_text (gxml->label); command = gtk_entry_get_text (gxml->command); extensions = gtk_entry_get_text (gxml->extensions); mimetypes = gtk_entry_get_text (gxml->mimetypes); _moo_tree_helper_set (helper, iter, COLUMN_LABEL, label[0] ? label : NULL, COLUMN_COMMAND, command[0] ? command : NULL, COLUMN_EXTENSIONS, extensions[0] ? extensions : NULL, COLUMN_MIMETYPES, mimetypes[0] ? mimetypes : NULL, -1); }