Merge branch 'use-libfm'
[lxde/lxpanel.git] / src / plugins / xkb / xkb-plugin.c
index e216d70..411c155 100644 (file)
@@ -51,15 +51,17 @@ enum
 
 enum
 {
-    COLUMN_MODEL_NAME,
+    COLUMN_MODEL_ID,
     COLUMN_MODEL_DESC,
     NUM_MODEL_COLUMNS
 };
 
 enum
 {
-    COLUMN_CHANGE_NAME,
+    COLUMN_CHANGE_ID,
     COLUMN_CHANGE_DESC,
+    COLUMN_CHANGE_INCL,
+    COLUMN_CHANGE_WEIGHT,
     NUM_CHANGE_COLUMNS
 };
 
@@ -342,7 +344,7 @@ static int xkb_constructor(Plugin * p_plugin, char ** fp)
         p_xkb->kbd_layouts = g_strdup(symbol_name_lowercase);
         g_free(symbol_name_lowercase);
         p_xkb->kbd_variants = g_strdup(",");
-        p_xkb->kbd_change_option = g_strdup("shift_caps_toggle");
+        p_xkb->kbd_change_option = g_strdup("grp:shift_caps_toggle");
         
         xkb_mechanism_destructor(p_xkb);
     }
@@ -564,6 +566,30 @@ static void on_dialog_config_response(GtkDialog *p_dialog, gint response, gpoint
     p_xkb->p_dialog_config = NULL;
 }
 
+static void  on_cell_renderer_layout_change_incl_toggled(GtkCellRendererToggle *cell,
+                                                        gchar                 *path_str,
+                                                        gpointer               data)
+{
+    GtkTreeModel *p_model = (GtkTreeModel *)data;
+    GtkTreeIter  tree_iter;
+    GtkTreePath *p_tree_path = gtk_tree_path_new_from_string(path_str);
+    gboolean     included;
+    
+    /* get toggled iter */
+    gtk_tree_model_get_iter(p_model, &tree_iter, p_tree_path);
+    gtk_tree_model_get(p_model, &tree_iter, COLUMN_CHANGE_INCL, &included, -1);
+    
+    /* do something with the value */
+    included = !included;
+    
+    /* set new value */
+    gtk_list_store_set(GTK_LIST_STORE(p_model), &tree_iter, COLUMN_CHANGE_INCL, included, -1);
+    gtk_list_store_set(GTK_LIST_STORE(p_model), &tree_iter, COLUMN_CHANGE_WEIGHT, included ? PANGO_WEIGHT_ULTRAHEAVY : PANGO_WEIGHT_NORMAL, -1);
+    
+    /* clean up */
+    gtk_tree_path_free(p_tree_path);
+}
+
 static gboolean  on_treeviews_lists_button_press_event(GtkWidget *p_widget,
                                                        GdkEventButton *p_event,
                                                        gpointer p_data)
@@ -620,17 +646,18 @@ static void on_button_kbd_model_clicked(GtkButton *p_button, gpointer *p_data)
     gtk_container_add(GTK_CONTAINER(p_scrolledwindow_kbd_model), p_treeview_kbd_model);
     GtkCellRenderer *p_renderer;
     GtkTreeViewColumn *p_column;
-    // model
+    // model desc
     p_renderer = gtk_cell_renderer_text_new();
-    p_column = gtk_tree_view_column_new_with_attributes(_("Model"), p_renderer, "text", COLUMN_CHANGE_NAME, NULL);
-    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_NAME);
+    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_MODEL_DESC, NULL);
+    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_MODEL_DESC);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_model), p_column);
-    // desc
+    // model id
     p_renderer = gtk_cell_renderer_text_new();
-    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_CHANGE_DESC, NULL);
-    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_DESC);
+    p_column = gtk_tree_view_column_new_with_attributes(_("Id"), p_renderer, "text", COLUMN_MODEL_ID, NULL);
+    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_MODEL_ID);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_model), p_column);
     
