Author: rpmcruz Date: Fri Dec 14 09:40:53 2007 New Revision: 43069 URL: http://svn.opensuse.org/viewcvs/yast?rev=43069&view=rev Log: * src/YGPackageSelector.cc: re-worked the package selector with input from some people. Special thanks to Christian Jäger and Martin Szulecki. I am confident people will like it; some code is pretty hacked through, this baby certainely deserved more time, but its beatiful how everything works together and the interface presents itself gracefully. Also fixed a few issues and added support for patches. Added: trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.c trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.h trunk/gtk/unstable-libyui/src/ygtktogglebutton.c trunk/gtk/unstable-libyui/src/ygtktogglebutton.h Modified: trunk/gtk/unstable-libyui/ChangeLog trunk/gtk/unstable-libyui/src/Makefile.am trunk/gtk/unstable-libyui/src/Y2CCGtk.cc trunk/gtk/unstable-libyui/src/YGLayout.cc trunk/gtk/unstable-libyui/src/YGPackageSelector.cc trunk/gtk/unstable-libyui/src/YGWidget.cc trunk/gtk/unstable-libyui/src/dummy.cc trunk/gtk/unstable-libyui/src/ygtkratiobox.c trunk/gtk/unstable-libyui/src/ygtkratiobox.h trunk/gtk/unstable-libyui/src/ygtkwizard.c trunk/gtk/unstable-libyui/src/ygtkwizard.h trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.cc trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.h trunk/gtk/unstable-libyui/src/yzyppwrapper.cc trunk/gtk/unstable-libyui/src/yzyppwrapper.h Modified: trunk/gtk/unstable-libyui/ChangeLog URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/ChangeLog?rev... ============================================================================== --- trunk/gtk/unstable-libyui/ChangeLog (original) +++ trunk/gtk/unstable-libyui/ChangeLog Fri Dec 14 09:40:53 2007 @@ -1,3 +1,12 @@ +2007-12-14 Ricardo Cruz <rpmcruz@alunos.dcc.fc.up.pt> + + * src/YGPackageSelector.cc: re-worked the package selector with input + from some people. Special thanks to Christian Jäger and Martin Szulecki. + I am confident people will like it; some code is pretty hacked through, + this baby certainely deserved more time, but its beatiful how everything + works together and the interface presents itself gracefully. + Also fixed a few issues and added support for patches. + 2007-12-09 Ricardo Cruz <rpmcruz@alunos.dcc.fc.up.pt> * src/YGUI.h.cc: fixed package selector issue. We weren't implementing Modified: trunk/gtk/unstable-libyui/src/Makefile.am URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/Makefile.... ============================================================================== --- trunk/gtk/unstable-libyui/src/Makefile.am (original) +++ trunk/gtk/unstable-libyui/src/Makefile.am Fri Dec 14 09:40:53 2007 @@ -49,6 +49,8 @@ ygdkmngloader.c \ ygtkimage.c \ ygtkcellrenderertextpixbuf.c \ + ygtkscrolledwindow.c \ + ygtktogglebutton.c \ ygtkhtmlwrap.c \ ygtkrichtext.c \ yzyppwrapper.cc \ Modified: trunk/gtk/unstable-libyui/src/Y2CCGtk.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/Y2CCGtk.c... ============================================================================== --- trunk/gtk/unstable-libyui/src/Y2CCGtk.cc (original) +++ trunk/gtk/unstable-libyui/src/Y2CCGtk.cc Fri Dec 14 09:40:53 2007 @@ -54,15 +54,14 @@ } return ret; #else + y2debug ("Component already created"); return new YGUIComponent(); #endif } - else - return 0; + return 0; } }; // Singleton plugin registration instance. Y2CCGtk g_y2ccgtk; - Modified: trunk/gtk/unstable-libyui/src/YGLayout.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/YGLayout.... ============================================================================== --- trunk/gtk/unstable-libyui/src/YGLayout.cc (original) +++ trunk/gtk/unstable-libyui/src/YGLayout.cc Fri Dec 14 09:40:53 2007 @@ -144,11 +144,14 @@ void setAlignment (YAlignmentType halign, YAlignmentType valign) { + bool hstretch = halign == YAlignUnchanged || stretchable (YD_HORIZ); + bool vstretch = valign == YAlignUnchanged || stretchable (YD_VERT); + GValue xalign, yalign, xscale, yscale; xalign = YGUtils::floatToGValue (yToGtkAlign (halign)); yalign = YGUtils::floatToGValue (yToGtkAlign (valign)); - xscale = YGUtils::floatToGValue (halign == YAlignUnchanged ? 1 : 0); - yscale = YGUtils::floatToGValue (valign == YAlignUnchanged ? 1 : 0); + xscale = YGUtils::floatToGValue (hstretch ? 1 : 0); + yscale = YGUtils::floatToGValue (vstretch ? 1 : 0); g_object_set_property (G_OBJECT (getWidget()), "xalign", &xalign); g_object_set_property (G_OBJECT (getWidget()), "yalign", &yalign); Modified: trunk/gtk/unstable-libyui/src/YGPackageSelector.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/YGPackage... ============================================================================== --- trunk/gtk/unstable-libyui/src/YGPackageSelector.cc (original) +++ trunk/gtk/unstable-libyui/src/YGPackageSelector.cc Fri Dec 14 09:40:53 2007 @@ -13,6 +13,8 @@ #if 1 #include "ygtkwizard.h" #include "ygtkfindentry.h" +#include "ygtkscrolledwindow.h" +#include "ygtktogglebutton.h" #include "ygtkhtmlwrap.h" #include "ygtkzyppwrapper.h" @@ -94,23 +96,24 @@ { GtkTreeView *view = GTK_TREE_VIEW (m_widget = gtk_tree_view_new()); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE); - gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), 1); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), YGtkZyppModel::NAME_COLUMN); GtkTreeViewColumn *column; GtkCellRenderer *renderer; renderer = gtk_cell_renderer_pixbuf_new(); column = gtk_tree_view_column_new_with_attributes ("", renderer, "pixbuf", YGtkZyppModel::ICON_COLUMN, NULL); + gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (column, 38); gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); renderer = gtk_cell_renderer_text_new(); g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); column = gtk_tree_view_column_new_with_attributes ("", renderer, "markup", YGtkZyppModel::NAME_DESCRIPTION_COLUMN, NULL); + gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); + gtk_tree_view_column_set_fixed_width (column, 50 /* it will expand */); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); - renderer = gtk_cell_renderer_pixbuf_new(); - column = gtk_tree_view_column_new_with_attributes ("", renderer, - "pixbuf", YGtkZyppModel::SPECIAL_ICON_COLUMN, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (view), column); + gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE); GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view)); gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); @@ -166,41 +169,25 @@ } }; -GtkWidget *m_box, *m_bin, *m_list_button, *m_icon_button; +GtkWidget *m_bin; GtkTreeModel *m_model; View *m_view; public: GtkWidget *getWidget() - { return m_box; } + { return m_bin; } PackagesView() : m_listener (NULL), m_model (NULL), m_view (NULL) { - m_bin = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (m_bin), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_bin), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - - GtkWidget *buttons = gtk_vbox_new (FALSE, 0), *image; - image = createImageFromXPM (pkg_list_mode_xpm); - m_list_button = gtk_toggle_button_new(); - gtk_button_set_image (GTK_BUTTON (m_list_button), image); - image = createImageFromXPM (pkg_tiles_mode_xpm); - m_icon_button = gtk_toggle_button_new(); - gtk_button_set_image (GTK_BUTTON (m_icon_button), image); - gtk_box_pack_start (GTK_BOX (buttons), gtk_label_new(""), TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (buttons), m_list_button, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (buttons), m_icon_button, FALSE, FALSE, 0); - g_signal_connect (G_OBJECT (m_list_button), "toggled", - G_CALLBACK (mode_toggled_cb), this); - g_signal_connect (G_OBJECT (m_icon_button), "toggled", - G_CALLBACK (mode_toggled_cb), this); - - m_box = gtk_hbox_new (FALSE, 2); - gtk_box_pack_start (GTK_BOX (m_box), m_bin, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_box), buttons, FALSE, TRUE, 0); + GtkWidget *buttons = gtk_vbox_new (FALSE, 0), *button; + button = create_toggle_button (pkg_list_mode_xpm, "List view", NULL); + gtk_box_pack_start (GTK_BOX (buttons), button, FALSE, TRUE, 0); + button = create_toggle_button (pkg_tiles_mode_xpm, "Tiles view", button); + gtk_box_pack_start (GTK_BOX (buttons), button, FALSE, TRUE, 0); + gtk_widget_show_all (buttons); + m_bin = ygtk_scrolled_window_new(); + ygtk_scrolled_window_set_corner_widget (YGTK_SCROLLED_WINDOW (m_bin), buttons); setMode (LIST_MODE); } @@ -218,14 +205,6 @@ { if (GTK_WIDGET_REALIZED (m_bin)) busyCursor(); - g_signal_handlers_block_by_func (m_list_button, (gpointer) mode_toggled_cb, this); - g_signal_handlers_block_by_func (m_icon_button, (gpointer) mode_toggled_cb, this); - - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_list_button), mode == LIST_MODE); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_icon_button), mode == ICON_MODE); - - g_signal_handlers_unblock_by_func (m_list_button, (gpointer) mode_toggled_cb, this); - g_signal_handlers_unblock_by_func (m_icon_button, (gpointer) mode_toggled_cb, this); if (m_view) gtk_container_remove (GTK_CONTAINER (m_bin), m_view->m_widget); @@ -234,15 +213,15 @@ m_view = new ListView (this); else m_view = new IconView (this); -fprintf (stderr, "adding new view to container\n"); gtk_container_add (GTK_CONTAINER (m_bin), m_view->m_widget); if (m_model) m_view->setModel (m_model); + packagesSelected (std::list <Ypp::Package *> ()); normalCursor(); } - void query (Ypp::Query *query) + void setQuery (Ypp::Query *query) { if (GTK_WIDGET_REALIZED (m_bin)) busyCursor(); @@ -260,90 +239,550 @@ } private: - static void mode_toggled_cb (GtkToggleButton *toggle, PackagesView *pThis) + GtkWidget *create_toggle_button (const char **xpm, const char *tooltip, GtkWidget *member) { - bool active = gtk_toggle_button_get_active (toggle); - if (!active) { - // don't let the button be un-pressed - g_signal_handlers_block_by_func (toggle, (gpointer) mode_toggled_cb, pThis); - gtk_toggle_button_set_active (toggle, TRUE); - g_signal_handlers_unblock_by_func (toggle, (gpointer) mode_toggled_cb, pThis); - return; - } - ViewMode mode = GTK_WIDGET (toggle) == pThis->m_list_button ? LIST_MODE : ICON_MODE; + GSList *group = NULL; + if (member) + group = ygtk_toggle_button_get_group (YGTK_TOGGLE_BUTTON (member)); + GtkWidget *button = ygtk_toggle_button_new (group); + gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); + gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE); + if (!member) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + + // make it tiny + GtkRcStyle *rcstyle = gtk_rc_style_new(); + rcstyle->xthickness = rcstyle->ythickness = 0; + gtk_widget_modify_style (button, rcstyle); + gtk_rc_style_unref (rcstyle), + + gtk_widget_set_tooltip_text (button, tooltip); + g_signal_connect (G_OBJECT (button), "toggle-changed", + G_CALLBACK (mode_toggled_cb), this); + + GtkWidget *image = createImageFromXPM (xpm); + gtk_container_add (GTK_CONTAINER (button), image); + return button; + } + + static void mode_toggled_cb (GtkToggleButton *toggle, gint nb, PackagesView *pThis) + { + ViewMode mode = (nb == 0) ? LIST_MODE : ICON_MODE; pThis->setMode (mode); } }; -// TEMP: a window of modified packages -class TrashWindow : PackagesView::Listener +class ChangesPane : public Ypp::Pool::Listener { -GtkWidget *m_window, *m_undo_button; -PackagesView *m_view; + struct Entry { + GtkWidget *m_box, *m_label, *m_button; + GtkWidget *getWidget() { return m_box; } + + Entry (Ypp::Package *package) + { + m_label = gtk_label_new (""); + gtk_misc_set_alignment (GTK_MISC (m_label), 0, 0.5); + gtk_label_set_ellipsize (GTK_LABEL (m_label), PANGO_ELLIPSIZE_END); + m_button = gtk_button_new(); + GtkWidget *undo_image = gtk_image_new_from_stock (GTK_STOCK_UNDO, GTK_ICON_SIZE_MENU); + gtk_button_set_image (GTK_BUTTON (m_button), undo_image); + m_box = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (m_box), m_label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_box), m_button, FALSE, FALSE, 0); + gtk_widget_set_size_request (m_box, 140, -1); + gtk_widget_show_all (m_box); + modified (package); + g_signal_connect (G_OBJECT (m_label), "style-set", + G_CALLBACK (style_set_cb), NULL); + g_signal_connect (G_OBJECT (m_button), "clicked", + G_CALLBACK (undo_clicked_cb), package); + } + + void modified (Ypp::Package *package) + { + std::string text; + if (package->isInstalled() && package->toInstall()) + text = "upgrade"; + else if (package->toInstall()) + text = "install"; + else + text = "remove"; + text += " " + package->name(); + if (package->isAuto()) { + text = "\t" + text; + gtk_widget_hide (m_button); + } + else + gtk_widget_show (m_button); + gtk_label_set_text (GTK_LABEL (m_label), text.c_str()); + } + + static void undo_clicked_cb (GtkButton *button, Ypp::Package *package) + { + package->undo(); + } + + static void style_set_cb (GtkWidget *widget, GtkStyle *prev_style) + { + static bool set_style = false; + if (set_style) + return; + set_style = true; + GdkColor *color = &widget->style->fg [GTK_STATE_SELECTED]; + gtk_widget_modify_fg (widget, GTK_STATE_NORMAL, color); + set_style = false; + } + }; + +GtkWidget *m_box, *m_entries_box, *m_container; +Ypp::Pool *m_pool; +GList *m_entries; public: - TrashWindow() + GtkWidget *getWidget() + { return m_box; } + + ChangesPane() + : m_entries (NULL) { - m_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_window_set_title (GTK_WINDOW (m_window), "Changes"); - gtk_window_set_default_size (GTK_WINDOW (m_window), 200, 250); + GtkWidget *heading = gtk_label_new (_("Changes:")); + YGUtils::setWidgetFont (heading, PANGO_WEIGHT_ULTRABOLD, PANGO_SCALE_LARGE); + gtk_misc_set_alignment (GTK_MISC (heading), 0, 0.5); + g_signal_connect (G_OBJECT (heading), "style-set", + G_CALLBACK (Entry::style_set_cb), NULL); + m_entries_box = gtk_vbox_new (FALSE, 4); + + GtkWidget *vbox = gtk_vbox_new (FALSE, 6); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); + gtk_box_pack_start (GTK_BOX (vbox), heading, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), m_entries_box, FALSE, TRUE, 0); + + GtkWidget *port = gtk_viewport_new (NULL, NULL); + gtk_viewport_set_shadow_type (GTK_VIEWPORT (port), GTK_SHADOW_NONE); + gtk_container_add (GTK_CONTAINER (port), vbox); + + GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add (GTK_CONTAINER (scroll), port); - m_view = new PackagesView(); - Ypp::Query *query = new Ypp::Query (Ypp::Package::PACKAGE_TYPE); + m_box = gtk_event_box_new(); + gtk_container_add (GTK_CONTAINER (m_box), scroll); + g_signal_connect_after (G_OBJECT (m_box), "style-set", + G_CALLBACK (style_set_cb), NULL); + g_signal_connect_after (G_OBJECT (scroll), "style-set", + G_CALLBACK (style_set_cb), NULL); + g_signal_connect_after (G_OBJECT (port), "style-set", + G_CALLBACK (style_set_cb), NULL); + + Ypp::Query *query = new Ypp::Query(); query->setIsModified (true); - m_view->query (query); - m_view->setListener (this); + m_pool = new Ypp::Pool (query); + m_pool->setListener (this); + } - GtkWidget *vbox = gtk_vbox_new (FALSE, 6), *undo_align; - m_undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO); - gtk_widget_set_sensitive (m_undo_button, FALSE); - g_signal_connect (G_OBJECT (m_undo_button), "clicked", - G_CALLBACK (undo_clicked_cb), this); - undo_align = gtk_alignment_new (1, 0, 0, 0); - gtk_container_add (GTK_CONTAINER (undo_align), m_undo_button); + ~ChangesPane() + { + delete m_pool; + for (GList *i = m_entries; i; i = i->next) + delete (Entry *) i->data; + g_list_free (m_entries); + } - gtk_box_pack_start (GTK_BOX (vbox), m_view->getWidget(), TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), undo_align, FALSE, FALSE, 0); - gtk_container_add (GTK_CONTAINER (m_window), vbox); - gtk_widget_show_all (m_window); + void setContainer (GtkWidget *container) + { + m_container = container; + gtk_widget_hide (m_container); } - ~TrashWindow() + virtual void entryInserted (Ypp::Pool::Iter iter, Ypp::Package *package) { - delete m_view; - gtk_widget_destroy (m_window); + Entry *entry = new Entry (package); + gtk_container_add (GTK_CONTAINER (m_entries_box), entry->getWidget()); + int index = m_pool->getIndex (iter); + m_entries = g_list_insert (m_entries, entry, index); + gtk_widget_show (m_container); } -private: -std::list <Ypp::Package *> m_selection; + virtual void entryDeleted (Ypp::Pool::Iter iter, Ypp::Package *package) + { + int index = m_pool->getIndex (iter); + GList *i = g_list_nth (m_entries, index); + Entry *entry = (Entry *) i->data; + gtk_container_remove (GTK_CONTAINER (m_entries_box), entry->getWidget()); + delete entry; + m_entries = g_list_delete_link (m_entries, i); + if (m_entries == NULL) + gtk_widget_hide (m_container); + } - virtual void packagesSelected (const std::list <Ypp::Package *> &selection) + virtual void entryChanged (Ypp::Pool::Iter iter, Ypp::Package *package) { - gtk_widget_set_sensitive (m_undo_button, !selection.empty()); - m_selection = selection; + int index = m_pool->getIndex (iter); + Entry *entry = (Entry *) g_list_nth_data (m_entries, index); + entry->modified (package); } - static void undo_clicked_cb (GtkButton *button, TrashWindow *pThis) + static void style_set_cb (GtkWidget *widget, GtkStyle *prev_style) { - for (std::list <Ypp::Package *>::iterator it = pThis->m_selection.begin(); - it != pThis->m_selection.end(); it++) - (*it)->undo(); + static bool set_style = false; + if (set_style) + return; + set_style = true; + GdkColor *color = &widget->style->bg [GTK_STATE_SELECTED]; + gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, color); + set_style = false; } }; -#include "icons/cat-development.xpm" -#include "icons/cat-documentation.xpm" -#include "icons/cat-emulators.xpm" -#include "icons/cat-games.xpm" -#include "icons/cat-hardware.xpm" -#include "icons/cat-network.xpm" -#include "icons/cat-multimedia.xpm" -#include "icons/cat-office.xpm" -#include "icons/cat-system.xpm" -#include "icons/cat-utilities.xpm" +// Maps icons to top package groups +struct CategoriesIconMap { + const char *category, *icon; +}; +static const CategoriesIconMap catIconMap[] = { + { "Amusements", "package_games" }, + { "Games", "package_games" }, + { "Development", "package_development" }, + { "Libraries", "package_development" }, + { "Documentation", "package_documentation" }, + { "Hardware", "package_settings_peripherals" }, + { "Applications", "package_applications" }, + { "Productivity", "package_applications" }, + { "System", "package_system" }, + { "X11", "package_system" }, + { "Multimedia", "package_multimedia" }, + { "Video", "package_multimedia" }, + { "Office", "package_office_documentviewer" }, +}; +#define CAT_SIZE (sizeof (catIconMap)/sizeof (CategoriesIconMap)) + +#include "icons/pkg-installed.xpm" +#include "icons/pkg-installed-upgradable.xpm" +#include "icons/pkg-available.xpm" class Filters { + class Collections + { + struct View + { + virtual GtkWidget *getWidget() = 0; + virtual void setQuery (Ypp::Query *query) = 0; + + Filters *m_filters; + View (Filters *filters) + : m_filters (filters) + {} + }; + + struct Categories : public View + { + GtkWidget *m_scroll, *m_view; + public: + virtual GtkWidget *getWidget() + { return m_scroll; } + + Categories (Filters *filters, Ypp::Package::Type type) + : View (filters) + { + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + + m_view = gtk_tree_view_new(); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_view), FALSE); + gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_view), 0); + renderer = gtk_cell_renderer_text_new(); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "text", 0, NULL); + gtk_tree_view_column_set_expand (column, TRUE); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_view), column); + renderer = gtk_cell_renderer_pixbuf_new(); + column = gtk_tree_view_column_new_with_attributes ("", + renderer, "pixbuf", 2, NULL); + gtk_tree_view_column_set_expand (column, FALSE); + gtk_tree_view_append_column (GTK_TREE_VIEW (m_view), column); + + GtkTreeSelection *selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (m_view)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + g_signal_connect (G_OBJECT (selection), "changed", + G_CALLBACK (selection_cb), this); + + m_scroll = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (m_scroll), + GTK_SHADOW_IN); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_scroll), + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_widget_set_size_request (m_scroll, -1, 200); + gtk_container_add (GTK_CONTAINER (m_scroll), m_view); + + build (type); + } + + void build (Ypp::Package::Type type) + { + GtkTreeModel *model = NULL; + + struct inner { + static void populate (GtkTreeStore *store, GtkTreeIter *parent, + Ypp::Node *category) + { + if (!category) + return; + GtkTreeIter iter; + gtk_tree_store_append (store, &iter, parent); + const std::string &name = category->name; + gtk_tree_store_set (store, &iter, 0, name.c_str(), 1, category, -1); + if (!parent) { + const gchar *icon = 0; + for (unsigned int i = 0; i < CAT_SIZE; i++) + if (name == catIconMap[i].category) { + icon = catIconMap[i].icon; + break; + } + if (icon) { + GtkIconTheme *icons = gtk_icon_theme_get_default(); + GdkPixbuf *pixbuf; + pixbuf = gtk_icon_theme_load_icon (icons, icon, 22, + GtkIconLookupFlags (0), NULL); + gtk_tree_store_set (store, &iter, 2, pixbuf, -1); + } + } + populate (store, &iter, category->child()); + populate (store, parent, category->next()); + } + }; + + GtkTreeStore *store = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_POINTER, + GDK_TYPE_PIXBUF); + model = GTK_TREE_MODEL (store); + + GtkTreeIter iter; + gtk_tree_store_append (store, &iter, NULL); + gtk_tree_store_set (store, &iter, 0, _("All"), 1, NULL, -1); + + inner::populate (store, NULL, Ypp::get()->getFirstCategory (type)); + + GtkTreeSelection *selection = gtk_tree_view_get_selection ( + GTK_TREE_VIEW (m_view)); + g_signal_handlers_block_by_func (selection, (gpointer) selection_cb, this); + + gtk_tree_view_set_model (GTK_TREE_VIEW (m_view), model); + if (model) { + g_object_unref (G_OBJECT (model)); + + /* we use gtk_tree_view_set_cursor(), rather than gtk_tree_selection_select_iter() + because that one is buggy in that when the user first interacts with the treeview, + a change signal is sent, even if he was just expanding one node... */ + GtkTreePath *path = gtk_tree_path_new_first(); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (m_view), path, NULL, FALSE); + gtk_tree_path_free (path); + } + + g_signal_handlers_unblock_by_func (selection, (gpointer) selection_cb, this); + } + + Ypp::Node *getActive() + { + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view)); + GtkTreeModel *model; + GtkTreeIter iter; + Ypp::Node *category = 0; + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + gtk_tree_model_get (model, &iter, 1, &category, -1); + return category; + } + + static void selection_cb (GtkTreeSelection *selection, View *pThis) + { + pThis->m_filters->signalChanged(); + } + + virtual void setQuery (Ypp::Query *query) + { + Ypp::Node *node = getActive(); + if (node) + query->setCategory (node); + } + }; + + struct Pool : public View, public PackagesView::Listener + { + PackagesView *m_view; + GtkWidget *m_box, *m_buttons_box; + public: + virtual GtkWidget *getWidget() + { return m_box; } + + Pool (Filters *filters, Ypp::Package::Type type) + : View (filters) + { + m_view = new PackagesView(); + Ypp::Query *query = new Ypp::Query(); + query->setType (type); + m_view->setQuery (query); + m_view->setListener (this); + + m_buttons_box = gtk_hbox_new (TRUE, 2); + GtkWidget *image, *button; + button = gtk_button_new_with_label (_("Install All")); + image = gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (button), image); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (install_cb), this); + gtk_box_pack_start (GTK_BOX (m_buttons_box), button, TRUE, TRUE, 0); + button = gtk_button_new_with_label (_("Remove All")); + image = gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON); + gtk_button_set_image (GTK_BUTTON (button), image); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (remove_cb), this); + gtk_box_pack_start (GTK_BOX (m_buttons_box), button, TRUE, TRUE, 0); + gtk_widget_set_sensitive (m_buttons_box, FALSE); + + m_box = gtk_vbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (m_box), m_view->getWidget(), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (m_box), m_buttons_box, FALSE, TRUE, 0); + } + + std::list <Ypp::Package *> m_selected; + + virtual void packagesSelected (const std::list <Ypp::Package *> &selection) + { + gtk_widget_set_sensitive (m_buttons_box, !selection.empty()); + m_selected = selection; + m_filters->signalChanged(); + } + + virtual void setQuery (Ypp::Query *query) + { + if (!m_selected.empty()) + query->setCollection (m_selected.front()); + } + + void doAll (bool install /*or remove*/) + { + // we just need to mark the collections themselves + for (std::list <Ypp::Package *>::iterator it = m_selected.begin(); + it != m_selected.end(); it++) + install ? (*it)->install(0) : (*it)->remove(); + } + + static void install_cb (GtkButton *button, Pool *pThis) + { pThis->doAll (true); } + static void remove_cb (GtkButton *button, Pool *pThis) + { pThis->doAll (false); } + }; + + View *m_view; + GtkWidget *m_bin; + Filters *m_filters; + + public: + Collections (Filters *filters) + : m_view (NULL), m_filters (filters) + { + m_bin = gtk_event_box_new(); + } + + ~Collections() + { + delete m_view; + } + + GtkWidget *getWidget() + { return m_bin; } + + void setType (Ypp::Package::Type type) + { + if (m_view) + gtk_container_remove (GTK_CONTAINER (m_bin), m_view->getWidget()); + delete m_view; + + switch (type) + { + case Ypp::Package::PACKAGE_TYPE: + case Ypp::Package::PATCH_TYPE: + m_view = new Categories (m_filters, type); + break; + case Ypp::Package::PATTERN_TYPE: + case Ypp::Package::LANGUAGE_TYPE: + m_view = new Pool (m_filters, type); + break; + default: + m_view = NULL; + break; + } + + if (m_view) { + gtk_widget_show_all (m_view->getWidget()); + gtk_container_add (GTK_CONTAINER (m_bin), m_view->getWidget()); + } + } + + void setQuery (Ypp::Query *query) + { + if (m_view) + m_view->setQuery (query); + } + }; + + class StatusButtons + { + GtkWidget *m_box; + Filters *m_filters; + int m_selectedStatus; + + public: + GtkWidget *getWidget() + { return m_box; } + + StatusButtons (Filters *filters) + : m_filters (filters), m_selectedStatus (0) + { + m_box = gtk_hbox_new (FALSE, 6); + GtkWidget *homo_box = gtk_hbox_new (TRUE, 6); // same size box + gtk_box_pack_start (GTK_BOX (m_box), homo_box, TRUE, TRUE, 0); + + GtkWidget *button; + GSList *group; + button = createButton ("Available", pkg_available_xpm, NULL); + group = ygtk_toggle_button_get_group (YGTK_TOGGLE_BUTTON (button)); + gtk_box_pack_start (GTK_BOX (homo_box), button, TRUE, TRUE, 0); + button = createButton ("Upgrades", pkg_installed_upgradable_xpm, group); + gtk_box_pack_start (GTK_BOX (homo_box), button, TRUE, TRUE, 0); + button = createButton ("Installed", pkg_installed_xpm, group); + gtk_box_pack_start (GTK_BOX (homo_box), button, TRUE, TRUE, 0); + button = createButton ("All", 0, group); + gtk_box_pack_start (GTK_BOX (m_box), button, FALSE, TRUE, 0); + } + + int getActive() + { + return m_selectedStatus; + } + + GtkWidget *createButton (const char *label, const char **xpm, GSList *group) + { + GtkWidget *button = ygtk_toggle_button_new (group); + GtkWidget *hbox = gtk_hbox_new (FALSE, 0); + if (xpm) + gtk_box_pack_start (GTK_BOX (hbox), createImageFromXPM (xpm), FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (label), TRUE, TRUE, 0); + gtk_container_add (GTK_CONTAINER (button), hbox); + if (!group) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + g_signal_connect (G_OBJECT (button), "toggle-changed", + G_CALLBACK (status_toggled_cb), this); + return button; + } + + static void status_toggled_cb (GtkToggleButton *toggle, gint nb, StatusButtons *pThis) + { + pThis->m_selectedStatus = nb; + pThis->m_filters->signalChanged(); + } + }; + public: struct Listener { virtual void doQuery (Ypp::Query *query) = 0; @@ -352,65 +791,61 @@ { m_listener = listener; signalChanged(); } private: - GtkWidget *m_widget, *m_name, *m_status, *m_categories, *m_repos, *m_type, - *m_categories_expander, *m_repos_expander; + Collections *m_collection; + StatusButtons *m_statuses; + GtkWidget *m_name, *m_repos, *m_type; Listener *m_listener; guint timeout_id; - int repoToggled; // how many repos are toggled? if 0, it can speed up query - int packageType; + int m_selectedType; public: - GtkWidget *getWidget() - { return m_widget; } + GtkWidget *getCollectionWidget() { return m_collection->getWidget(); } + GtkWidget *getStatusesWidget() { return m_statuses->getWidget(); } + GtkWidget *getNameWidget() { return m_name; } + GtkWidget *getReposWidget() { return m_repos; } + GtkWidget *getTypeWidget() { return m_type; } - Filters() - : m_listener (NULL), timeout_id (0), repoToggled (0), packageType (-1) + Filters (bool update_mode) + : m_listener (NULL), timeout_id (0), m_selectedType (-1) { - GtkWidget *vbox = gtk_vbox_new (FALSE, 4); - gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); - GtkSizeGroup *size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); + m_collection = new Collections (this); + m_statuses = new StatusButtons (this); m_name = ygtk_find_entry_new(); g_signal_connect_after (G_OBJECT (m_name), "changed", G_CALLBACK (entry_changed_cb), this); - gtk_box_pack_start (GTK_BOX (vbox), - labelWidget (_("Name: "), m_name, size_group), FALSE, TRUE, 0); - - m_status = gtk_combo_box_new_text(); - gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("All")); - gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Installed")); - gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Upgradable")); - gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Available")); - gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Modified")); - gtk_combo_box_set_active (GTK_COMBO_BOX (m_status), 0); - g_signal_connect_after (G_OBJECT (m_status), "changed", - G_CALLBACK (combo_changed_cb), this); - gtk_box_pack_start (GTK_BOX (vbox), - labelWidget (_("Status: "), m_status, size_group), FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), buildCategories(), FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), buildRepos(), FALSE, TRUE, 0); + m_repos = gtk_combo_box_new_text(); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_repos), _("All Repositories")); + for (int i = 0; Ypp::get()->getRepository (i); i++) { + const Ypp::Repository *repo = Ypp::get()->getRepository (i); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_repos), repo->name.c_str()); + } + gtk_combo_box_set_active (GTK_COMBO_BOX (m_repos), 0); + g_signal_connect (G_OBJECT (m_repos), "changed", + G_CALLBACK (combo_changed_cb), this); m_type = gtk_combo_box_new_text(); - gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Packages")); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Categories")); gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Patterns")); gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Languages")); - gtk_combo_box_set_active (GTK_COMBO_BOX (m_type), 0); + gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Patches")); + gtk_combo_box_set_active (GTK_COMBO_BOX (m_type), update_mode ? 3 : 0); g_signal_connect_after (G_OBJECT (m_type), "changed", G_CALLBACK (combo_changed_cb), this); - gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (""), TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), - labelWidget (_("Type: "), m_type, size_group), FALSE, TRUE, 0); - - m_widget = gtk_notebook_new(); - gtk_notebook_append_page (GTK_NOTEBOOK (m_widget), vbox, - gtk_label_new (_("Filters"))); - g_object_unref (G_OBJECT (size_group)); } ~Filters() { - if (timeout_id) g_source_remove (timeout_id); + if (timeout_id) + g_source_remove (timeout_id); + } + +public: + int selectedRepo() + { + int repo = gtk_combo_box_get_active (GTK_COMBO_BOX (m_repos))-1; + return repo; } private: @@ -423,61 +858,41 @@ { if (!m_listener) return; - Ypp::Package::Type type; - switch (gtk_combo_box_get_active (GTK_COMBO_BOX (m_type))) - { - case 0: default: type = Ypp::Package::PACKAGE_TYPE; break; - case 1: type = Ypp::Package::PATTERN_TYPE; break; - case 2: type = Ypp::Package::LANGUAGE_TYPE; break; - - } + Ypp::Package::Type type = (Ypp::Package::Type) + gtk_combo_box_get_active (GTK_COMBO_BOX (m_type)); - Ypp::Query *query = new Ypp::Query (type); + Ypp::Query *query = new Ypp::Query(); + if (type == Ypp::Package::PATCH_TYPE) + query->setType (Ypp::Package::PATCH_TYPE); + else + query->setType (Ypp::Package::PACKAGE_TYPE); const char *name = gtk_entry_get_text (GTK_ENTRY (m_name)); if (*name) query->setName (std::string (name)); - switch (gtk_combo_box_get_active (GTK_COMBO_BOX (m_status))) - { - case 1: query->setIsInstalled (true); break; - case 2: query->setHasUpgrade (true); break; - case 3: query->setIsInstalled (false); break; - case 4: query->setIsModified (true); break; - case 0: default: break; - - } + switch (m_statuses->getActive()) { - GtkTreeSelection *selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (m_categories)); - GtkTreeModel *model; - GtkTreeIter iter; - if (gtk_tree_selection_get_selected (selection, &model, &iter)) { - Ypp::Node *category; - gtk_tree_model_get (model, &iter, 1, &category, -1); - if (category) - query->setCategory (category); - } + case 0: query->setIsInstalled (false); break; + case 1: query->setHasUpgrade (true); break; + case 2: query->setIsInstalled (true); break; + case 3: default: break; } - if (repoToggled) { + m_collection->setQuery (query); + + if (selectedRepo() >= 0) { std::list <int> reposQuery; - GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_repos)); - GtkTreeIter iter; - if (gtk_tree_model_get_iter_first (model, &iter)) { - do { - gboolean enabled; - gint repo; - gtk_tree_model_get (model, &iter, 0, &enabled, 2, &repo, -1); - if (enabled) - reposQuery.push_back (repo); - } while (gtk_tree_model_iter_next (model, &iter)); - } + reposQuery.push_back (selectedRepo()); query->setRepositories (reposQuery); } m_listener->doQuery (query); - updateCategories (type); + + if (type != m_selectedType) { + m_collection->setType (type); + m_selectedType = type; + } } void signalChangedDelay() @@ -492,247 +907,7 @@ } }; if (timeout_id) g_source_remove (timeout_id); - timeout_id = g_timeout_add (500, inner::timeout_cb, this); - } - - void updateCategories (Ypp::Package::Type type) - { - if (packageType == type) - return; - packageType = type; - - GtkTreeModel *model = NULL; - - if (type == Ypp::Package::PACKAGE_TYPE) { - struct inner { - static void populate (GtkTreeStore *store, GtkTreeIter *parent, - Ypp::Node *category) - { - if (!category) - return; - GtkTreeIter iter; - gtk_tree_store_append (store, &iter, parent); - const std::string &name = category->name; - gtk_tree_store_set (store, &iter, 0, name.c_str(), 1, category, -1); - if (!parent) { - const char **icon = 0; - if (name == "Development") - icon = cat_development_xpm; - else if (name == "Documentation") - icon = cat_documentation_xpm; - else if (name == "Emulators") - icon = cat_emulators_xpm; - else if (name == "Games") - icon = cat_games_xpm; - else if (name == "Hardware") - icon = cat_hardware_xpm; - else if (name == "Multimedia") - icon = cat_multimedia_xpm; - else if (name == "Network") - icon = cat_network_xpm; - else if (name == "Office") - icon = cat_office_xpm; - else if (name == "System") - icon = cat_system_xpm; - else if (name == "Utilities") - icon = cat_utilities_xpm; - if (icon) { - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (icon); - gtk_tree_store_set (store, &iter, 2, pixbuf, -1); - } - } - populate (store, &iter, category->child()); - populate (store, parent, category->next()); - } - }; - - GtkTreeStore *store = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_POINTER, - GDK_TYPE_PIXBUF); - model = GTK_TREE_MODEL (store); - - GtkTreeIter iter; - gtk_tree_store_append (store, &iter, NULL); - gtk_tree_store_set (store, &iter, 0, _("All"), 1, NULL, -1); - - inner::populate (store, NULL, Ypp::get()->getFirstCategory (type)); - - } - else if (type == Ypp::Package::PATTERN_TYPE) { - GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_POINTER, - GDK_TYPE_PIXBUF); - model = GTK_TREE_MODEL (store); - - GtkTreeIter iter; - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, _("All"), 1, NULL, -1); - - for (Ypp::Node *i = Ypp::get()->getFirstCategory (type); i; i = i->next()) { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, i->name.c_str(), 1, i, -1); - } - } - - GtkTreeSelection *selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (m_categories)); - g_signal_handlers_block_by_func (selection, - (gpointer) categories_selection_cb, this); - - gtk_tree_view_set_model (GTK_TREE_VIEW (m_categories), model); - if (model) { - g_object_unref (G_OBJECT (model)); - gtk_widget_show (m_categories_expander); - - /* we use gtk_tree_view_set_cursor(), rather than gtk_tree_selection_select_iter() - because that one is buggy in that when the user first interacts with the treeview, - a change signal is sent, even if he was just expanding one node... */ - GtkTreePath *path = gtk_tree_path_new_first(); - gtk_tree_view_set_cursor (GTK_TREE_VIEW (m_categories), path, NULL, FALSE); - gtk_tree_path_free (path); - } - else - gtk_widget_hide (m_categories_expander); - - g_signal_handlers_unblock_by_func (selection, - (gpointer) categories_selection_cb, this); - } - - GtkWidget *buildCategories() - { - GtkWidget *scroll; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - - m_categories = gtk_tree_view_new(); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_categories), FALSE); - gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_categories), 0); - renderer = gtk_cell_renderer_text_new(); - column = gtk_tree_view_column_new_with_attributes ("", - renderer, "text", 0, NULL); - gtk_tree_view_column_set_expand (column, TRUE); - gtk_tree_view_append_column (GTK_TREE_VIEW (m_categories), column); - renderer = gtk_cell_renderer_pixbuf_new(); - column = gtk_tree_view_column_new_with_attributes ("", - renderer, "pixbuf", 2, NULL); - gtk_tree_view_column_set_expand (column, FALSE); - gtk_tree_view_append_column (GTK_TREE_VIEW (m_categories), column); - - GtkTreeSelection *selection = gtk_tree_view_get_selection ( - GTK_TREE_VIEW (m_categories)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - g_signal_connect (G_OBJECT (selection), "changed", - G_CALLBACK (categories_selection_cb), this); - - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_widget_set_size_request (scroll, -1, 200); - gtk_container_add (GTK_CONTAINER (scroll), m_categories); - - m_categories_expander = gtk_expander_new (_("Categories")); - gtk_container_add (GTK_CONTAINER (m_categories_expander), scroll); - gtk_expander_set_expanded (GTK_EXPANDER (m_categories_expander), TRUE); - return m_categories_expander; - } - - GtkWidget *buildRepos() - { - GtkWidget *scroll; - GtkListStore *store; - GtkTreeViewColumn *column; - GtkCellRenderer *renderer; - - // 0 - enabled, 1 - name, 2 - ptr - store = gtk_list_store_new (3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT); - for (int i = 0; Ypp::get()->getRepository (i); i++) { - const Ypp::Repository *repo = Ypp::get()->getRepository (i); - GtkTreeIter iter; - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, TRUE, 1, repo->name.c_str(), 2, i, -1); - } - m_repos = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_repos), FALSE); - gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_repos), 1); - gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (m_repos)), - GTK_SELECTION_NONE); - g_object_unref (G_OBJECT (store)); - renderer = gtk_cell_renderer_toggle_new(); - column = gtk_tree_view_column_new_with_attributes ("", renderer, "active", 0, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (m_repos), column); - g_signal_connect (G_OBJECT (renderer), "toggled", - G_CALLBACK (repo_toggled_cb), this); - g_signal_connect (G_OBJECT (m_repos), "row-activated", - G_CALLBACK (repo_clicked_cb), this); - renderer = gtk_cell_renderer_text_new(); - g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); - column = gtk_tree_view_column_new_with_attributes ("", - renderer, "text", 1, NULL); - gtk_tree_view_append_column (GTK_TREE_VIEW (m_repos), column); - - scroll = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), - GTK_SHADOW_IN); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), - GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); - gtk_widget_set_size_request (scroll, -1, 80); - gtk_container_add (GTK_CONTAINER (scroll), m_repos); - - m_repos_expander = gtk_expander_new (_("Repositories")); - gtk_container_add (GTK_CONTAINER (m_repos_expander), scroll); - return m_repos_expander; - } - - static void categories_selection_cb (GtkTreeSelection *selection, Filters *pThis) - { -fprintf (stderr, "CATEGORIES SELECTED\n"); - pThis->signalChanged(); - } - - void toggle_repo (GtkTreePath *path) - { - IMPL - GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_repos)); - GtkListStore *store = GTK_LIST_STORE (model); - GtkTreeIter iter; - gtk_tree_model_get_iter (model, &iter, path); - - gboolean enabled; - gtk_tree_model_get (model, &iter, 0, &enabled, -1); - gtk_list_store_set (store, &iter, 0, !enabled, -1); - if (enabled) repoToggled--; else repoToggled++; -fprintf (stderr, "repoToggled count: %d\n", repoToggled); - signalChanged(); - } - - static void repo_toggled_cb (GtkCellRendererToggle *renderer, - gchar *path_str, Filters *pThis) - { - IMPL - GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - pThis->toggle_repo (path); - gtk_tree_path_free (path); - } - - static void repo_clicked_cb (GtkTreeView *view, GtkTreePath *path, - GtkTreeViewColumn *column, Filters *pThis) - { - IMPL - pThis->toggle_repo (path); - } - - // utility - static GtkWidget *labelWidget (const char *label_str, GtkWidget *widget, - GtkSizeGroup *group) - { - GtkWidget *hbox = gtk_hbox_new (FALSE, 0); - GtkWidget *label = gtk_label_new_with_mnemonic (label_str); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); - gtk_size_group_add_widget (group, label); - return hbox; + timeout_id = g_timeout_add (250, inner::timeout_cb, this); } }; @@ -741,92 +916,94 @@ class PackageControl { -GtkWidget *m_vbox, *m_status, *m_lock_button, *m_locked_image, *m_unlocked_image, - *m_installed_box, *m_available_box, *m_remove_button, *m_install_button, - *m_undo_button, *m_versions_combo, *m_version_repo; -GtkTreeModel *m_versions_model; +GtkWidget *m_widget, *m_install_button, *m_remove_button, *m_installed_version, + *m_available_versions, *m_undo_button, *m_lock_button, *m_locked_image, + *m_unlocked_image, *m_package_image; public: -std::list <Ypp::Package *> m_packages; +std::list <Ypp::Package *> m_packages; // we keep a copy to test against modified... +Filters *m_filters; // used to filter repo versions... GtkWidget *getWidget() - { return m_vbox; } + { return m_widget; } - PackageControl() + PackageControl (Filters *filters) + : m_filters (filters) { - GtkSizeGroup *size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - m_vbox = gtk_vbox_new (FALSE, 6); - GtkWidget *hbox, *label; + // installed + m_install_button = createButton ("", GTK_STOCK_SAVE); + g_signal_connect (G_OBJECT (m_install_button), "clicked", + G_CALLBACK (install_clicked_cb), this); + + m_installed_version = gtk_label_new (""); + gtk_misc_set_alignment (GTK_MISC (m_installed_version), 0, 0.5); + // available + m_remove_button = createButton (_("_Remove"), GTK_STOCK_DELETE); + g_signal_connect (G_OBJECT (m_remove_button), "clicked", + G_CALLBACK (remove_clicked_cb), this); + + m_available_versions = gtk_combo_box_new_text(); + g_signal_connect (G_OBJECT (m_available_versions), "changed", + G_CALLBACK (version_changed_cb), this); + + // lock m_lock_button = gtk_toggle_button_new(); g_signal_connect (G_OBJECT (m_lock_button), "toggled", G_CALLBACK (locked_toggled_cb), this); - m_undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO); - g_signal_connect (G_OBJECT (m_undo_button), "clicked", - G_CALLBACK (undo_clicked_cb), this); - - hbox = gtk_hbox_new (FALSE, 6); - label = gtk_label_new (_("Status:")); - YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_size_group_add_widget (size_group, label); - m_status = gtk_label_new ("-"); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), m_status, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), m_undo_button, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new(0), TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (hbox), m_lock_button, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_vbox), hbox, TRUE, TRUE, 0); - m_locked_image = createImageFromXPM (pkg_locked_xpm); m_unlocked_image = createImageFromXPM (pkg_unlocked_xpm); g_object_ref_sink (G_OBJECT (m_locked_image)); g_object_ref_sink (G_OBJECT (m_unlocked_image)); - m_remove_button = createButton (_("_Remove"), GTK_STOCK_DELETE); - g_signal_connect (G_OBJECT (m_remove_button), "clicked", - G_CALLBACK (remove_clicked_cb), this); - m_install_button = createButton ("", GTK_STOCK_SAVE); - g_signal_connect (G_OBJECT (m_install_button), "clicked", - G_CALLBACK (install_clicked_cb), this); + m_package_image = gtk_image_new(); - m_installed_box = gtk_hbox_new (FALSE, 6); + m_undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO); + g_signal_connect (G_OBJECT (m_undo_button), "clicked", + G_CALLBACK (undo_clicked_cb), this); + + // layout + GtkWidget *table; + table = gtk_table_new (3, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + // versions + gtk_table_attach (GTK_TABLE (table), m_installed_version, 1, 2, 0, 1, + GTK_FILL, GTK_FILL, 0, 0); + gtk_table_attach (GTK_TABLE (table), m_available_versions, 1, 2, 1, 2, + GTK_FILL, GTK_FILL, 0, 0); + // buttons + gtk_table_attach (GTK_TABLE (table), m_remove_button, 2, 3, 0, 1, + GTK_FILL, GtkAttachOptions (0), 0, 0); + gtk_table_attach (GTK_TABLE (table), m_install_button, 2, 3, 1, 2, + GTK_FILL, GtkAttachOptions (0), 0, 0); + // labels + GtkWidget *label; label = gtk_label_new (_("Installed: ")); YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_size_group_add_widget (size_group, label); - gtk_box_pack_start (GTK_BOX (m_installed_box), label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_installed_box), m_remove_button, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_vbox), m_installed_box, TRUE, TRUE, 0); - - m_versions_model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT)); - m_versions_combo = gtk_combo_box_new_with_model (m_versions_model); - g_signal_connect (G_OBJECT (m_versions_combo), "changed", - G_CALLBACK (version_changed_cb), this); - - GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (m_versions_combo), renderer, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (m_versions_combo), - renderer, "text", 0, NULL); - - m_available_box = gtk_hbox_new (FALSE, 6); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 0, 0); label = gtk_label_new (_("Available: ")); YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - gtk_size_group_add_widget (size_group, label); - gtk_box_pack_start (GTK_BOX (m_available_box), label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_available_box), m_versions_combo, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_available_box), m_install_button, FALSE, TRUE, 0); - label = gtk_label_new (_("(Repository:")); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - m_version_repo = gtk_label_new (""); - gtk_misc_set_alignment (GTK_MISC (m_version_repo), 0, 0.5); - gtk_label_set_ellipsize (GTK_LABEL (m_version_repo), PANGO_ELLIPSIZE_END); - gtk_box_pack_start (GTK_BOX (m_available_box), label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_available_box), m_version_repo, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (m_vbox), m_available_box, TRUE, TRUE, 0); + gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 0, 0); + + GtkWidget *lock_align = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_container_add (GTK_CONTAINER (lock_align), m_lock_button); + + GtkWidget *undo_align = gtk_alignment_new (0.5, 0.5, 0, 0); + gtk_container_add (GTK_CONTAINER (undo_align), m_undo_button); - g_object_unref (G_OBJECT (size_group)); + GtkWidget *hbox = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), undo_align, FALSE, TRUE, 12); + gtk_box_pack_start (GTK_BOX (hbox), lock_align, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new(""), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (hbox), m_package_image, FALSE, TRUE, 0); + + m_widget = gtk_alignment_new (0, 0.5, 1, 0); + gtk_container_set_border_width (GTK_CONTAINER (m_widget), 6); + gtk_container_add (GTK_CONTAINER (m_widget), hbox); } ~PackageControl() @@ -839,171 +1016,118 @@ void setPackages (const std::list <Ypp::Package *> &packages) { -fprintf (stderr, "packages selected (%d)\n", packages.size()); - // FIXME: we'll probably want to re-work the controls interface - // for now, let's just handle none-one-multiple selections separatadely m_packages = packages; - if (packages.size() == 1) { - Ypp::Package *package = packages.front(); - // status label - std::string status; - if (package->isInstalled()) - status = _("Installed ") + package->getInstalledVersion()->number; - else - status = _("Not installed"); - if (package->toInstall()) { - int nb; - const Ypp::Package::Version *version; - package->toInstall (&nb); - version = package->getAvailableVersion (nb); - status += _(" (to install"); - if (version) - status += " " + version->number; - status += ")"; - } - else if (package->toRemove()) - status += _(" (to remove)"); - gtk_label_set_text (GTK_LABEL (m_status), status.c_str()); - if (package->isModified()) - gtk_widget_show (m_undo_button); - else - gtk_widget_hide (m_undo_button); - - // install version - if (package->isInstalled()) - gtk_widget_show (m_installed_box); - else - gtk_widget_hide (m_installed_box); + if (packages.empty()) + return; + Ypp::Package *single_package = packages.size() == 1 ? packages.front() : NULL; - // available versions - gtk_widget_show (m_versions_combo); - if (package->getAvailableVersion (0)) { - gtk_list_store_clear (GTK_LIST_STORE (m_versions_model)); - for (int i = 0; package->getAvailableVersion (i); i++) { - const char *version = package->getAvailableVersion (i)->number.c_str(); -fprintf (stderr, "adding version: %s\n", version); - GtkTreeIter iter; - gtk_list_store_append (GTK_LIST_STORE (m_versions_model), &iter); - gtk_list_store_set (GTK_LIST_STORE (m_versions_model), &iter, - 0, version, 1, i, -1); - } - gtk_combo_box_set_active (GTK_COMBO_BOX (m_versions_combo), 0); - gtk_widget_show (m_available_box); + bool allInstalled = true, allNotInstalled = true, allUpgradable = true, + allModified = true, allLocked = true, allUnlocked = true; + for (std::list <Ypp::Package *>::const_iterator it = packages.begin(); + it != packages.end(); it++) { + if (!(*it)->isInstalled()) { + allInstalled = false; + allUpgradable = false; + } + else { + allNotInstalled = false; + const Ypp::Package::Version *version = (*it)->getAvailableVersion(0); + if (!version || version->cmp <= 0) + allUpgradable = false; + } + if ((*it)->isModified()) { + // if modified, can't be locked or unlocked + allLocked = allUnlocked = false; } else - gtk_widget_hide (m_available_box); - - // is locked - gtk_widget_show (m_lock_button); - bool locked = package->isLocked(); - g_signal_handlers_block_by_func (m_lock_button, (gpointer) locked_toggled_cb, this); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_lock_button), locked); - g_signal_handlers_unblock_by_func (m_lock_button, (gpointer) locked_toggled_cb, this); - gtk_button_set_image (GTK_BUTTON (m_lock_button), - locked ? m_locked_image : m_unlocked_image); - gtk_widget_set_sensitive (m_install_button, !locked); - gtk_widget_set_sensitive (m_remove_button, !locked); - - gtk_widget_show (m_vbox); - } - else if (packages.size()) { - bool allInstalled = true, allNotInstalled = true, allUpgradable = true, - allModified = true, allLocked = true, allUnlocked = true; - for (std::list <Ypp::Package *>::const_iterator it = packages.begin(); - it != packages.end(); it++) { - if (!(*it)->isInstalled()) { - allInstalled = false; - allUpgradable = false; - } - else { - allNotInstalled = false; - const Ypp::Package::Version *version = (*it)->getAvailableVersion(0); - if (!version || version->cmp <= 0) - allUpgradable = false; - } - if (!(*it)->isModified()) - allModified = false; - if ((*it)->isLocked()) - allUnlocked = false; - else - allLocked = false; - } - - std::string status; - if (allInstalled) - status = _("Installed"); - else if (allNotInstalled) - status = _("Not installed"); + allModified = false; + if ((*it)->isLocked()) + allUnlocked = false; else - status = _("--"); + allLocked = false; + } - if (allModified) { - status += _(" (modified)"); - gtk_widget_show (m_undo_button); - } + if (allInstalled) { + gtk_widget_show (m_remove_button); + if (single_package) + gtk_label_set_text (GTK_LABEL (m_installed_version), + single_package->getInstalledVersion()->number.c_str()); else - gtk_widget_hide (m_undo_button); - gtk_label_set_text (GTK_LABEL (m_status), status.c_str()); + gtk_label_set_text (GTK_LABEL (m_installed_version), "(several)"); + } + else { + gtk_widget_hide (m_remove_button); + gtk_label_set_text (GTK_LABEL (m_installed_version), "--"); + } - // install version - if (allInstalled) - gtk_widget_show (m_installed_box); + GtkTreeModel *model = gtk_combo_box_get_model ( + GTK_COMBO_BOX (m_available_versions)); + gtk_list_store_clear (GTK_LIST_STORE (model)); + gtk_widget_set_sensitive (m_available_versions, FALSE); + gtk_widget_show (m_install_button); + if (single_package) { + if (single_package->getAvailableVersion (0)) { + gtk_widget_set_sensitive (m_available_versions, TRUE); + gtk_widget_show (m_install_button); + int selectedRepo = m_filters->selectedRepo(); + for (int i = 0; single_package->getAvailableVersion (i); i++) { + const Ypp::Package::Version *version = single_package->getAvailableVersion (i); + if (selectedRepo >= 0 && version->repo != selectedRepo) + continue; + string text = version->number + "\n"; + text += "(" + Ypp::get()->getRepository (version->repo)->name + ")"; + gtk_combo_box_append_text (GTK_COMBO_BOX (m_available_versions), text.c_str()); + } + gtk_combo_box_set_active (GTK_COMBO_BOX (m_available_versions), 0); + } else - gtk_widget_hide (m_installed_box); - - // available versions - gtk_widget_hide (m_versions_combo); - if (allNotInstalled || allUpgradable) { - gtk_widget_show (m_available_box); - const char *installLabel = _("Install"); - if (allUpgradable) - installLabel = _("Upgrade"); - gtk_button_set_label (GTK_BUTTON (m_install_button), installLabel); + gtk_widget_hide (m_install_button); + } + else { + if (allUpgradable) { + gtk_combo_box_append_text (GTK_COMBO_BOX (m_available_versions), "(upgrades)"); + gtk_combo_box_set_active (GTK_COMBO_BOX (m_available_versions), 0); + gtk_button_set_label (GTK_BUTTON (m_install_button), _("Upgrade")); + } + else if (allNotInstalled) { + gtk_combo_box_append_text (GTK_COMBO_BOX (m_available_versions), "(several)"); + gtk_combo_box_set_active (GTK_COMBO_BOX (m_available_versions), 0); + gtk_button_set_label (GTK_BUTTON (m_install_button), _("Install")); } else - gtk_widget_hide (m_available_box); + gtk_widget_hide (m_install_button); + } - // is locked - if (allLocked || allUnlocked) { - gtk_widget_show (m_lock_button); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_lock_button), allLocked); - gtk_button_set_image (GTK_BUTTON (m_lock_button), - allLocked ? m_locked_image : m_unlocked_image); - gtk_widget_set_sensitive (m_install_button, !allLocked); - gtk_widget_set_sensitive (m_remove_button, !allLocked); - } - else { - gtk_widget_hide (m_lock_button); - gtk_widget_set_sensitive (m_install_button, TRUE); - gtk_widget_set_sensitive (m_remove_button, TRUE); - } - gtk_widget_show (m_vbox); + // is locked + if (allLocked || allUnlocked) { + gtk_widget_show (m_lock_button); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_lock_button), allLocked); + gtk_button_set_image (GTK_BUTTON (m_lock_button), + allLocked ? m_locked_image : m_unlocked_image); + gtk_widget_set_sensitive (m_install_button, !allLocked); + gtk_widget_set_sensitive (m_remove_button, !allLocked); } + else { + gtk_widget_hide (m_lock_button); + gtk_widget_set_sensitive (m_install_button, TRUE); + gtk_widget_set_sensitive (m_remove_button, TRUE); + } + + if (allModified) + gtk_widget_show (m_undo_button); else - gtk_widget_hide (m_vbox); + gtk_widget_hide (m_undo_button); -#if 0 - m_package = package; - if (package) { - if (package->isInstalled()) { - gtk_widget_show (m_remove_button); - gtk_widget_hide (m_install_button); - } - else { - gtk_widget_show (m_install_button); - gtk_widget_hide (m_remove_button); + gtk_image_clear (GTK_IMAGE (m_package_image)); + if (single_package) { + GtkIconTheme *icons = gtk_icon_theme_get_default(); + GdkPixbuf *pixbuf = gtk_icon_theme_load_icon (icons, + single_package->name().c_str(), 32, GtkIconLookupFlags (0), NULL); + if (pixbuf) { + gtk_image_set_from_pixbuf (GTK_IMAGE (m_package_image), pixbuf); + g_object_unref (G_OBJECT (pixbuf)); } - if (package && package->hasUpgrade()) - gtk_widget_show (m_upgrade_button); - else - gtk_widget_hide (m_upgrade_button); - } - else { - gtk_widget_hide (m_install_button); - gtk_widget_hide (m_remove_button); - gtk_widget_hide (m_upgrade_button); } -#endif } private: @@ -1014,9 +1138,9 @@ for (std::list <Ypp::Package *>::iterator it = pThis->m_packages.begin(); it != pThis->m_packages.end(); it++) { int version; - if (GTK_WIDGET_VISIBLE (pThis->m_versions_combo)) + if (GTK_WIDGET_VISIBLE (pThis->m_available_versions)) version = gtk_combo_box_get_active (GTK_COMBO_BOX ( - pThis->m_versions_combo)); + pThis->m_available_versions)); else version = 0; // i.e. most recent (on multi-packages) (*it)->install (version); @@ -1036,62 +1160,50 @@ normalCursor(); } - static void undo_clicked_cb (GtkButton *button, PackageControl *pThis) + static void locked_toggled_cb (GtkToggleButton *button, PackageControl *pThis) { + bool lock = gtk_toggle_button_get_active (button); busyCursor(); Ypp::get()->startTransactions(); for (std::list <Ypp::Package *>::iterator it = pThis->m_packages.begin(); it != pThis->m_packages.end(); it++) - (*it)->undo(); + (*it)->lock (lock); Ypp::get()->finishTransactions(); normalCursor(); } - static void locked_toggled_cb (GtkToggleButton *button, PackageControl *pThis) + static void undo_clicked_cb (GtkButton *button, PackageControl *pThis) { busyCursor(); Ypp::get()->startTransactions(); for (std::list <Ypp::Package *>::iterator it = pThis->m_packages.begin(); it != pThis->m_packages.end(); it++) - (*it)->lock (gtk_toggle_button_get_active (button)); + (*it)->undo(); Ypp::get()->finishTransactions(); normalCursor(); } static void version_changed_cb (GtkComboBox *combo, PackageControl *pThis) { - fprintf (stderr, "version changed\n"); - if (!pThis->m_packages.empty()) { + if (pThis->m_packages.size() == 1) { Ypp::Package *package = pThis->m_packages.front(); - int nb; - GtkTreeIter iter; - if (gtk_combo_box_get_active_iter (combo, &iter)) { - gtk_tree_model_get (pThis->m_versions_model, &iter, 1, &nb, -1); - const Ypp::Package::Version *version; - fprintf (stderr, "get available version %d\n", nb); - version = package->getAvailableVersion (nb); - g_assert (version != NULL); - - const Ypp::Repository *repo = Ypp::get()->getRepository (version->repo); - if (repo) { - std::string repo_str = repo->name + ")"; - gtk_label_set_text (GTK_LABEL (pThis->m_version_repo), repo_str.c_str()); - } - else - gtk_label_set_text (GTK_LABEL (pThis->m_version_repo), - "TODO: hide this for collections)"); - - const char *installLabel = _("Install"); - if (package->isInstalled()) { - if (version->cmp > 0) - installLabel = _("Upgrade"); - else if (version->cmp == 0) - installLabel = _("Re-install"); - else //if (version->cmp < 0) - installLabel = _("Downgrade"); - } - gtk_button_set_label (GTK_BUTTON (pThis->m_install_button), installLabel); + int nb = gtk_combo_box_get_active (GTK_COMBO_BOX (pThis->m_available_versions)); + if (nb == -1) return; + + const Ypp::Package::Version *version; + version = package->getAvailableVersion (nb); + assert (version != NULL); + + const char *installLabel = _("Install"); + if (package->isInstalled()) { + if (version->cmp > 0) + installLabel = _("Upgrade"); + else if (version->cmp == 0) + installLabel = _("Re-install"); + else //if (version->cmp < 0) + installLabel = _("Downgrade"); } + gtk_button_set_label (GTK_BUTTON (pThis->m_install_button), installLabel); } } @@ -1108,40 +1220,61 @@ } }; -class PackageInfo +class PackageDetails { GtkWidget *m_widget, *m_description, *m_filelist, *m_changelog, *m_authors; +PackageControl *m_control; public: GtkWidget *getWidget() { return m_widget; } - PackageInfo() + PackageDetails (Filters *filters) { + m_control = new PackageControl (filters); m_widget = gtk_notebook_new(); + gtk_notebook_set_tab_pos (GTK_NOTEBOOK (m_widget), GTK_POS_BOTTOM); + addPage (_("Status"), m_control->getWidget()); addPage (_("Description"), createHtmlWidget (&m_description)); addPage (_("File List"), createHtmlWidget (&m_filelist)); addPage (_("ChangeLog"), createHtmlWidget (&m_changelog)); addPage (_("Authors"), createHtmlWidget (&m_authors)); - gtk_widget_set_size_request (m_widget, -1, 150); ygtk_html_wrap_connect_link_clicked (m_filelist, G_CALLBACK (path_pressed_cb), NULL); } - void setPackage (Ypp::Package *package) + void setPackages (std::list <Ypp::Package *> packages) { - if (package) { - setText (m_description, package->description()); - setText (m_filelist, package->filelist()); - setText (m_changelog, package->changelog()); - setText (m_authors, package->authors()); - if (!GTK_WIDGET_VISIBLE (m_widget)) { - gtk_notebook_set_current_page (GTK_NOTEBOOK (m_widget), 0); - gtk_widget_show (m_widget); + if (packages.empty()) { + gtk_widget_hide (m_widget); + } + else { + gtk_widget_show (m_widget); + m_control->setPackages (packages); + Ypp::Package *package = packages.front(); + if (package) { + setText (m_description, package->description()); + setText (m_filelist, package->filelist()); + setText (m_changelog, package->changelog()); + setText (m_authors, package->authors()); + if (!GTK_WIDGET_VISIBLE (m_widget)) { + gtk_notebook_set_current_page (GTK_NOTEBOOK (m_widget), 0); + gtk_widget_show (m_widget); + } } } - else - gtk_widget_hide (m_widget); + } + + void packageModified (Ypp::Package *package) + { + // GTK+ doesn't fire selection change when a selected row changes, so we need + // to re-load PackageControl in that occasions. + std::list <Ypp::Package *>::iterator it; + for (it = m_control->m_packages.begin(); it != m_control->m_packages.end(); it++) + if (*it == package) + break; + if (it != m_control->m_packages.end()) + m_control->setPackages (m_control->m_packages); } private: @@ -1176,6 +1309,7 @@ } }; +#if 0 class DiskView : public Ypp::Disk::Listener { GtkWidget *m_widget; @@ -1269,7 +1403,6 @@ GTK_SHADOW_IN); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_NEVER, GTK_POLICY_NEVER); -// gtk_widget_set_size_request (scroll, -1, 50); gtk_container_add (GTK_CONTAINER (scroll), view); gtk_widget_show_all (scroll); return scroll; @@ -1292,87 +1425,100 @@ return combo; } }; +#else +// disabled +struct DiskView +{ +GtkWidget *m_empty; +GtkWidget *getWidget() { return m_empty; } +DiskView() { m_empty = gtk_event_box_new(); } +}; +#endif class PackageSelector : public Filters::Listener, public PackagesView::Listener { PackagesView *m_packages; Filters *m_filters; -PackageInfo *m_info; -PackageControl *m_control; +PackageDetails *m_details; DiskView *m_disk; GtkWidget *m_box; -TrashWindow *m_trashWin; +ChangesPane *m_changes; public: GtkWidget *getWidget() { return m_box; } - PackageSelector() + PackageSelector (bool update_mode) { m_packages = new PackagesView(); + m_filters = new Filters (update_mode); + m_details = new PackageDetails (m_filters); + m_disk = new DiskView(); + m_changes = new ChangesPane(); m_packages->setListener (this); + m_filters->setListener (this); - m_control = new PackageControl(); - m_info = new PackageInfo(); + GtkWidget *filter_box = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (filter_box), gtk_label_new (_("Filters:")), FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (filter_box), m_filters->getNameWidget(), FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (filter_box), m_filters->getReposWidget(), FALSE, TRUE, 0); + + GtkWidget *categories_box = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (categories_box), m_filters->getCollectionWidget(), + TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (categories_box), m_filters->getTypeWidget(), FALSE, TRUE, 0); + + GtkWidget *packages_box = gtk_hpaned_new(); + gtk_paned_pack1 (GTK_PANED (packages_box), categories_box, TRUE, TRUE); + gtk_paned_pack2 (GTK_PANED (packages_box), m_packages->getWidget(), TRUE, FALSE); + gtk_paned_set_position (GTK_PANED (packages_box), 180); + + GtkWidget *details_box = gtk_vpaned_new(); + gtk_paned_pack1 (GTK_PANED (details_box), packages_box, TRUE, FALSE); + gtk_paned_pack2 (GTK_PANED (details_box), m_details->getWidget(), TRUE, FALSE); + gtk_paned_set_position (GTK_PANED (details_box), 30000 /* minimal size */); GtkWidget *vbox = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (vbox), m_packages->getWidget(), TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (vbox), m_control->getWidget(), FALSE, FALSE, 0); - gtk_box_pack_start (GTK_BOX (vbox), m_info->getWidget(), FALSE, TRUE, 0); - - m_filters = new Filters(); - m_filters->setListener (this); - m_disk = new DiskView(); + gtk_box_pack_start (GTK_BOX (vbox), m_filters->getStatusesWidget(), FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), filter_box, FALSE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (vbox), details_box, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 6); - GtkWidget *left_box = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (left_box), m_filters->getWidget(), TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (left_box), m_disk->getWidget(), FALSE, TRUE, 0); + GtkWidget *changes_box = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (changes_box), m_changes->getWidget(), TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (changes_box), m_disk->getWidget(), FALSE, TRUE, 0); m_box = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (m_box), left_box, FALSE, TRUE, 0); gtk_box_pack_start (GTK_BOX (m_box), vbox, TRUE, TRUE, 0); - gtk_widget_show_all (m_box); + gtk_box_pack_start (GTK_BOX (m_box), changes_box, FALSE, TRUE, 0); - m_control->setPackages (std::list Ypp::Package* ()); - m_info->setPackage (NULL); - - m_trashWin = new TrashWindow(); + gtk_widget_show_all (m_box); + m_changes->setContainer (changes_box); + m_details->setPackages (std::list <Ypp::Package *> ()); } ~PackageSelector() { delete m_packages; - delete m_control; - delete m_info; + delete m_details; delete m_filters; delete m_disk; - delete m_trashWin; + delete m_changes; } virtual void doQuery (Ypp::Query *query) { - m_packages->query (query); + m_packages->setQuery (query); } virtual void packagesSelected (const std::list <Ypp::Package *> &packages) { - m_control->setPackages (packages); - if (packages.size() == 1) - m_info->setPackage (packages.front()); - else - m_info->setPackage (NULL); + m_details->setPackages (packages); } void packageModified (Ypp::Package *package) { - // GTK+ doesn't fire selection change when a selected row changes, so we need - // to re-load PackageControl in that occasions. - std::list <Ypp::Package *>::iterator it; - for (it = m_control->m_packages.begin(); it != m_control->m_packages.end(); it++) - if (*it == package) - break; - if (it != m_control->m_packages.end()) - m_control->setPackages (m_control->m_packages); + m_details->packageModified (package); } }; @@ -1387,25 +1533,23 @@ : YPackageSelector (NULL, mode), YGWidget (this, parent, true, YGTK_TYPE_WIZARD, NULL) { -fprintf (stderr, "YGPackageSelector()\n"); setBorder (0); + YGTK_WIZARD (getWidget())->child_border_width = 0; + YGDialog *dialog = YGDialog::currentDialog(); dialog->setCloseCallback (confirm_cb, this); GtkWindow *window = YGDialog::currentWindow(); - gtk_window_resize (window, GTK_WIDGET (window)->allocation.width, - MAX (580, GTK_WIDGET (window)->allocation.height)); + gtk_window_resize (window, + MAX (700, GTK_WIDGET (window)->allocation.width), + MAX (680, GTK_WIDGET (window)->allocation.height)); -fprintf (stderr, "wizard setup\n"); YGtkWizard *wizard = YGTK_WIZARD (getWidget()); ygtk_wizard_set_header_icon (wizard, window, - THEMEDIR "/icons/32x32/apps/yast-software.png"); + THEMEDIR "/icons/22x22/apps/yast-software.png"); ygtk_wizard_set_header_text (wizard, window, _("Package Selector")); - ygtk_wizard_set_help_text (wizard, - _("TO WRITE") - ); + ygtk_wizard_set_help_text (wizard, ""); -fprintf (stderr, "buttons strings\n"); ygtk_wizard_set_abort_button_label (wizard, _("_Cancel")); ygtk_wizard_set_abort_button_str_id (wizard, "cancel"); ygtk_wizard_set_back_button_label (wizard, ""); @@ -1414,13 +1558,10 @@ g_signal_connect (G_OBJECT (getWidget()), "action-triggered", G_CALLBACK (wizard_action_cb), this); -fprintf (stderr, "create package selector\n"); - m_package_selector = new PackageSelector(); + m_package_selector = new PackageSelector (onlineUpdateMode()); gtk_container_add (GTK_CONTAINER (wizard), m_package_selector->getWidget()); -fprintf (stderr, "ypp::set interface()\n"); Ypp::get()->setInterface (this); -fprintf (stderr, "done()\n"); } virtual ~YGPackageSelector() @@ -1434,9 +1575,7 @@ gint id_type, YGPackageSelector *pThis) { IMPL -fprintf (stderr, "wizard action\n"); const gchar *action = (gchar *) id; -fprintf (stderr, "action: %s\n", action); if (!strcmp (action, "accept")) { y2milestone ("Closing PackageSelector with 'accept'"); @@ -1508,7 +1647,6 @@ virtual bool resolveProblems (std::list <Ypp::Problem *> problems) { -fprintf (stderr, "resolving %d problems\n", problems.size()); // we can't use ordinary radio buttons, as gtk+ enforces that in a group // one must be selected... @@ -1547,15 +1685,6 @@ gtk_tree_model_get_iter (model, &iter, path); gtk_tree_store_set (store, &iter, ACTIVE_TOGGLE_COL, enabled, -1); } -#if 0 - static void renderer_toggled_cb (GtkCellRenderer *render, gchar *path_str, - GtkTreeModel *model) - { - GtkTreePath *path = gtk_tree_path_new_from_string (path_str); - solution_toggled (model, path); - gtk_tree_path_free (path); - } -#endif static void cursor_changed_cb (GtkTreeView *view, GtkTreeModel *model) { GtkTreePath *path; @@ -1583,33 +1712,6 @@ } } return FALSE; - - -/* - GtkTreePath *path; - if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), x, y, - &path, NULL, NULL, NULL)) { - GtkTreeIter iter; - gchar *tooltip_text; - gtk_tree_model_get_iter (model, &iter, path); - gtk_tree_path_free (path); - gtk_tree_model_get (model, &iter, - TOOLTIP_TEXT_COL, &tooltip_text, -1); - // some strings are just " ", so we need to check that - // now, - bool empty = true; - for (int i = 0; tooltip_text[i] && empty; i++) - if (tooltip_text[i] != ' ') - empty = false; - if (empty) - gtk_tooltip_set_text (tooltip, "(no details)"); - else - gtk_tooltip_set_text (tooltip, tooltip_text); - g_free (tooltip_text); - return TRUE; - } - return FALSE; -*/ } }; @@ -1660,8 +1762,6 @@ renderer = gtk_cell_renderer_toggle_new(); gtk_cell_renderer_toggle_set_radio ( GTK_CELL_RENDERER_TOGGLE (renderer), TRUE); -/* g_signal_connect (G_OBJECT (renderer), "toggled", - G_CALLBACK (inner::renderer_toggled_cb), store);*/ // we should not connect the actual toggle button, as we toggle on row press g_signal_connect (G_OBJECT (view), "cursor-changed", G_CALLBACK (inner::cursor_changed_cb), store); @@ -1685,62 +1785,6 @@ gtk_container_add (GTK_CONTAINER (scroll), view); gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll); -#if 0 - // version that uses viewport, labels and radio buttons -- unfortunately, - // gtk+ enforces that one radio button per group to be selected -- we don't - // want that as the user may decide to do nothing for a certain action. - // We also don't want to add a "Do nothing" radio, as that would imply would - // dismiss the conflict. No, we just want to let the user try to resolve current - // conflicts... - struct inner { - static void solution_toggled (GtkToggleButton *toggle, bool *apply) - { *apply = gtk_toggle_button_get_active (toggle); } - }; - - GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Problem Resolver"), - YGUI::ui()->currentWindow(), GtkDialogFlags (0), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL); - - GtkWidget *view_port = gtk_viewport_new (NULL, NULL); - gtk_viewport_set_shadow_type (GTK_VIEWPORT (view_port), GTK_SHADOW_NONE); - gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), view_port, - TRUE, TRUE, 0); - GtkWidget *main_box = gtk_vbox_new (FALSE, 6); - gtk_container_add (GTK_CONTAINER (view_port), main_box); - -fprintf (stderr, "populating main box\n"); - for (std::list <Ypp::Problem *>::iterator it = problems.begin(); - it != problems.end(); it++) { - GtkWidget *label, *box; -fprintf (stderr, "creating label: %s\n", (*it)->description.c_str()); - label = gtk_label_new ((*it)->description.c_str()); - YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM); -fprintf (stderr, "setting tooltyp: %s\n", (*it)->details.c_str()); - if (!(*it)->details.empty()) - gtk_widget_set_tooltip_text (label, (*it)->details.c_str()); - - GSList *group = NULL; - box = gtk_vbox_new (FALSE, 6); - for (int i = 0; (*it)->getSolution (i); i++) { - Ypp::Problem::Solution *solution = (*it)->getSolution (i); -fprintf (stderr, "creating radio: %s\n", solution->description.c_str()); - GtkWidget *radio = gtk_radio_button_new_with_label ( - group, solution->description.c_str()); -fprintf (stderr, "setting tooltip: %s\n", (*it)->details.c_str()); - if (!solution->details.empty()) - gtk_widget_set_tooltip_text (radio, solution->details.c_str()); - group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio)); - gtk_box_pack_start (GTK_BOX (box), radio, FALSE, TRUE, 0); - g_signal_connect (G_OBJECT (radio), "toggled", - G_CALLBACK (inner::solution_toggled), &solution->apply); - } - - gtk_box_pack_start (GTK_BOX (main_box), label, FALSE, TRUE, 0); - gtk_box_pack_start (GTK_BOX (main_box), box, FALSE, TRUE, 0); - } -#endif - gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 480); gtk_widget_show_all (dialog); @@ -1774,9 +1818,6 @@ YPackageSelector *YGWidgetFactory::createPackageSelector (YWidget *parent, long mode) { -/* if (opt.youMode.value()) - return new YGPatchSelector (opt, YGWidget::get (parent)); - else*/ - return new YGPackageSelector (parent, mode); + return new YGPackageSelector (parent, mode); } Modified: trunk/gtk/unstable-libyui/src/YGWidget.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/YGWidget.... ============================================================================== --- trunk/gtk/unstable-libyui/src/YGWidget.cc (original) +++ trunk/gtk/unstable-libyui/src/YGWidget.cc Fri Dec 14 09:40:53 2007 @@ -233,7 +233,7 @@ bool show, GType type, const char *property_name, ...) : YGLabeledWidget (ywidget, parent, string(), YD_VERT, show, - YGTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL) + YGTK_TYPE_TUNED_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL) { va_list args; va_start (args, property_name); @@ -248,7 +248,7 @@ bool show, GType type, const char *property_name, ...) : YGLabeledWidget (ywidget, parent, label_text, label_ori, show, - YGTK_TYPE_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL) + YGTK_TYPE_TUNED_SCROLLED_WINDOW, "shadow-type", GTK_SHADOW_IN, NULL) { va_list args; va_start (args, property_name); @@ -271,7 +271,8 @@ { gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (YGLabeledWidget::getWidget()), hpolicy, vpolicy); - ygtk_scrolled_window_set_auto_policy (YGTK_SCROLLED_WINDOW (YGLabeledWidget::getWidget()), + ygtk_tuned_scrolled_window_set_auto_policy ( + YGTK_TUNED_SCROLLED_WINDOW (YGLabeledWidget::getWidget()), hpolicy == GTK_POLICY_AUTOMATIC ? MAX_SCROLL_WIDTH : 0, 0); } Modified: trunk/gtk/unstable-libyui/src/dummy.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/dummy.cc?... ============================================================================== --- trunk/gtk/unstable-libyui/src/dummy.cc (original) +++ trunk/gtk/unstable-libyui/src/dummy.cc Fri Dec 14 09:40:53 2007 @@ -10,3 +10,4 @@ YGUI(argc, argv, false, "foo"); return 0; } + Modified: trunk/gtk/unstable-libyui/src/ygtkratiobox.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkratio... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkratiobox.c (original) +++ trunk/gtk/unstable-libyui/src/ygtkratiobox.c Fri Dec 14 09:40:53 2007 @@ -521,18 +521,18 @@ widget_class->size_allocate = ygtk_adj_size_size_allocate; } -//** YGtkScrolledWindow +//** YGtkTunedScrolledWindow -G_DEFINE_TYPE (YGtkScrolledWindow, ygtk_scrolled_window, GTK_TYPE_SCROLLED_WINDOW) +G_DEFINE_TYPE (YGtkTunedScrolledWindow, ygtk_tuned_scrolled_window, GTK_TYPE_SCROLLED_WINDOW) -static void ygtk_scrolled_window_init (YGtkScrolledWindow *scroll) +static void ygtk_tuned_scrolled_window_init (YGtkTunedScrolledWindow *scroll) { } -static void ygtk_scrolled_window_size_request (GtkWidget *widget, +static void ygtk_tuned_scrolled_window_size_request (GtkWidget *widget, GtkRequisition *requisition) { - YGtkScrolledWindow *scroll = YGTK_SCROLLED_WINDOW (widget); + YGtkTunedScrolledWindow *scroll = YGTK_TUNED_SCROLLED_WINDOW (widget); GtkRequisition child_req; GtkWidget *child = GTK_BIN (widget)->child; @@ -555,33 +555,33 @@ gscroll->vscrollbar_policy = GTK_POLICY_AUTOMATIC; } - GTK_WIDGET_CLASS (ygtk_scrolled_window_parent_class)->size_request (widget, requisition); + GTK_WIDGET_CLASS (ygtk_tuned_scrolled_window_parent_class)->size_request (widget, requisition); if (scroll->max_width) requisition->width = MIN (requisition->width, scroll->max_width); if (scroll->max_height) requisition->height = MIN (requisition->height, scroll->max_height); } -GtkWidget* ygtk_scrolled_window_new (GtkWidget *child) +GtkWidget* ygtk_tuned_scrolled_window_new (GtkWidget *child) { - YGtkScrolledWindow *scroll = g_object_new (YGTK_TYPE_SCROLLED_WINDOW, NULL); + YGtkTunedScrolledWindow *scroll = g_object_new (YGTK_TYPE_TUNED_SCROLLED_WINDOW, NULL); if (child) gtk_container_add (GTK_CONTAINER (scroll), child); return GTK_WIDGET (scroll); } -void ygtk_scrolled_window_set_auto_policy (YGtkScrolledWindow *scroll, +void ygtk_tuned_scrolled_window_set_auto_policy (YGtkTunedScrolledWindow *scroll, guint max_width, guint max_height) { scroll->max_width = max_width; scroll->max_height = max_height; } -static void ygtk_scrolled_window_class_init (YGtkScrolledWindowClass *klass) +static void ygtk_tuned_scrolled_window_class_init (YGtkTunedScrolledWindowClass *klass) { - ygtk_scrolled_window_parent_class = g_type_class_peek_parent (klass); + ygtk_tuned_scrolled_window_parent_class = g_type_class_peek_parent (klass); GtkWidgetClass* widget_class = GTK_WIDGET_CLASS (klass); - widget_class->size_request = ygtk_scrolled_window_size_request; + widget_class->size_request = ygtk_tuned_scrolled_window_size_request; } Modified: trunk/gtk/unstable-libyui/src/ygtkratiobox.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkratio... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkratiobox.h (original) +++ trunk/gtk/unstable-libyui/src/ygtkratiobox.h Fri Dec 14 09:40:53 2007 @@ -199,41 +199,42 @@ /* YGtkScrolledWindow gives some a more fine-grained automatic scroll policy. It allows the user to specify from which size scrolling should be applied. */ -#ifndef YGTK_SCROLLED_WIDOW_H -#define YGTK_SCROLLED_WIDOW_H +#ifndef YGTK_TUNED_SCROLLED_WIDOW_H +#define YGTK_TUNED_SCROLLED_WIDOW_H #include <gtk/gtkscrolledwindow.h> G_BEGIN_DECLS -#define YGTK_TYPE_SCROLLED_WINDOW (ygtk_scrolled_window_get_type ()) -#define YGTK_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindow)) -#define YGTK_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ - YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindowClass)) -#define YGTK_IS_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - YGTK_TYPE_SCROLLED_WINDOW)) -#define YGTK_IS_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ - YGTK_TYPE_SCROLLED_WINDOW)) -#define YGTK_SCROLLED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ - YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindowClass)) +#define YGTK_TYPE_TUNED_SCROLLED_WINDOW (ygtk_tuned_scrolled_window_get_type ()) +#define YGTK_TUNED_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_TUNED_SCROLLED_WINDOW, YGtkTunedScrolledWindow)) +#define YGTK_TUNED_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_TUNED_SCROLLED_WINDOW, YGtkTunedScrolledWindowClass)) +#define YGTK_IS_TUNED_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_TUNED_SCROLLED_WINDOW)) +#define YGTK_IS_TUNED_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_TUNED_SCROLLED_WINDOW)) +#define YGTK_TUNED_SCROLLED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_TUNED_SCROLLED_WINDOW, YGtkTunedScrolledWindowClass)) -typedef struct _YGtkScrolledWindow +typedef struct _YGtkTunedScrolledWindow { GtkScrolledWindow parent; // members guint max_width, max_height; -} YGtkScrolledWindow; +} YGtkTunedScrolledWindow; -typedef struct _YGtkScrolledWindowClass +typedef struct _YGtkTunedScrolledWindowClass { GtkScrolledWindowClass parent_class; -} YGtkScrolledWindowClass; +} YGtkTunedScrolledWindowClass; -GType ygtk_scrolled_window_get_type (void) G_GNUC_CONST; -GtkWidget* ygtk_scrolled_window_new (GtkWidget *child /*or NULL*/); +GType ygtk_tuned_scrolled_window_get_type (void) G_GNUC_CONST; +GtkWidget* ygtk_tuned_scrolled_window_new (GtkWidget *child /*or NULL*/); -void ygtk_scrolled_window_set_auto_policy (YGtkScrolledWindow *scroll, - guint max_width, guint max_height); +void ygtk_tuned_scrolled_window_set_auto_policy (YGtkTunedScrolledWindow *scroll, + guint max_width, guint max_height); G_END_DECLS -#endif /*YGTK_SCROLLED_WIDOW_H*/ +#endif /*YGTK_TUNED_SCROLLED_WIDOW_H*/ + Added: trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkscrol... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.c (added) +++ trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.c Fri Dec 14 09:40:53 2007 @@ -0,0 +1,99 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkScrolledWindow widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtkscrolledwindow.h" +#include <gtk/gtk.h> + +#define CHILD_SPACING 2 + +G_DEFINE_TYPE (YGtkScrolledWindow, ygtk_scrolled_window, GTK_TYPE_SCROLLED_WINDOW) + +static void ygtk_scrolled_window_init (YGtkScrolledWindow *scroll) +{ + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); +} + +static void ygtk_scrolled_window_destroy (GtkObject *object) +{ + GTK_OBJECT_CLASS (ygtk_scrolled_window_parent_class)->destroy (object); + YGtkScrolledWindow *scroll = YGTK_SCROLLED_WINDOW (object); + ygtk_scrolled_window_set_corner_widget (scroll, NULL); +} + +static void ygtk_scrolled_window_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GTK_WIDGET_CLASS (ygtk_scrolled_window_parent_class)->size_allocate + (widget, allocation); + if (!GTK_WIDGET_REALIZED (widget)) + return; + + YGtkScrolledWindow *scroll = YGTK_SCROLLED_WINDOW (widget); + if (scroll->corner_child) { + GtkRequisition req; + gtk_widget_size_request (scroll->corner_child, &req); + + GtkWidget *vbar; + vbar = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (scroll)); + + vbar->allocation.height = MAX (0, widget->allocation.height - req.height - CHILD_SPACING); + GtkAllocation alloc = { vbar->allocation.x, + vbar->allocation.y + vbar->allocation.height + CHILD_SPACING, + vbar->allocation.width, + req.height }; + gtk_widget_size_allocate (scroll->corner_child, &alloc); + } +} + +static void ygtk_scrolled_window_forall (GtkContainer *container, + gboolean include_internals, GtkCallback callback, gpointer callback_data) +{ + GTK_CONTAINER_CLASS (ygtk_scrolled_window_parent_class)->forall (container, + include_internals, callback, callback_data); + if (include_internals) { + YGtkScrolledWindow *scroll = YGTK_SCROLLED_WINDOW (container); + if (scroll->corner_child) + callback (scroll->corner_child, callback_data); + } +} + +void ygtk_scrolled_window_set_corner_widget (YGtkScrolledWindow *scroll, GtkWidget *child) +{ + if (scroll->corner_child) + gtk_widget_unparent (scroll->corner_child); + scroll->corner_child = child; + if (child) + gtk_widget_set_parent (child, GTK_WIDGET (scroll)); +} + +void ygtk_scrolled_window_replace (YGtkScrolledWindow *scroll, GtkWidget *child) +{ + GtkWidget *current = gtk_bin_get_child (GTK_BIN (scroll)); + if (current) + gtk_container_remove (GTK_CONTAINER (scroll), current); + if (child) + gtk_container_add (GTK_CONTAINER (scroll), child); +} + +GtkWidget *ygtk_scrolled_window_new (void) +{ return g_object_new (YGTK_TYPE_SCROLLED_WINDOW, NULL); } + +static void ygtk_scrolled_window_class_init (YGtkScrolledWindowClass *klass) +{ + GtkContainerClass *gtkcontainer_class = GTK_CONTAINER_CLASS (klass); + gtkcontainer_class->forall = ygtk_scrolled_window_forall; + + GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS (klass); + gtkwidget_class->size_allocate = ygtk_scrolled_window_size_allocate; + + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_scrolled_window_destroy; +} + Added: trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkscrol... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.h (added) +++ trunk/gtk/unstable-libyui/src/ygtkscrolledwindow.h Fri Dec 14 09:40:53 2007 @@ -0,0 +1,51 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkScrolledWindow extends GtkScrolledWindow adding the possibility to add + a widget in the corner between the scrollbars, flowing into the vertical + scroll bar (which is why the policy should be ALWAYS for the vertical bar). +*/ + +#ifndef YGTK_SCROLLED_WINDOW_H +#define YGTK_SCROLLED_WINDOW_H + +#include <gtk/gtkscrolledwindow.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_SCROLLED_WINDOW (ygtk_scrolled_window_get_type ()) +#define YGTK_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindow)) +#define YGTK_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindowClass)) +#define YGTK_IS_SCROLLED_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_SCROLLED_WINDOW)) +#define YGTK_IS_SCROLLED_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_SCROLLED_WINDOW)) +#define YGTK_SCROLLED_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_SCROLLED_WINDOW, YGtkScrolledWindowClass)) + +typedef struct _YGtkScrolledWindow +{ + GtkScrolledWindow parent; + //members: + GtkWidget *corner_child; +} YGtkScrolledWindow; + +typedef struct _YGtkScrolledWindowClass +{ + GtkScrolledWindowClass parent_class; +} YGtkScrolledWindowClass; + +GtkWidget* ygtk_scrolled_window_new (void); +GType ygtk_scrolled_window_get_type (void) G_GNUC_CONST; + +// container_add/remove combo +void ygtk_scrolled_window_replace (YGtkScrolledWindow *scroll, GtkWidget *child); + +void ygtk_scrolled_window_set_corner_widget (YGtkScrolledWindow *scroll, + GtkWidget *widget); + +G_END_DECLS +#endif /*YGTK_SCROLLED_WINDOW_H*/ + Added: trunk/gtk/unstable-libyui/src/ygtktogglebutton.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtktoggl... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtktogglebutton.c (added) +++ trunk/gtk/unstable-libyui/src/ygtktogglebutton.c Fri Dec 14 09:40:53 2007 @@ -0,0 +1,90 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkToggleButton widget */ +// check the header file for information about this widget + +#include <config.h> +#include "ygtktogglebutton.h" +#include <gtk/gtk.h> + +static guint toggle_changed_signal; + +G_DEFINE_TYPE (YGtkToggleButton, ygtk_toggle_button, GTK_TYPE_TOGGLE_BUTTON) + +static void ygtk_toggle_button_init (YGtkToggleButton *button) +{ +} + +static void ygtk_toggle_button_destroy (GtkObject *object) +{ + GTK_OBJECT_CLASS (ygtk_toggle_button_parent_class)->destroy (object); + YGtkToggleButton *button = YGTK_TOGGLE_BUTTON (object); + if (button->group && !button->foreign_group) { + g_slist_free (button->group); + button->group = NULL; + } +} + +static void ygtk_toggle_button_toggled (GtkToggleButton *toggle) +{ + GSList *group = YGTK_TOGGLE_BUTTON (toggle)->group; + + if (gtk_toggle_button_get_active (toggle)) { + // disable any active + GSList *i; + for (i = group; i; i = i->next) { + GtkToggleButton *t = i->data; + if (t->active && t != toggle) { + gtk_toggle_button_set_active (t, FALSE); + break; + } + } + + if (i) { + gint nb = g_slist_index (group, toggle); + g_signal_emit (YGTK_TOGGLE_BUTTON (toggle), toggle_changed_signal, 0, nb); + } + } + else { + // force it to be enabled, if no other is (other could be enabled; eg. when + // this code gets triggered from the previous case). + GSList *i; + for (i = group; i; i = i->next) { + GtkToggleButton *t = i->data; + if (t->active && t != toggle) + break; + } + if (!i) + gtk_toggle_button_set_active (toggle, TRUE); + } +} + +GSList *ygtk_toggle_button_get_group (YGtkToggleButton *button) +{ + return button->group; +} + +GtkWidget *ygtk_toggle_button_new (GSList *group) +{ + YGtkToggleButton *button = g_object_new (YGTK_TYPE_TOGGLE_BUTTON, NULL); + button->group = g_slist_append (group, button); + button->foreign_group = group != NULL; + return (GtkWidget *) button; +} + +static void ygtk_toggle_button_class_init (YGtkToggleButtonClass *klass) +{ + GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); + gtkobject_class->destroy = ygtk_toggle_button_destroy; + + GtkToggleButtonClass *gtktogglebutton_class = GTK_TOGGLE_BUTTON_CLASS (klass); + gtktogglebutton_class->toggled = ygtk_toggle_button_toggled; + + toggle_changed_signal = g_signal_new ("toggle-changed", + G_TYPE_FROM_CLASS (G_OBJECT_CLASS (klass)), G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (YGtkToggleButtonClass, toggle_changed), NULL, NULL, + g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); +} + Added: trunk/gtk/unstable-libyui/src/ygtktogglebutton.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtktoggl... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtktogglebutton.h (added) +++ trunk/gtk/unstable-libyui/src/ygtktogglebutton.h Fri Dec 14 09:40:53 2007 @@ -0,0 +1,49 @@ +/******************************************************************** + * YaST2-GTK - http://en.opensuse.org/YaST2-GTK * + ********************************************************************/ + +/* YGtkToggleButton extends GtkToggleButton to add groups, just like GtkRadioButtons. +*/ + +#ifndef YGTK_TOGGLE_BUTTON_H +#define YGTK_TOGGLE_BUTTON_H + +#include <gtk/gtktogglebutton.h> +G_BEGIN_DECLS + +#define YGTK_TYPE_TOGGLE_BUTTON (ygtk_toggle_button_get_type ()) +#define YGTK_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ + YGTK_TYPE_TOGGLE_BUTTON, YGtkToggleButton)) +#define YGTK_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \ + YGTK_TYPE_TOGGLE_BUTTON, YGtkToggleButtonClass)) +#define YGTK_IS_TOGGLE_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ + YGTK_TYPE_TOGGLE_BUTTON)) +#define YGTK_IS_TOGGLE_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \ + YGTK_TYPE_TOGGLE_BUTTON)) +#define YGTK_TOGGLE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + YGTK_TYPE_TOGGLE_BUTTON, YGtkToggleButtonClass)) + +typedef struct _YGtkToggleButton +{ + GtkToggleButton parent; + // members: + GSList *group; + gboolean foreign_group; // (shouldn't be needed...) +} YGtkToggleButton; + +typedef struct _YGtkToggleButtonClass +{ + GtkToggleButtonClass parent_class; + + // signals: + void (*toggle_changed) (GtkToggleButton *toggle, gint nb); +} YGtkToggleButtonClass; + +GtkWidget* ygtk_toggle_button_new (GSList *group); +GType ygtk_toggle_button_get_type (void) G_GNUC_CONST; + +GSList *ygtk_toggle_button_get_group (YGtkToggleButton *button); + +G_END_DECLS +#endif /*YGTK_TOGGLE_BUTTON_H*/ + Modified: trunk/gtk/unstable-libyui/src/ygtkwizard.c URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkwizar... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkwizard.c (original) +++ trunk/gtk/unstable-libyui/src/ygtkwizard.c Fri Dec 14 09:40:53 2007 @@ -310,6 +310,7 @@ g_free, NULL); gtk_container_set_border_width (GTK_CONTAINER (wizard), BORDER); + wizard->child_border_width = CHILD_BORDER; //** Title wizard->m_title = gtk_hbox_new (FALSE, 0); @@ -893,6 +894,7 @@ YGtkWizard *wizard = YGTK_WIZARD (widget); gint border = GTK_CONTAINER (wizard)->border_width; + gint child_border = wizard->child_border_width; gint header_padding = get_header_padding (GTK_WIDGET (wizard)); gint content_padding = get_content_padding (GTK_WIDGET (wizard)); GtkRequisition req; // temp usage @@ -931,8 +933,8 @@ gtk_widget_size_request (child, &child_req); else child_req.width = child_req.height = 0; - child_req.width += content_padding * 2 + CHILD_BORDER*2; - child_req.height += content_padding * 2 + CHILD_BORDER*2; + child_req.width += content_padding * 2 + child_border*2; + child_req.height += content_padding * 2 + child_border*2; req.width = nav_req.width + child_req.width + border*2; req.height = MAX (nav_req.height, child_req.height); @@ -1032,7 +1034,7 @@ // child GtkWidget *child = GTK_BIN (wizard)->child; if (child && GTK_WIDGET_VISIBLE (child)) { - apply_allocation_padding (&child_area, content_padding + CHILD_BORDER); + apply_allocation_padding (&child_area, content_padding + wizard->child_border_width); gtk_widget_size_allocate (child, &child_area); } Modified: trunk/gtk/unstable-libyui/src/ygtkwizard.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkwizar... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkwizard.h (original) +++ trunk/gtk/unstable-libyui/src/ygtkwizard.h Fri Dec 14 09:40:53 2007 @@ -93,6 +93,8 @@ /* The help text. */ gchar *m_help; GtkWidget *m_help_dialog; + + guint child_border_width; } YGtkWizard; typedef struct _YGtkWizardClass Modified: trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkzyppw... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.cc (original) +++ trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.cc Fri Dec 14 09:40:53 2007 @@ -19,7 +19,6 @@ #include "icons/pkg-remove.xpm" #include "icons/pkg-install-auto.xpm" #include "icons/pkg-remove-auto.xpm" -#include "icons/pkg-3D.xpm" // bridge as we don't want to mix c++ class polymorphism and gobject struct YGtkZyppModel::PoolNotify : public Ypp::Pool::Listener { @@ -36,8 +35,7 @@ struct PackageIcons { GdkPixbuf *installed, *installed_upgradable, *installed_locked, *installed_upgradable_locked, *available, *available_locked, - *to_install, *to_remove, *to_auto_install, *to_auto_remove, - *is_3D; + *to_install, *to_remove, *to_auto_install, *to_auto_remove; PackageIcons() { installed = gdk_pixbuf_new_from_xpm_data (pkg_installed_xpm); installed_upgradable = @@ -51,7 +49,6 @@ to_remove = gdk_pixbuf_new_from_xpm_data (pkg_remove_xpm); to_auto_install = gdk_pixbuf_new_from_xpm_data (pkg_install_auto_xpm); to_auto_remove = gdk_pixbuf_new_from_xpm_data (pkg_remove_auto_xpm); - is_3D = gdk_pixbuf_new_from_xpm_data (pkg_3D_xpm); } ~PackageIcons() { g_object_unref (G_OBJECT (installed)); @@ -64,7 +61,6 @@ g_object_unref (G_OBJECT (to_remove)); g_object_unref (G_OBJECT (to_auto_install)); g_object_unref (G_OBJECT (to_auto_remove)); - g_object_unref (G_OBJECT (is_3D)); } }; @@ -115,7 +111,6 @@ { YGtkZyppModel *zmodel = YGTK_ZYPP_MODEL (model); int row = zmodel->pool->getIndex (iter->user_data); -fprintf (stderr, "get index: %d\n", row); GtkTreePath *path = gtk_tree_path_new(); gtk_tree_path_append_index (path, row); @@ -140,13 +135,10 @@ void ygtk_zypp_model_entry_inserted (YGtkZyppModel *model, Ypp::Pool::Iter it) { -fprintf (stderr, "inserted row\n"); GtkTreeIter iter; iter.user_data = it; GtkTreePath *path = ygtk_zypp_model_get_path (GTK_TREE_MODEL (model), &iter); -fprintf (stderr, "signal\n"); gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter); -fprintf (stderr, "done\n"); gtk_tree_path_free (path); } @@ -175,8 +167,6 @@ return G_TYPE_STRING; case YGtkZyppModel::PTR_COLUMN: return G_TYPE_POINTER; - case YGtkZyppModel::SPECIAL_ICON_COLUMN: - return GDK_TYPE_PIXBUF; } return 0; } @@ -257,14 +247,6 @@ g_value_set_pointer (value, ptr); break; } - case YGtkZyppModel::SPECIAL_ICON_COLUMN: - { - if (package->is3D()) - g_value_set_object (value, (GObject *) icons->is_3D); - else - g_value_set_object (value, NULL); - break; - } default: g_warning ("YGtkZyppModel column %d doesn't exist.", column); break; Modified: trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/ygtkzyppw... ============================================================================== --- trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.h (original) +++ trunk/gtk/unstable-libyui/src/ygtkzyppwrapper.h Fri Dec 14 09:40:53 2007 @@ -26,8 +26,7 @@ GObject parent; enum Columns { - ICON_COLUMN, NAME_COLUMN, NAME_DESCRIPTION_COLUMN, PTR_COLUMN, - SPECIAL_ICON_COLUMN, TOTAL_COLUMNS + ICON_COLUMN, NAME_COLUMN, NAME_DESCRIPTION_COLUMN, PTR_COLUMN, TOTAL_COLUMNS }; Ypp::Pool *pool; Modified: trunk/gtk/unstable-libyui/src/yzyppwrapper.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/yzyppwrap... ============================================================================== --- trunk/gtk/unstable-libyui/src/yzyppwrapper.cc (original) +++ trunk/gtk/unstable-libyui/src/yzyppwrapper.cc Fri Dec 14 09:40:53 2007 @@ -156,7 +156,7 @@ private: bool resolveProblems(); - Node *addCategory (Package::Type type, const std::string &str, Package *package); + Node *addCategory (Ypp::Package::Type type, const std::string &str); void polishCategories (Ypp::Package::Type type); void startTransactions(); @@ -178,7 +178,7 @@ struct Ypp::Package::Impl { Impl (ZyppSelectable sel) - : zyppSel (sel), index (-1), availableVersions (NULL), installedVersion (NULL), is3D (false) + : zyppSel (sel), index (-1), availableVersions (NULL), installedVersion (NULL) { // don't use getAvailableVersion(0) for hasUpgrade() has its inneficient. // let's just cache candidate() at start, which should point to the newest version. @@ -211,7 +211,6 @@ GSList *availableVersions; Version *installedVersion; bool hasUpgrade; - bool is3D; zypp::ui::Status curStatus; // so we know if resolver touched it }; @@ -233,10 +232,13 @@ switch (impl->type) { case PATTERN_TYPE: ret = obj->summary(); + break; case LANGUAGE_TYPE: ret = obj->description(); + break; default: ret = sel->name(); + break; } } return ret; @@ -278,6 +280,9 @@ if (!license.empty()) text += br + _("License: ") + license; } + else if (impl->type == PATCH_TYPE) { + + } text += br + _("Size: ") + object->size().asString(); return text; } @@ -367,7 +372,6 @@ std::string Ypp::Package::authors() { -fprintf (stderr, "authors %s\n", name().c_str()); std::string text; ZyppObject object = impl->zyppSel->theObj(); ZyppPackage package = tryCastToZyppPkg (object); @@ -382,7 +386,6 @@ if (!authors.empty()) authors += "<br>"; authors += author; -fprintf (stderr, "\t add author %s\n", author.c_str()); } // Some packagers put Authors over the Descriptions field. This seems to be rare // on, so I'm not even going to bother. @@ -428,12 +431,43 @@ return impl->category; } -bool Ypp::Package::is3D() +bool Ypp::Package::fromCollection (Ypp::Package *collection) { - return impl->is3D; + switch (collection->type()) { + case Ypp::Package::PATTERN_TYPE: + { + ZyppSelectable selectable = collection->impl->zyppSel; + ZyppObject object = selectable->theObj(); + ZyppPattern pattern = tryCastToZyppPattern (object); + + const set <string> &packages = pattern->install_packages(); + for (set <string>::iterator it = packages.begin(); + it != packages.end(); it++) { + if (this->impl->zyppSel->name() == *it) + return true; + } + break; + } + case Ypp::Package::LANGUAGE_TYPE: + { + ZyppSelectable selectable = collection->impl->zyppSel; + ZyppObject object = selectable->theObj(); + ZyppLanguage language = tryCastToZyppLanguage (object); + + ZyppObject pkgobj = this->impl->zyppSel->theObj(); + const zypp::CapSet &capSet = pkgobj->dep (zypp::Dep::FRESHENS); + for (zypp::CapSet::const_iterator it = capSet.begin(); + it != capSet.end(); it++) { + if (it->index() == language->name()) + return true; + } + } + default: + break; + } + return false; } - bool Ypp::Package::isInstalled() { return impl->zyppSel->hasInstalledObj(); @@ -703,6 +737,7 @@ Key <bool> hasUpgrade; Key <bool> isModified; Key <std::list <int> > onRepositories; + Key <Ypp::Package *> onCollection; Impl() {} @@ -731,6 +766,8 @@ } } } + if (match && onCollection.defined) + match = package->fromCollection (onCollection.value); if (match && category.defined) { Ypp::Node *query_category = category.value; Ypp::Node *pkg_category = package->category(); @@ -750,14 +787,13 @@ } }; -Ypp::Query::Query (Ypp::Package::Type type) -{ - impl = new Impl(); - impl->type.define (type); -} +Ypp::Query::Query() +{ impl = new Impl(); } Ypp::Query::~Query() { delete impl; } +void Ypp::Query::setType (Ypp::Package::Type value) +{ impl->type.define (value); } void Ypp::Query::setName (std::string value) { impl->name.define (YGUtils::splitString (value, ' ')); } void Ypp::Query::setCategory (Ypp::Node *value) @@ -770,6 +806,8 @@ { impl->isModified.define (value); } void Ypp::Query::setRepositories (std::list <int> value) { impl->onRepositories.define (value); } +void Ypp::Query::setCollection (Ypp::Package *value) +{ impl->onCollection.define (value); } //** Pool @@ -783,13 +821,11 @@ : query (query), listener (NULL) { packages = buildPool (query); -fprintf (stderr, "created pool, adding to Ypp\n"); ypp->impl->addPool (this); } ~Impl() { -fprintf (stderr, "destroyed pool, removing from Ypp\n"); ypp->impl->removePool (this); delete query; g_slist_free (packages); @@ -809,12 +845,10 @@ } if (cmp == 0) { if (match) { // modified -fprintf (stderr, "pool (%d) - touched: %s\n", g_slist_length (packages), package->name().c_str()); if (listener) listener->entryChanged ((Iter) i, package); } else { // removed -fprintf (stderr, "pool (%d) - remove: %s\n", g_slist_length (packages), package->name().c_str()); if (listener) listener->entryDeleted ((Iter) i, package); packages = g_slist_delete_link (packages, i); @@ -822,7 +856,6 @@ } else { if (match) { // inserted -fprintf (stderr, "pool (%d) - insert: %s\n", g_slist_length (packages), package->name().c_str()); if (i == NULL) { packages = g_slist_append (packages, (gpointer) package); i = g_slist_last (packages); @@ -841,19 +874,20 @@ private: static GSList *buildPool (Query *query) // at construction { -long time1 = time(NULL); -fprintf (stderr, "build pool...\n"); GSList *pool = NULL; - GSList *entire_pool = ypp->impl->getPackages (query->impl->type.value); - int index = 0; - for (GSList *i = entire_pool; i; i = i->next) { - Package *pkg = (Package *) i->data; - if (query->impl->match (pkg)) - pool = g_slist_append (pool, i->data); - if (pkg->impl->index == -1) - pkg->impl->index = index++; + for (int t = 0; t < Ypp::Package::TOTAL_TYPES; t++) { + if (!query->impl->type.is ((Ypp::Package::Type) t)) + continue; + GSList *entire_pool = ypp->impl->getPackages ((Ypp::Package::Type) t); + int index = 0; + for (GSList *i = entire_pool; i; i = i->next) { + Package *pkg = (Package *) i->data; + if (query->impl->match (pkg)) + pool = g_slist_append (pool, i->data); + if (pkg->impl->index == -1) + pkg->impl->index = index++; + } } -fprintf (stderr, "delta time: %ld\n", time(NULL)-time1); return pool; } }; @@ -973,54 +1007,7 @@ return NULL; } -struct CatConversor { - const char *from, *to; -}; -static const CatConversor catConversor[] = { - { "Amusements/Games/3D", "Games/Action" }, - { "Amusements/Games/Board/Puzzle", "Games/Logic" }, - { "Amusements/Games/Board/Card", "Games/Card" }, - { "Amusements/Games", "Games" }, - { "Amusements", "Games" }, - { "Applications/Publishing", "Office" }, - { "Applications/Internet", "Network" }, - { "Applications", "" }, - { "Development/C", "Development/Libraries/C and C++" }, - { "Development/Python", "Development/Libraries/Python" }, - { "Development/Libraries/C", "Development/Libraries/C and C++" }, - { "Libraries", "Development/Libraries" }, - { "Productivity/Multimedia/Player", "Multimedia/Sound/Players" }, - { "Productivity/Multimedia/Audio", "Multimedia/Sound/Players" }, - { "Video", "Multimedia/Video" }, - { "Productivity/Multimedia", "Multimedia" }, - { "Productivity/Graphics", "Multimedia/Graphics" }, - { "Productivity/Networking", "Network" }, - { "Productivity/Network", "Network" }, - { "Productivity/Office", "Office" }, - { "Productivity/Publishing", "Office/Publishing" }, - { "Productivity/Telephony", "Network/Telephony" }, - { "Productivity", "Utilities" }, - { "System/Emulators", "Emulators" }, - { "System/GUI", "Utilities/GUI" }, - { "System/Video", "Emulators" }, - { "System/Libraries", "Development/Libraries/C and C++/System" }, - { "X11/Applications/Multimedia", "Multimedia" }, - { "X11/GNOME/Multimedia", "Multimedia" }, - { "X11/Applications", "Utilities/GUI" }, -}; -#define CAT_CONVERSOR_SIZE (sizeof (catConversor)/sizeof (CatConversor)) -struct TypoConversor { - const char *from, *to, len; -}; -static const TypoConversor catTypos[] = { - { "Others", "Other", 6 }, { "Utilites", "Utilities", 8 }, - { "AOLInstantMessenge", "AOLInstantMessenger", 18 }, - { "Library", "Libraries", 7 }, { "Libs", "Libraries", 4 }, -}; -#define CAT_TYPOS_SIZE (sizeof (catTypos)/sizeof (TypoConversor)) - -Ypp::Node *Ypp::Impl::addCategory (Ypp::Package::Type type, - const std::string &category_str, Package *pkg) +Ypp::Node *Ypp::Impl::addCategory (Ypp::Package::Type type, const std::string &category_str) { struct inner { static int cmp (const char *a, const char *b) @@ -1032,59 +1019,17 @@ return -1; return YGUtils::strcmp (a, b); } - - // Package categories guide-line don't seem to be enforced, some categories - // are duplicated, or don't make much sense. Let's try to cut on that. - - static std::string treatCategory (const std::string &category, Package *pkg) - { - std::string ret (category); - - // typos (end group only) - for (unsigned int c = 0; c < CAT_TYPOS_SIZE; c++) { - const char *from = catTypos[c].from, from_len = catTypos[c].len; - int ret_index = ret.length() - from_len; - - if (ret_index >= 0 && ret.compare (ret_index, from_len, from, from_len) == 0) { - const char *to = catTypos[c].to; - ret.erase (ret_index); - ret.append (to); - break; - } - } - - for (unsigned int c = 0; c < CAT_CONVERSOR_SIZE; c++) { - const char *from = catConversor[c].from; - unsigned int i; - for (i = 0; from[i] && i < ret.length(); i++) - if (from[i] != ret[i]) - break; - if (!from[i] && (i == ret.length() || ret[i] == '/')) { - const char *to = catConversor[c].to; - ret.erase (0, i); - ret.insert (0, to); - if (c == 0 && pkg) - pkg->impl->is3D = true; - break; - } - } - return ret; - } }; if (!categories[type]) categories[type] = new StringTree (inner::cmp, '/'); - if (type == Package::PACKAGE_TYPE) - return categories[type]->add (inner::treatCategory (category_str, pkg)); - else - return categories[type]->add (category_str); + return categories[type]->add (category_str); } void Ypp::Impl::polishCategories (Ypp::Package::Type type) { // some treatment on categories - // Put all packages under a node (as opposite to packages on a leaf) to - // the Other category. + // Packages must be on leaves. If not, create a "Other" leaf, and put it there. if (type == Package::PACKAGE_TYPE) { GSList *pool = ypp->impl->getPackages (type); for (GSList *i = pool; i; i = i->next) { @@ -1097,7 +1042,6 @@ pkg->impl->category = (Ypp::Node *) last->data; else { // must create a "Other" node - fprintf (stderr, "creating Other\n"); Ypp::Node *yN = new Ypp::Node(); GNode *n = g_node_new ((void *) yN); yN->name = "Other"; @@ -1229,20 +1173,21 @@ resolved = interface->resolveProblems (problems); - zypp::ProblemSolutionList choices; - for (std::list <Problem *>::iterator it = problems.begin(); - it != problems.end(); it++) { - for (int i = 0; (*it)->getSolution (i); i++) { - Problem::Solution *solution = (*it)->getSolution (i); - if (resolved && solution->apply) - choices.push_back ((zypp::ProblemSolution *) solution->impl); - delete solution; + if (resolved) { + zypp::ProblemSolutionList choices; + for (std::list <Problem *>::iterator it = problems.begin(); + it != problems.end(); it++) { + for (int i = 0; (*it)->getSolution (i); i++) { + Problem::Solution *solution = (*it)->getSolution (i); + if (resolved && solution->apply) + choices.push_back ((zypp::ProblemSolution *) solution->impl); + delete solution; + } + delete *it; } - delete *it; - } - if (resolved) zResolver->applySolutions (choices); + } else break; } @@ -1255,16 +1200,15 @@ void Ypp::Impl::packageModified (Ypp::Package *package) { // notify listeners of package change - for (GSList *i = pools; i; i = i->next) { -fprintf (stderr, "ypp: informing pool of package modified\n"); + for (GSList *i = pools; i; i = i->next) ((Pool::Impl *) i->data)->packageModified (package); - } if (disk) disk->impl->packageModified (package); if (interface) interface->packageModified (package); - transactions = g_slist_append (transactions, package); + if (!g_slist_find (transactions, package)) /* could be a result of undo */ + transactions = g_slist_append (transactions, package); if (!inTransaction) finishTransactions(); } @@ -1300,79 +1244,13 @@ } void Ypp::Impl::addPool (Pool::Impl *pool) -{ fprintf (stderr, "ypp: adding pool\n"); pools = g_slist_append (pools, pool); } +{ pools = g_slist_append (pools, pool); } void Ypp::Impl::removePool (Pool::Impl *pool) -{ fprintf (stderr, "ypp: removing pool\n"); pools = g_slist_remove (pools, pool); } +{ pools = g_slist_remove (pools, pool); } -#if 0 -// using auxiliary GSequence tree -- not yet shiped by Glib :X -// in any case, a sort merge is very fast, as packages are more or less -// sorted anyway... GSList *Ypp::Impl::getPackages (Ypp::Package::Type type) { if (!packages[type]) { - // auxiliary for efficient alphabetic sorting - GSequence *pool = g_sequence_new (NULL); - struct inner { - static gint compare (gconstpointer _a, gconstpointer _b, gpointer _data) - { - Package *a = (Package *) _a; - Package *b = (Package *) _b; - return YGUtils::strcmp (a->name().c_str(), b->name().c_str()); - } -/* static void pool_foreach (gpointer data, gpointer _list) - { - GSList **list = (GSList **) _list; - *list = g_slist_append (*list, data); - }*/ - }; - - ZyppPool::const_iterator it, end; - switch (type) - { - case Package::PACKAGE_TYPE: - it = zyppPool().byKindBegin zypp::Package(); - end = zyppPool().byKindEnd zypp::Package(); - break; - case Package::PATTERN_TYPE: - it = zyppPool().byKindBegin zypp::Pattern(); - end = zyppPool().byKindEnd zypp::Pattern(); - break; - case Package::LANGUAGE_TYPE: - it = zyppPool().byKindBegin zypp::Language(); - end = zyppPool().byKindEnd zypp::Language(); - break; - default: - break; - } - for (; it != end; it++) - { - Package *package = new Package (new Package::Impl (*it)); - g_sequence_insert_sorted (pool, package, inner::compare, NULL); - } - - // add stuff to the actual pool now - int index = 0; - for (GSequenceIter *it = g_sequence_get_begin_iter (pool); - !g_sequence_iter_is_end (it); it = g_sequence_iter_next (it)) { - gpointer data = g_sequence_get (it); - Package *pkg = (Package *) data; - pkg->impl->index = index++; - pkg->impl->type = type; - packages[type] = g_slist_append (packages[type], data); - } - -// g_sequence_foreach (pool, inner::pool_foreach, &); - g_sequence_free (pool); - } - return packages[type]; -} -#else -GSList *Ypp::Impl::getPackages (Ypp::Package::Type type) -{ - if (!packages[type]) { -long time1 = time(NULL); -fprintf (stderr, "creating pool of %d...\n", type); GSList *pool = NULL; struct inner { static gint compare (gconstpointer _a, gconstpointer _b) @@ -1397,25 +1275,34 @@ it = zyppPool().byKindBegin zypp::Language(); end = zyppPool().byKindEnd zypp::Language(); break; + case Package::PATCH_TYPE: + it = zyppPool().byKindBegin zypp::Patch(); + end = zyppPool().byKindEnd zypp::Patch(); + break; default: break; } for (; it != end; it++) { Package *package = new Package (new Package::Impl (*it)); Ypp::Node *category = 0; + ZyppObject object = (*it)->theObj(); if (type == Package::PACKAGE_TYPE) { - ZyppObject object = (*it)->theObj(); ZyppPackage zpackage = tryCastToZyppPkg (object); if (!zpackage) continue; - category = addCategory (type, zpackage->group(), package); + category = addCategory (type, zpackage->group()); } else if (type == Package::PATTERN_TYPE) { - ZyppObject object = (*it)->theObj(); ZyppPattern pattern = tryCastToZyppPattern (object); if (!pattern || !pattern->userVisible()) continue; - category = addCategory (type, pattern->category(), 0); + category = addCategory (type, pattern->category()); + } + else if (type == Package::PATCH_TYPE) { + ZyppPatch patch = tryCastToZyppPatch (object); + if (!patch) + continue; + category = addCategory (type, patch->category()); } package->impl->type = type; @@ -1430,11 +1317,9 @@ packages[type] = pool; polishCategories (type); -fprintf (stderr, "delta time: %ld\n", time(NULL)-time1); } return packages[type]; } -#endif Ypp::Ypp() { Modified: trunk/gtk/unstable-libyui/src/yzyppwrapper.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/unstable-libyui/src/yzyppwrap... ============================================================================== --- trunk/gtk/unstable-libyui/src/yzyppwrapper.h (original) +++ trunk/gtk/unstable-libyui/src/yzyppwrapper.h Fri Dec 14 09:40:53 2007 @@ -38,14 +38,14 @@ // Entries struct Package { enum Type { - PACKAGE_TYPE, PATTERN_TYPE, LANGUAGE_TYPE, TOTAL_TYPES + PACKAGE_TYPE, PATTERN_TYPE, LANGUAGE_TYPE, PATCH_TYPE, TOTAL_TYPES }; Type type(); const std::string &name(); const std::string &summary(); Node *category(); - bool is3D(); + bool fromCollection (Ypp::Package *package); std::string description(); std::string filelist(); @@ -93,13 +93,15 @@ // Query struct Query { - Query (Package::Type type); + Query(); + void setType (Package::Type type); void setName (std::string name); void setCategory (Ypp::Node *category); void setIsInstalled (bool installed); void setHasUpgrade (bool upgradable); void setIsModified (bool modified); void setRepositories (std::list <int> repositories); + void setCollection (Ypp::Package *package); ~Query(); struct Impl; @@ -118,9 +120,9 @@ Iter getIter (int index); struct Listener { - virtual void entryChanged (Iter iter, Package *package) = 0; virtual void entryInserted (Iter iter, Package *package) = 0; virtual void entryDeleted (Iter iter, Package *package) = 0; + virtual void entryChanged (Iter iter, Package *package) = 0; }; void setListener (Listener *listener); -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org