ClipIt-v1.3.0-14112010001

+ Added: Added "Edit" and "Remove" buttons to the "Manage History" dialog.
+ Fixed: Major speed improvements for big history entries while:
		searching through the history;
		populating the "Manage History" dialog;
		generating the popup menus;
	All of these should now be more than 99% faster, at the expense
	of an (at most) 1MB overhead. I think it's worth it, though.
+ Fixed: Fixed a drawing issue with the small history menu when activated
		by clicking on the systray icon.
This commit is contained in:
Cristian Henzel 2010-11-14 21:03:11 +02:00 committed by Cristian Henzel
parent 49b85b9c5e
commit d1fe47618e
6 changed files with 306 additions and 164 deletions

View File

@ -1,3 +1,14 @@
ClipIt-v1.3.0-14112010001 - 14 Nov. 2010
+ Added: Added "Edit" and "Remove" buttons to the "Manage History" dialog.
+ Fixed: Major speed improvements for big history entries while:
searching through the history;
populating the "Manage History" dialog;
generating the popup menus;
All of these should now be more than 99% faster, at the expense
of an (at most) 1MB overhead. I think it's worth it, though.
+ Fixed: Fixed a drawing issue with the small history menu when activated
by clicking on the systray icon.
ClipIt-v1.2.6-12112010003 - 12 Nov. 2010 ClipIt-v1.2.6-12112010003 - 12 Nov. 2010
+ Fixed: Removed reference to pthread.h from configure.in. + Fixed: Removed reference to pthread.h from configure.in.
+ Fixed: Set AM_MAINTAINER_MODE to disabled by default. + Fixed: Set AM_MAINTAINER_MODE to disabled by default.

3
TODO
View File

@ -1,10 +1,7 @@
+ Add primary support for CLI. + Add primary support for CLI.
+ Dialog with listed history contents for searching and removing.
+ Static entries. + Static entries.
+ Added variable to hold return values of fread and system, we should + Added variable to hold return values of fread and system, we should
actually use that return value to display an error if there was one. actually use that return value to display an error if there was one.
+ Redo Preferences dialog. + Redo Preferences dialog.
+ Clean up the code and indent it properly. + Clean up the code and indent it properly.
+ Add "Edit" and "Remove" buttons to the search window and rename
it to "Manage Clipboard".
+ Move all pop-up and menu functions from main.c to menus.c. + Move all pop-up and menu functions from main.c to menus.c.

View File

@ -2,7 +2,7 @@
# Autoconf/automake. # Autoconf/automake.
# ------------------------------------------------------------------------------- # -------------------------------------------------------------------------------
AC_PREREQ([2.5]) AC_PREREQ([2.5])
AC_INIT([clipit], [1.2.6], [oss@web-tm.com]) AC_INIT([clipit], [1.3.0], [oss@web-tm.com])
AM_INIT_AUTOMAKE([AC_PACKAGE_TARNAME()], [AC_PACKAGE_VERSION()]) AM_INIT_AUTOMAKE([AC_PACKAGE_TARNAME()], [AC_PACKAGE_VERSION()])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View File

@ -25,9 +25,11 @@
G_BEGIN_DECLS G_BEGIN_DECLS
#define HISTORY_FILE ".local/share/clipit/history" #define HISTORY_FILE ".local/share/clipit/history"
/* Set maximum size of one clipboard entry to 512KB /* Set maximum size of one clipboard entry to 1024KB (1MB)
* 250 pages × 2000 characters per page - should be more than enough */ * 1024 pages × 2000 characters per page - should be more than enough.
#define ENTRY_MAX_SIZE 524288 * WARNING: if you use all 1000 history items, clipit could use up to
* 1 GB of RAM. If you don't want that, set this lower. */
#define ENTRY_MAX_SIZE 1048576
extern GSList* history; extern GSList* history;

View File

