Author: rpmcruz Date: Fri Jan 29 13:00:08 2010 New Revision: 60613 URL: http://svn.opensuse.org/viewcvs/yast?rev=60613&view=rev Log: * src/YGTable.cc: bug fix 567505: crash when cell is unset: see firewall tool. Modified: branches/SuSE-Code-11-Branch/gtk/ChangeLog branches/SuSE-Code-11-Branch/gtk/src/YGTable.cc Modified: branches/SuSE-Code-11-Branch/gtk/ChangeLog URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-Branch/gtk/ChangeLog?rev=60613&r1=60612&r2=60613&view=diff ============================================================================== --- branches/SuSE-Code-11-Branch/gtk/ChangeLog (original) +++ branches/SuSE-Code-11-Branch/gtk/ChangeLog Fri Jan 29 13:00:08 2010 @@ -1,3 +1,8 @@ +2010-01-29 Ricardo Cruz <rpmcruz@alunos.dcc.fc.up.pt> + + * src/YGTable.cc: bug fix 567505: crash when cell is + unset: see firewall tool. + 2009-07-18 Ricardo Cruz <rpmcruz@alunos.dcc.fc.up.pt> * src/yzyppwrapper.cc: bug fix 504424: don't crash on empty Modified: branches/SuSE-Code-11-Branch/gtk/src/YGTable.cc URL: http://svn.opensuse.org/viewcvs/yast/branches/SuSE-Code-11-Branch/gtk/src/YGTable.cc?rev=60613&r1=60612&r2=60613&view=diff ============================================================================== --- branches/SuSE-Code-11-Branch/gtk/src/YGTable.cc (original) +++ branches/SuSE-Code-11-Branch/gtk/src/YGTable.cc Fri Jan 29 13:00:08 2010 @@ -2,22 +2,22 @@ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * ********************************************************************/ -#include <config.h> -#include <YGUI.h> +#define YUILogComponent "gtk" +#include "config.h" +#include "YGUI.h" #include "YGUtils.h" #include "YGWidget.h" #include "YSelectionWidget.h" #include "YGSelectionModel.h" #include "ygtkcellrenderertextpixbuf.h" #include "ygtkscrolledwindow.h" -#include <time.h> /* A generic widget for table related widgets. */ class YGTableView : public YGScrolledWidget, public YGSelectionModel { protected: int m_colsNb; - time_t m_blockTime; // GtkTreeSelection signals act weird + guint m_blockTimeout; public: YGTableView (YWidget *ywidget, YWidget *parent, const string &label, @@ -26,8 +26,6 @@ YGTK_TYPE_TREE_VIEW, NULL) , YGSelectionModel ((YSelectionWidget *) ywidget, ordinaryModel, isTree) { - IMPL - m_blockTime = time (NULL); if (ordinaryModel) { appendIconTextColumn ("", YAlignUnchanged, YGSelectionModel::ICON_COLUMN, YGSelectionModel::LABEL_COLUMN); @@ -41,6 +39,14 @@ gtk_tree_selection_set_mode (getSelection(), GTK_SELECTION_BROWSE); // let the derivates do the event hooks. They have subtile differences. + + m_blockTimeout = 0; // GtkTreeSelection idiotically fires when showing widget + g_signal_connect (getWidget(), "map", G_CALLBACK (block_init_cb), this); + } + + virtual ~YGTableView() + { + if (m_blockTimeout) g_source_remove (m_blockTimeout); } inline GtkTreeView *getView() @@ -50,7 +56,6 @@ void appendIconTextColumn (string header, YAlignmentType align, int icon_col, int text_col) { - IMPL GtkTreeViewColumn *column; GtkCellRenderer *renderer; @@ -108,12 +113,24 @@ virtual bool immediateEvent() { return true; } - // YGSelectionModel + static gboolean block_selected_timeout_cb (gpointer data) + { + YGTableView *pThis = (YGTableView *) data; + pThis->m_blockTimeout = 0; + return FALSE; + } + + void blockSelected() + { // GtkTreeSelection only fires when idle; so set a timeout + if (m_blockTimeout) g_source_remove (m_blockTimeout); + m_blockTimeout = g_timeout_add_full (G_PRIORITY_LOW, 250, block_selected_timeout_cb, this, NULL); + } + // YGSelectionModel virtual void doSelectItem (GtkTreeIter *iter) { if (!gtk_tree_selection_iter_is_selected (getSelection(), iter)) { - m_blockTime = time (NULL); + blockSelected(); GtkTreePath *path = gtk_tree_model_get_path (getModel(), iter); gtk_tree_view_expand_to_path (getView(), path); @@ -128,7 +145,7 @@ virtual void doUnselectAll() { if (gtk_tree_selection_count_selected_rows (getSelection())) { - m_blockTime = time (NULL); + blockSelected(); gtk_tree_selection_unselect_all (getSelection()); } } @@ -156,11 +173,13 @@ return 80; } -protected: + // GTK callbacks + static void block_init_cb (GtkWidget *widget, YGTableView *pThis) + { pThis->blockSelected(); } + // toggled by user (through clicking on the renderer or some other action) void toggle (GtkTreePath *path, gint column) { - IMPL GtkTreeIter iter; if (!gtk_tree_model_get_iter (getModel(), &iter, path)) return; @@ -175,7 +194,7 @@ static void selection_changed_cb (GtkTreeSelection *selection, YGTableView *pThis) { - if (time (NULL) - pThis->m_blockTime <= 2) + if (pThis->m_blockTimeout) return; if (!pThis->toggleMode()) { GtkTreeSelection *selection = pThis->getSelection(); @@ -200,17 +219,24 @@ static void toggled_cb (GtkCellRendererToggle *renderer, gchar *path_str, YGTableView *pThis) { - IMPL GtkTreePath *path = gtk_tree_path_new_from_string (path_str); gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), "column")); pThis->toggle (path, column); gtk_tree_path_free (path); } + +#if YAST2_VERSION > 2018003 + static void right_click_cb (YGtkTreeView *view, gboolean outreach, YGTableView *pThis) + { + pThis->emitEvent (YEvent::ContextMenuActivated); + } +#endif }; #include "YTable.h" #include "YGDialog.h" #include <gdk/gdkkeysyms.h> +#include <string.h> class YGTable : public YTable, public YGTableView { @@ -224,7 +250,6 @@ #endif , YGTableView (this, parent, string(), false, false) { - IMPL gtk_tree_view_set_headers_visible (getView(), TRUE); gtk_tree_view_set_rules_hint (getView(), columns() > 1); #if YAST2_VERSION >= 2017005 @@ -251,7 +276,7 @@ connect (getWidget(), "row-activated", G_CALLBACK (activated_cb), (YGTableView *) this); connect (getSelection(), "changed", G_CALLBACK (selection_changed_cb), (YGTableView *) this); - connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this); + connect (getWidget(), "right-click", G_CALLBACK (hack_right_click_cb), this); connect (getWidget(), "key-press-event", G_CALLBACK (key_press_event_cb), this); } @@ -270,22 +295,25 @@ { GtkTreeIter iter; if (getIter (cell->parent(), &iter)) - setCell (&iter, cell); + setCell (&iter, cell->column(), cell); } - void setCell (GtkTreeIter *iter, const YTableCell *cell) + void setCell (GtkTreeIter *iter, int column, const YTableCell *cell) { - int index = cell->column() * 2; - setCellIcon (iter, index, cell->iconName()); - std::string label (cell->label()); - if (label == "X") - label = YUI::app()->glyph (YUIGlyph_CheckMark); + int index = column * 2; + std::string icon, label; + if (cell) { + icon = cell->iconName(); + label = cell->label(); + if (label == "X") + label = YUI::app()->glyph (YUIGlyph_CheckMark); + } + setCellIcon (iter, index, icon); setCellLabel (iter, index+1, label); } void setSortable (bool sortable) { - IMPL if (!sortable && !GTK_WIDGET_REALIZED (getWidget())) return; int n = 0; @@ -298,6 +326,9 @@ int index = (n*2)+1; if (!sortable) index = -1; + gtk_tree_sortable_set_sort_func ( + GTK_TREE_SORTABLE (getModel()), index, tree_sort_cb, + GINT_TO_POINTER (index), NULL); gtk_tree_view_column_set_sort_column_id (column, index); } else @@ -314,8 +345,6 @@ virtual unsigned int getMinSize (YUIDimension dim) { return 30; } - YGWIDGET_IMPL_COMMON (YTable) - // YGSelectionModel virtual void doAddItem (YItem *_item) @@ -325,14 +354,12 @@ GtkTreeIter iter; addRow (&iter, _item, true); for (int i = 0; i < columns(); i++) - setCell (&iter, item->cell (i)); + setCell (&iter, i, item->cell (i)); } else yuiError() << "Can only add YTableItems to a YTable.\n"; } - YGSELECTION_WIDGET_IMPL (YTable) - // callbacks // hack up a popup menu and honor the delete key as suggested at: @@ -343,8 +370,12 @@ YGUI::ui()->sendEvent (event); } - static void right_click_cb (YGtkTreeView *view, gboolean outreach, YGTable *pThis) + static void hack_right_click_cb (YGtkTreeView *view, gboolean outreach, YGTable *pThis) { +#if YAST2_VERSION > 2018003 + if (pThis->notifyContextMenu()) + return YGTableView::right_click_cb (view, outreach, pThis); +#endif if (!YGDialog::currentDialog()->getFunctionWidget (5) || // undetermined case -- more than one table exists YGDialog::currentDialog()->getClassWidgets ("YTable").size() > 1) { @@ -391,6 +422,21 @@ return FALSE; } + static gint tree_sort_cb (GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, + gpointer _index) + { + int index = GPOINTER_TO_INT (_index); + gchar *str_a, *str_b; + gtk_tree_model_get (model, a, index, &str_a, -1); + gtk_tree_model_get (model, b, index, &str_b, -1); + int ret = strcmp (str_a, str_b); + g_free (str_a); + g_free (str_b); + return ret; + } + + YGLABEL_WIDGET_IMPL (YTable) + YGSELECTION_WIDGET_IMPL (YTable) }; #if YAST2_VERSION >= 2017005 @@ -417,19 +463,19 @@ { connect (getWidget(), "row-activated", G_CALLBACK (activated_cb), (YGTableView *) this); connect (getSelection(), "changed", G_CALLBACK (selection_changed_cb), (YGTableView *) this); +#if YAST2_VERSION > 2018003 + connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this); +#endif } virtual bool isShrinkable() { return shrinkable(); } - YGWIDGET_IMPL_COMMON (YSelectionBox) + YGLABEL_WIDGET_IMPL (YSelectionBox) YGSELECTION_WIDGET_IMPL (YSelectionBox) }; YSelectionBox *YGWidgetFactory::createSelectionBox (YWidget *parent, const string &label) -{ - IMPL - return new YGSelectionBox (parent, label); -} +{ return new YGSelectionBox (parent, label); } #include "YMultiSelectionBox.h" @@ -447,11 +493,15 @@ createModel (types); appendCheckColumn ("", 0); appendIconTextColumn ("", YAlignUnchanged, 1, 2); + gtk_tree_view_set_search_column (getView(), 2); setModel(); connect (getSelection(), "changed", G_CALLBACK (selection_changed_cb), (YGTableView *) this); // Let the user toggle, using space/enter or double click (not an event). connect (getWidget(), "row-activated", G_CALLBACK (multi_activated_cb), this); +#if YAST2_VERSION > 2018003 + connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this); +#endif } // YMultiSelectionBox @@ -484,7 +534,6 @@ { pThis->toggle (path, 0); } // YGSelectionModel - virtual void doSelectItem (GtkTreeIter *iter) { setCellToggle (iter, 0, true); @@ -501,18 +550,14 @@ } // YGWidget - virtual bool isShrinkable() { return shrinkable(); } - YGWIDGET_IMPL_COMMON (YMultiSelectionBox) + + YGLABEL_WIDGET_IMPL (YMultiSelectionBox) YGSELECTION_WIDGET_IMPL (YMultiSelectionBox) }; -YMultiSelectionBox *YGWidgetFactory::createMultiSelectionBox (YWidget *parent, - const string &label) -{ - IMPL - return new YGMultiSelectionBox (parent, label); -} +YMultiSelectionBox *YGWidgetFactory::createMultiSelectionBox (YWidget *parent, const string &label) +{ return new YGMultiSelectionBox (parent, label); } #include "YTree.h" #include "YTreeItem.h" @@ -528,6 +573,9 @@ connect (getWidget(), "row-expanded", G_CALLBACK (row_expanded_cb), this); connect (getWidget(), "cursor-changed", G_CALLBACK (row_selected_cb), this); connect (getWidget(), "row-activated", G_CALLBACK (activated_cb), (YGTableView *) this); +#if YAST2_VERSION > 2018003 + connect (getWidget(), "right-click", G_CALLBACK (right_click_cb), this); +#endif } // YTree -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org