=== modified file 'glade/hub.glade' --- glade/hub.glade 2010-12-10 05:50:31 +0000 +++ glade/hub.glade 2011-02-16 19:17:53 +0000 @@ -189,10 +189,14 @@ - + True - _Copy user + _Copy True + + + + === modified file 'linux/hub.cc' --- linux/hub.cc 2010-12-23 04:10:02 +0000 +++ linux/hub.cc 2011-02-16 19:17:31 +0000 @@ -105,7 +105,6 @@ g_signal_connect(getWidget("chatText"), "visibility-notify-event", G_CALLBACK(onChatVisibilityChanged_gui), (gpointer)this); g_signal_connect(adjustment, "value_changed", G_CALLBACK(onChatScroll_gui), (gpointer)this); g_signal_connect(adjustment, "changed", G_CALLBACK(onChatResize_gui), (gpointer)this); - g_signal_connect(getWidget("copyNickItem"), "activate", G_CALLBACK(onCopyNickItemClicked_gui), (gpointer)this); g_signal_connect(getWidget("browseItem"), "activate", G_CALLBACK(onBrowseItemClicked_gui), (gpointer)this); g_signal_connect(getWidget("matchItem"), "activate", G_CALLBACK(onMatchItemClicked_gui), (gpointer)this); g_signal_connect(getWidget("msgItem"), "activate", G_CALLBACK(onMsgItemClicked_gui), (gpointer)this); @@ -312,6 +311,12 @@ void Hub::popupNickMenu_gui() { + buildUserCommandMenu_gui(); + buildCopyMenu_gui(); +} + +void Hub::buildUserCommandMenu_gui() +{ // Build user command menu userCommandMenu->cleanMenu_gui(); @@ -336,6 +341,43 @@ gtk_widget_show_all(getWidget("nickMenu")); } +void Hub::buildCopyMenu_gui() +{ + // Build copy menu + GtkWidget *menuItem; + GtkWidget *menu = getWidget("copyMenu"); + + gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)gtk_widget_destroy, NULL); + + menuItem = gtk_menu_item_new_with_label(_("Copy row")); + g_signal_connect(menuItem, "activate", GCallback(onCopyRowClicked_gui), (gpointer)this); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItem); + + menuItem = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItem); + + for (size_t i = 0; i < nickView.getColCount(); i++) + { + GtkTreeViewColumn *col = gtk_tree_view_get_column(nickView.get(), i); + if (col == NULL) + continue; + + string title = gtk_tree_view_column_get_title(col); + gboolean visible = gtk_tree_view_column_get_visible(col); + + if (visible && !title.empty()) + { + menuItem = gtk_menu_item_new_with_label(title.c_str()); + g_signal_connect(menuItem, "activate", GCallback(onCopyDataItemClicked_gui), (gpointer)this); + g_object_set_data_full(G_OBJECT(menuItem), "title", g_strdup(title.c_str()), g_free); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuItem); + } + } + + gtk_menu_popup(GTK_MENU(getWidget("nickMenu")), NULL, NULL, NULL, NULL, 0, gtk_get_current_event_time()); + gtk_widget_show_all(getWidget("nickMenu")); +} + void Hub::getPassword_gui() { gint ret; @@ -1006,32 +1048,85 @@ } } -void Hub::onCopyNickItemClicked_gui(GtkMenuItem *item, gpointer data) -{ - Hub *hub = (Hub *)data; - - if (gtk_tree_selection_count_selected_rows(hub->nickSelection) > 0) - { - string nicks; - GtkTreeIter iter; - GtkTreePath *path; - GList *list = gtk_tree_selection_get_selected_rows(hub->nickSelection, NULL); - - for (GList *i = list; i; i = i->next) - { - path = (GtkTreePath *)i->data; - if (gtk_tree_model_get_iter(GTK_TREE_MODEL(hub->nickStore), &iter, path)) - { - nicks += hub->nickView.getString(&iter, "User") + ' '; - } - gtk_tree_path_free(path); - } - g_list_free(list); - - if (!nicks.empty()) - { - nicks.erase(nicks.length() - 1); - gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), nicks.c_str(), nicks.length()); +void Hub::onCopyRowClicked_gui(GtkMenuItem *item, gpointer data) +{ + Hub *hub = (Hub *)data; + + if (gtk_tree_selection_count_selected_rows(hub->nickSelection) > 0) + { + string data; + GtkTreeIter iter; + GtkTreePath *path; + GList *list = gtk_tree_selection_get_selected_rows(hub->nickSelection, NULL); + + for (GList *i = list; i; i = i->next) + { + path = (GtkTreePath *)i->data; + + for (size_t j = 0; j < hub->nickView.getColCount(); j++) + { + GtkTreeViewColumn *col = gtk_tree_view_get_column(hub->nickView.get(), j); + if (col == NULL) + continue; + + string title = gtk_tree_view_column_get_title(col); + gboolean visible = gtk_tree_view_column_get_visible(col); + + if (visible && !title.empty()) + { + if (gtk_tree_model_get_iter(GTK_TREE_MODEL(hub->nickStore), &iter, path)) + { + GtkTreeModel *m = gtk_tree_view_get_model(hub->nickView.get()); + data += hub->nickView.getFormattedText(&iter, title) + '\t'; + } + } + } + + data += '\n'; + + gtk_tree_path_free(path); + } + g_list_free(list); + + if (!data.empty()) + { + data.erase(data.length() - 1); + gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), data.c_str(), data.length()); + } + } +} + +void Hub::onCopyDataItemClicked_gui(GtkMenuItem *item, gpointer data) +{ + Hub *hub = (Hub *)data; + + string title = (gchar *)g_object_get_data(G_OBJECT(item), "title"); + + if (gtk_tree_selection_count_selected_rows(hub->nickSelection) > 0) + { + string data; + GtkTreeIter iter; + GtkTreePath *path; + GList *list = gtk_tree_selection_get_selected_rows(hub->nickSelection, NULL); + + for (GList *i = list; i; i = i->next) + { + path = (GtkTreePath *)i->data; + + if (gtk_tree_model_get_iter(GTK_TREE_MODEL(hub->nickStore), &iter, path)) + { + GtkTreeModel *m = gtk_tree_view_get_model(hub->nickView.get()); + data += hub->nickView.getFormattedText(&iter, title) + '\n'; + } + + gtk_tree_path_free(path); + } + g_list_free(list); + + if (!data.empty()) + { + data.erase(data.length() - 1); + gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), data.c_str(), data.length()); } } } === modified file 'linux/hub.hh' --- linux/hub.hh 2010-11-10 07:07:40 +0000 +++ linux/hub.hh 2011-02-16 19:17:31 +0000 @@ -56,6 +56,8 @@ void removeTag_gui(const std::string &nick); void clearNickList_gui(); void popupNickMenu_gui(); + void buildUserCommandMenu_gui(); + void buildCopyMenu_gui(); void getPassword_gui(); void addMessage_gui(std::string message); void applyTags_gui(const std::string &line); @@ -78,7 +80,8 @@ static void onChatScroll_gui(GtkAdjustment *adjustment, gpointer data); static void onChatResize_gui(GtkAdjustment *adjustment, gpointer data); static void onSendMessage_gui(GtkEntry *entry, gpointer data); - static void onCopyNickItemClicked_gui(GtkMenuItem *item, gpointer data); + static void onCopyRowClicked_gui(GtkMenuItem *item, gpointer data); + static void onCopyDataItemClicked_gui(GtkMenuItem *item, gpointer data); static void onBrowseItemClicked_gui(GtkMenuItem *item, gpointer data); static void onMatchItemClicked_gui(GtkMenuItem *item, gpointer data); static void onMsgItemClicked_gui(GtkMenuItem *item, gpointer data); === modified file 'linux/treeview.cc' --- linux/treeview.cc 2010-11-14 06:31:40 +0000 +++ linux/treeview.cc 2011-02-16 19:22:37 +0000 @@ -85,6 +85,40 @@ return value; } +/* + * Implemented only for values that can be copied to clipboard + */ + +string TreeView::getFormattedText(GtkTreeIter *i, const string &title) +{ + GtkTreeModel *m = gtk_tree_view_get_model(view); + + GtkTreeViewColumn *col = NULL; + + if (!title.empty()) + { + col = gtk_tree_view_get_column(view, this->col(title)); + if (col != NULL) + { + Column *column = (Column*)g_object_get_data(G_OBJECT(col), "column"); + + switch (column->type) + { + case STRING: + case ICON_STRING: + return getString(i, title, m); + case SIZE: + char buf[128]; + int64_t size = getValue(i, title); + snprintf(buf, sizeof(buf), "%.f", (double)(size)); + return buf; + } + } + } + + return ""; +} + void TreeView::insertColumn(const string &title, const GType >ype, const columnType type, const int width, const string &linkedCol) { // All insertColumn's have to be called before any insertHiddenColumn's. === modified file 'linux/treeview.hh' --- linux/treeview.hh 2010-10-22 03:36:33 +0000 +++ linux/treeview.hh 2011-02-16 19:17:31 +0000 @@ -59,6 +59,7 @@ int col(const std::string &title); void saveSettings(); std::string getString(GtkTreeIter *i, const std::string &column, GtkTreeModel *m = NULL); + std::string getFormattedText(GtkTreeIter *i, const std::string &column); template T getValue(GtkTreeIter *i, const std::string &column, GtkTreeModel *m = NULL)