From d1fe47618e83c4ec57bff71ba28783938f48bf01 Mon Sep 17 00:00:00 2001 From: Cristian Henzel Date: Sun, 14 Nov 2010 21:03:11 +0200 Subject: [PATCH] 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. --- ChangeLog | 11 ++ TODO | 3 - configure.in | 2 +- src/history.h | 8 +- src/main.c | 130 ++++++--------------- src/manage.c | 316 ++++++++++++++++++++++++++++++++++++++++---------- 6 files changed, 306 insertions(+), 164 deletions(-) diff --git a/ChangeLog b/ChangeLog index a803bfb..b395a96 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 + Fixed: Removed reference to pthread.h from configure.in. + Fixed: Set AM_MAINTAINER_MODE to disabled by default. diff --git a/TODO b/TODO index be80c4f..04aeb1b 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,7 @@ + Add primary support for CLI. -+ Dialog with listed history contents for searching and removing. + Static entries. + 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. + Redo Preferences dialog. + 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. diff --git a/configure.in b/configure.in index 09cc6b6..09cc86c 100644 --- a/configure.in +++ b/configure.in @@ -2,7 +2,7 @@ # Autoconf/automake. # ------------------------------------------------------------------------------- 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()]) AC_CONFIG_MACRO_DIR([m4]) diff --git a/src/history.h b/src/history.h index 30e1db6..bca7e71 100644 --- a/src/history.h +++ b/src/history.h @@ -25,9 +25,11 @@ G_BEGIN_DECLS #define HISTORY_FILE ".local/share/clipit/history" -/* Set maximum size of one clipboard entry to 512KB - * 250 pages × 2000 characters per page - should be more than enough */ -#define ENTRY_MAX_SIZE 524288 +/* Set maximum size of one clipboard entry to 1024KB (1MB) + * 1024 pages × 2000 characters per page - should be more than enough. + * 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; diff --git a/src/main.c b/src/main.c index 8ced7fa..71addfa 100644 --- a/src/main.c +++ b/src/main.c @@ -264,60 +264,6 @@ edit_actions_selected(GtkButton *button, gpointer user_data) 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 */ static void item_selected(GtkMenuItem *menu_item, gpointer user_data) @@ -584,14 +530,6 @@ show_history_menu_full(gpointer data) /* Create the menu */ menu = gtk_menu_new(); 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 */ if ((history != NULL) && (history->data != NULL)) { @@ -610,15 +548,6 @@ show_history_menu_full(gpointer data) for (element = history; element != NULL; element = element->next) { 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 */ if (string->len > prefs.item_length) { @@ -638,6 +567,14 @@ show_history_menu_full(gpointer data) 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 */ gchar* list_item; 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) { 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 */ if (string->len > prefs.item_length) { @@ -761,6 +689,14 @@ show_history_menu_small(gpointer data) 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 */ gchar* list_item; if (prefs.show_indexes) @@ -835,20 +771,19 @@ show_history_menu_small(gpointer data) /* Called when status icon is left-clicked */ static gboolean -show_history_menu(gpointer data) +show_history_menu() { - if (prefs.small_history) - g_timeout_add(POPUP_DELAY, show_history_menu_small, NULL); - else - g_timeout_add(POPUP_DELAY, show_history_menu_full, NULL); + if (prefs.small_history) + g_timeout_add(POPUP_DELAY, show_history_menu_small, NULL); + else + g_timeout_add(POPUP_DELAY, show_history_menu_full, NULL); /* Return FALSE so the g_timeout_add() function is called only once */ return FALSE; } /* Called when status icon is right-clicked */ static void -show_clipit_menu(GtkStatusIcon *status_icon, guint button, - guint activate_time, gpointer user_data) +show_clipit_menu(GtkStatusIcon *status_icon, guint button, guint activate_time) { /* Declare some variables */ GtkWidget *menu, *menu_item, @@ -886,13 +821,13 @@ show_clipit_menu(GtkStatusIcon *status_icon, guint button, gtk_menu_shell_append((GtkMenuShell*)menu, menu_item); /* Popup the 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 */ /* (checks type of click and calls correct function */ 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 */ GdkModifierType state; @@ -906,9 +841,13 @@ status_icon_clicked(GtkStatusIcon *status_icon, gpointer user_data) } } /* Normal click */ + else if (event->button == 1) + { + show_history_menu(); + } else { - g_timeout_add(POPUP_DELAY, show_history_menu, NULL); + show_clipit_menu(status_icon, event->button, gtk_get_current_event_time()); } } @@ -930,16 +869,14 @@ actions_hotkey(char *keystring, gpointer user_data) void 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 */ void 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); } /* Startup calls and initializations */ @@ -970,8 +907,7 @@ clipit_init() { status_icon = gtk_status_icon_new_from_stock(GTK_STOCK_PASTE); 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, "popup-menu", (GCallback)show_clipit_menu, NULL); + g_signal_connect((GObject*)status_icon, "button_release_event", (GCallback)status_icon_clicked, NULL); } } @@ -1029,7 +965,7 @@ main(int argc, char *argv[]) /* Init ClipIt */ clipit_init(); - + /* Run GTK+ loop */ gtk_main(); diff --git a/src/manage.c b/src/manage.c index 3537ae3..6277a9b 100644 --- a/src/manage.c +++ b/src/manage.c @@ -21,6 +21,7 @@ #include #include +#include #include "main.h" #include "utils.h" #include "history.h" @@ -30,22 +31,233 @@ GtkListStore* search_list; 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 search_doubleclick() { GtkTreeIter sel_iter; + GtkTreeSelection* search_selection = gtk_tree_view_get_selection((GtkTreeView*)treeview_search); /* Check if selected */ if (gtk_tree_selection_get_selected(search_selection, NULL, &sel_iter)) { gchar *selected_item; - gtk_tree_model_get((GtkTreeModel*)search_list, &sel_iter, 0, &selected_item, -1); - GString* s_selected_item = g_string_new(selected_item); + gtk_tree_model_get((GtkTreeModel*)search_list, &sel_iter, 1, &selected_item, -1); + GtkClipboard* prim = gtk_clipboard_get(GDK_SELECTION_PRIMARY); 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); 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; } -/* 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 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; } +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 */ gboolean show_search() { + /* Prevent multiple instances */ + if(gtk_grab_get_current()) + return FALSE; /* Declare some variables */ GtkWidget *frame, *label, *alignment, *hbox, @@ -123,15 +306,14 @@ show_search() GtkTreeViewColumn *tree_column; /* Create the dialog */ - GtkWidget* search_dialog = gtk_dialog_new_with_buttons(_("Search"), NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); + GtkWidget* search_dialog = gtk_dialog_new(); 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_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_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_shadow_type((GtkScrolledWindow*)scrolled_window_search, GTK_SHADOW_ETCHED_OUT); - GtkWidget* treeview_search = gtk_tree_view_new(); - gtk_tree_view_set_reorderable((GtkTreeView*)treeview_search, TRUE); + treeview_search = gtk_tree_view_new(); 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); - GtkCellRenderer* name_renderer_exclude = gtk_cell_renderer_text_new(); - g_object_set(name_renderer_exclude, "ellipsize", PANGO_ELLIPSIZE_END, NULL); - g_object_set(name_renderer_exclude, "single-paragraph-mode", TRUE, NULL); - tree_column = gtk_tree_view_column_new_with_attributes(_("Results"), name_renderer_exclude, "text", 0, NULL); - gtk_tree_view_column_set_resizable(tree_column, TRUE); + GtkCellRenderer* cell_renderer = gtk_cell_renderer_text_new(); + tree_column = gtk_tree_view_column_new_with_attributes("ID", cell_renderer, NULL); + gtk_tree_view_column_set_visible(tree_column, FALSE); + gtk_tree_view_append_column((GtkTreeView*)treeview_search, tree_column); + 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_container_add((GtkContainer*)scrolled_window_search, treeview_search); 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); 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); /* show the 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; }