[Goodies-commits] r6385 - in xfce4-clipman-plugin/trunk: . panel-plugin

Mike Massonnet mmassonnet at xfce.org
Wed Dec 31 18:50:13 CET 2008


Author: mmassonnet
Date: 2008-12-31 17:50:13 +0000 (Wed, 31 Dec 2008)
New Revision: 6385

Modified:
   xfce4-clipman-plugin/trunk/ChangeLog
   xfce4-clipman-plugin/trunk/panel-plugin/clipman-dialogs.c
   xfce4-clipman-plugin/trunk/panel-plugin/clipman.c
   xfce4-clipman-plugin/trunk/panel-plugin/clipman.h
Log:
	- Drop the behaviors NORMAL and STRICTLY
	- Drop PREVENTEMPTY which will be the case by default
	- Replace IGNORESELECT against ADDSELECT to avoid double negation reads
	in the code
	- New definitions ClipDataType and ClipMenuFormat
	- Keep an index of the latest clipboard in the plugin struct for easier
	find on menu item clicks
	- Display always one list in the menu, thus merge the functions
	clipman_clicked_separated and not_separated
	- The clipboards are checked out on events with the owner-change signal
	from the GtkClipboards classes 
 

Modified: xfce4-clipman-plugin/trunk/ChangeLog
===================================================================
--- xfce4-clipman-plugin/trunk/ChangeLog	2008-12-30 13:00:00 UTC (rev 6384)
+++ xfce4-clipman-plugin/trunk/ChangeLog	2008-12-31 17:50:13 UTC (rev 6385)
@@ -1,3 +1,21 @@
+2008-12-31	Mike Massonnet <mmassonnet at xfce.org>
+
+This is the first part of the rewrite to make it more userfriendly, work done
+by David Collins.  The patches are applied as-is until his work is clearly done
+to avoid merge processes during that time.
+
+	- Drop the behaviors NORMAL and STRICTLY
+	- Drop PREVENTEMPTY which will be the case by default
+	- Replace IGNORESELECT against ADDSELECT to avoid double negation reads
+	in the code
+	- New definitions ClipDataType and ClipMenuFormat
+	- Keep an index of the latest clipboard in the plugin struct for easier
+	find on menu item clicks
+	- Display always one list in the menu, thus merge the functions
+	clipman_clicked_separated and not_separated
+	- The clipboards are checked out on events with the owner-change signal
+	from the GtkClipboards classes
+
 2008-12-27	Mike Massonnet <mmassonnet at xfce.org>
 
 	* panel-plugin/clipman.c (clipman_check): Don't restore the clipboard 

Modified: xfce4-clipman-plugin/trunk/panel-plugin/clipman-dialogs.c
===================================================================
--- xfce4-clipman-plugin/trunk/panel-plugin/clipman-dialogs.c	2008-12-30 13:00:00 UTC (rev 6384)
+++ xfce4-clipman-plugin/trunk/panel-plugin/clipman-dialogs.c	2008-12-31 17:50:13 UTC (rev 6385)
@@ -37,13 +37,9 @@
     ClipmanPlugin *clipman;
 
     GtkWidget     *ExitSave;
-    GtkWidget     *IgnoreSelection;
-    GtkWidget     *PreventEmpty;
+    GtkWidget     *AddSelection;
 
-    GtkWidget     *Behaviour;
-
     GtkWidget     *ItemNumbers;
-    GtkWidget     *SeparateMenu;
 
     GtkWidget     *HistorySize;
     GtkWidget     *ItemChars;
@@ -72,23 +68,16 @@
 
     g_object_set_data (G_OBJECT (options->clipman->plugin), "dialog", NULL);
 
-    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (options->Behaviour)))
-        options->clipman->Behaviour = NORMAL;
-    else
-        options->clipman->Behaviour = STRICTLY;
-
     if (options->clipman->HistoryItems != gtk_range_get_value (GTK_RANGE (options->HistorySize)))
     {
         options->clipman->HistoryItems   = gtk_range_get_value (GTK_RANGE (options->HistorySize));
-        clipman_check_array_len (options->clipman);
+        clipman_array_remove_oldest (options->clipman);
     }
 
     options->clipman->MenuCharacters = gtk_range_get_value (GTK_RANGE (options->ItemChars));
 
     clipman_save (options->clipman->plugin, options->clipman);
 
-    clipman_remove_selection_clips (options->clipman);
-
     xfce_panel_plugin_unblock_menu (options->clipman->plugin);
 
     gtk_widget_destroy (dialog);
@@ -122,27 +111,13 @@
         options->clipman->ExitSave =
            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
 
-    else if (button == options->IgnoreSelection)
-    {
-        options->clipman->IgnoreSelect =
+    else if (button == options->AddSelection)
+        options->clipman->AddSelect =
            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
 
-        if (options->clipman->IgnoreSelect)
-            gtk_widget_set_sensitive (options->SeparateMenu, FALSE);
-        else
-            gtk_widget_set_sensitive (options->SeparateMenu, TRUE);
-    }
-    else if (button == options->PreventEmpty)
-        options->clipman->PreventEmpty =
-           gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
-
     else if (button == options->ItemNumbers)
         options->clipman->ItemNumbers =
            gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
-
-    else if (button == options->SeparateMenu)
-        options->clipman->SeparateMenu =
-           gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
 }
 
 void
@@ -152,7 +127,6 @@
     GtkWidget      *dialog, *dialog_vbox, *frame, *button, *label;
     GtkWidget      *vbox, *hbox, *notebook_vbox, *notebook;
     ClipmanOptions *options;
-    GSList         *group;
 
     options = panel_slice_new0 (ClipmanOptions);
     options->clipman = clipman;
@@ -198,63 +172,19 @@
     g_signal_connect (G_OBJECT (button), "toggled",
             G_CALLBACK (toggle_button), options);
 
