typedef struct ClipboardMenuItem {
GtkWidget *widget; /* pointer to GtkMenuItem */
gchar *buffer; /* value and it's length */
- size_t buflen;
gint flags;
} ClipboardMenuItem;
GtkWidget *widget; /* GtkMenu */
+ GtkWidget *activator; /* GtkMenuItem for manage active state */
+ gboolean is_active;
+
ClipboardMenuItem *items[NHistItem]; /* histories item's */
gint nitems; /* number of items */
gint nlocked; /* number of locked items */
* buffer and -1 if it isn't found
*/
static gint
-existMenuItem(ClipboardDescr *descr, const gchar *buffer, size_t buflen)
+existMenuItem(ClipboardDescr *descr, const gchar *buffer)
{
gint i;
for(i=0;i<descr->nitems;i++)
- if ( descr->items[i]->buflen == buflen && strcmp( descr->items[i]->buffer, buffer ) == 0 )
+ if ( strcmp( descr->items[i]->buffer, buffer ) == 0 )
return i;
return -1;
moveMenuItemFirst( descr, n );
gtk_clipboard_set_text(
gtk_clipboard_get(GDK_SELECTION_PRIMARY),
- descr->items[0]->buffer,
- descr->items[0]->buflen);
+ descr->items[0]->buffer, -1 );
}
return TRUE;
* existing
*/
static void
-addMenuItem( ClipboardDescr *descr, const gchar *buffer, size_t buflen )
+addMenuItem( ClipboardDescr *descr, gchar *buffer )
{
gint i;
static gchar itemname[5*MaxItemName + 1];
/*
* if such value already exists just move to to head
*/
- if ( (i=existMenuItem(descr, buffer, buflen)) >= 0 )
+ if ( (i=existMenuItem(descr, buffer)) >= 0 )
{
moveMenuItemFirst( descr, i );
return;
if ( descr->items[0]->buffer )
g_free( descr->items[0]->buffer );
- descr->items[0]->buffer = g_memdup(buffer, buflen+1);
- descr->items[0]->buflen = buflen;
+ descr->items[0]->buffer = buffer;
descr->items[0]->flags = 0;
/*
ptrname = itemname;
ptrbuffer = (gchar*)buffer;
- for(i=0; *ptrbuffer && (ptrbuffer - buffer)<buflen && i < MaxItemName; i++)
+ for(i=0; *ptrbuffer && i < MaxItemName; i++)
{
int charlen = g_utf8_offset_to_pointer(ptrbuffer, 1) - ptrbuffer;
gunichar widechar;
);
}
+static gboolean
+appToggleActivate(GtkWidget *widget, gpointer user_data)
+{
+ ClipboardDescr *descr = (ClipboardDescr*)user_data;
+
+ if ( descr->is_active == TRUE )
+ {
+ gtk_widget_set_style( GTK_BIN(descr->activator)->child, descr->style_locked);
+ gtk_label_set_text(
+ GTK_LABEL( gtk_bin_get_child(GTK_BIN(descr->activator)) ),
+ "Activate"
+ );
+ descr->is_active = FALSE;
+ }
+ else
+ {
+ gtk_widget_set_style( GTK_BIN(descr->activator)->child, descr->style_normal);
+ gtk_label_set_text(
+ GTK_LABEL( gtk_bin_get_child(GTK_BIN(descr->activator)) ),
+ "Deactivate"
+ );
+ descr->is_active = TRUE;
+ }
+
+ return TRUE;
+}
+
/*
* Initialize main struct
*/
static void
initHistMenu( ClipboardDescr *descr )
{
+ GtkWidget *separator;
/*
* set up hotkey to call menu
*/
*/
descr->widget = gtk_menu_new();
gtk_menu_set_title(GTK_MENU(descr->widget), "Clipboard history");
+
+ separator = gtk_separator_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(descr->widget), separator);
+
+ descr->activator = gtk_menu_item_new_with_label("Deactivate");
+ gtk_label_set_max_width_chars(
+ GTK_LABEL( gtk_bin_get_child(GTK_BIN(descr->activator)) ),
+ MaxItemName
+ );
+ g_signal_connect(descr->activator,
+ "activate",
+ G_CALLBACK(appToggleActivate),
+ (gpointer)descr);
+ gtk_menu_shell_append(GTK_MENU_SHELL(descr->widget), descr->activator);
+
+ gtk_widget_show(descr->activator);
+ gtk_widget_show(separator);
gtk_widget_show(descr->widget);
descr->nitems = 0;
* Create first item and mark it as INIT due to
* void menu is showed very bad
*/
- addMenuItem( descr, StartupItem, strlen(StartupItem) );
+ addMenuItem( descr, g_strdup(StartupItem) );
descr->items[0]->flags = CMI_INIT;
+
+ descr->is_active = TRUE;
}
/*
- * Retrieves content of clipoard in a text form
+ * Receive text content of buffer
+ *
+ * it seems to me, that there is some problem in gtk+
+ * when targets MULTIPLE and TARGETS are set (at least with russian
+ * characters in OO ). So just ignore such cases...
*/
static void
-receiveText(GtkClipboard *cpb, const gchar *text, gpointer data)
+receiveTarget(GtkClipboard *clipboard, GdkAtom *atoms, gint n_atoms, gpointer data)
{
- if ( text != NULL )
- addMenuItem( (ClipboardDescr*)data, text, strlen(text) );
+ gint i;
+ gboolean has_text = FALSE,
+ has_multiple = FALSE,
+ has_targets = FALSE;
+
+ /*
+ * checks all avaliable targets
+ */
+ for(i=0;i<n_atoms;i++)
+ {
+ if ( atoms[i] == gdk_atom_intern_static_string("UTF8_STRING") ||
+ atoms[i] == gdk_atom_intern_static_string("COMPOUND_TEXT") )
+ {
+ has_text = TRUE;
+ }
+ else if ( atoms[i] == gdk_atom_intern_static_string("MULTIPLE") )
+ {
+ has_multiple = TRUE;
+ }
+ else if ( atoms[i] == gdk_atom_intern_static_string("TARGETS") )
+ {
+ has_targets = TRUE;
+ }
+ }
+
+ /*
+ * check for workaround
+ */
+ if ( has_text == TRUE && ( has_multiple==FALSE || has_targets == TRUE ) )
+ {
+ gchar *text = gtk_clipboard_wait_for_text(clipboard);
+
+ if (text)
+ addMenuItem( (ClipboardDescr*)data, text );
+ }
}
/*
static void
ClipboardChange(GtkClipboard *clipboard, GdkEvent *event, gpointer data)
{
- gtk_clipboard_request_text( clipboard, receiveText, data );
+ /*
+ * Do real work if and only if application is active
+ */
+ if ( ((ClipboardDescr*)data)->is_active )
+ gtk_clipboard_request_targets( clipboard, receiveTarget, data );
}
int