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:
parent
49b85b9c5e
commit
d1fe47618e
11
ChangeLog
11
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.
|
||||
|
3
TODO
3
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.
|
||||
|
@ -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])
|
||||
|
@ -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;
|
||||
|
||||
|
128
src/main.c
128
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
316
src/manage.c
316
src/manage.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user