@ -264,60 +264,6 @@ edit_actions_selected(GtkButton *button, gpointer user_data)
show_preferences(ACTIONS_TAB); show_preferences(ACTIONS_TAB);
} }
/* Called when Edit is selected from history menu */
static void
edit_selected(GtkMenuItem *menu_item, gpointer user_data)
{
/* This helps prevent multiple instances */
if (!gtk_grab_get_current())
{
/* Create clipboard buffer and set its text */
GtkTextBuffer* clipboard_buffer = gtk_text_buffer_new(NULL);
gchar* current_clipboard_text = gtk_clipboard_wait_for_text(clipboard);
if (current_clipboard_text != NULL)
{
gtk_text_buffer_set_text(clipboard_buffer, current_clipboard_text, -1);
}
/* Create the dialog */
GtkWidget* dialog = gtk_dialog_new_with_buttons(_("Editing Clipboard"), NULL,
(GTK_DIALOG_MODAL + GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
gtk_window_set_default_size((GtkWindow*)dialog, 450, 300);
gtk_window_set_icon((GtkWindow*)dialog, gtk_widget_render_icon(dialog, GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU, NULL));
/* Build the scrolled window with the text view */
GtkWidget* scrolled_window = gtk_scrolled_window_new((GtkAdjustment*) gtk_adjustment_new(0, 0, 0, 0, 0, 0),
(GtkAdjustment*) gtk_adjustment_new(0, 0, 0, 0, 0, 0));
gtk_scrolled_window_set_policy((GtkScrolledWindow*)scrolled_window,
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrolled_window, TRUE, TRUE, 2);
GtkWidget* text_view = gtk_text_view_new_with_buffer(clipboard_buffer);
gtk_text_view_set_left_margin((GtkTextView*)text_view, 2);
gtk_text_view_set_right_margin((GtkTextView*)text_view, 2);
gtk_container_add((GtkContainer*)scrolled_window, text_view);
/* Run the dialog */
gtk_widget_show_all(dialog);
if (gtk_dialog_run((GtkDialog*)dialog) == GTK_RESPONSE_ACCEPT)
{
/* Save changes done to the clipboard */
GtkTextIter start, end;
gtk_text_buffer_get_start_iter(clipboard_buffer, &start);
gtk_text_buffer_get_end_iter(clipboard_buffer, &end);
gchar* new_clipboard_text = gtk_text_buffer_get_text(clipboard_buffer, &start, &end, TRUE);
gtk_clipboard_set_text(clipboard, new_clipboard_text, -1);
g_free(new_clipboard_text);
}
gtk_widget_destroy(dialog);
g_free(current_clipboard_text);
}
}
/* Called when an item is selected from history menu */ /* Called when an item is selected from history menu */
static void static void
item_selected(GtkMenuItem *menu_item, gpointer user_data) item_selected(GtkMenuItem *menu_item, gpointer user_data)
@ -584,14 +530,6 @@ show_history_menu_full(gpointer data)
/* Create the menu */ /* Create the menu */
menu = gtk_menu_new(); menu = gtk_menu_new();
g_signal_connect((GObject*)menu, "selection-done", (GCallback)gtk_widget_destroy, NULL); g_signal_connect((GObject*)menu, "selection-done", (GCallback)gtk_widget_destroy, NULL);
/* Edit clipboard */
menu_item = gtk_image_menu_item_new_with_mnemonic(_("_Edit Clipboard"));
menu_image = gtk_image_new_from_stock(GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image((GtkImageMenuItem*)menu_item, menu_image);
g_signal_connect((GObject*)menu_item, "activate", (GCallback)edit_selected, NULL);
gtk_menu_shell_append((GtkMenuShell*)menu, menu_item);
/* -------------------- */
gtk_menu_shell_append((GtkMenuShell*)menu, gtk_separator_menu_item_new());
/* Items */ /* Items */
if ((history != NULL) && (history->data != NULL)) if ((history != NULL) && (history->data != NULL))
{ {
@ -610,15 +548,6 @@ show_history_menu_full(gpointer data)
for (element = history; element != NULL; element = element->next) for (element = history; element != NULL; element = element->next)
{ {
GString* string = g_string_new((gchar*)element->data); GString* string = g_string_new((gchar*)element->data);
/* Remove control characters */
int i = 0;
while (i < string->len)
{
if (string->str[i] == '\n')
g_string_erase(string, i, 1);
else
i++;
}
/* Ellipsize text */ /* Ellipsize text */
if (string->len > prefs.item_length) if (string->len > prefs.item_length)
{ {
@ -638,6 +567,14 @@ show_history_menu_full(gpointer data)
break; break;
} }
} }
/* Remove control characters */
int i = 0;
while (i < string->len)
{
if (string->str[i] == '\n')
g_string_overwrite(string, i, " ");
i++;
}
/* Make new item with ellipsized text */ /* Make new item with ellipsized text */
gchar* list_item; gchar* list_item;
if (prefs.show_indexes) if (prefs.show_indexes)
@ -733,15 +670,6 @@ show_history_menu_small(gpointer data)
for (element = history; (element != NULL) && (element_number_small < prefs.history_small); element = element->next) for (element = history; (element != NULL) && (element_number_small < prefs.history_small); element = element->next)
{ {
GString* string = g_string_new((gchar*)element->data); GString* string = g_string_new((gchar*)element->data);
/* Remove control characters */
int i = 0;
while (i < string->len)
{
if (string->str[i] == '\n')
g_string_erase(string, i, 1);
else
i++;
}
/* Ellipsize text */ /* Ellipsize text */
if (string->len > prefs.item_length) if (string->len > prefs.item_length)
{ {
@ -761,6 +689,14 @@ show_history_menu_small(gpointer data)
break; break;
} }
} }
/* Remove control characters */
int i = 0;
while (i < string->len)
{
if (string->str[i] == '\n')
g_string_overwrite(string, i, " ");
i++;
}
/* Make new item with ellipsized text */ /* Make new item with ellipsized text */
gchar* list_item; gchar* list_item;
if (prefs.show_indexes) if (prefs.show_indexes)
@ -835,7 +771,7 @@ show_history_menu_small(gpointer data)
/* Called when status icon is left-clicked */ /* Called when status icon is left-clicked */
static gboolean static gboolean
show_history_menu(gpointer data) show_history_menu()
{ {
if (prefs.small_history) if (prefs.small_history)
g_timeout_add(POPUP_DELAY, show_history_menu_small, NULL); g_timeout_add(POPUP_DELAY, show_history_menu_small, NULL);
@ -847,8 +783,7 @@ show_history_menu(gpointer data)
/* Called when status icon is right-clicked */ /* Called when status icon is right-clicked */
static void static void
show_clipit_menu(GtkStatusIcon *status_icon, guint button, show_clipit_menu(GtkStatusIcon *status_icon, guint button, guint activate_time)
guint activate_time, gpointer user_data)
{ {
/* Declare some variables */ /* Declare some variables */
GtkWidget *menu, *menu_item, GtkWidget *menu, *menu_item,
@ -886,13 +821,13 @@ show_clipit_menu(GtkStatusIcon *status_icon, guint button,
gtk_menu_shell_append((GtkMenuShell*)menu, menu_item); gtk_menu_shell_append((GtkMenuShell*)menu, menu_item);
/* Popup the menu... */ /* Popup the menu... */
gtk_widget_show_all(menu); gtk_widget_show_all(menu);
gtk_menu_popup((GtkMenu*)menu, NULL, NULL, NULL, user_data, button, activate_time); gtk_menu_popup((GtkMenu*)menu, NULL, NULL, NULL, NULL, button, activate_time);
} }
/* Called when status icon is clicked */ /* Called when status icon is clicked */
/* (checks type of click and calls correct function */ /* (checks type of click and calls correct function */
static void static void
status_icon_clicked(GtkStatusIcon *status_icon, gpointer user_data) status_icon_clicked(GtkStatusIcon *status_icon, GdkEventButton *event )
{ {
/* Check what type of click was recieved */ /* Check what type of click was recieved */
GdkModifierType state; GdkModifierType state;
@ -906,9 +841,13 @@ status_icon_clicked(GtkStatusIcon *status_icon, gpointer user_data)
} }
} }
/* Normal click */ /* Normal click */
else if (event->button == 1)
{
show_history_menu();
}
else else
{ {
g_timeout_add(POPUP_DELAY, show_history_menu, NULL); show_clipit_menu(status_icon, event->button, gtk_get_current_event_time());
} }
} }
@ -930,15 +869,13 @@ actions_hotkey(char *keystring, gpointer user_data)
void void
menu_hotkey(char *keystring, gpointer user_data) menu_hotkey(char *keystring, gpointer user_data)
{ {
show_clipit_menu(status_icon, 0, 0, NULL); show_clipit_menu(status_icon, 0, 0);
} }
/* Called when search global hotkey is pressed */ /* Called when search global hotkey is pressed */
void void
search_hotkey(char *keystring, gpointer user_data) search_hotkey(char *keystring, gpointer user_data)
{ {
if (!gtk_grab_get_current())
/* Show the search dialog */
g_timeout_add(POPUP_DELAY, show_search, NULL); g_timeout_add(POPUP_DELAY, show_search, NULL);
} }
@ -970,8 +907,7 @@ clipit_init()
{ {
status_icon = gtk_status_icon_new_from_stock(GTK_STOCK_PASTE); status_icon = gtk_status_icon_new_from_stock(GTK_STOCK_PASTE);
gtk_status_icon_set_tooltip((GtkStatusIcon*)status_icon, _("Clipboard Manager")); gtk_status_icon_set_tooltip((GtkStatusIcon*)status_icon, _("Clipboard Manager"));
g_signal_connect((GObject*)status_icon, "activate", (GCallback)status_icon_clicked, NULL); g_signal_connect((GObject*)status_icon, "button_release_event", (GCallback)status_icon_clicked, NULL);
g_signal_connect((GObject*)status_icon, "popup-menu", (GCallback)show_clipit_menu, NULL);
} }
} }

View File

@ -21,6 +21,7 @@
#include <glib.h> #include <glib.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <string.h>
#include "main.h" #include "main.h"
#include "utils.h" #include "utils.h"
#include "history.h" #include "history.h"
@ -30,22 +31,233 @@
GtkListStore* search_list; GtkListStore* search_list;
GtkWidget *search_entry; GtkWidget *search_entry;
GtkTreeSelection* search_selection; GtkWidget* treeview_search;
/* Search through the history */
static void
search_history()
{
guint16 search_len = gtk_entry_get_text_length((GtkEntry*)search_entry);
/* Test if there is text in the search box */
if(search_len > 0)
{
if ((history != NULL) && (history->data != NULL))
{
char* search_input = (char *)g_strdup(gtk_entry_get_text((GtkEntry*)search_entry));
GtkTreeIter search_iter;
while(gtk_tree_model_get_iter_first((GtkTreeModel*)search_list, &search_iter))
gtk_list_store_remove(search_list, &search_iter);
/* Declare some variables */
GSList* element;
gint element_number = 0;
/* Go through each element and adding each */
for (element = history; element != NULL; element = element->next)
{
GString* string = g_string_new((gchar*)element->data);
gchar* strn_cmp_to = g_utf8_strdown(string->str, string->len);
gchar* strn_find = g_utf8_strdown(search_input, search_len);
char* result = strstr(strn_cmp_to, strn_find);
if(result)
{
GtkTreeIter row_iter;
gtk_list_store_append(search_list, &row_iter);
if (string->len > prefs.item_length)
{
switch (prefs.ellipsize)
{
case PANGO_ELLIPSIZE_START:
string = g_string_erase(string, 0, string->len-(prefs.item_length));
string = g_string_prepend(string, "...");
break;
case PANGO_ELLIPSIZE_MIDDLE:
string = g_string_erase(string, (prefs.item_length/2), string->len-(prefs.item_length));
string = g_string_insert(string, (string->len/2), "...");
break;
case PANGO_ELLIPSIZE_END:
string = g_string_truncate(string, prefs.item_length);
string = g_string_append(string, "...");
break;
}
}
int i = 0;
while (i < string->len)
{
if (string->str[i] == '\n')
g_string_overwrite(string, i, " ");
i++;
}
int row_num = g_slist_position(history, element);
gtk_list_store_set(search_list, &row_iter, 0, row_num, 1, string->str, -1);
}
/* Prepare for next item */
g_string_free(string, TRUE);
element_number++;
}
}
}
else
{
/* If nothing is searched for, we show all items */
if ((history != NULL) && (history->data != NULL))
{
GtkTreeIter search_iter;
/* First, we remove all items */
while(gtk_tree_model_get_iter_first((GtkTreeModel*)search_list, &search_iter))
gtk_list_store_remove(search_list, &search_iter);
/* Declare some variables */
GSList* element;
/* Go through each element and adding each */
for (element = history; element != NULL; element = element->next)
{
GString* string = g_string_new((gchar*)element->data);
GtkTreeIter row_iter;
gtk_list_store_append(search_list, &row_iter);
if (string->len > prefs.item_length)
{
switch (prefs.ellipsize)
{
case PANGO_ELLIPSIZE_START:
string = g_string_erase(string, 0, string->len-(prefs.item_length));
string = g_string_prepend(string, "...");
break;
case PANGO_ELLIPSIZE_MIDDLE:
string = g_string_erase(string, (prefs.item_length/2), string->len-(prefs.item_length));
string = g_string_insert(string, (string->len/2), "...");
break;
case PANGO_ELLIPSIZE_END:
string = g_string_truncate(string, prefs.item_length);
string = g_string_append(string, "...");
break;
}
}
int i = 0;
while (i < string->len)
{
if (string->str[i] == '\n')
g_string_overwrite(string, i, " ");
i++;
}
int row_num = g_slist_position(history, element);
gtk_list_store_set(search_list, &row_iter, 0, row_num, 1, string->str, -1);
/* Prepare for next item */
g_string_free(string, TRUE);
}
}
}
}
/* Called when Edit is selected from Manage dialog */
static void
edit_selected()
{
GtkTreeIter sel_iter;
GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search);
/* This helps prevent multiple instances and checks if there's anything selected */
if (!gtk_grab_get_current() &&
gtk_tree_selection_get_selected(search_selection, NULL, &sel_iter))
{
/* Create clipboard buffer and set its text */
gint selected_item_nr;
gtk_tree_model_get((GtkTreeModel*)search_list, &sel_iter, 0, &selected_item_nr, -1);
GSList* element = g_slist_nth(history, selected_item_nr);
GString* s_selected_item = g_string_new((gchar*)element->data);
GtkTextBuffer* clipboard_buffer = gtk_text_buffer_new(NULL);
gtk_text_buffer_set_text(clipboard_buffer, s_selected_item->str, -1);
/* Create the dialog */
GtkWidget* dialog = gtk_dialog_new_with_buttons(_("Editing Clipboard"), NULL,
(GTK_DIALOG_MODAL + GTK_DIALOG_NO_SEPARATOR),
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);
gtk_window_set_default_size((GtkWindow*)dialog, 450, 300);
gtk_window_set_icon((GtkWindow*)dialog, gtk_widget_render_icon(dialog, GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU, NULL));
/* Build the scrolled window with the text view */
GtkWidget* scrolled_window = gtk_scrolled_window_new((GtkAdjustment*) gtk_adjustment_new(0, 0, 0, 0, 0, 0),
(GtkAdjustment*) gtk_adjustment_new(0, 0, 0, 0, 0, 0));
gtk_scrolled_window_set_policy((GtkScrolledWindow*)scrolled_window,
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), scrolled_window, TRUE, TRUE, 2);
GtkWidget* text_view = gtk_text_view_new_with_buffer(clipboard_buffer);
gtk_text_view_set_left_margin((GtkTextView*)text_view, 2);
gtk_text_view_set_right_margin((GtkTextView*)text_view, 2);
gtk_container_add((GtkContainer*)scrolled_window, text_view);
/* Run the dialog */
gtk_widget_show_all(dialog);
if (gtk_dialog_run((GtkDialog*)dialog) == GTK_RESPONSE_ACCEPT)
{
/* Save changes done to the clipboard */
GtkTextIter start, end;
gtk_text_buffer_get_start_iter(clipboard_buffer, &start);
gtk_text_buffer_get_end_iter(clipboard_buffer, &end);
/* Delete any duplicate */
delete_duplicate(gtk_text_buffer_get_text(clipboard_buffer, &start, &end, TRUE));
/* Insert new element before the old one */
history = g_slist_insert_before(history, element->next,
g_strdup(gtk_text_buffer_get_text(clipboard_buffer, &start, &end, TRUE))
);
/* Remove old entry */
history = g_slist_remove(history, element->data);
if(selected_item_nr == 0)
{
GtkClipboard* clipboard;
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_text(clipboard,
gtk_text_buffer_get_text(clipboard_buffer, &start, &end, TRUE),
-1
);
}
}
gtk_widget_destroy(dialog);
g_string_free(s_selected_item, TRUE);
search_history();
}
}
/* Called when Remove is selected from Manage dialog */
static void
remove_selected()
{
GtkTreeIter sel_iter;
GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search);
/* This checks if there's anything selected */
if (gtk_tree_selection_get_selected(search_selection, NULL, &sel_iter))
{
/* Get item to delete */
gint selected_item_nr;
gtk_tree_model_get((GtkTreeModel*)search_list, &sel_iter, 0, &selected_item_nr, -1);
GSList* element = g_slist_nth(history, selected_item_nr);
/* Remove entry */
history = g_slist_remove(history, element->data);
search_history();
}
}
static void static void
search_doubleclick() search_doubleclick()
{ {
GtkTreeIter sel_iter; GtkTreeIter sel_iter;
GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search);
/* Check if selected */ /* Check if selected */
if (gtk_tree_selection_get_selected(search_selection, NULL, &sel_iter)) if (gtk_tree_selection_get_selected(search_selection, NULL, &sel_iter))
{ {
gchar *selected_item; gchar *selected_item;
gtk_tree_model_get((GtkTreeModel*)search_list, &sel_iter, 0, &selected_item, -1); gtk_tree_model_get((GtkTreeModel*)search_list, &sel_iter, 1, &selected_item, -1);
GString* s_selected_item = g_string_new(selected_item); GtkClipboard* prim = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); GtkClipboard* clip = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
gtk_clipboard_set_text(prim, (gchar*)selected_item, -1);
gtk_clipboard_set_text(clip, (gchar*)selected_item, -1); gtk_clipboard_set_text(clip, (gchar*)selected_item, -1);
g_free(selected_item); g_free(selected_item);
g_string_free(s_selected_item, TRUE);
} }
} }
@ -60,48 +272,6 @@ search_click(GtkWidget *widget, GdkEventButton *event, GtkWidget *search_window)
return FALSE; return FALSE;
} }
/* Search through the history */
static void
search_history()
{
guint16 search_len = gtk_entry_get_text_length((GtkEntry*)search_entry);
gchar* search_input = g_strdup(gtk_entry_get_text((GtkEntry*)search_entry));
gchar* search_reg = g_regex_escape_string(search_input, search_len);
gchar* search_regex = g_strconcat (".*", search_reg, ".*", NULL);
GRegex* regex = g_regex_new(search_regex, G_REGEX_CASELESS, 0, NULL);
GtkTreeIter search_iter;
while(gtk_tree_model_get_iter_first((GtkTreeModel*)search_list, &search_iter))
gtk_list_store_remove(search_list, &search_iter);
/* Test if there is text in the search box */
if(search_len > 0)
{
if ((history != NULL) && (history->data != NULL))
{
/* Declare some variables */
GSList* element;
gint element_number = 0;
/* Go through each element and adding each */
for (element = history; element != NULL; element = element->next)
{
GString* string = g_string_new((gchar*)element->data);
gchar* compare = string->str;
gboolean result = g_regex_match(regex, compare, 0, NULL);
if(result)
{
GtkTreeIter row_iter;
gtk_list_store_append(search_list, &row_iter);
gtk_list_store_set(search_list, &row_iter, 0, string->str, -1);
}
/* Prepare for next item */
g_string_free(string, TRUE);
element_number++;
}
}
g_regex_unref(regex);
}
g_free(search_regex);
}
static gint static gint
search_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data) search_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{ {
@ -111,10 +281,23 @@ search_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
return FALSE; return FALSE;
} }
void
search_window_response(GtkDialog *dialog, gint response_id, gpointer user_data)
{
if(response_id < 0)
{
save_history();
gtk_widget_destroy((GtkWidget*)dialog);
}
}
/* Shows the search dialog */ /* Shows the search dialog */
gboolean gboolean
show_search() show_search()
{ {
/* Prevent multiple instances */
if(gtk_grab_get_current())
return FALSE;
/* Declare some variables */ /* Declare some variables */
GtkWidget *frame, *label, GtkWidget *frame, *label,
*alignment, *hbox, *alignment, *hbox,
@ -123,15 +306,14 @@ show_search()
GtkTreeViewColumn *tree_column; GtkTreeViewColumn *tree_column;
/* Create the dialog */ /* Create the dialog */
GtkWidget* search_dialog = gtk_dialog_new_with_buttons(_("Search"), NULL, GtkWidget* search_dialog = gtk_dialog_new();
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
gtk_window_set_icon((GtkWindow*)search_dialog, gtk_widget_render_icon(search_dialog, GTK_STOCK_FIND, GTK_ICON_SIZE_MENU, NULL)); gtk_window_set_icon((GtkWindow*)search_dialog, gtk_widget_render_icon(search_dialog, GTK_STOCK_FIND, GTK_ICON_SIZE_MENU, NULL));
gtk_window_set_title((GtkWindow*)search_dialog, "Manage History");
gtk_window_set_resizable((GtkWindow*)search_dialog, TRUE); gtk_window_set_resizable((GtkWindow*)search_dialog, TRUE);
gtk_window_set_position((GtkWindow*)search_dialog, GTK_WIN_POS_CENTER); gtk_window_set_position((GtkWindow*)search_dialog, GTK_WIN_POS_CENTER);
GtkWidget* vbox_search = gtk_vbox_new(FALSE, 12); GtkWidget* vbox_search = gtk_vbox_new(FALSE, 10);
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area (GTK_DIALOG(search_dialog))), vbox_search, TRUE, TRUE, 2); gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area (GTK_DIALOG(search_dialog))), vbox_search, TRUE, TRUE, 2);
gtk_widget_set_size_request((GtkWidget*)vbox_search, 400, 600); gtk_widget_set_size_request((GtkWidget*)vbox_search, 400, 600);
@ -148,29 +330,43 @@ show_search()
gtk_scrolled_window_set_policy((GtkScrolledWindow*)scrolled_window_search, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_policy((GtkScrolledWindow*)scrolled_window_search, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type((GtkScrolledWindow*)scrolled_window_search, GTK_SHADOW_ETCHED_OUT); gtk_scrolled_window_set_shadow_type((GtkScrolledWindow*)scrolled_window_search, GTK_SHADOW_ETCHED_OUT);
GtkWidget* treeview_search = gtk_tree_view_new(); treeview_search = gtk_tree_view_new();
gtk_tree_view_set_reorderable((GtkTreeView*)treeview_search, TRUE);
gtk_tree_view_set_rules_hint((GtkTreeView*)treeview_search, TRUE); gtk_tree_view_set_rules_hint((GtkTreeView*)treeview_search, TRUE);
search_list = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); search_list = gtk_list_store_new(2, G_TYPE_UINT, G_TYPE_STRING);
gtk_tree_view_set_model((GtkTreeView*)treeview_search, (GtkTreeModel*)search_list); gtk_tree_view_set_model((GtkTreeView*)treeview_search, (GtkTreeModel*)search_list);
GtkCellRenderer* name_renderer_exclude = gtk_cell_renderer_text_new(); GtkCellRenderer* cell_renderer = gtk_cell_renderer_text_new();
g_object_set(name_renderer_exclude, "ellipsize", PANGO_ELLIPSIZE_END, NULL); tree_column = gtk_tree_view_column_new_with_attributes("ID", cell_renderer, NULL);
g_object_set(name_renderer_exclude, "single-paragraph-mode", TRUE, NULL); gtk_tree_view_column_set_visible(tree_column, FALSE);
tree_column = gtk_tree_view_column_new_with_attributes(_("Results"), name_renderer_exclude, "text", 0, NULL); gtk_tree_view_append_column((GtkTreeView*)treeview_search, tree_column);
gtk_tree_view_column_set_resizable(tree_column, TRUE); cell_renderer = gtk_cell_renderer_text_new();
g_object_set(cell_renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
g_object_set(cell_renderer, "single-paragraph-mode", TRUE, NULL);
tree_column = gtk_tree_view_column_new_with_attributes("Results", cell_renderer, "text", 1, NULL);
gtk_tree_view_append_column((GtkTreeView*)treeview_search, tree_column); gtk_tree_view_append_column((GtkTreeView*)treeview_search, tree_column);
gtk_container_add((GtkContainer*)scrolled_window_search, treeview_search); gtk_container_add((GtkContainer*)scrolled_window_search, treeview_search);
gtk_box_pack_start((GtkBox*)vbox_search, scrolled_window_search, TRUE, TRUE, 0); gtk_box_pack_start((GtkBox*)vbox_search, scrolled_window_search, TRUE, TRUE, 0);
search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search); GtkWidget* edit_button = gtk_dialog_add_button((GtkDialog*)search_dialog, "Edit", 1);
g_signal_connect((GObject*)edit_button, "clicked", (GCallback)edit_selected, NULL);
GtkWidget* remove_button = gtk_dialog_add_button((GtkDialog*)search_dialog, "Remove", 1);
g_signal_connect((GObject*)remove_button, "clicked", (GCallback)remove_selected, NULL);
GtkWidget* close_button = gtk_dialog_add_button((GtkDialog*)search_dialog, "Close", GTK_RESPONSE_OK);
g_signal_connect((GObject*)close_button, "clicked", (GCallback)search_history, NULL);
GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search);
gtk_tree_selection_set_mode(search_selection, GTK_SELECTION_BROWSE); gtk_tree_selection_set_mode(search_selection, GTK_SELECTION_BROWSE);
g_signal_connect((GObject*)treeview_search, "button_press_event", (GCallback)search_click, search_dialog); g_signal_connect((GObject*)treeview_search, "button_press_event", (GCallback)search_click, search_dialog);
g_signal_connect((GtkDialog*)search_dialog, "response", (GCallback)gtk_widget_destroy, search_dialog); g_signal_connect((GtkDialog*)search_dialog, "response", (GCallback)search_window_response, search_dialog);
gtk_widget_show_all(vbox_search); gtk_widget_show_all(vbox_search);
/* show the dialog */ /* show the dialog */
gtk_widget_show_all((GtkWidget*)search_dialog); gtk_widget_show_all((GtkWidget*)search_dialog);
gtk_widget_set_sensitive((GtkWidget*)search_dialog, TRUE);
gtk_grab_add((GtkWidget*)search_dialog);
/* Populate the list */
search_history();
return FALSE; return FALSE;
} }