+    
     // populate model
     GKeyFile *p_keyfile = g_key_file_new();
     gchar *xkbcfg_filepath = g_strdup_printf("%s/models.cfg", XKBCONFDIR);
@@ -645,7 +672,7 @@ static void on_button_kbd_model_clicked(GtkButton *p_button, gpointer *p_data)
             p_model_desc = g_key_file_get_string(p_keyfile, "MODELS", keys_models[model_idx], NULL);
             gtk_list_store_append(p_liststore_kbd_model, &tree_iter);
             gtk_list_store_set(p_liststore_kbd_model, &tree_iter,
-                                COLUMN_MODEL_NAME, keys_models[model_idx],
+                                COLUMN_MODEL_ID, keys_models[model_idx],
                                 COLUMN_MODEL_DESC, p_model_desc,
                                 -1);
             g_free(p_model_desc);
@@ -676,7 +703,7 @@ static void on_button_kbd_model_clicked(GtkButton *p_button, gpointer *p_data)
         {
             gchar *kbd_model_new;
             gtk_tree_model_get(GTK_TREE_MODEL(p_liststore_kbd_model),
-                               &tree_iter_sel, COLUMN_MODEL_NAME, &kbd_model_new, -1);
+                               &tree_iter_sel, COLUMN_MODEL_ID, &kbd_model_new, -1);
             g_free(p_xkb->kbd_model);
             p_xkb->kbd_model = g_strdup(kbd_model_new);
             gtk_button_set_label(GTK_BUTTON(p_xkb->p_button_kbd_model), p_xkb->kbd_model);
@@ -688,6 +715,33 @@ static void on_button_kbd_model_clicked(GtkButton *p_button, gpointer *p_data)
     gtk_widget_destroy(p_dialog);
 }
 
+static gboolean  change_opt_tree_model_foreach(GtkTreeModel *p_model,
+                                               GtkTreePath *p_path,
+                                               GtkTreeIter *p_iter,
+                                               gpointer p_data)
+{
+    XkbPlugin *p_xkb = (XkbPlugin *)p_data;
+    
+    gboolean  included;
+    
+    gtk_tree_model_get(p_model, p_iter, COLUMN_CHANGE_INCL, &included,  -1);
+    if(included)
+    {
+        gchar  *change_opt_id;
+        gtk_tree_model_get(p_model, p_iter, COLUMN_CHANGE_ID, &change_opt_id,  -1);
+        if(strlen(p_xkb->p_gstring_change_opt_partial->str))
+        {
+            g_string_append_c(p_xkb->p_gstring_change_opt_partial, ',');
+        }
+        g_string_append(p_xkb->p_gstring_change_opt_partial, change_opt_id);
+        
+        //g_printf("\npartial change opt = '%s'\n", p_xkb->p_gstring_change_opt_partial->str);
+        
+        g_free(change_opt_id);
+    }
+    return FALSE;
+}
+
 static void on_button_kbd_change_layout_clicked(GtkButton *p_button, gpointer *p_data)
 {
     XkbPlugin *p_xkb = (XkbPlugin *)p_data;
@@ -707,20 +761,31 @@ static void on_button_kbd_change_layout_clicked(GtkButton *p_button, gpointer *p
     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(p_dialog)->vbox), p_scrolledwindow_kbd_change, TRUE, TRUE, 2);
     
     // liststore
-    GtkListStore *p_liststore_kbd_change = gtk_list_store_new(NUM_CHANGE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
+    GtkListStore *p_liststore_kbd_change = gtk_list_store_new(NUM_CHANGE_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT);
     GtkWidget *p_treeview_kbd_change = gtk_tree_view_new_with_model(GTK_TREE_MODEL(p_liststore_kbd_change));
     g_object_unref(G_OBJECT(p_liststore_kbd_change));
     gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(p_treeview_kbd_change), TRUE);
     gtk_container_add(GTK_CONTAINER(p_scrolledwindow_kbd_change), p_treeview_kbd_change);
     GtkCellRenderer *p_renderer;
     GtkTreeViewColumn *p_column;