-    button = options->IgnoreSelection = gtk_check_button_new_with_mnemonic (_("_Ignore selections"));
+    button = options->AddSelection = gtk_check_button_new_with_mnemonic (_("_Add selections"));
     gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clipman->IgnoreSelect);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clipman->AddSelect);
 
     g_signal_connect (G_OBJECT (button), "toggled",
             G_CALLBACK (toggle_button), options);
 
-    button = options->PreventEmpty = gtk_check_button_new_with_mnemonic (_("Pre_vent empty clipboard"));
-    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clipman->PreventEmpty);
-
-    g_signal_connect (G_OBJECT (button), "toggled",
-            G_CALLBACK (toggle_button), options);
-
-
     label = gtk_label_new (_("<b>General</b>"));
     gtk_frame_set_label_widget (GTK_FRAME (frame), label);
     gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
     gtk_misc_set_padding (GTK_MISC (label), 2, 0);
 
     /**
-     * separate clipboards frame
-     **/
-    frame = gtk_frame_new (NULL);
-    gtk_box_pack_start (GTK_BOX (notebook_vbox), frame, FALSE, TRUE, 0);
-    gtk_container_set_border_width (GTK_CONTAINER (frame), BORDER-3);
-
-    vbox = gtk_vbox_new (FALSE, 2);
-    gtk_container_add (GTK_CONTAINER (frame), vbox);
-    gtk_container_set_border_width (GTK_CONTAINER (vbox), BORDER);
-
-    group = NULL;
-
-    button = options->Behaviour = gtk_radio_button_new_with_mnemonic (group, _("Normal clipboard _management"));
-    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
-    gtk_radio_button_set_group (GTK_RADIO_BUTTON (button), group);
-    group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
-
-    if(clipman->Behaviour == NORMAL)
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-
-    button = gtk_radio_button_new_with_mnemonic (group, _("Strictly separate _both clipboards"));
-    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
-    gtk_radio_button_set_group (GTK_RADIO_BUTTON (button), group);
-    group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
-
-    if(clipman->Behaviour == STRICTLY)
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-
-    label = gtk_label_new (_("<b>Clipboard Behaviour</b>"));
-    gtk_frame_set_label_widget (GTK_FRAME (frame), label);
-    gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-    gtk_misc_set_padding (GTK_MISC (label), 2, 0);
-
-    /**
      * Notebook label
      **/
     label = gtk_label_new (_("General"));
@@ -281,13 +211,6 @@
     g_signal_connect (G_OBJECT (button), "toggled",
             G_CALLBACK (toggle_button), options);
 
-    button = options->SeparateMenu = gtk_check_button_new_with_mnemonic (_("Se_parate clipboards"));
-    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), clipman->SeparateMenu);
-
-    g_signal_connect (G_OBJECT (button), "toggled",
-            G_CALLBACK (toggle_button), options);
-
     label = gtk_label_new (_("<b>Menu Appearance</b>"));
     gtk_frame_set_label_widget (GTK_FRAME (frame), label);
     gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
@@ -297,7 +220,7 @@
      * Call some functions
      **/
 
-   toggle_button (options->IgnoreSelection, options);
+   toggle_button (options->AddSelection, options);
 
     /**
      * Numbers frame

Modified: xfce4-clipman-plugin/trunk/panel-plugin/clipman.c
===================================================================
--- xfce4-clipman-plugin/trunk/panel-plugin/clipman.c	2008-12-30 13:00:00 UTC (rev 6384)
+++ xfce4-clipman-plugin/trunk/panel-plugin/clipman.c	2008-12-31 17:50:13 UTC (rev 6385)
@@ -37,6 +37,10 @@
 static GtkClipboard *primaryClip;
 static GtkClipboard *defaultClip;
 
+/* For event-driven clipboard_change() function */
+gboolean MouseSelecting=FALSE;
+gboolean ShiftSelecting=FALSE;
+
 /* Register the plugin */
 static void
 clipman_construct (XfcePanelPlugin *plugin);
@@ -65,6 +69,7 @@
     DBG ("Menu Destroyed");
 }
 
+/* Clear list of items AND both clipboards */
 static gboolean
 clipman_clear (GtkWidget      *mi,
                GdkEventButton *ev,
@@ -76,42 +81,49 @@
 	              "gtk-yes",
                       NULL))
     {
-        gtk_clipboard_clear (primaryClip);
-	gtk_clipboard_clear (defaultClip);
+      gtk_clipboard_clear (primaryClip);
+	    gtk_clipboard_clear (defaultClip);
 
-        while (clipman->clips->len > 0)
-        {
-            clip = g_ptr_array_index (clipman->clips, 0);
-            g_ptr_array_remove (clipman->clips, clip);
-            clipman_free_clip (clip);
-        }
+      while (clipman->clips->len > 0)
+      {
+        clip = g_ptr_array_index (clipman->clips, 0);
+        g_ptr_array_remove (clipman->clips, clip);
+        clipman_free_clip (clip);
+      }
+      clipman->DefaultIndex=-1;
+      clipman->PrimaryIndex=-1;
     }
-
-    /* 'Save' the empty clipboard */
-    clipman_save (clipman->plugin, clipman);
-
     return FALSE;
 }
 
+/* Remove the oldest items - these are at the start of the list */
 void
