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
+ Fixed: Removed reference to pthread.h from configure.in.
+ Fixed: Set AM_MAINTAINER_MODE to disabled by default.

3
TODO
View File

@ -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.

View File

@ -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])

View File

@ -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;

View File

@ -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,7 +771,7 @@ 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);
@ -847,8 +783,7 @@ show_history_menu(gpointer data)
/* 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,15 +869,13 @@ 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);
}
@ -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);
}
}

View File

@ -21,6 +21,7 @@
#include <glib.h>
#include <gtk/gtk.h>
#include <string.h>
#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;
}