-    // model
+    // change included
+    p_renderer = gtk_cell_renderer_toggle_new();
+    g_signal_connect(p_renderer, "toggled", G_CALLBACK(on_cell_renderer_layout_change_incl_toggled), p_liststore_kbd_change);
+    p_column = gtk_tree_view_column_new_with_attributes("", p_renderer, "active", COLUMN_CHANGE_INCL, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_change), p_column);
+    // change desc
     p_renderer = gtk_cell_renderer_text_new();
-    p_column = gtk_tree_view_column_new_with_attributes(_("Change Type"), p_renderer, "text", COLUMN_CHANGE_NAME, NULL);
+    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_CHANGE_DESC,
+                                                                                      "weight", COLUMN_CHANGE_WEIGHT,
+                                                                                      NULL);
+    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_DESC);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_change), p_column);
-    // desc
+    // change id
     p_renderer = gtk_cell_renderer_text_new();
-    p_column = gtk_tree_view_column_new_with_attributes(_("Description"), p_renderer, "text", COLUMN_CHANGE_DESC, NULL);
+    p_column = gtk_tree_view_column_new_with_attributes(_("Id"), p_renderer, "text", COLUMN_CHANGE_ID,
+                                                                             "weight", COLUMN_CHANGE_WEIGHT,
+                                                                             NULL);
+    gtk_tree_view_column_set_sort_column_id(p_column, COLUMN_CHANGE_ID);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p_treeview_kbd_change), p_column);
     
     // populate model