-clipman_check_array_len (ClipmanPlugin *clipman)
+clipman_array_remove_oldest (ClipmanPlugin *clipman)
 {
     ClipmanClip *clip;
-
+    gint i;
+    
     DBG ("Checking Array Length");
 
-    while (clipman->clips->len > clipman->HistoryItems)
-    {
-        clip = g_ptr_array_index (clipman->clips, 0);
-        g_ptr_array_remove (clipman->clips, clip);
-        clipman_free_clip (clip);
+    while (clipman->clips->len > clipman->HistoryItems) {
 
-        DBG("A clip have been removed");
+      // Leave items in list if they are active
+      for (i=0; i<2; ++i) {
+        if (clipman->DefaultIndex != i && clipman->PrimaryIndex != i) break;
+      }
+
+      clip = g_ptr_array_index (clipman->clips, i);
+      g_ptr_array_remove (clipman->clips, clip);
+      clipman_free_clip (clip);
+      /* Adjust indexes to clipboard data */
+      if (clipman->DefaultIndex > i) --clipman->DefaultIndex;
+      if (clipman->PrimaryIndex > i) --clipman->PrimaryIndex;
+
+      DBG("A clip have been removed");
     }
 }
 
 
-
 static gchar *
 clipman_create_title (gchar *text,
                       gint   length)
@@ -143,97 +155,69 @@
   return short_text;
 }
 
