1 #include "wmcliphist.h"
2 #include <gdk/gdkkeysyms.h>
5 /* color of locked item */
6 gchar locked_color_str
[32] = DEF_LOCKED_COLOR
;
9 /* Exec on middle click? */
10 int exec_middleclick
= 1;
12 /* main window widget */
13 GtkWidget
*main_window
;
15 /* dock icon widget */
18 /* clipboard history menu */
20 GtkWidget
*menu_title
;
21 gint submenu_count
= 0;
23 /* application menu */
25 GtkWidget
*menu_app_clip_lock
;
26 GtkWidget
*menu_app_clip_ignore
;
27 GtkWidget
*menu_app_exit
;
28 GtkWidget
*menu_app_save
;
39 /* which clipboard to use */
40 gchar clipboard_str
[32] = DEF_CLIPBOARD_STR
;
43 /* ==========================================================================
44 * clipboard history menu
48 * history menu item button click function
51 menu_item_button_released(GtkWidget
*widget
,
55 GdkEventButton
*bevent
= (GdkEventButton
*)event
;
56 HISTORY_ITEM
*data
= user_data
;
58 begin_func("menu_item_button_released");
60 /* button 2 or 3 - exec or (un)lock item respectively */
61 if (bevent
->button
== 2) {
62 if (exec_middleclick
) {
63 gtk_menu_popdown(GTK_MENU(menu_hist
));
64 exec_item(data
->content
, NULL
);
67 } else if (bevent
->button
== 3) {
68 if (data
->locked
== 0) {
70 /* cannot lock all records */
71 if (locked_count
== num_items_to_keep
- 1) {
72 show_message("There must remain at least one "
73 "unlocked item\nwhen menu is full!",
74 "Warning", "OK", NULL
, NULL
);
78 gtk_widget_override_color(
79 gtk_bin_get_child(GTK_BIN(data
->menu_item
)),
80 GTK_STATE_FLAG_NORMAL
, &locked_color
);
85 gtk_widget_override_color(
86 gtk_bin_get_child(GTK_BIN(data
->menu_item
)),
87 GTK_STATE_FLAG_NORMAL
, NULL
);
100 * history menu item left click or keypress function
103 menu_item_activated(GtkWidget
*widget
, gpointer user_data
)
105 move_item_to_begin((HISTORY_ITEM
*) user_data
);
111 * checks, if there is already such item in menu,
112 * in which case it moves it to the begining
115 menu_item_exists(gchar
*content
, GtkWidget
*submenu
)
117 HISTORY_ITEM
*hist_item
;
120 begin_func("menu_item_exists");
122 list_node
= g_list_last(history_items
);
124 hist_item
= (HISTORY_ITEM
*)list_node
->data
;
125 if (hist_item
->menu
== submenu
126 && g_utf8_collate(hist_item
->content
, content
)
128 gtk_menu_reorder_child(GTK_MENU(hist_item
->menu
),
129 hist_item
->menu_item
, 1);
130 history_items
= g_list_remove_link(history_items
,
132 history_items
= g_list_concat(list_node
, history_items
);
134 return_val(hist_item
);
136 list_node
= g_list_previous(list_node
);
144 * add new item to menu
147 menu_item_add(gchar
*content
, gint locked
, GtkWidget
*target_menu
)
151 gchar
*menu_item_name
;
152 gchar
*fixed_menu_item_name
;
154 HISTORY_ITEM
*hist_item
;
156 begin_func("menu_item_add");
158 hist_item
= menu_item_exists(content
, target_menu
);
159 if (hist_item
!= NULL
) {
160 dump_history_list("reorder");
161 return_val(hist_item
);
164 if (num_items
== num_items_to_keep
) {
165 /* max item limit reached, destroy oldest one */
166 list_node
= g_list_last(history_items
);
168 hist_item
= (HISTORY_ITEM
*)
170 if (hist_item
->locked
== 0)
172 list_node
= g_list_previous(list_node
);
173 g_assert((list_node
!= NULL
));
176 history_items
= g_list_remove_link(history_items
, list_node
);
177 /* gtk_container_remove(GTK_CONTAINER(hist_item->menu),
178 hist_item->menu_item); */
179 gtk_widget_destroy(hist_item
->menu_item
);
180 g_free(hist_item
->content
);
182 g_list_free_1(list_node
);
184 dump_history_list("remove oldest");
187 /* prepare menu item name */
188 menu_item_name
= g_new0(char, MAX_ITEM_LENGTH
* 2 + 1);
189 memset(menu_item_name
, 0, MAX_ITEM_LENGTH
* 2 + 1);
190 length
= g_utf8_strlen(content
, -1);
191 if (length
> (size_t) (MAX_ITEM_LENGTH
)) {
192 g_utf8_strncpy(menu_item_name
, content
, MAX_ITEM_LENGTH
- 4);
193 strcat(menu_item_name
, "...");
195 strcpy(menu_item_name
, content
);
198 /* do some menu item name cleanups */
199 fixed_menu_item_name
= g_new0(char, strlen(menu_item_name
) + 1);
200 for (i
= 0; i
< g_utf8_strlen(menu_item_name
, -1); i
++) {
201 gchar
*uchar_ptr
= g_utf8_offset_to_pointer(menu_item_name
, i
);
202 gunichar uchar
= g_utf8_get_char(uchar_ptr
);
203 if (g_unichar_isprint(uchar
)) {
204 gchar
*decoded_char
= g_ucs4_to_utf8(&uchar
, 1, NULL
,
206 strcat(fixed_menu_item_name
, decoded_char
);
207 g_free(decoded_char
);
209 strcat(fixed_menu_item_name
, "_");
212 g_free(menu_item_name
);
213 menu_item_name
= fixed_menu_item_name
;
215 /* create menu item */
216 hist_item
= g_new0(HISTORY_ITEM
, 1);
217 hist_item
->menu_item
= gtk_menu_item_new_with_label(menu_item_name
);
218 hist_item
->content
= g_strdup(content
);
219 hist_item
->locked
= locked
;
220 hist_item
->menu
= target_menu
;
223 gtk_widget_override_color(
224 gtk_bin_get_child(GTK_BIN(hist_item
->menu_item
)),
225 GTK_STATE_FLAG_NORMAL
, &locked_color
);
230 gtk_menu_shell_insert(GTK_MENU_SHELL(hist_item
->menu
), hist_item
->menu_item
, 1);
233 /* connect actions to signals */
234 g_signal_connect(G_OBJECT(hist_item
->menu_item
),
235 "button-release-event",
236 G_CALLBACK(menu_item_button_released
),
237 (gpointer
)hist_item
);
239 g_signal_connect(G_OBJECT(hist_item
->menu_item
),
241 G_CALLBACK(menu_item_activated
),
242 (gpointer
)hist_item
);
244 gtk_widget_show(hist_item
->menu_item
);
246 history_items
= g_list_insert(history_items
, hist_item
, 0);
250 return_val(hist_item
);
255 /* ==========================================================================
260 * application main menu handler
263 menu_app_item_click(GtkWidget
*menuitem
, gpointer data
)
267 begin_func("menu_app_item_click");
269 switch (GPOINTER_TO_INT(data
)) {
270 /* save history menu */
272 if (history_save() != 0) {
273 button
= show_message("History was NOT saved.\n",
274 "Warning", "OK", NULL
, NULL
);
280 if (history_save() != 0) {
281 button
= show_message("History was NOT saved.\n"
282 "Do you really want to exit?",
283 "Error", "Yes", "No", NULL
);
299 /* ==========================================================================
304 * dock button click response
307 button_press(GtkWidget
*widget
, GdkEvent
*event
, gpointer data
)
309 begin_func("button_press");
311 if (event
->type
== GDK_BUTTON_PRESS
) {
312 GdkEventButton
*bevent
= (GdkEventButton
*)event
;
314 switch (bevent
->button
) {
316 /* popup history menu */
317 gtk_menu_popup(GTK_MENU(menu_hist
),
325 /* popup application menu */
326 gtk_menu_popup(GTK_MENU(menu_app
),
339 /* ==========================================================================
345 * open dialog with specified message and buttons
346 * and return number of button pressed
349 show_message(gchar
*message
, char *title
,
350 char *b0_text
, char *b1_text
, char *b2_text
)
356 gint button_pressed
= 1;
358 begin_func("show_message");
360 /* create the main widgets */
361 dialog
= gtk_dialog_new();
363 content_area
= gtk_dialog_get_content_area(GTK_DIALOG(dialog
));
365 /* Show the message */
366 label
= gtk_label_new(message
);
367 gtk_container_add(GTK_CONTAINER (content_area
), label
);
368 gtk_widget_show(label
);
371 gtk_dialog_add_button(GTK_DIALOG (dialog
), b0_text
, 0);
372 if(b1_text
!= NULL
) gtk_dialog_add_button(GTK_DIALOG (dialog
), b1_text
, 1);
373 if(b2_text
!= NULL
) gtk_dialog_add_button(GTK_DIALOG (dialog
), b2_text
, 2);
375 gtk_widget_show_all(dialog
);
377 /* set the dialog title */
378 gtk_window_set_title(GTK_WINDOW(dialog
), title
);
380 /* set the dialog modal and transient */
381 /* gtk_window_set_modal(GTK_WINDOW (dialog), TRUE);*/
382 gtk_window_set_transient_for(GTK_WINDOW (dialog
), GTK_WINDOW (dock_app
));
384 /*wait for the user response */
385 result
= gtk_dialog_run (GTK_DIALOG (dialog
));
401 /*destroy the dialog box, when the user responds */
402 gtk_widget_destroy(dialog
);
404 return_val(button_pressed
);