@@ -728,6 +793,8 @@ static void on_button_kbd_change_layout_clicked(GtkButton *p_button, gpointer *p
     gchar *xkbcfg_filepath = g_strdup_printf("%s/toggle.cfg", XKBCONFDIR);
     if(g_key_file_load_from_file(p_keyfile, xkbcfg_filepath, 0, NULL))
     {
+        char **change_opts = g_strsplit_set(p_xkb->kbd_change_option, ",", 0);
+        int    num_change_opts;
         gchar **keys_changes = g_key_file_get_keys(p_keyfile, "TOGGLE", NULL, NULL);
         guint   change_idx = 0;
         GtkTreeIter  tree_iter;
@@ -736,43 +803,56 @@ static void on_button_kbd_change_layout_clicked(GtkButton *p_button, gpointer *p
         {
             p_change_desc = g_key_file_get_string(p_keyfile, "TOGGLE", keys_changes[change_idx], NULL);
             gtk_list_store_append(p_liststore_kbd_change, &tree_iter);
+            gboolean  included = FALSE;
+            num_change_opts = 0;
+            while(change_opts[num_change_opts] != NULL)
+            {
+                if(strcmp(change_opts[num_change_opts], keys_changes[change_idx]) == 0)
+                {
+                    included = TRUE;
+                    break;
+                }
+                num_change_opts++;
+            }
             gtk_list_store_set(p_liststore_kbd_change, &tree_iter,
-                                COLUMN_CHANGE_NAME, keys_changes[change_idx],
+                                COLUMN_CHANGE_ID, keys_changes[change_idx],
                                 COLUMN_CHANGE_DESC, p_change_desc,
+                                COLUMN_CHANGE_INCL, included,
+                                COLUMN_CHANGE_WEIGHT, included ? PANGO_WEIGHT_ULTRAHEAVY : PANGO_WEIGHT_NORMAL,
                                 -1);
             g_free(p_change_desc);
             change_idx++;
         }
         g_strfreev(keys_changes);
         g_key_file_free(p_keyfile);
+        g_strfreev(change_opts);
     }
     g_free(xkbcfg_filepath);
     
     // callback for double click
-    g_signal_connect(p_treeview_kbd_change, "button-press-event",
-                     G_CALLBACK(on_treeviews_lists_button_press_event),
-                     gtk_dialog_get_widget_for_response(GTK_DIALOG(p_dialog), GTK_RESPONSE_OK));
+    //g_signal_connect(p_treeview_kbd_change, "button-press-event",
+                     //G_CALLBACK(on_treeviews_lists_button_press_event),
+                     //gtk_dialog_get_widget_for_response(GTK_DIALOG(p_dialog), GTK_RESPONSE_OK));
     gtk_widget_set_size_request(p_dialog, 700, 500);
     gtk_widget_show_all(GTK_WIDGET(p_scrolledwindow_kbd_change));
     gint  response = gtk_dialog_run(GTK_DIALOG(p_dialog));
     if(response == GTK_RESPONSE_OK)
     {
-        GtkTreeIter  tree_iter_sel;
-        GtkTreeSelection *p_treeselection_kbd_change = gtk_tree_view_get_selection(GTK_TREE_VIEW(p_treeview_kbd_change));
-        if(gtk_tree_selection_get_selected(p_treeselection_kbd_change,
-                                           (GtkTreeModel **)(&p_liststore_kbd_change),
-                                           &tree_iter_sel))
+        p_xkb->p_gstring_change_opt_partial = g_string_new("");
+        gtk_tree_model_foreach(GTK_TREE_MODEL(p_liststore_kbd_change),
+                               change_opt_tree_model_foreach,
+                               p_xkb);
+        if(!strlen(p_xkb->p_gstring_change_opt_partial->str))
         {
-            gchar *kbd_change_new;
-            gtk_tree_model_get(GTK_TREE_MODEL(p_liststore_kbd_change),
-                               &tree_iter_sel, COLUMN_CHANGE_NAME, &kbd_change_new, -1);
-            g_free(p_xkb->kbd_change_option);
-            p_xkb->kbd_change_option = g_strdup(kbd_change_new);
-            gtk_button_set_label(GTK_BUTTON(p_xkb->p_button_change_layout), p_xkb->kbd_change_option);
-            g_free(kbd_change_new);
-            xkb_setxkbmap(p_xkb);
-            xkb_redraw(p_xkb);
+            g_string_append_c(p_xkb->p_gstring_change_opt_partial, ',');
         }
+        g_free(p_xkb->kbd_change_option);
+        p_xkb->kbd_change_option = g_strdup(p_xkb->p_gstring_change_opt_partial->str);
+        g_string_free(p_xkb->p_gstring_change_opt_partial, TRUE/*free also gstring->str*/);
+        
+        gtk_button_set_label(GTK_BUTTON(p_xkb->p_button_change_layout), p_xkb->kbd_change_option);
+        xkb_setxkbmap(p_xkb);
+        xkb_redraw(p_xkb);
     }
     gtk_widget_destroy(p_dialog);
 }
@@ -1011,7 +1091,7 @@ void xkb_setxkbmap(XkbPlugin *p_xkb)
     
     GString *p_gstring_syscmd = g_string_new("");
     g_string_printf(p_gstring_syscmd,
-                    "setxkbmap -model %s -layout %s -variant %s -option grp:%s",
+                    "setxkbmap -model %s -layout %s -variant %s -option %s",
                     p_xkb->kbd_model, p_xkb->kbd_layouts, p_xkb->kbd_variants,
                     p_xkb->kbd_change_option);
     if( (p_xkb->kbd_advanced_options != NULL) && strlen(p_xkb->kbd_advanced_options) )
@@ -1034,10 +1114,10 @@ void xkb_setxkbmap(XkbPlugin *p_xkb)
     g_string_free(p_gstring_syscmd, TRUE/*free also gstring->str*/);
 }
 
-static gboolean layouts_tree_model_foreach(GtkTreeModel *p_model,
-                                           GtkTreePath *p_path,
-                                           GtkTreeIter *p_iter,
-                                           gpointer p_data)
+static gboolean  layouts_tree_model_foreach(GtkTreeModel *p_model,
+                                            GtkTreePath *p_path,
+                                            GtkTreeIter *p_iter,
+                                            gpointer p_data)
 {
     XkbPlugin *p_xkb = (XkbPlugin *)p_data;
     gchar *layout_val;