-void
-clipman_remove_selection_clips (ClipmanPlugin *clipman)
-{
-    ClipmanClip *clip;
-    guint        i;
-
-    if (!clipman->IgnoreSelect)
-        return;
-
-    DBG ("Cleaning up all selection clips");
-
-    for (i = clipman->clips->len; i--; )
-    {
-        clip = g_ptr_array_index (clipman->clips, i);
-
-        if (clip->fromtype == PRIMARY)
-        {
-             g_ptr_array_remove (clipman->clips, clip);
-             clipman_free_clip (clip);
-        }
-    }
-}
-
+/* Add new item to the end of the list */
 static void
 clipman_add_clip (ClipmanPlugin *clipman,
                   gchar         *txt,
-                  ClipboardType  type)
-{
-    ClipmanClip *new_clip;
+                  ClipboardType  type) {
+                  
+  ClipmanClip *new_clip;
 
-    if (G_LIKELY (txt != NULL) &&
+  if (G_LIKELY (txt != NULL) &&
         G_LIKELY (strcmp (txt, "")))
     {
-        new_clip = panel_slice_new0 (ClipmanClip);
+    new_clip = panel_slice_new0 (ClipmanClip);
+    new_clip->title = clipman_create_title (txt, clipman->MenuCharacters);
 
-        new_clip->title = clipman_create_title (txt,
-                                                clipman->MenuCharacters);
-
-	/* No valid title could be created, drop it... */
-	if (new_clip->title == NULL)
-	{
+  	/* No valid title could be created, drop it... */
+	  if (new_clip->title == NULL)
+    {
 	    g_free (new_clip);
 	    return;
-	}
+	  }
 
-	new_clip->text     = g_strdup (txt);
-        new_clip->fromtype = type;
+	  new_clip->text     = g_strdup (txt);
 
-        g_ptr_array_add (clipman->clips, new_clip);
-
-        DBG("Added clip %d of %d", clipman->clips->len, clipman->HistoryItems);
+    g_ptr_array_add (clipman->clips, new_clip);
+    
+    /* Indicate this item is in the clipboard */
+    if (type == DEFAULT) {
+      clipman->DefaultIndex=clipman->clips->len-1;
+    } else if (type == PRIMARY) {
+      clipman->PrimaryIndex=clipman->clips->len-1;
     }
+    DBG("Added clip %d of %d", clipman->clips->len, clipman->HistoryItems);
+  }
 }
 
+/* If we are looking for a DEFAULT value in the list and it matches a PRIMARY value,
+   then simply change the Primary value to a Default value and indicate that it exists. */
 static gboolean
 clipman_exists (ClipmanPlugin *clipman,
                 gchar         *txt,
-                ClipboardType  type)
-{
-    guint        i;
+                ClipboardType  type) {
+                
+    gint        i;
     ClipmanClip *clip;
 
     /* Walk through the array backwards, because
      * if the text exists, this will probably be the newest */
-
-    for (i = clipman->clips->len; i--; )
-    {
+    for (i=(gint)clipman->clips->len-1; i>=0; i--) {
+    
         clip = g_ptr_array_index (clipman->clips, i);
 
         if (G_LIKELY ((clip->text != NULL) &&
-                      (strcmp(clip->text, txt) == 0))
-           )
-        {
-            switch (clipman->Behaviour)
-            {
-                case NORMAL:
-                    if (type == DEFAULT &&
-                        clip->fromtype == PRIMARY)
-                            clip->fromtype = DEFAULT;
-
-                    return TRUE;
-
-                case STRICTLY:
-                    if (type == clip->fromtype)
-                        return TRUE;
-
-                    return FALSE;
-            }
+                      (strcmp(clip->text, txt) == 0))) {
+          if (type == PRIMARY) {
+            clipman->PrimaryIndex=i;
+            DBG("String re-selected");
+          } else if (type == DEFAULT) {
+            clipman->DefaultIndex=i;
+            DBG("Selection Copied");
+          }
+          return TRUE;
         }
     }
-
     return FALSE;
 }
 
@@ -243,64 +227,82 @@
                       ClipmanAction  *action)
 {
     gchar *dtext, *ptext;
+    gboolean defaultcleared, primarycleared; 
+    
+    /* Left mouse button - put item in BOTH clipboards */
+    if (ev->button == 1) {
+      gtk_clipboard_clear (defaultClip);
+      gtk_clipboard_set_text (defaultClip, action->clip->text, -1);
+      action->clipman->DefaultIndex = action->index;
+	    DBG ("Clip copied to default clipboard");
 
-    if (ev->button == 1 && action->clipman->Behaviour == STRICTLY)
-    {
-        DBG("Clip copied to his own clipboard (STRICTLY)");
+	    if (action->clipman->AddSelect)	{
+	      gtk_clipboard_clear (primaryClip);
+	      gtk_clipboard_set_text (primaryClip, action->clip->text, -1);
+        action->clipman->PrimaryIndex = action->index;
+	      DBG ("Clip copied to primary clipboard");
+	    }
+	    
+	  /* Right mouse button - remove item */  
+    } else if (ev->button == 3) {
 
-        if (action->clip->fromtype == DEFAULT)
-	{
-	    gtk_clipboard_clear (defaultClip);
-            gtk_clipboard_set_text (defaultClip, action->clip->text, -1);
-	}
-
-        if (action->clip->fromtype == PRIMARY)
-	{
-	    gtk_clipboard_clear (primaryClip);
-            gtk_clipboard_set_text (primaryClip, action->clip->text, -1);
-	}
-    }
-    else if (ev->button == 1)
-    {
+      defaultcleared=FALSE;
+      primarycleared=FALSE; 
+      
+      DBG ("Removed the selected clip from the History");
+	    /* If this item is in clipboard, clear the clipbard */
+      if (action->clipman->DefaultIndex == action->index) {
         gtk_clipboard_clear (defaultClip);
-        gtk_clipboard_set_text (defaultClip, action->clip->text, -1);
-	DBG ("Clip copied to default clipboard");
+        defaultcleared=TRUE;
+	    } else if (action->clipman->DefaultIndex > action->index) {
+	      // index needs adjustment
+        --action->clipman->DefaultIndex;
+      }
+      
+	    if (action->clipman->AddSelect)	{
+  	    /* If this item is in clipboard, clear the clipbard */
+        if (action->clipman->PrimaryIndex == action->index) {
+          gtk_clipboard_clear (primaryClip);
+          primarycleared=TRUE;
+	      } else if (action->clipman->PrimaryIndex > action->index) {
+	        // index needs adjustment
+          --action->clipman->PrimaryIndex;
+    		}
+	    }
 
-	if (!action->clipman->IgnoreSelect)
-	{
-	    gtk_clipboard_clear (primaryClip);
-	    gtk_clipboard_set_text (primaryClip, action->clip->text, -1);
-	    DBG ("Clip copied to primary clipboard");
-	}
-    }
-    else if (ev->button == 3)
-    {
-        if (xfce_confirm (_("Are you sure you want to remove this clip from the history?"),
-	              "gtk-yes", NULL))
-        {
-            DBG ("Removed the selected clip from the History");
+      /* Remove chosen item from the list */
+      g_ptr_array_remove (action->clipman->clips, action->clip);
+      clipman_free_clip (action->clip);
+      guint len = action->clipman->clips->len;
 
-	    dtext = gtk_clipboard_wait_for_text (defaultClip);
-            if (dtext && !strcmp(dtext, action->clip->text))
-	    {
-                gtk_clipboard_clear (defaultClip);
-		gtk_clipboard_set_text (defaultClip, "", -1);
-	    }
-	    g_free (dtext);
+      /* List is now empty */
+      if (len == 0) {
+  		  if (defaultcleared) {
+   		    gtk_clipboard_set_text (defaultClip, "", -1);
+   		    action->clipman->DefaultIndex = -1;
+   		  }
+   		  if (primarycleared) {
+   		    gtk_clipboard_set_text (primaryClip, "", -1);
+     		  action->clipman->PrimaryIndex = -1;
+   		  }
 
-	    ptext = gtk_clipboard_wait_for_text (primaryClip);
-            if (ptext && !strcmp(ptext, action->clip->text))
-	    {
-                gtk_clipboard_clear (primaryClip);
-		gtk_clipboard_set_text (primaryClip, "", -1);
-	    }
-            g_free (ptext);
+      } else {
+        /* Get the newest item left in the list */
+        ClipmanClip *clip = g_ptr_array_index (action->clipman->clips, len-1);
 
-            g_ptr_array_remove (action->clipman->clips, action->clip);
-            clipman_free_clip (action->clip);
-        }
+        /* If Clipboard has been cleared, put in a replacement */
+    		if (defaultcleared) {
+    		  gtk_clipboard_set_text (defaultClip, clip->text, -1);
+    		  action->clipman->DefaultIndex = len-1;
+    		}
+    		if (primarycleared) {
+    		  gtk_clipboard_set_text (primaryClip, clip->text, -1);
+    		  action->clipman->PrimaryIndex = len-1;
+    		}
+    	} 
     }
 
+    // Menu disappears ..
     panel_slice_free (ClipmanAction, action);
 
     return FALSE;
@@ -310,31 +312,29 @@
 clipman_create_menuitem (ClipmanAction *action,
                          guint          width,
                          guint          number,
-                         gboolean       bold)
-{
+                         ClipMenuFormat format) {
+
     GtkWidget *mi;
     gchar     *title, *string_num;
 
-    if (action->clipman->ItemNumbers)
-    {
+    if (action->clipman->ItemNumbers) {
         if (number < 10)
             string_num = g_strdup_printf("<tt><span size=\"smaller\">%d. </span></tt> ", number);
         else
             string_num = g_strdup_printf("<tt><span size=\"smaller\">%d.</span></tt> ", number);
-    }
-    else
-    {
+    } else {
         string_num = g_strdup ("");
     }
 
-    if (bold)
+    if (format==BOLD)
         title = g_strdup_printf("%s<b>%s</b>", string_num, action->clip->title);
-    else
+    else if (format==ITALICS)
+        title = g_strdup_printf("%s<i>%s</i>", string_num, action->clip->title);
+    else if (format==PLAIN)
         title = g_strdup_printf("%s%s", string_num, action->clip->title);
 
     g_free (string_num);
 
-
     mi = gtk_menu_item_new_with_label ("");
     gtk_label_set_markup (GTK_LABEL (GTK_BIN (mi)->child), title);
     g_free (title);
@@ -343,178 +343,38 @@
 }
 
 static void
-clipman_clicked_separated (GtkWidget     *menu,
-                           ClipmanPlugin *clipman)
-{
-    gchar         *ptext, *dtext;
-    guint          i, j;
-    ClipmanAction *action = NULL;
-    ClipmanClip   *clip;
-    GtkWidget     *mi;
-
-    /* Default Clips */
-    dtext = gtk_clipboard_wait_for_text (defaultClip);
-    j = 0;
-
-    for (i = clipman->clips->len; i--; )
-    {
-        clip = g_ptr_array_index (clipman->clips, i);
-
-        if (clip->fromtype == DEFAULT)
-        {
-            j++;
-
-            action = panel_slice_new0 (ClipmanAction);
-            action->clipman = clipman;
-            action->clip = clip;
-
-            if (dtext != NULL                 &&
-                G_LIKELY (clip->text != NULL) &&
-                strcmp(clip->text, dtext) == 0)
-            {
-                mi = clipman_create_menuitem (action, clipman->MenuCharacters,
-                                              j, TRUE);
-		g_free (dtext);
-		dtext = NULL;
-            }
-            else
-            {
-                mi = clipman_create_menuitem (action, clipman->MenuCharacters,
-                                              j, FALSE);
-            }
-
-            g_signal_connect (G_OBJECT(mi), "button_release_event",
-                    G_CALLBACK(clipman_item_clicked), action);
-
-            gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-        }
-    }
-
-    g_free (dtext);
-
-    if (j == 0)
-    {
-        mi = gtk_menu_item_new_with_label (_("< Default History Empty >"));
-        gtk_widget_set_sensitive (mi, FALSE);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-    }
-
-    /* Primairy Clips */
-    mi = gtk_separator_menu_item_new ();
-    gtk_widget_set_sensitive (mi, FALSE);
-    gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-
-    ptext = gtk_clipboard_wait_for_text (primaryClip);
-    j = 0;
-
-    for (i = clipman->clips->len; i--; )
-    {
-        clip = g_ptr_array_index (clipman->clips, i);
-
-        if (clip->fromtype == PRIMARY)
-        {
-            j++;
-
-            action = panel_slice_new0 (ClipmanAction);
-            action->clipman = clipman;
-            action->clip = clip;
-
-            if (ptext != NULL                 &&
-                G_LIKELY (clip->text != NULL) &&
-                strcmp(clip->text, ptext) == 0)
-            {
-                mi = clipman_create_menuitem (action, clipman->MenuCharacters,
-                                              j, TRUE);
-                g_free (ptext);
-		ptext = NULL;
-            }
-            else
-            {
-                mi = clipman_create_menuitem (action, clipman->MenuCharacters,
-                                              j, FALSE);
-            }
-
-            g_signal_connect (G_OBJECT(mi), "button_release_event",
-                    G_CALLBACK(clipman_item_clicked), action);
-
-            gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-        }
-    }
-
-    g_free (ptext);
-
-    if (j == 0)
-    {
-        mi = gtk_menu_item_new_with_label (_("< Selection History Empty >"));
-        gtk_widget_set_sensitive (mi, FALSE);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-    }
-
-    mi = gtk_separator_menu_item_new ();
-    gtk_widget_set_sensitive (mi, FALSE);
-    gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-
-    mi = gtk_menu_item_new_with_label (_("Clear History"));
-    gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
-
-    g_signal_connect (G_OBJECT (mi), "button_release_event",
-        G_CALLBACK (clipman_clear), clipman);
-}
-
-static void
-clipman_clicked_not_separated (GtkWidget     *menu,
-                               ClipmanPlugin *clipman)
-{
-    gchar         *ptext, *dtext;
+clipman_build_menu_body (GtkWidget *menu, ClipmanPlugin *clipman) {
+                               
     guint          i;
     ClipmanAction *action = NULL;
     ClipmanClip   *clip;
     GtkWidget     *mi;
 
-    ptext = gtk_clipboard_wait_for_text (primaryClip);
-    dtext = gtk_clipboard_wait_for_text (defaultClip);
-
-    for (i = clipman->clips->len; i--;)
-    {
+    for (i=clipman->clips->len; i--;) {
         clip = g_ptr_array_index (clipman->clips, i);
 
         action = panel_slice_new0 (ClipmanAction);
         action->clipman = clipman;
         action->clip = clip;
+        action->index = i;
 
-        if (dtext != NULL                 &&
-            G_LIKELY (clip->text != NULL) &&
-            strcmp(clip->text, dtext) == 0)
-        {
+        if (clipman->DefaultIndex == i) {
             mi = clipman_create_menuitem (action, clipman->MenuCharacters,
-                                          clipman->clips->len-i, TRUE);
-            g_free (dtext);
-	    dtext = NULL;
+                                          clipman->clips->len-i, BOLD);
         }
-        else if (ptext != NULL                 &&
-                 G_LIKELY (clip->text != NULL) &&
-                 strcmp(clip->text, ptext) == 0)
-        {
+        else if (clipman->PrimaryIndex == i) {
             mi = clipman_create_menuitem (action, clipman->MenuCharacters,
-                                          clipman->clips->len-i, TRUE);
-            g_free (ptext);
-	    ptext = NULL;
-        }
-        else
-        {
+                                          clipman->clips->len-i, ITALICS);
+        } else {
             mi = clipman_create_menuitem (action, clipman->MenuCharacters,
-                                          clipman->clips->len-i, FALSE);
+                                          clipman->clips->len-i, PLAIN);
         }
 
         g_signal_connect (G_OBJECT(mi), "button_release_event",
                 G_CALLBACK(clipman_item_clicked), action);
-
         gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
     }
 
-    g_free (ptext);
-    g_free (dtext);
-
     mi = gtk_separator_menu_item_new ();
     gtk_widget_set_sensitive (mi, FALSE);
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
@@ -597,8 +457,9 @@
         *y = geom.y;
 }
 
+/* Show list when the clipman icon is clicked with the left mouse button */
 static gboolean
-clipman_clicked (GtkWidget      *button,
+clipman_icon_clicked (GtkWidget      *button,
                  GdkEventButton *ev,
                  ClipmanPlugin  *clipman)
 {
@@ -606,8 +467,7 @@
     GtkWidget *menu;
     gchar     *title;
 
-    if (ev->button != 1)
-	return FALSE;
+    if (ev->button != 1) return FALSE;
 
     gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (clipman->button), TRUE);
 
@@ -623,18 +483,9 @@
     gtk_widget_set_sensitive (mi, FALSE);
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
 
-    if (clipman->SeparateMenu  &&
-        !clipman->IgnoreSelect &&
-        G_LIKELY (clipman->clips->len > 0))
-    {
-        clipman_clicked_separated (menu, clipman);
-    }
-    else if (G_LIKELY (clipman->clips->len > 0))
-    {
-        clipman_clicked_not_separated (menu, clipman);
-    }
-    else
-    {
+    if (G_LIKELY (clipman->clips->len > 0)) {
+        clipman_build_menu_body (menu, clipman);
+    } else {
         mi = gtk_menu_item_new_with_label (_("< Clipboard Empty >"));
         gtk_widget_set_sensitive (mi, FALSE);
         gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
@@ -654,111 +505,130 @@
     return TRUE;
 }
 
+/* Called when a program closes. */
 static void
-clipman_restore_empty (ClipmanPlugin *clipman,
+clipman_refill_clipboard (ClipmanPlugin *clipman,
                        ClipboardType  type)
 {
     guint        i;
     ClipmanClip *clip;
 
-    if (clipman->Behaviour == STRICTLY &&
-        G_LIKELY (clipman->clips->len > 0))
-    {
-        /* Walk through the array till a clip of it's own
-         * type is found, then past it in the clipboard */
-        for (i = clipman->clips->len; i--;)
-        {
-            clip = g_ptr_array_index (clipman->clips, i);
+    if (clipman->clips->len > 0) {
+    
+        if (type == DEFAULT) {
+          clip = g_ptr_array_index(clipman->clips, clipman->DefaultIndex);
+          gtk_clipboard_set_text(defaultClip, clip->text, -1);
+        } else if (type == PRIMARY) {
+          clip = g_ptr_array_index(clipman->clips, clipman->PrimaryIndex);
+          gtk_clipboard_set_text(primaryClip, clip->text, -1);
+        }
+        DBG("Active clip restored");
+    }
+}
 
-            if (clip->fromtype == type)
-            {
-                switch (type)
-                {
-                    case PRIMARY:
-                        gtk_clipboard_set_text(primaryClip, clip->text, -1);
-                        break;
-                    case DEFAULT:
-                        gtk_clipboard_set_text(defaultClip, clip->text, -1);
-                        break;
-                }
+/* This function is called when populating the clipboard in these events -
+  - user selects data             - add to list
+  - user copies data to clipboard - add to list
+  - program holding the DEFAULT clipboard closes down - populate DEFAULT clipboard with active list item
+  - program holding the PRIMARY clipboard closes down - populate PRIMARY clipboard with active list item
+*/
+static void clipman_populate_clipboard(GtkClipboard *clipboard, ClipmanPlugin *clipman, GdkOwnerChange reason) {
 
-                DBG("Clipboard restored with a clip from same type");
+  gchar *ptext = NULL, *dtext;
+  GdkModifierType  state;
 
-                break;
-            }
-        }
+  /* DEFAULT clipboard */
+  if (clipboard == defaultClip) {
+       
+    // Program holding selection has closed
+    if (reason == GDK_OWNER_CHANGE_CLOSE) {
+      clipman_refill_clipboard (clipman, DEFAULT);
+      return;
     }
-    else if (clipman->clips->len > 0)
-    {
-        /* Grap the latest clip and paste it in the clipboard */
-        clip = g_ptr_array_index (clipman->clips, (clipman->clips->len-1));
 
-        switch (type)
-        {
-            case PRIMARY:
-                gtk_clipboard_set_text(primaryClip, clip->text, -1);
-                break;
-            case DEFAULT:
-                gtk_clipboard_set_text(defaultClip, clip->text, -1);
-                break;
-        }
-
-        DBG("Last clip added");
+    dtext = gtk_clipboard_wait_for_text (defaultClip);
+    if (G_LIKELY (dtext != NULL) && reason == GDK_OWNER_CHANGE_NEW_OWNER &&
+	                             !clipman_exists (clipman, dtext, DEFAULT)) {
+        DBG("Item added from default clipboard");
+        DBG("Copy done");
+        clipman_add_clip (clipman, dtext, DEFAULT);
+        clipman_array_remove_oldest (clipman);
     }
-}
+    g_free (dtext);
+  }
 
-static gboolean
-clipman_check (ClipmanPlugin *clipman)
-{
-    gboolean         clipboard_has_image;
-    gchar           *ptext = NULL, *dtext;
-    GdkModifierType  state;
+  /* PRIMARY - only if 'Add Selections' is ticked */
+  if (clipboard == primaryClip && clipman->AddSelect)
+  {
+      // Program holding selection has closed - no action required.
+      if (reason == GDK_OWNER_CHANGE_CLOSE) {
+        clipman_refill_clipboard (clipman, PRIMARY);
+        return;
+      }
+      
+      // Get selection
+      ptext = gtk_clipboard_wait_for_text (primaryClip);
+      // User has selected text.
+      if (ptext != NULL && reason == GDK_OWNER_CHANGE_NEW_OWNER &&
+               !clipman_exists (clipman, ptext, PRIMARY))
+      {
+          DBG("Item added from primary clipboard");
+          DBG("Select done");
+          clipman_add_clip (clipman, ptext, PRIMARY);
+          clipman_array_remove_oldest (clipman);
+      }
+      g_free (ptext);
+  }
 
-    /* We ignore the selection clipboard entirely if you've activated this in the options dialog */
-    if (!clipman->IgnoreSelect)
-    {
-	/* Get mouse button information */
-	gdk_window_get_pointer(NULL, NULL, NULL, &state);
+}
 
-        clipboard_has_image = gtk_clipboard_wait_is_image_available (primaryClip);
+/* Called when -
+  - user selects data
+  - user copies data to clipboard
+  - program holding a clipboard closes down
+*/
+static void clipboard_changed(GtkClipboard *clipboard, GdkEvent *event, ClipmanPlugin *clipman) {
 
-        ptext = gtk_clipboard_wait_for_text (primaryClip);
-
-        if (clipman->PreventEmpty && ptext == NULL && clipboard_has_image == FALSE)
-        {
-            clipman_restore_empty (clipman, PRIMARY);
-        }
-        else if (ptext != NULL               &&
-                 !(state & GDK_BUTTON1_MASK) &&
-                 !clipman_exists (clipman, ptext, PRIMARY))
-        {
-            DBG("Item added from primary clipboard");
-            clipman_add_clip (clipman, ptext, PRIMARY);
-            clipman_check_array_len (clipman);
-        }
-
-        g_free (ptext);
+  /* Note this extra effort is only required for the PRIMARY selects
+     in some applications */
+  if (clipboard == primaryClip && clipman->AddSelect) {
+    GdkModifierType  state;
+    gdk_window_get_pointer(NULL, NULL, NULL, &state);
+    if (state & GDK_BUTTON1_MASK) {
+      DBG("Left btn pressed");
+      MouseSelecting=TRUE;
+      return;  // not done yet
+    } else if (state & GDK_SHIFT_MASK) {
+      DBG("Shift key pressed");
+      ShiftSelecting=TRUE;
+      return;  // not done yet
     }
+  }
+  
+  /* Why the signal was sent */
+  GdkOwnerChange reason = ((GdkEventOwnerChange*)event)->reason;
+  clipman_populate_clipboard(clipboard, clipman, reason);
 
-    dtext = gtk_clipboard_wait_for_text (defaultClip);
+}
 
-    clipboard_has_image = gtk_clipboard_wait_is_image_available (defaultClip);
+/* This runs every 0.5 seconds - minimize what it does. */
+static gboolean clipman_check (ClipmanPlugin *clipman)
+{
+    // Nearly always, this is all this function will do ..
+    if (!MouseSelecting && !ShiftSelecting) return TRUE;
 
-    /* Check default clipboard */
-    if (clipman->PreventEmpty && dtext == NULL && clipboard_has_image == FALSE)
-    {
-        clipman_restore_empty (clipman, DEFAULT);
-    }
-    else if (G_LIKELY (dtext != NULL) &&
-	     !clipman_exists (clipman, dtext, DEFAULT))
-    {
-        DBG("Item added from default clipboard");
-        clipman_add_clip (clipman, dtext, DEFAULT);
-        clipman_check_array_len (clipman);
-    }
+    printf(".");    
+    GdkModifierType  state;
+    gdk_window_get_pointer(NULL, NULL, NULL, &state);
+    if (MouseSelecting==TRUE && !(state & GDK_BUTTON1_MASK)) MouseSelecting=FALSE;
+    if (ShiftSelecting==TRUE && !(state & GDK_SHIFT_MASK))   ShiftSelecting=FALSE;
 
-    g_free (dtext);
-
+    // Now that the selection is finished, run the necessary code ..
+    if (!MouseSelecting && !ShiftSelecting) {
+      printf("Finished selecting.\n");    
+      clipman_populate_clipboard(primaryClip, clipman, GDK_OWNER_CHANGE_NEW_OWNER);
+    }
+    
     return TRUE;
 }
 
@@ -802,21 +672,9 @@
     xfce_rc_set_group (rc, "Properties");
 
     xfce_rc_write_bool_entry (rc, "ExitSave",     clipman->ExitSave);
-    xfce_rc_write_bool_entry (rc, "IgnoreSelect", clipman->IgnoreSelect);
-    xfce_rc_write_bool_entry (rc, "PreventEmpty", clipman->PreventEmpty);
-
-    switch (clipman->Behaviour)
-    {
-        case NORMAL:
-            xfce_rc_write_int_entry (rc, "Behaviour", 1);
-            break;
-        case STRICTLY:
-            xfce_rc_write_int_entry (rc, "Behaviour", 2);
-            break;
-    }
-
+    xfce_rc_write_bool_entry (rc, "AddSelect", clipman->AddSelect);
+    
     xfce_rc_write_bool_entry (rc, "ItemNumbers",  clipman->ItemNumbers);
-    xfce_rc_write_bool_entry (rc, "SeparateMenu", clipman->SeparateMenu);
 
     xfce_rc_write_int_entry (rc, "HistoryItems",   clipman->HistoryItems);
     xfce_rc_write_int_entry (rc, "MenuCharacters", clipman->MenuCharacters);
@@ -841,10 +699,7 @@
             xfce_rc_write_entry (rc, name, clip->text);
 
             g_snprintf (name, 13, "clip_%d_from", i);
-            if (clip->fromtype == PRIMARY)
-                xfce_rc_write_int_entry (rc, name, 0);
-            else
-                xfce_rc_write_int_entry (rc, name, 1);
+            xfce_rc_write_int_entry (rc, name, 1);
         }
     }
 
@@ -876,23 +731,8 @@
     xfce_rc_set_group (rc, "Properties");
 
     clipman->ExitSave         = xfce_rc_read_bool_entry (rc, "ExitSave",     DEFEXITSAVE);
-    clipman->IgnoreSelect     = xfce_rc_read_bool_entry (rc, "IgnoreSelect", DEFIGNORESELECT);
-    clipman->PreventEmpty     = xfce_rc_read_bool_entry (rc, "PreventEmpty", DEFPREVENTEMPTY);
-
-    switch (xfce_rc_read_int_entry (rc, "Behaviour", DEFBEHAVIOUR))
-    {
-        case 1:
-            clipman->Behaviour = NORMAL;
-            DBG ("Behaviour = NORMAL");
-            break;
-        case 2:
-            clipman->Behaviour = STRICTLY;
-            DBG ("Behaviour = STRICTLY");
-            break;
-    }
-
+    clipman->AddSelect     = xfce_rc_read_bool_entry (rc, "AddSelect", DEFADDSELECT);
     clipman->ItemNumbers      = xfce_rc_read_bool_entry (rc, "ItemNumbers",    DEFITEMNUMBERS);
-    clipman->SeparateMenu     = xfce_rc_read_bool_entry (rc, "SeparateMenu",   DEFSEPMENU);
 
     clipman->HistoryItems     = xfce_rc_read_int_entry  (rc, "HistoryItems",   DEFHISTORY);
     clipman->MenuCharacters   = xfce_rc_read_int_entry  (rc, "MenuCharacters", DEFCHARS);
@@ -951,7 +791,10 @@
     clipman->tooltip = gtk_tooltips_new ();
     g_object_ref (G_OBJECT (clipman->tooltip));
 
-    /* Load Settings */
+    clipman->DefaultIndex=-1;
+    clipman->PrimaryIndex=-1;
+
+    /* Load Settings, and possibly Data */
     clipman_read (clipman);
 
     /* Create panel widgets */
@@ -967,7 +810,7 @@
                           NULL);
 
     g_signal_connect(clipman->button, "button_press_event",
-            G_CALLBACK(clipman_clicked), clipman);
+            G_CALLBACK(clipman_icon_clicked), clipman);
 
     /* Start the clipman_check function */
     clipman->TimeoutId = g_timeout_add_full(G_PRIORITY_LOW,
@@ -980,6 +823,10 @@
     defaultClip = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
     primaryClip = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
 
+    /* Respond to clipboard events - rather than polling twice a second */
+  	g_signal_connect(G_OBJECT(defaultClip), "owner-change", G_CALLBACK(clipboard_changed), clipman);
+	  g_signal_connect(G_OBJECT(primaryClip), "owner-change", G_CALLBACK(clipboard_changed), clipman);
+
     return clipman;
 }
 
@@ -987,7 +834,7 @@
 clipman_free (XfcePanelPlugin *plugin,
               ClipmanPlugin   *clipman)
 {
-    guint        i;
+    gint        i;
     ClipmanClip *clip;
     GtkWidget   *dialog;
 
@@ -1015,7 +862,7 @@
     }
 
     /* Remove clipboard items */
-    for (i = clipman->clips->len; i--;)
+    for (i=(gint)clipman->clips->len-1; i>=0; i--)
     {
         clip = g_ptr_array_index (clipman->clips, i);
         g_ptr_array_remove_fast (clipman->clips, clip);

Modified: xfce4-clipman-plugin/trunk/panel-plugin/clipman.h
===================================================================
--- xfce4-clipman-plugin/trunk/panel-plugin/clipman.h	2008-12-30 13:00:00 UTC (rev 6384)
+++ xfce4-clipman-plugin/trunk/panel-plugin/clipman.h	2008-12-31 17:50:13 UTC (rev 6385)
@@ -37,12 +37,8 @@
 
 /* Default options */
 #define DEFEXITSAVE     FALSE
-#define DEFIGNORESELECT TRUE
-#define DEFPREVENTEMPTY TRUE
-#define DEFBEHAVIOUR    1
-
+#define DEFADDSELECT    FALSE
 #define DEFITEMNUMBERS  FALSE
-#define DEFSEPMENU      FALSE
 
 /* Milisecond to check the clipboards(s) */
 #define TIMER_INTERVAL  500
@@ -56,11 +52,19 @@
 
 typedef enum
 {
-    NORMAL = 0,
-    STRICTLY
+    RAWTEXT,
+    IMAGE
 }
-ClipboardBehaviour;
+ClipDataType;
 
+typedef enum
+{
+    PLAIN,
+    BOLD,
+    ITALICS
+}
+ClipMenuFormat;
+
 typedef struct
 {
     XfcePanelPlugin *plugin;
@@ -69,19 +73,17 @@
     GtkWidget    *button;
     GtkTooltips  *tooltip;
 
-    GPtrArray    *clips;
-
     gint          TimeoutId;
     gboolean      killTimeout;
 
     gboolean      ExitSave;
-    gboolean      IgnoreSelect;
-    gboolean      PreventEmpty;
+    gboolean      AddSelect;
 
-    ClipboardBehaviour Behaviour;
+    GPtrArray    *clips;
+    gint          DefaultIndex;
+    gint          PrimaryIndex;
 
     gboolean      ItemNumbers;
-    gboolean      SeparateMenu;
 
     guint         HistoryItems;
     guint         MenuCharacters;
@@ -91,9 +93,8 @@
 typedef struct
 {
     gchar        *text;
-    gchar        *title;        /* I've added the title to save
-                                 * some time when opening the menu */
-    ClipboardType fromtype;
+    gchar        *title;  /* Save time when creating the menu */
+    ClipDataType  datatype;
 }
 ClipmanClip;
 
@@ -101,6 +102,7 @@
 {
     ClipmanPlugin  *clipman;
     ClipmanClip    *clip;
+    gint            index;
 }
 ClipmanAction;
 
@@ -116,3 +118,4 @@
 G_END_DECLS
 
 #endif /* CLIPMAN_H */
+




More information about the Goodies-commits mailing list