Mailinglist Archive: yast-commit (1771 mails)

< Previous Next >
[yast-commit] r58481 - in /trunk/gtk: ./ src/
  • From: rpmcruz@xxxxxxxxxxxxxxxx
  • Date: Thu, 03 Sep 2009 01:35:38 -0000
  • Message-id: <E1Mj1Eh-0005TQ-7L@xxxxxxxxxxxxxxxx>
Author: rpmcruz
Date: Thu Sep 3 03:35:38 2009
New Revision: 58481

URL: http://svn.opensuse.org/viewcvs/yast?rev=58481&view=rev
Log:
* src/ygtktreemodel.h/cc: nice wrapper for GtkTreeModel.

* src/yzyppview.h/cc: moved PackagesView and PackageDetails
here. Re-worked the model: in particular, added support for
multiple lists and apply all entry.

* src/YGPackageSelector.cc: made use of new PackagesView
functionality: in particular, split out undo tab.

* src/YGPackageSelector.cc: added confirmation dialog on
apply.

* src/YGPackageSelector.cc: added progress bar.

* src/yzyppwrapper.h/.cc: PkgList now a vector: much nicer
for the multiple lists enable model.

* src/yzyppwrapper.h/.cc: added progress bar signal.

* src/ygtkwizard.c: fixed set_child().

* src/YGMenuButton.cc: implemented new YGContextMenu.

* src/YGUI.h: respective hook for YGContextMenu.

* src/YGTable.cc: respective context-menu signals.

* src/YGWidget.cc: emitEvent(): contain context-menu signals
to flags notifyContextMenu().

Added:
trunk/gtk/src/ygtktreemodel.cc
trunk/gtk/src/ygtktreemodel.h
trunk/gtk/src/ygtkzyppview.cc
trunk/gtk/src/ygtkzyppview.h
Removed:
trunk/gtk/src/ygtkzyppwrapper.cc
trunk/gtk/src/ygtkzyppwrapper.h
Modified:
trunk/gtk/ChangeLog
trunk/gtk/src/Makefile.am
trunk/gtk/src/YGMenuButton.cc
trunk/gtk/src/YGPackageSelector.cc
trunk/gtk/src/YGTable.cc
trunk/gtk/src/YGUI.h
trunk/gtk/src/YGWidget.cc
trunk/gtk/src/ygtktreeview.h
trunk/gtk/src/ygtkwizard.c
trunk/gtk/src/yzyppwrapper.cc
trunk/gtk/src/yzyppwrapper.h

Modified: trunk/gtk/ChangeLog
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/ChangeLog?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/ChangeLog (original)
+++ trunk/gtk/ChangeLog Thu Sep 3 03:35:38 2009
@@ -1,3 +1,35 @@
+2009-09-02 Ricardo Cruz <rpmcruz@xxxxxxxxxxxxxxxxxxx>
+
+ * src/ygtktreemodel.h/cc: nice wrapper for GtkTreeModel.
+
+ * src/yzyppview.h/cc: moved PackagesView and PackageDetails
+ here. Re-worked the model: in particular, added support for
+ multiple lists and apply all entry.
+
+ * src/YGPackageSelector.cc: made use of new PackagesView
+ functionality: in particular, split out undo tab.
+
+ * src/YGPackageSelector.cc: added confirmation dialog on
+ apply.
+
+ * src/YGPackageSelector.cc: added progress bar.
+
+ * src/yzyppwrapper.h/.cc: PkgList now a vector: much nicer
+ for the multiple lists enable model.
+
+ * src/yzyppwrapper.h/.cc: added progress bar signal.
+
+ * src/ygtkwizard.c: fixed set_child().
+
+ * src/YGMenuButton.cc: implemented new YGContextMenu.
+
+ * src/YGUI.h: respective hook for YGContextMenu.
+
+ * src/YGTable.cc: respective context-menu signals.
+
+ * src/YGWidget.cc: emitEvent(): contain context-menu signals
+ to flags notifyContextMenu().
+
2009-08-29 Ricardo Cruz <rpmcruz@xxxxxxxxxxxxxxxxxxx>

* src/yzyppwrapper.h/.cc: split up Package::support()

Modified: trunk/gtk/src/Makefile.am
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/Makefile.am?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/Makefile.am (original)
+++ trunk/gtk/src/Makefile.am Thu Sep 3 03:35:38 2009
@@ -66,9 +66,10 @@
ygtklinklabel.c \
ygtktextview.c \
ygtkrichtext.c \
+ ygtktreemodel.cc \
+ ygtkzyppview.cc \
yzyppwrapper.cc \
- yzypptags.cc \
- ygtkzyppwrapper.cc
+ yzypptags.cc
# should (maybe?) only append ygtkrichtext.c if WITH_GTKHTML or WEBKIT isn't
set

dummy_SOURCES = dummy.cc

Modified: trunk/gtk/src/YGMenuButton.cc
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGMenuButton.cc?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/YGMenuButton.cc (original)
+++ trunk/gtk/src/YGMenuButton.cc Thu Sep 3 03:35:38 2009
@@ -10,6 +10,45 @@
#include "YMenuButton.h"
#include "ygtkmenubutton.h"

+static void selected_item_cb (GtkMenuItem *menuitem, YItem *item)
+{
+ YGUI::ui()->sendEvent (new YMenuEvent (item));
+}
+
+static void doCreateMenu (GtkWidget *parent, YItemIterator begin,
YItemIterator end)
+{
+ for (YItemIterator it = begin; it != end; it++) {
+ GtkWidget *entry, *image = 0;
+ string str = YGUtils::mapKBAccel ((*it)->label());
+
+ if ((*it)->hasIconName()) {
+ GdkPixbuf *pixbuf = YGUtils::loadPixbuf
((*it)->iconName());
+ if (pixbuf) {
+ image = gtk_image_new_from_pixbuf (pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+ }
+
+ if (image) {
+ entry = gtk_image_menu_item_new_with_mnemonic
(str.c_str());
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM
(entry), image);
+ }
+ else
+ entry = gtk_menu_item_new_with_mnemonic (str.c_str());
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (parent), entry);
+
+ if ((*it)->hasChildren()) {
+ GtkWidget *submenu = gtk_menu_new();
+ doCreateMenu (submenu, (*it)->childrenBegin(),
(*it)->childrenEnd());
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (entry),
submenu);
+ }
+ else
+ g_signal_connect (G_OBJECT (entry), "activate",
+ G_CALLBACK (selected_item_cb), *it);
+ }
+}
+
class YGMenuButton : public YMenuButton, public YGWidget
{
public:
@@ -25,56 +64,54 @@
// YMenuButton
virtual void rebuildMenuTree()
{
- GtkWidget *menu = doCreateMenu (itemsBegin(), itemsEnd());
+ GtkWidget *menu = gtk_menu_new();
+ doCreateMenu (menu, itemsBegin(), itemsEnd());
gtk_widget_show_all (menu);
ygtk_menu_button_set_popup (YGTK_MENU_BUTTON (getWidget()),
menu);
}

- static GtkWidget* doCreateMenu (YItemIterator begin, YItemIterator end)
- {
- GtkWidget *menu = gtk_menu_new();
- for (YItemIterator it = begin; it != end; it++) {
- GtkWidget *entry, *image = 0;
- string str = YGUtils::mapKBAccel ((*it)->label());
-
- if ((*it)->hasIconName()) {
- GdkPixbuf *pixbuf = YGUtils::loadPixbuf
((*it)->iconName());
- if (pixbuf) {
- image = gtk_image_new_from_pixbuf
(pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
-
- if (image) {
- entry = gtk_image_menu_item_new_with_mnemonic
(str.c_str());
- gtk_image_menu_item_set_image
(GTK_IMAGE_MENU_ITEM (entry), image);
- }
- else
- entry = gtk_menu_item_new_with_mnemonic
(str.c_str());
+ YGWIDGET_IMPL_COMMON (YMenuButton)
+};

- gtk_menu_shell_append (GTK_MENU_SHELL (menu), entry);
+YMenuButton *YGWidgetFactory::createMenuButton (YWidget *parent, const string
&label)
+{
+ return new YGMenuButton (parent, label);
+}

- if ((*it)->hasChildren())
- gtk_menu_item_set_submenu (GTK_MENU_ITEM
(entry),
- doCreateMenu ((*it)->childrenBegin(),
(*it)->childrenEnd()));
- else
- g_signal_connect (G_OBJECT (entry), "activate",
- G_CALLBACK
(selected_item_cb), *it);
- }
+#if YAST2_VERSION > 2018003
+#include <YContextMenu.h>

- return menu;
+class YGContextMenu : public YContextMenu, public YGWidget
+{
+public:
+ YGContextMenu()
+ : YContextMenu(),
+ YGWidget (this, parent, GTK_TYPE_MENU, NULL)
+ {
+ connect (getWidget(), "cancel", G_CALLBACK (cancel_cb), this);
}

- static void selected_item_cb (GtkMenuItem *menuitem, YItem *item)
+ // YContextMenu
+ virtual void rebuildMenuTree()
{
- YGUI::ui()->sendEvent (new YMenuEvent (item));
+ GtkWidget *menu = getWidget();
+ doCreateMenu (menu, itemsBegin(), itemsEnd());
+ gtk_widget_show_all (menu);
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 3,
gtk_get_current_event_time());
}

+ // callbacks
+ static void cancel_cb (GtkMenuShell *menu, YGContextMenu *pThis)
+ { YGUI::ui()->sendEvent (new YCancelEvent()); }
+
YGWIDGET_IMPL_COMMON (YMenuButton)
};

-YMenuButton *YGWidgetFactory::createMenuButton (YWidget *parent, const string
&label)
+bool YGApplication::openContextMenu (const YItemCollection &itemCollection)
{
- return new YGMenuButton (parent, label);
+ YQContextMenu *menu = new YGContextMenu();
+ menu->addItems (itemCollection);
+ return true;
}
+#endif


Modified: trunk/gtk/src/YGPackageSelector.cc
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGPackageSelector.cc?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/YGPackageSelector.cc (original)
+++ trunk/gtk/src/YGPackageSelector.cc Thu Sep 3 03:35:38 2009
@@ -19,974 +19,7 @@
#include "ygtkhtmlwrap.h"
#include "ygtkrichtext.h"
#include "ygtktreeview.h"
-#include "ygtkzyppwrapper.h"
-
-//** Utilities
-
-#define GNOME_OPEN_PATH "/usr/bin/gnome-open"
-inline bool CAN_OPEN_URIS()
-{ return g_file_test (GNOME_OPEN_PATH, G_FILE_TEST_IS_EXECUTABLE); }
-inline void OPEN_URI (const char *uri)
-{ system ((std::string (GNOME_OPEN_PATH " ") + uri + " &").c_str()); }
-
-namespace Cursor {
- static int busyI = 0; // private
-
- static void normal()
- {
- busyI = MAX (0, busyI-1);
- if (!busyI)
- YGUI::ui()->normalCursor();
- }
- static void busy()
- {
- if (!busyI)
- YGUI::ui()->busyCursor();
- // ensure the cursor is actually set and update the UI...
- while (g_main_context_iteration (NULL, FALSE)) ;
- busyI++;
- }
-};
-
-//** UI components
-
-// Create a view of packages through the sub-classes PackagesList and
PackagesTable
-class PackagesView
-{
-public:
- GtkWidget *getWidget() { return m_scroll; }
-
- struct Listener {
- virtual void packagesSelected (Ypp::PkgList packages) = 0;
- };
- void setListener (Listener *listener)
- { m_listener = listener; }
-
- void setModel (const Ypp::PkgList list)
- {
- GtkTreeView *view = GTK_TREE_VIEW (m_view);
- YGtkZyppModel *zmodel = ygtk_zypp_model_new (list);
- gtk_tree_view_set_model (view, GTK_TREE_MODEL (zmodel));
- g_object_unref (G_OBJECT (zmodel));
- gtk_tree_view_expand_all (view);
- }
-
- void clearModel()
- { gtk_tree_view_set_model (GTK_TREE_VIEW (m_view), NULL); }
-
- GList *getSelectedPaths (GtkTreeModel **model)
- { return gtk_tree_selection_get_selected_rows (getTreeSelection(),
model); }
-
- void selectAll()
- { gtk_tree_selection_select_all (getTreeSelection()); }
-
- void unselectAll()
- { gtk_tree_selection_unselect_all (getTreeSelection()); }
-
- int countSelected()
- { return gtk_tree_selection_count_selected_rows (getTreeSelection()); }
-
- Ypp::PkgList getSelected()
- {
- GtkTreeModel *model;
- GList *paths = getSelectedPaths (&model);
- Ypp::PkgList packages;
- for (GList *i = paths; i; i = i->next) {
- Ypp::Package *package;
- GtkTreePath *path = (GtkTreePath *) i->data;
- GtkTreeIter iter;
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter,
YGtkZyppModel::PTR_COLUMN, &package, -1);
- gtk_tree_path_free (path);
-
- if (package)
- packages.prepend (package);
- }
- g_list_free (paths);
- return packages;
- }
-
- virtual ~PackagesView()
- {
- if (m_popup_hack) gtk_widget_destroy (m_popup_hack);
- g_object_unref (G_OBJECT (m_scroll));
- }
-
- void appendIconColumn (const char *header, int col)
- {
- GtkTreeView *view = GTK_TREE_VIEW (m_view);
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
- int height = MAX (34, YGUtils::getCharsHeight (m_view,
2));
- gtk_cell_renderer_set_fixed_size (renderer, -1, height);
- column = gtk_tree_view_column_new_with_attributes (
- header, renderer, "pixbuf", col, 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 (view, column);
- }
-
- void appendCheckColumn (const char *header, int modelCol)
- {
- GtkTreeView *view = GTK_TREE_VIEW (m_view);
- GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
- GtkTreeViewColumn *column;
- column = gtk_tree_view_column_new_with_attributes (header,
- renderer, "active", modelCol,
- "sensitive", YGtkZyppModel::IS_UNLOCKED_COLUMN, NULL);
- g_object_set_data (G_OBJECT (renderer), "col", GINT_TO_POINTER
(modelCol));
- g_signal_connect (G_OBJECT (renderer), "toggled",
- G_CALLBACK (renderer_toggled_cb), this);
- // it seems like GtkCellRendererToggle has no width at start,
so fixed doesn't work
- gtk_tree_view_column_set_sizing (column,
GTK_TREE_VIEW_COLUMN_FIXED);
- gtk_tree_view_column_set_fixed_width (column, 25);
- gtk_tree_view_append_column (view, column);
- }
-
- void appendTextColumn (const char *header, int col, int size = -1)
- {
- GtkTreeView *view = GTK_TREE_VIEW (m_view);
- GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
- g_object_set (G_OBJECT (renderer), "ellipsize",
- size == -1 ? PANGO_ELLIPSIZE_END :
PANGO_ELLIPSIZE_MIDDLE, NULL);
-/* gboolean reverse = gtk_widget_get_default_direction() ==
GTK_TEXT_DIR_RTL;
- if (reverse) { // work-around: Pango ignored alignment flag on
RTL
- gtk_widget_set_direction (m_view, GTK_TEXT_DIR_LTR);
- g_object_set (renderer, "alignment", PANGO_ALIGN_RIGHT,
NULL);
- }*/
- GtkTreeViewColumn *column;
- column = gtk_tree_view_column_new_with_attributes (
- header, renderer, "markup", col,
- "sensitive", YGtkZyppModel::IS_UNLOCKED_COLUMN,
-// "style", YGtkZyppModel::IS_MODIFIED_ITALIC_COLUMN,
- "weight", YGtkZyppModel::IS_HIGHLIGHT_WEIGHT_COLUMN,
- NULL);
- gtk_tree_view_column_set_sizing (column,
GTK_TREE_VIEW_COLUMN_FIXED);
- gtk_tree_view_column_set_resizable (column, TRUE);
- if (size >= 0)
- gtk_tree_view_column_set_fixed_width (column, size);
- else
- gtk_tree_view_column_set_expand (column, TRUE);
-// gtk_tree_view_insert_column (view, column, reverse ? 0 : -1);
- gtk_tree_view_append_column (view, column);
- }
-
-private:
- Listener *m_listener;
- GtkWidget *m_scroll, *m_view, *m_popup_hack;
- bool m_descriptiveTooltip;
-
-protected:
- PackagesView (bool descriptiveTooltip)
- : m_listener (NULL), m_popup_hack (NULL), m_descriptiveTooltip
(descriptiveTooltip)
- {
- m_scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_scroll),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- g_object_ref_sink (G_OBJECT (m_scroll));
-
- GtkTreeView *view = GTK_TREE_VIEW (m_view =
ygtk_tree_view_new());
- gtk_tree_view_set_search_column (view,
YGtkZyppModel::NAME_COLUMN);
- gtk_tree_view_set_fixed_height_mode (view, TRUE);
- gtk_tree_view_set_show_expanders (view, FALSE); /* would
conflict with icons */
-
- GtkTreeSelection *selection = gtk_tree_view_get_selection
(view);
- gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
- g_signal_connect (G_OBJECT (selection), "changed",
- G_CALLBACK (packages_selected_cb), this);
- gtk_tree_selection_set_select_function (selection,
can_select_row_cb,
- this, NULL);
-
- g_signal_connect (G_OBJECT (m_view), "row-activated",
- G_CALLBACK (package_activated_cb), this);
- g_signal_connect (G_OBJECT (m_view), "right-click",
- G_CALLBACK (popup_menu_cb), this);
- gtk_widget_set_has_tooltip (m_view, TRUE);
- g_signal_connect (G_OBJECT (m_view), "query-tooltip",
- G_CALLBACK (query_tooltip_cb), this);
-
- gtk_container_add (GTK_CONTAINER (m_scroll), m_view);
- gtk_widget_show_all (m_scroll);
- }
-
- void hideHeaders()
- { gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_view), FALSE); }
-
-private:
- GtkTreeSelection *getTreeSelection()
- { return gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view)); }
-
- void signalSelected()
- { if (m_listener) m_listener->packagesSelected (getSelected()); }
-
- void signalPopup (int button, int event_time)
- {
- // GtkMenu emits "deactivate" before Items notifications, so
there isn't
- // a better way to de-allocate the popup
- if (m_popup_hack) gtk_widget_destroy (m_popup_hack);
- GtkWidget *menu = m_popup_hack = gtk_menu_new();
-
- struct inner {
- static void appendItem (GtkWidget *menu, const char
*label,
- const char *tooltip, const char *icon, bool
sensitive,
- void (& callback) (GtkMenuItem *item,
PackagesView *pThis), PackagesView *pThis)
- {
- GtkWidget *item;
- if (icon) {
- if (label) {
- item =
gtk_image_menu_item_new_with_mnemonic (label);
- GtkWidget *image;
- if (*icon == 'g')
- image =
gtk_image_new_from_stock (icon, GTK_ICON_SIZE_MENU);
- else {
- std::string filename =
std::string (DATADIR) + "/" + icon;
- image =
gtk_image_new_from_file (filename.c_str());
- }
- gtk_image_menu_item_set_image
(GTK_IMAGE_MENU_ITEM (item), image);
- }
- else
- item =
gtk_image_menu_item_new_from_stock (icon, NULL);
- }
- else
- item = gtk_menu_item_new_with_mnemonic
(label);
- if (tooltip)
- gtk_widget_set_tooltip_markup (item,
tooltip);
- if (!sensitive)
- gtk_widget_set_sensitive (item, FALSE);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu),
item);
- g_signal_connect (G_OBJECT (item), "activate",
G_CALLBACK (callback), pThis);
- }
- static void install_cb (GtkMenuItem *item, PackagesView
*pThis)
- { pThis->getSelected().install(); }
- static void remove_cb (GtkMenuItem *item, PackagesView
*pThis)
- { pThis->getSelected().remove(); }
- static void undo_cb (GtkMenuItem *item, PackagesView
*pThis)
- { pThis->getSelected().undo(); }
- static void lock_cb (GtkMenuItem *item, PackagesView
*pThis)
- { pThis->getSelected().lock (true); }
- static void unlock_cb (GtkMenuItem *item, PackagesView
*pThis)
- { pThis->getSelected().lock (false); }
- static void select_all_cb (GtkMenuItem *item,
PackagesView *pThis)
- { pThis->selectAll(); }
- };
-
- Ypp::PkgList packages = getSelected();
- bool empty = true, canLock = packages.canLock(), unlocked =
packages.unlocked();
- bool locked = !unlocked && canLock;
- if (packages.notInstalled())
- inner::appendItem (menu, _("_Install"), 0,
GTK_STOCK_SAVE,
- !locked, inner::install_cb, this),
empty = false;
- if (packages.upgradable())
- inner::appendItem (menu, _("_Upgrade"), 0,
GTK_STOCK_GOTO_TOP,
- !locked, inner::install_cb, this),
empty = false;
- if (packages.installed())
- inner::appendItem (menu, _("_Remove"), 0,
GTK_STOCK_DELETE,
- !locked, inner::remove_cb, this),
empty = false;
- if (packages.modified())
- inner::appendItem (menu, _("_Undo"), 0, GTK_STOCK_UNDO,
- true, inner::undo_cb, this), empty =
false;
- if (canLock) {
- static const char *lock_tooltip =
- "<b>Package lock:</b> prevents the package
status from being modified by "
- "the solver (that is, it won't honour
dependencies or collections ties.)";
- if (packages.locked())
- inner::appendItem (menu, _("_Unlock"),
_(lock_tooltip), "pkg-unlocked.png",
- true, inner::unlock_cb,
this), empty = false;
- if (unlocked)
- inner::appendItem (menu, _("_Lock"),
_(lock_tooltip), "pkg-locked.png",
- true, inner::lock_cb, this),
empty = false;
- }
- if (!empty)
- gtk_menu_shell_append (GTK_MENU_SHELL (menu),
gtk_separator_menu_item_new());
- inner::appendItem (menu, 0, 0, GTK_STOCK_SELECT_ALL,
- true, inner::select_all_cb, this);
-
- gtk_menu_attach_to_widget (GTK_MENU (menu), m_view, NULL);
- gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
button, event_time);
- gtk_widget_show_all (menu);
- }
-
- static void packages_selected_cb (GtkTreeSelection *selection,
PackagesView *pThis)
- { if (GTK_WIDGET_REALIZED (pThis->m_view)) pThis->signalSelected(); }
-
- static void package_activated_cb (GtkTreeView *view, GtkTreePath *path,
- GtkTreeViewColumn *column,
PackagesView *pThis)
- {
- Ypp::PkgList packages = pThis->getSelected();
- if (packages.notInstalled() || packages.upgradable())
- packages.install();
- }
-
- static void popup_menu_cb (YGtkTreeView *view, gboolean outreach,
PackagesView *pThis)
- { if (!outreach) pThis->signalPopup(3, gtk_get_current_event_time()); }
-
- static gboolean can_select_row_cb (GtkTreeSelection *selection,
GtkTreeModel *model,
- GtkTreePath *path, gboolean path_currently_selected, gpointer
data)
- {
- void *package;
- GtkTreeIter iter;
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, YGtkZyppModel::PTR_COLUMN,
&package, -1);
- return package != NULL;
- }
-
- static void renderer_toggled_cb (GtkCellRendererToggle *renderer, gchar
*path_str,
- PackagesView *pThis)
- {
- Ypp::Package *package = 0;
- GtkTreeView *view = GTK_TREE_VIEW (pThis->m_view);
- GtkTreeModel *model = gtk_tree_view_get_model (view);
- GtkTreeIter iter;
- gtk_tree_model_get_iter_from_string (model, &iter, path_str);
- gtk_tree_model_get (model, &iter, YGtkZyppModel::PTR_COLUMN,
&package, -1);
-
- //gboolean active = gtk_cell_renderer_toggle_get_active
(renderer);
- int col = GPOINTER_TO_INT (g_object_get_data (G_OBJECT
(renderer), "col"));
-fprintf (stderr, "render toggle: %d\n", col);
- if (package->toModify())
- package->undo();
- else switch (col) {
- case YGtkZyppModel::TO_INSTALL_COLUMN:
- case YGtkZyppModel::TO_UPGRADE_COLUMN:
- package->install (0);
- break;
- case YGtkZyppModel::NOT_TO_REMOVE_COLUMN:
-fprintf (stderr, "\tremove!\n");
- package->remove();
- break;
- default: break;
- }
- }
-
- static gboolean query_tooltip_cb (GtkWidget *widget, gint x, gint y,
- gboolean keyboard_mode, GtkTooltip *tooltip, PackagesView
*pThis)
- {
- GtkTreeView *view = GTK_TREE_VIEW (widget);
- GtkTreeModel *model;
- GtkTreePath *path;
- GtkTreeIter iter;
- if (gtk_tree_view_get_tooltip_context (view,
- &x, &y, keyboard_mode, &model, &path, &iter)) {
- gtk_tree_view_set_tooltip_row (view, tooltip, path);
- gtk_tree_path_free (path);
-
- Ypp::Package *package = 0;
- gtk_tree_model_get (model, &iter,
YGtkZyppModel::PTR_COLUMN, &package, -1);
- if (!package) return FALSE;
-
- std::string text;
- if (!pThis->m_descriptiveTooltip) {
- GtkTreeViewColumn *column;
- int bx, by;
-
gtk_tree_view_convert_widget_to_bin_window_coords (
- view, x, y, &bx, &by);
- gtk_tree_view_get_path_at_pos (
- view, x, y, NULL, &column, NULL, NULL);
- int status_col =
- gtk_widget_get_default_direction() ==
GTK_TEXT_DIR_RTL ? 1 : 0;
- if (column == gtk_tree_view_get_column (view,
status_col)) {
- if (package->toInstall()) {
- if (package->isInstalled())
- text = _("To re-install
a different version");
- else
- text = _("To install");
- }
- else if (package->toRemove())
- text = _("To remove");
- else if (package->isInstalled()) {
- text = _("Installed");
- if (package->hasUpgrade())
- text += _(" (upgrade
available)");
- }
- else
- text = _("Not installed");
- if (package->isAuto())
- text += _("\n<i>status changed
by the dependency solver</i>");
- if (package->isLocked())
- text += _("\n<i>locked:
right-click to unlock</i>");
- }
- }
- else {
- text = std::string ("<b>") + package->name() +
"</b>\n";
- text += package->description (GTK_MARKUP);
- }
- if (text.empty())
- return FALSE;
- gtk_tooltip_set_markup (tooltip, text.c_str());
-
- if (package->type() == Ypp::Package::LANGUAGE_TYPE) {
- GdkPixbuf *pixbuf = 0;
- std::string filename (package->icon());
- if (!filename.empty())
- pixbuf = YGUtils::loadPixbuf
(filename.c_str());
- if (pixbuf) {
- gtk_tooltip_set_icon (tooltip, pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- }
- }
-#if 0
- GdkPixbuf *pixbuf = 0;
- switch (package->type())
- {
- case Ypp::Package::LANGUAGE_TYPE: {
- std::string filename (package->icon());
- if (!filename.empty())
- pixbuf = YGUtils::loadPixbuf
(filename.c_str());
- break;
- }
- default:
- break;
- }
- if (!pixbuf)
- gtk_tree_model_get (model, &iter,
- YGtkZyppModel::ICON_COLUMN, &pixbuf,
-1);
- if (pixbuf) {
- gtk_tooltip_set_icon (tooltip, pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- }
-#endif
- return TRUE;
- }
- return FALSE;
- }
-};
-
-struct PackagesList : public PackagesView
-{
- PackagesList (bool descriptiveTooltip)
- : PackagesView (descriptiveTooltip)
- {
- appendIconColumn (NULL, YGtkZyppModel::ICON_COLUMN);
- appendTextColumn (NULL, YGtkZyppModel::NAME_SUMMARY_COLUMN);
- hideHeaders();
- }
-};
-struct PackagesTable : public PackagesView
-{
- PackagesTable() : PackagesView (false)
- {}
-};
-
-class PackageDetails
-{
-private:
- struct Versions {
- GtkWidget *m_box, *m_versions_box, *m_button, *m_undo_button;
- Ypp::PkgList m_packages; // we keep a copy to test against
modified...
-
- GtkWidget *getWidget() { return m_box; }
-
- Versions()
- {
- GtkWidget *label = gtk_label_new (_("Versions:"));
- YGUtils::setWidgetFont (label, PANGO_STYLE_NORMAL,
PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
-
- m_versions_box = gtk_vbox_new (FALSE, 2);
- m_button = gtk_button_new_with_label ("");
- g_signal_connect (G_OBJECT (m_button), "clicked",
G_CALLBACK (button_clicked_cb), this);
- m_undo_button = gtk_button_new_with_label ("");
- gtk_button_set_image (GTK_BUTTON (m_undo_button),
- gtk_image_new_from_stock (GTK_STOCK_UNDO,
GTK_ICON_SIZE_BUTTON));
- g_signal_connect (G_OBJECT (m_undo_button), "clicked",
G_CALLBACK (undo_clicked_cb), this);
- GtkWidget *button_box = gtk_hbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (button_box),
gtk_label_new(""), TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (button_box), m_button,
FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (button_box),
m_undo_button, FALSE, TRUE, 0);
-
- m_box = gtk_vbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (m_box), label, FALSE,
TRUE, 0);
- gtk_box_pack_start (GTK_BOX (m_box), m_versions_box,
TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (m_box), button_box, FALSE,
TRUE, 0);
- }
-
- void setPackages (Ypp::PkgList packages)
- {
- m_packages = packages;
- m_packages.refreshProps();
-
- GList *children = gtk_container_get_children
(GTK_CONTAINER (m_versions_box));
- for (GList *i = children; i; i = i->next)
- gtk_container_remove (GTK_CONTAINER
(m_versions_box), (GtkWidget *) i->data);
- g_list_free (children);
-
- if (packages.empty()) {
- gtk_widget_hide (m_box);
- return;
- }
- gtk_widget_show (m_box);
- if (packages.single()) {
- Ypp::Package *package = packages.get
(packages.first());
-
- int children = 0;
- GtkWidget *radio = 0;
- const Ypp::Package::Version *version;
- if ((version = package->getInstalledVersion()))
{
- std::string _version =
YGUtils::truncate (version->number, 20, 0);
-
- bool italic = package->toRemove();
- char *text = g_strdup_printf ("%s%s
<small>(%s)</small>\n%s%s",
- italic ? "<i>" : "",
- _version.c_str(),
version->arch.c_str(), _("Installed"),
- italic ? "</i>" : "");
- radio = gtk_radio_button_new_with_label
(NULL, text);
- gtk_label_set_use_markup (GTK_LABEL
(GTK_BIN (radio)->child), TRUE);
- if (version->number.size() > 20) {
- char *text = g_strdup_printf
("%s <small>(%s)</small>\n%s",
-
version->number.c_str(), version->arch.c_str(), _("Installed"));
- gtk_widget_set_tooltip_markup
(radio, text);
- g_free (text);
- }
- gtk_box_pack_start (GTK_BOX
(m_versions_box), radio, FALSE, TRUE, 0);
- g_free (text);
- gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (radio), TRUE);
- g_object_set_data (G_OBJECT (radio),
"version", (void *) version);
- g_signal_connect (G_OBJECT (radio),
"toggled",
- G_CALLBACK
(version_toggled_cb), this);
- children++;
- }
- bool activeSet = package->toRemove();
- const Ypp::Package::Version *toInstall = 0;
- if (!package->toInstall (&toInstall))
- toInstall = 0;
- const Ypp::Repository *favoriteRepo =
Ypp::get()->favoriteRepository();
- for (int i = 0; (version =
package->getAvailableVersion (i)); i++) {
- std::string _version =
YGUtils::truncate (version->number, 20, 0);
- std::string repo;
- if (version->repo)
- repo = YGUtils::truncate
(version->repo->name, 22, 0);
-
- bool italic = toInstall == version;
- char *text = g_strdup_printf ("%s%s
<small>(%s)</small>\n%s%s",
- italic ? "<i>" : "",
- _version.c_str(),
version->arch.c_str(), repo.c_str(),
- italic ? "</i>" : "");
- radio =
gtk_radio_button_new_with_label_from_widget (
- GTK_RADIO_BUTTON (radio), text);
- gtk_label_set_use_markup (GTK_LABEL
(GTK_BIN (radio)->child), TRUE);
- g_free (text);
- if (version->number.size() > 20 ||
- (version->repo &&
version->repo->name.size() > 22)) {
- char *text = g_strdup_printf
("%s <small>(%s)</small>\n%s",
-
version->number.c_str(), version->arch.c_str(),
- version->repo ?
version->repo->name.c_str() : "");
- gtk_widget_set_tooltip_markup
(radio, text);
- g_free (text);
- }
- gtk_box_pack_start (GTK_BOX
(m_versions_box), radio, FALSE, TRUE, 0);
- if (!activeSet) {
- if (toInstall == version) {
-
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
- activeSet = true;
- }
- else if (i == 0)
-
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
- else if (version->repo ==
favoriteRepo) {
-
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
- favoriteRepo = 0; //
select only the 1st hit
- }
- }
- g_object_set_data (G_OBJECT (radio),
"version", (void *) version);
- g_signal_connect (G_OBJECT (radio),
"toggled",
- G_CALLBACK
(version_toggled_cb), this);
- if ((children % 2) == 1)
- g_signal_connect (G_OBJECT
(radio), "expose-event", G_CALLBACK (draw_gray_cb), this);
- children++;
- }
- gtk_widget_show_all (m_versions_box);
- }
-
- // is locked
- if (packages.locked() || packages.unlocked())
- gtk_widget_set_sensitive (m_button,
!packages.locked());
- else
- gtk_widget_set_sensitive (m_button, TRUE);
- syncButton();
- }
-
- private:
- static gboolean draw_gray_cb (GtkWidget *widget, GdkEventExpose
*event, Versions *pThis)
- {
- GtkAllocation *alloc = &widget->allocation;
- int x = alloc->x, y = alloc->y, w = alloc->width, h =
alloc->height;
-
- cairo_t *cr = gdk_cairo_create (widget->window);
- cairo_rectangle (cr, x, y, w, h);
- cairo_set_source_rgb (cr, 245/255.0, 245/255.0,
245/255.0);
- cairo_fill (cr);
- cairo_destroy (cr);
- return FALSE;
- }
-
- const Ypp::Package::Version *getVersion()
- {
- GtkWidget *radio = 0;
- GList *children = gtk_container_get_children
(GTK_CONTAINER (m_versions_box));
- for (GList *i = children; i; i = i->next)
- if (gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (i->data))) {
- radio = (GtkWidget *) i->data;
- break;
- }
- g_list_free (children);
- if (radio)
- return (Ypp::Package::Version *)
g_object_get_data (G_OBJECT (radio), "version");
- return NULL;
- }
-
- void syncButton()
- {
- gtk_widget_hide (m_undo_button);
- const char *label = 0, *stock = 0;
- if (m_packages.single()) {
- Ypp::Package *package = m_packages.get
(m_packages.first());
- const Ypp::Package::Version *version =
getVersion();
- const Ypp::Package::Version *installed =
package->getInstalledVersion();
- if (installed == version) {
- label = _("Remove");
- stock = GTK_STOCK_DELETE;
- if (package->toRemove())
- gtk_widget_show (m_undo_button);
- }
- else {
- if (installed) {
- if (version->cmp > 0) {
- label = _("Upgrade");
- stock = GTK_STOCK_GO_UP;
- }
- else if (version->cmp < 0) {
- label = _("Downgrade");
- stock =
GTK_STOCK_GO_DOWN;
- }
- else {
- label = _("Re-install");
- stock =
GTK_STOCK_REFRESH;
- }
- }
- else {
- label = _("Install");
- stock = GTK_STOCK_SAVE;
- }
-
- const Ypp::Package::Version *toInstall
= 0;
- if (!package->toInstall (&toInstall))
- toInstall = 0;
- if (toInstall == version)
- gtk_widget_show (m_undo_button);
- }
- }
- else {
- if (m_packages.modified())
- gtk_widget_show (m_undo_button);
- if (m_packages.upgradable()) {
- label = _("Upgrade");
- stock = GTK_STOCK_GO_UP;
- }
- else if (m_packages.installed()) {
- label = _("Remove");
- stock = GTK_STOCK_DELETE;
- }
- else if (m_packages.notInstalled()) {
- label = _("Install");
- stock = GTK_STOCK_SAVE;
- }
- else if (m_packages.modified()) {
- label = _("Undo");
- stock = GTK_STOCK_UNDO;
- gtk_widget_hide (m_undo_button);
- }
- }
- if (label) {
- gtk_button_set_label (GTK_BUTTON (m_button),
label);
- GtkWidget *image = gtk_image_new_from_stock (
- stock, GTK_ICON_SIZE_BUTTON);
- gtk_button_set_image (GTK_BUTTON (m_button),
image);
- gtk_widget_show (m_button);
- }
- else
- gtk_widget_hide (m_button);
- }
-
- static void version_toggled_cb (GtkToggleButton *radio,
Versions *pThis)
- { if (gtk_toggle_button_get_active (radio))
pThis->syncButton(); }
-
- static void button_clicked_cb (GtkButton *button, Versions
*pThis)
- {
- if (pThis->m_packages.single()) {
- Ypp::Package *package = pThis->m_packages.get
(pThis->m_packages.first());
- const Ypp::Package::Version *version =
pThis->getVersion();
- const Ypp::Package::Version *installed =
package->getInstalledVersion();
- if (installed == version)
- pThis->m_packages.remove();
- else
- package->install (version);
- }
- else {
- if (pThis->m_packages.upgradable())
- pThis->m_packages.install();
- else if (pThis->m_packages.installed())
- pThis->m_packages.remove();
- else if (pThis->m_packages.notInstalled())
- pThis->m_packages.install();
- else if (pThis->m_packages.modified())
- pThis->m_packages.undo();
- }
- pThis->setPackages (pThis->m_packages); // refresh
- }
-
- static void undo_clicked_cb (GtkButton *button, Versions *pThis)
- {
- pThis->m_packages.undo();
- pThis->setPackages (pThis->m_packages); // refresh
- }
-
-#if 0
- void packageModified (Ypp::Package *package)
- {
- // GTK+ doesn't fire selection change when a selected
row changes, so we need
- // to re-load Versions in that occasions.
- if (m_packages.contains (package)) {
- m_packages.clearCache();
- setPackages (m_packages);
- }
- }
-#endif
- };
-
-GtkWidget *m_widget, *m_icon, *m_icon_frame, *m_description, *m_filelist,
*m_changelog,
- *m_authors, *m_support, *m_requires, *m_provides;
-Versions *m_versions;
-PackagesTable *m_contents;
-
-public:
- GtkWidget *getWidget() { return m_widget; }
-
- PackageDetails (bool onlineUpdate)
- {
- m_versions = new Versions();
- GtkWidget *vbox;
- m_widget = createWhiteViewPort (&vbox);
-
- GtkWidget *versions_box = gtk_vbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (versions_box),
- createIconWidget (&m_icon, &m_icon_frame), FALSE, TRUE,
0);
- gtk_box_pack_start (GTK_BOX (versions_box),
m_versions->getWidget(), FALSE, TRUE, 0);
-
- m_description = ygtk_rich_text_new();
- g_signal_connect (G_OBJECT (m_description), "link-clicked",
- G_CALLBACK (link_pressed_cb), this);
-
- GtkWidget *description_box = gtk_hbox_new (FALSE, 2);
- gtk_box_pack_start (GTK_BOX (description_box), m_description,
TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (description_box), versions_box,
FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), description_box, FALSE,
TRUE, 0);
-
- if (!onlineUpdate) {
- m_filelist = ygtk_rich_text_new();
- m_changelog = ygtk_rich_text_new();
- m_authors = ygtk_rich_text_new();
- m_support = ygtk_rich_text_new();
- m_requires = ygtk_rich_text_new();
- m_provides = ygtk_rich_text_new();
- GtkWidget *dependencies_box = gtk_hbox_new (TRUE, 0);
- gtk_box_pack_start (GTK_BOX (dependencies_box),
m_requires, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (dependencies_box),
m_provides, TRUE, TRUE, 0);
-
- appendExpander (vbox, _("File List"), m_filelist);
- appendExpander (vbox, _("Changelog"), m_changelog);
- appendExpander (vbox, _("Authors"), m_authors);
- appendExpander (vbox, _("Dependencies"),
dependencies_box);
- appendExpander (vbox, _(""), m_support);
- m_contents = NULL;
- if (CAN_OPEN_URIS())
- g_signal_connect (G_OBJECT (m_filelist),
"link-clicked",
- G_CALLBACK
(link_pressed_cb), this);
- }
- else {
- m_filelist = m_changelog = m_authors = m_support =
m_requires = m_provides = NULL;
- m_contents = new PackagesTable();
- m_contents->appendTextColumn (_("Name"),
YGtkZyppModel::NAME_COLUMN, 150);
- m_contents->appendTextColumn (_("Summary"),
YGtkZyppModel::SUMMARY_COLUMN);
- appendExpander (vbox, _("Applies to"),
m_contents->getWidget());
- }
- gtk_widget_show_all (vbox);
- }
-
- ~PackageDetails()
- {
- delete m_contents;
- delete m_versions;
- }
-
- void setPackages (Ypp::PkgList packages)
- {
- gtk_widget_hide (m_icon_frame);
- if (packages.single()) {
- Ypp::Package *package = packages.get (packages.first());
- string description = "<b>" + package->name() +
"</b><br>";
- description += package->description (HTML_MARKUP);
- setText (m_description, description);
- if (m_filelist) setText (m_filelist, package->filelist
(true));
- if (m_changelog) setText (m_changelog,
package->changelog());
- if (m_authors) setText (m_authors, package->authors
(true));
- if (m_support) {
- GtkWidget *expander = gtk_widget_get_ancestor
(m_support, GTK_TYPE_EXPANDER);
- std::string label ("<b>" + std::string
(_("Support:")) + "</b> ");
- label += package->support();
- gtk_expander_set_label (GTK_EXPANDER
(expander), label.c_str());
- setText (m_support, package->supportText
(true));
- }
- if (m_requires && m_provides) {
- std::string requires_str = _("Requires:");
- std::string provides_str = _("Provides:");
- requires_str += "<br><blockquote>";
- requires_str += package->requires (true);
- YGUtils::replace (provides_str, "\n", 1,
"<br>");
- requires_str += "</blockquote>";
- provides_str += "<br><blockquote>";
- provides_str += package->provides (true);
- YGUtils::replace (requires_str, "\n", 1,
"<br>");
- provides_str += "</blockquote>";
- setText (m_requires, requires_str);
- setText (m_provides, provides_str);
- }
-
- if (m_contents) { // patches -- "apply to"
- Ypp::PkgQuery::Query *query = new
Ypp::PkgQuery::Query();
- query->addCollection (package);
- m_contents->setModel (Ypp::PkgQuery
(Ypp::Package::PACKAGE_TYPE, query));
- }
-
- gtk_image_clear (GTK_IMAGE (m_icon));
- GtkIconTheme *icons = gtk_icon_theme_get_default();
- GdkPixbuf *pixbuf = gtk_icon_theme_load_icon (icons,
- package->name().c_str(), 32, GtkIconLookupFlags
(0), NULL);
- if (pixbuf) {
- gtk_image_set_from_pixbuf (GTK_IMAGE (m_icon),
pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- gtk_widget_show (m_icon_frame);
- }
- }
- else {
- string description;
- if (!packages.empty()) {
- description = "Selected:";
- description += "<ul>";
- for (Ypp::PkgList::Iter it = packages.first();
it; it = packages.next (it))
- description += "<li>" + packages.get
(it)->name() + "</li>";
- description += "</ul>";
- }
- setText (m_description, description);
- if (m_filelist) setText (m_filelist, "");
- if (m_changelog) setText (m_changelog, "");
- if (m_authors) setText (m_authors, "");
- if (m_support) setText (m_support, "");
- if (m_requires) setText (m_requires, "");
- if (m_provides) setText (m_provides, "");
- if (m_contents) {
- gtk_widget_hide (gtk_widget_get_ancestor
(m_contents->getWidget(), GTK_TYPE_EXPANDER));
- m_contents->clearModel();
- }
- }
-
- m_versions->setPackages (packages);
- scrollTop();
- }
-
- void setPackage (Ypp::Package *package)
- {
- Ypp::PkgList packages;
- packages.append (package);
- setPackages (packages);
- }
-
-private:
- static void link_pressed_cb (GtkWidget *text, const gchar *link,
PackageDetails *pThis)
- {
- if (!strncmp (link, "pkg://", 6)) {
- const gchar *pkg_name = link + 6;
- yuiMilestone() << "Hyperlinking to package \"" <<
pkg_name << "\"" << endl;
- Ypp::Package *pkg = Ypp::get()->getPackages
(Ypp::Package::PACKAGE_TYPE).find (pkg_name);
- if (pkg)
- pThis->setPackage (pkg);
- else {
- GtkWidget *dialog = gtk_message_dialog_new
(YGDialog::currentWindow(),
- GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK, _("Package '%s' was not
found."), pkg_name);
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- }
- }
- else
- OPEN_URI (link);
- }
-
- void scrollTop()
- {
- GtkScrolledWindow *scroll = GTK_SCROLLED_WINDOW (m_widget);
- YGUtils::scrollWidget (gtk_scrolled_window_get_vadjustment
(scroll), true);
- }
-
- // utilities:
- static GtkWidget *createIconWidget (GtkWidget **icon_widget, GtkWidget
**icon_frame)
- {
- *icon_widget = gtk_image_new();
-
- GtkWidget *box, *align, *frame;
- box = gtk_event_box_new();
- gtk_container_add (GTK_CONTAINER (box), *icon_widget);
- gtk_container_set_border_width (GTK_CONTAINER (box), 2);
-
- frame = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (frame), box);
-
- align = gtk_alignment_new (0, 0, 0, 0);
- gtk_container_add (GTK_CONTAINER (align), frame);
- gtk_container_set_border_width (GTK_CONTAINER (align), 6);
- *icon_frame = align;
- return align;
- }
- static GtkWidget *createWhiteViewPort (GtkWidget **vbox)
- {
- struct inner {
- static gboolean expose_cb (GtkWidget *widget,
GdkEventExpose *event)
- {
- cairo_t *cr = gdk_cairo_create (widget->window);
- GdkColor color = { 0, 255 << 8, 255 << 8, 255
<< 8 };
- gdk_cairo_set_source_color (cr, &color);
- cairo_rectangle (cr, event->area.x,
event->area.y,
- event->area.width,
event->area.height);
- cairo_fill (cr);
- cairo_destroy (cr);
- return FALSE;
- }
- };
-
- *vbox = gtk_vbox_new (FALSE, 0);
- g_signal_connect (G_OBJECT (*vbox), "expose-event",
- G_CALLBACK (inner::expose_cb), NULL);
-
- GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW
(scroll), *vbox);
- return scroll;
- }
- static void appendExpander (GtkWidget *box, const char *label,
GtkWidget *child)
- {
- string str = string ("<b>") + label + "</b>";
- GtkWidget *expander = gtk_expander_new (str.c_str());
- gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
- gtk_container_add (GTK_CONTAINER (expander), child);
- gtk_box_pack_start (GTK_BOX (box), expander, FALSE, TRUE, 0);
- }
- static void setText (GtkWidget *text, const std::string &str)
- {
- ygtk_rich_text_set_text (YGTK_RICH_TEXT (text), str.c_str(),
FALSE);
- GtkWidget *expander = gtk_widget_get_ancestor (text,
GTK_TYPE_EXPANDER);
- if (expander)
- str.empty() ? gtk_widget_hide (expander) :
gtk_widget_show (expander);
- }
-};
+#include "ygtkzyppview.h"

//** UI components -- split up for re-usability, but mostly for readability

@@ -1344,9 +377,15 @@
Collection (Ypp::Package::Type type)
: QueryWidget()
{
- m_view = new PackagesList (true);
- m_view->setModel (Ypp::PkgTree (type));
+ m_view = new PackagesView (true);
+ m_view->appendIconColumn (NULL, ZyppModel::ICON_COLUMN);
+ m_view->appendTextColumn (NULL, ZyppModel::NAME_SUMMARY_COLUMN);
+ if (type == Ypp::Package::LANGUAGE_TYPE)
+ m_view->setRows (Ypp::PkgQuery (type, NULL), NULL);
+ else
+ populateView (m_view, type);
m_view->setListener (this);
+ m_view->setFrame (true);

// control buttons
m_buttons_box = gtk_alignment_new (0, 0, 0, 0);
@@ -1368,7 +407,17 @@
virtual ~Collection()
{ delete m_view; }

- void packagesSelected (Ypp::PkgList selection)
+ static void populateView (PackagesView *view, Ypp::Package::Type type)
+ { // list 1D categories intertwined with its constituent packages
+ Ypp::Node *category = Ypp::get()->getFirstCategory (type);
+ for (; category; category = category->next()) {
+ Ypp::PkgQuery::Query *query = new
Ypp::PkgQuery::Query();
+ query->addCategory (category);
+ view->appendRows (category->name.c_str(), Ypp::PkgQuery
(type, query), NULL);
+ }
+ }
+
+ virtual void packagesSelected (Ypp::PkgList selection)
{
gtk_widget_set_sensitive (m_buttons_box,
selection.notInstalled());
notify();
@@ -1377,15 +426,14 @@
virtual void writeQuery (Ypp::PkgQuery::Query *query)
{
Ypp::PkgList selected = m_view->getSelected();
- for (Ypp::PkgList::Iter it = selected.first(); it; it =
selected.next (it))
- query->addCollection (selected.get (it));
- if (selected.empty())
+ for (int i = 0; selected.get (i); i++)
+ query->addCollection (selected.get (i));
+ if (selected.size() == 0)
query->setClear();
}

void doAll (bool install /*or remove*/)
- {
- // we just need to mark the collections themselves
+ { // we just need to mark the collections themselves
Ypp::PkgList selected = m_view->getSelected();
install ? selected.install() : selected.remove();
}
@@ -1497,7 +545,7 @@
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_radio[0]),
TRUE);
GtkRadioButton *radiob = GTK_RADIO_BUTTON (m_radio[0]);
m_radio[1] = gtk_radio_button_new_with_label_from_widget
(radiob, _("Description"));
- m_radio[2] = gtk_radio_button_new_with_label_from_widget
(radiob, _("File"));
+ m_radio[2] = gtk_radio_button_new_with_label_from_widget
(radiob, _("File name"));
gtk_widget_set_tooltip_markup (m_radio[2],
_("Only applicable to <b>installed</b> packages."));
if (m_onlineUpdate)
@@ -1512,8 +560,14 @@
if (m_radio [i])
gtk_box_pack_start (GTK_BOX (radio_box),
m_radio[i], FALSE, TRUE, 0);

- GtkWidget *radio_frame = gtk_frame_new (_("Options:"));
- gtk_container_add (GTK_CONTAINER (radio_frame), radio_box);
+ GtkWidget *radio_frame = gtk_frame_new (_("Search in:"));
+ YGUtils::setWidgetFont (gtk_frame_get_label_widget (GTK_FRAME
(radio_frame)),
+ PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD,
PANGO_SCALE_MEDIUM);
+ gtk_frame_set_shadow_type (GTK_FRAME (radio_frame),
GTK_SHADOW_NONE);
+ GtkWidget *align = gtk_alignment_new (0, 0, 1, 1);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 15, 0);
+ gtk_container_add (GTK_CONTAINER (align), radio_box);
+ gtk_container_add (GTK_CONTAINER (radio_frame), align);

m_info_box = gtk_hbox_new (FALSE, 6);
m_info_label = gtk_label_new ("");
@@ -1525,7 +579,7 @@
GtkWidget *separator = gtk_event_box_new();
gtk_widget_set_size_request (separator, -1, 50);

- m_box = gtk_vbox_new (FALSE, 6);
+ m_box = gtk_vbox_new (FALSE, 12);
gtk_box_pack_start (GTK_BOX (m_box), name_box, FALSE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (m_box), radio_frame, FALSE, TRUE,
0);
gtk_box_pack_start (GTK_BOX (m_box), separator, FALSE, TRUE, 0);
@@ -1577,8 +631,8 @@
query->addNames (name, ' ', true,
false, false, false, false, true);
query->setIsInstalled (false);
Ypp::PkgQuery pool
(Ypp::Package::PATTERN_TYPE, query);
- if (!pool.empty()) {
- std::string _name = pool.get
(pool.first())->name();
+ if (pool.size() > 0) {
+ std::string _name = pool.get
(0)->name();
std::string text = _("Patterns
are available that can "
"assist you in the
installment of");
text += " <i>" + _name +
"</i>.";
@@ -1614,9 +668,9 @@

static void name_changed_cb (YGtkFindEntry *entry, FindBox *pThis)
{
- // novelty only allows numbers
+ const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry));
+ // novelty allows only numbers
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
(pThis->m_radio[4]))) {
- const gchar *text = gtk_entry_get_text (GTK_ENTRY
(entry));
gboolean correct = TRUE;
for (const gchar *i = text; *i; i++)
if (!g_ascii_isdigit (*i)) {
@@ -1625,6 +679,8 @@
}
ygtk_find_entry_set_state (entry, correct);
}
+ if (*text == '\0') // user may have pressed brush icon thus
except search clear
+ pThis->notify();
}

static void button_clicked_cb (GtkWidget *widget, FindBox *pThis)
@@ -1695,7 +751,6 @@

void select (int nb)
{
- Cursor::busy();
delete m_queryWidget;
if (m_onlineUpdate) {
switch (nb) {
@@ -1716,7 +771,6 @@
}
m_queryWidget->setListener (m_listener);
set (m_queryWidget->getWidget());
- Cursor::normal();
}

static void combo_changed_cb (GtkComboBox *combo, FilterCombo *pThis)
@@ -1770,10 +824,8 @@
void setup()
{
bool isVer = isVertical (m_bin->allocation.width);
-fprintf (stderr, "FlexPane::setup - width? %d - isVer? %d\n",
m_bin->allocation.width, isVer);
GtkWidget *oldPane = GTK_BIN (m_bin)->child;
if (!oldPane || (m_isVertical != isVer)) {
-fprintf (stderr, "\tcreate pane!\n");
m_isVertical = isVer;
if (oldPane) {
gtk_container_remove (GTK_CONTAINER (oldPane),
m_child1);
@@ -1804,13 +856,13 @@
{
GtkWidget *m_widget, *m_notebook;
bool m_onlineUpdate;
-PackagesTable *m_view;
+PackagesView *m_view;
FilterCombo *m_combo;
PackageDetails *m_details;
FlexPane *m_pane;
GtkWidget *m_oldPage;
guint m_timeout_id;
-Ypp::PkgList *m_changes;
+Ypp::PkgList m_changes;

public:
GtkWidget *getWidget() { return m_widget; }
@@ -1827,7 +879,7 @@
appendPage (m_notebook, _("_Undo"), GTK_STOCK_UNDO, 3);
Ypp::PkgQuery::Query *query = new
Ypp::PkgQuery::Query();
query->setToModify (true);
- m_changes = new Ypp::PkgQuery
(Ypp::Package::PACKAGE_TYPE, query);
+ m_changes = Ypp::PkgQuery (Ypp::Package::PACKAGE_TYPE,
query);
}
gtk_widget_show (m_notebook);
g_signal_connect_after (G_OBJECT (m_notebook), "switch-page",
@@ -1860,7 +912,6 @@
delete m_combo;
delete m_details;
delete m_pane;
- delete m_changes;
}

private:
@@ -1893,21 +944,21 @@
int col;
switch (selectedPage()) {
default:
- case 0: col = YGtkZyppModel::TO_INSTALL_COLUMN; break;
- case 1: col = YGtkZyppModel::TO_UPGRADE_COLUMN; break;
- case 2: col = YGtkZyppModel::NOT_TO_REMOVE_COLUMN;
break;
- case 3: col = YGtkZyppModel::TO_MODIFY_COLUMN; break;
- }
- m_view = new PackagesTable();
- m_view->appendCheckColumn (NULL, col);
- int nameSize = (col == YGtkZyppModel::TO_UPGRADE_COLUMN) ? -1 :
150;
- m_view->appendTextColumn (_("Name"),
YGtkZyppModel::NAME_COLUMN, nameSize);
- if (col == YGtkZyppModel::TO_UPGRADE_COLUMN) {
- m_view->appendTextColumn (_("Installed"),
YGtkZyppModel::INSTALLED_VERSION_COLUMN, 150);
- m_view->appendTextColumn (_("Available"),
YGtkZyppModel::AVAILABLE_VERSION_COLUMN, 150);
+ case 0: col = ZyppModel::TO_INSTALL_COLUMN; break;
+ case 1: col = ZyppModel::TO_UPGRADE_COLUMN; break;
+ case 2: col = ZyppModel::NOT_TO_REMOVE_COLUMN; break;
+ case 3: col = ZyppModel::TO_MODIFY_COLUMN; break;
+ }
+ m_view = new PackagesView (false);
+ m_view->appendCheckColumn (col);
+ int nameSize = (col == ZyppModel::TO_UPGRADE_COLUMN) ? -1 : 150;
+ m_view->appendTextColumn (_("Name"), ZyppModel::NAME_COLUMN,
nameSize);
+ if (col == ZyppModel::TO_UPGRADE_COLUMN) {
+ m_view->appendTextColumn (_("Installed"),
ZyppModel::INSTALLED_VERSION_COLUMN, 150);
+ m_view->appendTextColumn (_("Available"),
ZyppModel::AVAILABLE_VERSION_COLUMN, 150);
}
else
- m_view->appendTextColumn (_("Summary"),
YGtkZyppModel::SUMMARY_COLUMN);
+ m_view->appendTextColumn (_("Summary"),
ZyppModel::SUMMARY_COLUMN);
m_view->setListener (this);

m_oldPage = gtk_notebook_get_nth_page (GTK_NOTEBOOK
(m_notebook), nb);
@@ -1975,14 +1026,15 @@
}

// set query
- Cursor::busy();
+ m_view->clear();
Ypp::Package::Type type =
m_onlineUpdate ? Ypp::Package::PATCH_TYPE :
Ypp::Package::PACKAGE_TYPE;
Ypp::PkgList list (Ypp::get()->getPackages (type));

Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();

- switch (selectedPage()) {
+ int page = selectedPage();
+ switch (page) {
case 0: // available
if (m_onlineUpdate)
// special pane for patches upgrades
makes little sense, so
@@ -1997,15 +1049,26 @@
query->setIsInstalled (true);
break;
case 3: // undo
- list = *m_changes;
+ list = m_changes;
break;
default: break;
}

m_combo->writeQuery (query);

- m_view->setModel (Ypp::PkgQuery::PkgQuery (list, query));
- Cursor::normal();
+ if (page == 3) {
+ query = new Ypp::PkgQuery::Query();
+ query->setToInstall (true);
+ m_view->appendRows (_("To install:"), Ypp::PkgQuery
(m_changes, query), NULL);
+
+ query = new Ypp::PkgQuery::Query();
+ query->setToRemove (true);;
+ m_view->appendRows (_("To remove:"), Ypp::PkgQuery
(m_changes, query), NULL);
+ }
+ else {
+ const char *applyAll = page == 1 ? _("Upgrade All") : 0;
+ m_view->setRows (Ypp::PkgQuery (list, query), applyAll);
+ }
}

virtual void queryNotifyDelay()
@@ -2020,13 +1083,13 @@
}
};
if (m_timeout_id) g_source_remove (m_timeout_id);
- m_timeout_id = g_timeout_add (250, inner::timeout_cb, this);
+ m_timeout_id = g_timeout_add (500, inner::timeout_cb, this);
}

virtual void packagesSelected (Ypp::PkgList packages)
{
m_details->setPackages (packages);
- if (!packages.empty())
+ if (packages.size() > 0)
gtk_widget_show (m_details->getWidget());
}
};
@@ -2227,6 +1290,9 @@
gtk_widget_show_all (m_box);
}

+ ~ToolsBox()
+ { delete m_disk; }
+
private:
static void errorMsg (const std::string &header, const std::string
&message)
{
@@ -2329,6 +1395,84 @@

//** Dialogs

+static bool confirmApply()
+{
+ if (!Ypp::get()->isModified())
+ return true;
+
+ GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Confirm Changes"),
+ YGDialog::currentWindow(), GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_NO, GTK_STOCK_APPLY,
GTK_RESPONSE_YES, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 450);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 6);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area
(GTK_DIALOG (dialog))), vbox);
+ GtkWidget *label = gtk_label_new (_("Please confirm changes:"));
+ YGUtils::setWidgetFont (label, PANGO_STYLE_NORMAL, PANGO_WEIGHT_BOLD,
PANGO_SCALE_MEDIUM);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, .5);
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
+
+ GtkWidget *hbox = gtk_hbox_new (TRUE, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+ for (int i = 0; i < 3; i++) {
+ const char *str, *stock;
+ Ypp::PkgQuery::Query *query = new Ypp::PkgQuery::Query();
+ int checkCol;
+ switch (i) {
+ case 0:
+ str = _("To install:");
+ stock = GTK_STOCK_ADD;
+ query->setToInstall (true);
+ query->setIsInstalled (false);
+ checkCol = ZyppModel::TO_INSTALL_COLUMN;
+ break;
+ case 1:
+ str = _("To upgrade:");
+ stock = GTK_STOCK_GO_UP;
+ query->setToInstall (true);
+ query->setIsInstalled (true);
+ checkCol = ZyppModel::TO_UPGRADE_COLUMN;
+ break;
+ case 2:
+ str = _("To remove:");
+ stock = GTK_STOCK_REMOVE;
+ query->setToRemove (true);
+ checkCol = ZyppModel::NOT_TO_REMOVE_COLUMN;
+ break;
+ default: break;
+ }
+
+ Ypp::PkgQuery list (Ypp::Package::PACKAGE_TYPE, query);
+ if (list.size() == 0)
+ continue;
+
+ GtkWidget *label_box, *icon, *label;
+ label = gtk_label_new (str);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, .5);
+ icon = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
+ label_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (label_box), icon, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (label_box), label, TRUE, TRUE, 0);
+ PackagesView *view = new PackagesView (true);
+ view->appendCheckColumn (checkCol);
+ view->appendTextColumn (NULL, ZyppModel::NAME_COLUMN);
+ view->setRows (list, NULL);
+ view->setFrame (true);
+
+ GtkWidget *box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (box), label_box, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (box), view->getWidget(), TRUE,
TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), box, TRUE, TRUE, 0);
+ }
+
+ gtk_widget_show_all (vbox);
+ bool ok = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES;
+ gtk_widget_destroy (dialog);
+ return ok;
+}
+
static bool confirmExit()
{
if (!Ypp::get()->isModified())
@@ -2362,11 +1506,11 @@
gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 480);
gtk_widget_show_all (dialog);

- PackagesTable *view = new PackagesTable();
- view->appendCheckColumn (NULL, YGtkZyppModel::TO_INSTALL_COLUMN);
- view->appendTextColumn (_("Name"), YGtkZyppModel::NAME_COLUMN, 150);
+ PackagesView *view = new PackagesView (false);
+ view->appendCheckColumn (ZyppModel::TO_INSTALL_COLUMN);
+ view->appendTextColumn (_("Name"), ZyppModel::NAME_COLUMN, 150);
view->appendTextColumn (extraColTitle, extraCol);
- view->setModel (list);
+ view->setRows (list, NULL);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox),
view->getWidget());

bool confirm = (gtk_dialog_run (GTK_DIALOG (dialog)) ==
GTK_RESPONSE_YES);
@@ -2383,11 +1527,11 @@
query->setIsUnsupported (true);

Ypp::PkgQuery list (Ypp::Package::PACKAGE_TYPE, query);
- if (!list.empty())
+ if (list.size() > 0)
return confirmPkgs (_("Unsupported Packages"), _("Please
realize that the following "
"software is either unsupported or requires an
additional customer contract "
"for support."), GTK_MESSAGE_WARNING, list,
- _("Support"), YGtkZyppModel::SUPPORT_COLUMN);
+ _("Support"), ZyppModel::SUPPORT_COLUMN);
return true;
}

@@ -2568,6 +1712,7 @@
{
QueryNotebook *m_notebook;
ToolsBox *m_tools;
+GtkWidget *m_progressbar;
guint m_button_timeout_id;

public:
@@ -2578,19 +1723,17 @@
setBorder (0);
bool onlineUpdate = onlineUpdateMode();
YGDialog *dialog = YGDialog::currentDialog();
- dialog->setMinSize (650, 800); // enlarge
dialog->setCloseCallback (confirm_cb, this);
+ dialog->setMinSize (650, 800); // enlarge

YGtkWizard *wizard = YGTK_WIZARD (getWidget());
ygtk_wizard_set_header_icon (wizard,
THEMEDIR "/icons/22x22/apps/yast-software.png");
const char *title = onlineUpdate ? _("Online Update") :
_("Software Manager");
ygtk_wizard_set_header_text (wizard, title);
- YGDialog::currentDialog()->setTitle (title);
+ dialog->setTitle (title);
ygtk_wizard_set_help_text (wizard, _("Please wait..."));

-while (g_main_context_iteration (NULL, FALSE)) ; // FIXME: debug
-
ygtk_wizard_set_button_label (wizard, wizard->abort_button,
_("_Cancel"), GTK_STOCK_CANCEL);
ygtk_wizard_set_button_str_id (wizard, wizard->abort_button,
"cancel");
@@ -2602,13 +1745,23 @@
G_CALLBACK (wizard_action_cb), this);
ygtk_wizard_enable_button (wizard, wizard->next_button, FALSE);

- Cursor::busy();
- m_notebook = new QueryNotebook (onlineUpdate, repoMgrEnabled());
m_tools = new ToolsBox();
- ygtk_wizard_set_child (YGTK_WIZARD (wizard),
m_notebook->getWidget());
ygtk_wizard_set_extra_button (YGTK_WIZARD (getWidget()),
m_tools->getWidget());

+ m_progressbar = gtk_progress_bar_new();
+ GtkWidget *align = gtk_alignment_new (0, .95, 1, 0);
+ gtk_container_add (GTK_CONTAINER (align), m_progressbar);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_end (GTK_BOX (vbox), align, FALSE, TRUE, 0);
+ gtk_widget_show (align);
+ gtk_widget_show (vbox);
+ ygtk_wizard_set_child (YGTK_WIZARD (wizard), vbox);
Ypp::get()->setInterface (this);
+
+ m_notebook = new QueryNotebook (onlineUpdate, repoMgrEnabled());
+ gtk_box_pack_start (GTK_BOX (vbox), m_notebook->getWidget(),
TRUE, TRUE, 0);
+
const char **help = onlineUpdate ? patch_help : pkg_help;
std::string str;
str.reserve (6144);
@@ -2616,7 +1769,6 @@
str.append (help [i]);
ygtk_wizard_set_help_text (wizard, str.c_str());
m_button_timeout_id = g_timeout_add (7500,
wizard_enable_button_cb, this);
- Cursor::normal();
}

virtual ~YGPackageSelector()
@@ -2625,7 +1777,7 @@
g_source_remove (m_button_timeout_id);
delete m_notebook;
delete m_tools;
- ygtk_zypp_model_finish();
+ ygtk_zypp_finish();
}

// (Y)Gtk callbacks
@@ -2648,9 +1800,13 @@
const gchar *action = (gchar *) id;
yuiMilestone() << "Closing PackageSelector with '" << action <<
"'\n";
if (!strcmp (action, "accept")) {
- if (pThis->confirmUnsupported())
- if (!askConfirmUnsupported())
+ if (!pThis->onlineUpdateMode()) {
+ if (pThis->confirmUnsupported())
+ if (!askConfirmUnsupported())
+ return;
+ if (!confirmApply())
return;
+ }
YGUI::ui()->sendEvent (new YMenuEvent ("accept"));
}
else if (!strcmp (action, "cancel"))
@@ -2676,14 +1832,32 @@
return confirmPkgs (_("Dependencies from Filtered
Repositories"),
_("The following packages have necessary dependencies
that are not provided "
"by the filtered repository. Install them?"),
GTK_MESSAGE_WARNING, list,
- _("Repository"), YGtkZyppModel::REPOSITORY_COLUMN);
+ _("Repository"), ZyppModel::REPOSITORY_COLUMN);
+ }
+
+ virtual void loading (float progress)
+ {
+ if (progress == 1) {
+ if (GTK_WIDGET_VISIBLE (m_progressbar)) {
+ gtk_widget_hide (m_progressbar);
+ while (g_main_context_iteration (NULL, FALSE)) ;
+ }
+ YGUI::ui()->normalCursor();
+ }
+ else {
+ if (progress == 0)
+ YGUI::ui()->busyCursor();
+ else { // progress=0 may be to trigger cursor only
+ gtk_widget_show (m_progressbar);
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR
(m_progressbar), progress);
+ }
+ while (g_main_context_iteration (NULL, FALSE)) ;
+ }
}

YGWIDGET_IMPL_COMMON (YPackageSelector)
};

YPackageSelector *YGWidgetFactory::createPackageSelector (YWidget *parent,
long mode)
-{
- return new YGPackageSelector (parent, mode);
-}
+{ return new YGPackageSelector (parent, mode); }


Modified: trunk/gtk/src/YGTable.cc
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGTable.cc?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/YGTable.cc (original)
+++ trunk/gtk/src/YGTable.cc Thu Sep 3 03:35:38 2009
@@ -206,6 +206,13 @@
pThis->toggle (path, column);
gtk_tree_path_free (path);
}
+
+#if YAST2_VERSION > 2018003
+ static void right_click_cb (YGtkTreeView *view, gboolean outreach,
YGTableView *pThis)
+ {
+ emitEvent (YEvent::ContextMenuActivated);
+ }
+#endif
};

#include "YTable.h"
@@ -251,7 +258,7 @@

connect (getWidget(), "row-activated", G_CALLBACK
(activated_cb), (YGTableView *) this);
connect (getSelection(), "changed", G_CALLBACK
(selection_changed_cb), (YGTableView *) this);
- connect (getWidget(), "right-click", G_CALLBACK
(right_click_cb), this);
+ connect (getWidget(), "right-click", G_CALLBACK
(hack_right_click_cb), this);
connect (getWidget(), "key-press-event", G_CALLBACK
(key_press_event_cb), this);
}

@@ -343,8 +350,12 @@
YGUI::ui()->sendEvent (event);
}

- static void right_click_cb (YGtkTreeView *view, gboolean outreach,
YGTable *pThis)
+ static void hack_right_click_cb (YGtkTreeView *view, gboolean outreach,
YGTable *pThis)
{
+#if YAST2_VERSION > 2018003
+ if (pThis->notifyContextMenu())
+ return YGTableview::hack_right_click_cb (view,
outreach, pThis);
+#endif
if (!YGDialog::currentDialog()->getFunctionWidget (5) ||
// undetermined case -- more than one table exists
YGDialog::currentDialog()->getClassWidgets
("YTable").size() > 1) {
@@ -417,6 +428,9 @@
{
connect (getWidget(), "row-activated", G_CALLBACK
(activated_cb), (YGTableView *) this);
connect (getSelection(), "changed", G_CALLBACK
(selection_changed_cb), (YGTableView *) this);
+#if YAST2_VERSION > 2018003
+ connect (getWidget(), "right-click", G_CALLBACK
(right_click_cb), this);
+#endif
}

virtual bool isShrinkable() { return shrinkable(); }
@@ -452,6 +466,9 @@
connect (getSelection(), "changed", G_CALLBACK
(selection_changed_cb), (YGTableView *) this);
// Let the user toggle, using space/enter or double click (not
an event).
connect (getWidget(), "row-activated", G_CALLBACK
(multi_activated_cb), this);
+#if YAST2_VERSION > 2018003
+ connect (getWidget(), "right-click", G_CALLBACK
(right_click_cb), this);
+#endif
}

// YMultiSelectionBox
@@ -528,6 +545,9 @@
connect (getWidget(), "row-expanded", G_CALLBACK
(row_expanded_cb), this);
connect (getWidget(), "cursor-changed", G_CALLBACK
(row_selected_cb), this);
connect (getWidget(), "row-activated", G_CALLBACK
(activated_cb), (YGTableView *) this);
+#if YAST2_VERSION > 2018003
+ connect (getWidget(), "right-click", G_CALLBACK
(right_click_cb), this);
+#endif
}

// YTree

Modified: trunk/gtk/src/YGUI.h
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUI.h?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/YGUI.h (original)
+++ trunk/gtk/src/YGUI.h Thu Sep 3 03:35:38 2009
@@ -47,6 +47,9 @@
YEvent *waitInput (unsigned long timeout_ms, bool block);

virtual YEvent *runPkgSelection (YWidget *packageSelector);
+#if YAST2_VERSION > 2018003
+ virtual bool openContextMenu (const YItemCollection &itemCollection);
+#endif

// used internally: for public use, see YApplication
void busyCursor();
@@ -182,6 +185,8 @@
virtual YDownloadProgress *createDownloadProgress (YWidget *parent,
const string &label, const string & filename, YFileSize_t
expectedFileSize);

+ virtual bool hasContextMenu() IMPL_RET (true)
+
virtual bool hasSimplePatchSelector() IMPL_RET (false)
virtual YWidget *createSimplePatchSelector (YWidget *parent, long
modeFlags)
IMPL_RET (NULL)

Modified: trunk/gtk/src/YGWidget.cc
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGWidget.cc?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/YGWidget.cc (original)
+++ trunk/gtk/src/YGWidget.cc Thu Sep 3 03:35:38 2009
@@ -68,7 +68,7 @@
{
m_widget = GTK_WIDGET (g_object_new_valist (type, property_name, args));

- if (type == GTK_TYPE_WINDOW)
+ if (type == GTK_TYPE_WINDOW || type == GTK_TYPE_MENU)
m_adj_size = m_widget;
else {
m_adj_size = ygtk_adj_size_new();
@@ -194,6 +194,10 @@
}
};

+#if YAST2_VERSION > 2018003
+ if (reason == YEvent::ContextMenuActivated &&
!m_ywidget->notifyContextMenu())
+ ; // cancel
+#endif
if (flags & IGNORE_NOTIFY_EVENT || m_ywidget->notify()) {
YWidgetEvent *event = new YWidgetEvent (m_ywidget, reason);
if (flags & DELAY_EVENT)

Added: trunk/gtk/src/ygtktreemodel.cc
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtktreemodel.cc?rev=58481&view=auto
==============================================================================
--- trunk/gtk/src/ygtktreemodel.cc (added)
+++ trunk/gtk/src/ygtktreemodel.cc Thu Sep 3 03:35:38 2009
@@ -0,0 +1,222 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkTreeModel, C++ wrapper for gtk+ */
+// check the header file for information about this wrapper
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include "ygtktreemodel.h"
+
+#define YGTK_TYPE_WRAP_MODEL (ygtk_wrap_model_get_type ())
+#define YGTK_WRAP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ YGTK_TYPE_WRAP_MODEL, YGtkWrapModel))
+#define YGTK_WRAP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ YGTK_TYPE_WRAP_MODEL,
YGtkWrapModelClass))
+#define YGTK_IS_WRAP_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE
((obj), YGTK_TYPE_WRAP_MODEL))
+#define YGTK_IS_WRAP_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass),
YGTK_TYPE_WRAP_MODEL))
+#define YGTK_WRAP_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ YGTK_TYPE_WRAP_MODEL,
YGtkWrapModelClass))
+
+struct YGtkWrapModel
+{
+ GObject parent;
+ YGtkTreeModel *model;
+ struct Notify;
+ Notify *notify;
+};
+
+struct YGtkWrapModelClass
+{
+ GObjectClass parent_class;
+};
+
+// bridge as we don't want to mix c++ class polymorphism and gobject
+static void ygtk_wrap_model_entry_changed (YGtkWrapModel *model, int row);
+static void ygtk_wrap_model_entry_inserted (YGtkWrapModel *model, int row);
+static void ygtk_wrap_model_entry_deleted (YGtkWrapModel *model, int row);
+
+struct YGtkWrapModel::Notify : public YGtkTreeModel::Listener {
+YGtkWrapModel *model;
+ Notify (YGtkWrapModel *model) : model (model) {}
+ virtual void rowChanged (int row)
+ { ygtk_wrap_model_entry_changed (model, row); }
+ virtual void rowInserted (int row)
+ { ygtk_wrap_model_entry_inserted (model, row); }
+ virtual void rowDeleted (int row)
+ { ygtk_wrap_model_entry_deleted (model, row); }
+};
+
+static void ygtk_wrap_model_tree_model_init (GtkTreeModelIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (YGtkWrapModel, ygtk_wrap_model, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
ygtk_wrap_model_tree_model_init))
+
+static void ygtk_wrap_model_init (YGtkWrapModel *zmodel)
+{}
+
+static void ygtk_wrap_model_finalize (GObject *object)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (object);
+ delete ymodel->model;
+ ymodel->model = NULL;
+ delete ymodel->notify;
+ ymodel->notify = NULL;
+ G_OBJECT_CLASS (ygtk_wrap_model_parent_class)->finalize (object);
+}
+
+static GtkTreeModelFlags ygtk_wrap_model_get_flags (GtkTreeModel *model)
+{ return (GtkTreeModelFlags)
(GTK_TREE_MODEL_ITERS_PERSIST|GTK_TREE_MODEL_LIST_ONLY); }
+
+static gboolean ygtk_wrap_model_get_iter (GtkTreeModel *model, GtkTreeIter
*iter,
+ GtkTreePath *path)
+{ // from Path to Iter
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ gint index = gtk_tree_path_get_indices (path)[0];
+ iter->user_data = GINT_TO_POINTER (index);
+ int rowsNb = ymodel->model->rowsNb();
+ if (!rowsNb && index == 0 && ymodel->model->showEmptyEntry())
+ return TRUE;
+ return index < rowsNb;
+}
+
+static GtkTreePath *ygtk_wrap_model_get_path (GtkTreeModel *model, GtkTreeIter
*iter)
+{ // from Iter to Path
+ int index = GPOINTER_TO_INT (iter->user_data);
+ GtkTreePath *path = gtk_tree_path_new();
+ gtk_tree_path_append_index (path, index);
+ return path;
+}
+
+static gboolean ygtk_wrap_model_iter_next (GtkTreeModel *model, GtkTreeIter
*iter)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ int index = GPOINTER_TO_INT (iter->user_data) + 1;
+ iter->user_data = GINT_TO_POINTER (index);
+ int rowsNb = ymodel->model->rowsNb();
+ return index < rowsNb;
+}
+
+static gboolean ygtk_wrap_model_iter_parent (GtkTreeModel *, GtkTreeIter *,
GtkTreeIter *)
+{ return FALSE; }
+
+static gboolean ygtk_wrap_model_iter_has_child (GtkTreeModel *, GtkTreeIter *)
+{ return FALSE; }
+
+static gint ygtk_wrap_model_iter_n_children (GtkTreeModel *model, GtkTreeIter
*iter)
+{ return 0; }
+
+static gboolean ygtk_wrap_model_iter_nth_child (GtkTreeModel *model,
GtkTreeIter *iter,
+ GtkTreeIter *parent, gint
index)
+{
+ if (parent) return FALSE;
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ iter->user_data = GINT_TO_POINTER (index);
+ int rowsNb = ymodel->model->rowsNb();
+ if (!rowsNb && index == 0 && ymodel->model->showEmptyEntry())
+ return TRUE;
+ return index < rowsNb;
+}
+
+static gboolean ygtk_wrap_model_iter_children (
+ GtkTreeModel *model, GtkTreeIter *iter, GtkTreeIter *parent)
+{ return ygtk_wrap_model_iter_nth_child (model, iter, parent, 0); }
+
+void ygtk_wrap_model_entry_changed (YGtkWrapModel *model, int row)
+{
+ GtkTreeIter iter;
+ iter.user_data = GINT_TO_POINTER (row);
+ GtkTreePath *path = ygtk_wrap_model_get_path (GTK_TREE_MODEL (model),
&iter);
+ gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
+ gtk_tree_path_free (path);
+}
+
+void ygtk_wrap_model_entry_inserted (YGtkWrapModel *ymodel, int row)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL (ymodel);
+ GtkTreeIter iter;
+ iter.user_data = GINT_TO_POINTER (row);
+ GtkTreePath *path = ygtk_wrap_model_get_path (model, &iter);
+
+ if (row == 0 && ymodel->model->rowsNb() == 1 &&
ymodel->model->showEmptyEntry())
+ gtk_tree_model_row_changed (model, path, &iter);
+ else
+ gtk_tree_model_row_inserted (model, path, &iter);
+ gtk_tree_path_free (path);
+}
+
+void ygtk_wrap_model_entry_deleted (YGtkWrapModel *ymodel, int row)
+{
+ GtkTreeModel *model = GTK_TREE_MODEL (ymodel);
+ GtkTreeIter iter;
+ iter.user_data = GINT_TO_POINTER (row);
+ GtkTreePath *path = ygtk_wrap_model_get_path (model, &iter);
+
+ if (row == 0 && ymodel->model->rowsNb() == 1 &&
ymodel->model->showEmptyEntry())
+ gtk_tree_model_row_changed (model, path, &iter);
+ else
+ gtk_tree_model_row_deleted (model, path);
+ gtk_tree_path_free (path);
+}
+
+static gint ygtk_wrap_model_get_n_columns (GtkTreeModel *model)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ return ymodel->model->columnsNb();
+}
+
+static GType ygtk_wrap_model_get_column_type (GtkTreeModel *model, gint column)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ return ymodel->model->columnType (column);
+}
+
+static void ygtk_wrap_model_get_value (GtkTreeModel *model, GtkTreeIter *iter,
+ gint column, GValue *value)
+{
+ int row = GPOINTER_TO_INT (iter->user_data);
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ g_value_init (value, ymodel->model->columnType (column));
+ if (row == 0 && ymodel->model->rowsNb() == 0)
+ row = -1;
+ ymodel->model->getValue (row, column, value);
+}
+
+GtkTreeModel *ygtk_tree_model_new (YGtkTreeModel *model)
+{
+ YGtkWrapModel *ymodel = (YGtkWrapModel *) g_object_new
(YGTK_TYPE_WRAP_MODEL, NULL);
+ ymodel->model = model;
+ ymodel->notify = new YGtkWrapModel::Notify (ymodel);
+ model->listener = ymodel->notify;
+ return GTK_TREE_MODEL (ymodel);
+}
+
+YGtkTreeModel *ygtk_tree_model_get_model (GtkTreeModel *model)
+{
+ YGtkWrapModel *ymodel = YGTK_WRAP_MODEL (model);
+ return ymodel->model;
+}
+
+static void ygtk_wrap_model_class_init (YGtkWrapModelClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = ygtk_wrap_model_finalize;
+}
+
+static void ygtk_wrap_model_tree_model_init (GtkTreeModelIface *iface)
+{
+ iface->get_flags = ygtk_wrap_model_get_flags;
+ iface->get_n_columns = ygtk_wrap_model_get_n_columns;
+ iface->get_column_type = ygtk_wrap_model_get_column_type;
+ iface->get_iter = ygtk_wrap_model_get_iter;
+ iface->get_path = ygtk_wrap_model_get_path;
+ iface->get_value = ygtk_wrap_model_get_value;
+ iface->iter_next = ygtk_wrap_model_iter_next;
+ iface->iter_children = ygtk_wrap_model_iter_children;
+ iface->iter_has_child = ygtk_wrap_model_iter_has_child;
+ iface->iter_n_children = ygtk_wrap_model_iter_n_children;
+ iface->iter_nth_child = ygtk_wrap_model_iter_nth_child;
+ iface->iter_parent = ygtk_wrap_model_iter_parent;
+}
+

Added: trunk/gtk/src/ygtktreemodel.h
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtktreemodel.h?rev=58481&view=auto
==============================================================================
--- trunk/gtk/src/ygtktreemodel.h (added)
+++ trunk/gtk/src/ygtktreemodel.h Thu Sep 3 03:35:38 2009
@@ -0,0 +1,38 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* Wraps GtkTreeModel as a C++ model.
+*/
+
+#ifndef YGTK_TREE_MODEL_H
+#define YGTK_TREE_MODEL_H
+
+#include <gtk/gtktreemodel.h>
+
+struct YGtkTreeModel
+{
+ virtual void getValue (int row, int col, GValue *value) = 0;
+ virtual int rowsNb() = 0;
+ virtual int columnsNb() const = 0;
+ virtual GType columnType (int col) const = 0;
+ // if 'showEmptyEntry' will call getValue(row=-1) for the empty entry
+ virtual bool showEmptyEntry() const = 0;
+
+ // implement setListener() to signal model changes, if dynamic
+ struct Listener {
+ virtual void rowChanged (int row) = 0;
+ virtual void rowInserted (int row) = 0;
+ virtual void rowDeleted (int row) = 0;
+ };
+ Listener *listener;
+
+ virtual ~YGtkTreeModel() {}
+};
+
+GtkTreeModel *ygtk_tree_model_new (YGtkTreeModel *model);
+
+YGtkTreeModel *ygtk_tree_model_get_model (GtkTreeModel *model);
+
+#endif /*YGTK_TREE_MODEL_H*/
+

Modified: trunk/gtk/src/ygtktreeview.h
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtktreeview.h?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/ygtktreeview.h (original)
+++ trunk/gtk/src/ygtktreeview.h Thu Sep 3 03:35:38 2009
@@ -13,15 +13,15 @@

#define YGTK_TYPE_TREE_VIEW (ygtk_tree_view_get_type ())
#define YGTK_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
- YGTK_TYPE_TREE_VIEW, YGtkScrolledWindow))
+ YGTK_TYPE_TREE_VIEW, YGtkTreeView))
#define YGTK_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), \
- YGTK_TYPE_TREE_VIEW, YGtkScrolledWindowClass))
+ YGTK_TYPE_TREE_VIEW, YGtkTreeViewClass))
#define YGTK_IS_TREE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
YGTK_TYPE_TREE_VIEW))
#define YGTK_IS_TREE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
YGTK_TYPE_TREE_VIEW))
#define YGTK_TREE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \
- YGTK_TYPE_TREE_VIEW, YGtkScrolledWindowClass))
+ YGTK_TYPE_TREE_VIEW, YGtkTreeViewClass))

typedef struct _YGtkTreeView
{

Modified: trunk/gtk/src/ygtkwizard.c
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkwizard.c?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/ygtkwizard.c (original)
+++ trunk/gtk/src/ygtkwizard.c Thu Sep 3 03:35:38 2009
@@ -705,10 +705,13 @@
g_signal_emit (wizard, action_triggered_signal, 0, id,
G_TYPE_STRING);
}

-void ygtk_wizard_set_child (YGtkWizard *wizard, GtkWidget *widget)
+void ygtk_wizard_set_child (YGtkWizard *wizard, GtkWidget *child)
{
- wizard->m_child = widget;
- gtk_paned_pack2 (GTK_PANED (wizard->m_pane), widget, TRUE, TRUE);
+ if (wizard->m_child)
+ gtk_container_remove (GTK_CONTAINER (wizard->m_pane),
wizard->m_child);
+ wizard->m_child = child;
+ if (child)
+ gtk_paned_pack2 (GTK_PANED (wizard->m_pane), child, TRUE, TRUE);
}

static gboolean ygtk_wizard_set_information_expose_cb (GtkWidget *widget,
GdkEventExpose *event,

Added: trunk/gtk/src/ygtkzyppview.cc
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkzyppview.cc?rev=58481&view=auto
==============================================================================
--- trunk/gtk/src/ygtkzyppview.cc (added)
+++ trunk/gtk/src/ygtkzyppview.cc Thu Sep 3 03:35:38 2009
@@ -0,0 +1,1564 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* YGtkZyppView, Zypp GtkTreeView implementation */
+// check the header file for information about this widget
+
+/*
+ Textdomain "yast2-gtk"
+ */
+#define YUILogComponent "gtk"
+#include <config.h>
+#include <gtk/gtk.h>
+#include "ygtkzyppview.h"
+#include "ygtktreeview.h"
+#include "ygtktreemodel.h"
+#include "ygtkrichtext.h"
+#include "YGi18n.h"
+#include "YGUtils.h"
+#include "YGDialog.h"
+#include <stdlib.h>
+#include <string.h>
+#include <list>
+
+//** Utilities
+
+#define GNOME_OPEN_PATH "/usr/bin/gnome-open"
+inline bool CAN_OPEN_URIS()
+{ return g_file_test (GNOME_OPEN_PATH, G_FILE_TEST_IS_EXECUTABLE); }
+inline void OPEN_URI (const char *uri)
+{ system ((std::string (GNOME_OPEN_PATH " ") + uri + " &").c_str()); }
+
+static GdkPixbuf *loadPixbuf (const char *icon)
+{ return YGUtils::loadPixbuf (std::string (DATADIR) + "/" + icon); }
+
+//** Icons resources
+
+struct PackageIcons {
+ GdkPixbuf *installed, *installed_upgradable, *installed_locked,
+ *installed_upgradable_locked, *available, *available_locked,
+ *to_install, *to_install_upgrade, *to_remove,
*to_auto_install,
+ *to_auto_remove;
+ PackageIcons() {
+ installed = loadPixbuf ("pkg-installed.png");
+ installed_upgradable = loadPixbuf
("pkg-installed-upgradable.png");
+ installed_locked = loadPixbuf ("pkg-installed-locked.png");
+ installed_upgradable_locked = loadPixbuf
("pkg-installed-upgradable-locked.png");
+ available = loadPixbuf ("pkg-available.png");
+ available_locked = loadPixbuf ("pkg-available-locked.png");
+ to_install = loadPixbuf ("pkg-install.png");
+ to_install_upgrade = loadPixbuf ("pkg-upgrade.png");
+ to_remove = loadPixbuf ("pkg-remove.png");
+ to_auto_install = loadPixbuf ("pkg-install-auto.png");
+ to_auto_remove = loadPixbuf ("pkg-remove-auto.png");
+ }
+ ~PackageIcons() {
+ g_object_unref (G_OBJECT (installed));
+ g_object_unref (G_OBJECT (installed_upgradable));
+ g_object_unref (G_OBJECT (installed_upgradable_locked));
+ g_object_unref (G_OBJECT (installed_locked));
+ g_object_unref (G_OBJECT (available));
+ g_object_unref (G_OBJECT (available_locked));
+ g_object_unref (G_OBJECT (to_install));
+ g_object_unref (G_OBJECT (to_remove));
+ g_object_unref (G_OBJECT (to_install_upgrade));
+ g_object_unref (G_OBJECT (to_auto_install));
+ g_object_unref (G_OBJECT (to_auto_remove));
+ }
+};
+
+static PackageIcons *icons = NULL;
+void ygtk_zypp_finish (void)
+{
+ delete icons; icons = NULL;
+ Ypp::finish();
+}
+
+//** Model
+
+static GType _columnType (int col)
+{
+ switch (col) {
+ case ZyppModel::ICON_COLUMN:
+ return GDK_TYPE_PIXBUF;
+ case ZyppModel::NAME_COLUMN:
+ case ZyppModel::SUMMARY_COLUMN:
+ case ZyppModel::NAME_SUMMARY_COLUMN:
+ case ZyppModel::REPOSITORY_COLUMN:
+ case ZyppModel::SUPPORT_COLUMN:
+ case ZyppModel::INSTALLED_VERSION_COLUMN:
+ case ZyppModel::AVAILABLE_VERSION_COLUMN:
+ case ZyppModel::FOREGROUND_COLUMN:
+ case ZyppModel::BACKGROUND_COLUMN:
+ return G_TYPE_STRING;
+ case ZyppModel::TO_INSTALL_COLUMN:
+ case ZyppModel::TO_UPGRADE_COLUMN:
+ case ZyppModel::NOT_TO_REMOVE_COLUMN:
+ case ZyppModel::TO_MODIFY_COLUMN:
+ case ZyppModel::SENSITIVE_COLUMN:
+ case ZyppModel::CHECK_VISIBLE_COLUMN:
+ return G_TYPE_BOOLEAN;
+ case ZyppModel::STYLE_COLUMN:
+ case ZyppModel::WEIGHT_COLUMN:
+ return G_TYPE_INT;
+ case ZyppModel::PTR_COLUMN:
+ return G_TYPE_POINTER;
+ }
+ return 0;
+}
+
+static void _getValueDefault (int col, GValue *value)
+{
+ switch (col) {
+ case ZyppModel::ICON_COLUMN:
+ g_value_set_object (value, NULL);
+ break;
+ case ZyppModel::NAME_COLUMN:
+ case ZyppModel::SUMMARY_COLUMN:
+ case ZyppModel::NAME_SUMMARY_COLUMN:
+ case ZyppModel::REPOSITORY_COLUMN:
+ case ZyppModel::SUPPORT_COLUMN:
+ case ZyppModel::INSTALLED_VERSION_COLUMN:
+ case ZyppModel::AVAILABLE_VERSION_COLUMN:
+ g_value_set_string (value, g_strdup (""));
+ break;
+ case ZyppModel::FOREGROUND_COLUMN:
+ case ZyppModel::BACKGROUND_COLUMN:
+ g_value_set_string (value, NULL);
+ break;
+ case ZyppModel::TO_INSTALL_COLUMN:
+ case ZyppModel::TO_UPGRADE_COLUMN:
+ case ZyppModel::NOT_TO_REMOVE_COLUMN:
+ case ZyppModel::TO_MODIFY_COLUMN:
+ g_value_set_boolean (value, FALSE);
+ break;
+ case ZyppModel::STYLE_COLUMN:
+ g_value_set_int (value, PANGO_STYLE_NORMAL);
+ break;
+ case ZyppModel::WEIGHT_COLUMN:
+ g_value_set_int (value, PANGO_WEIGHT_NORMAL);
+ break;
+ case ZyppModel::SENSITIVE_COLUMN:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case ZyppModel::CHECK_VISIBLE_COLUMN:
+ g_value_set_boolean (value, TRUE);
+ break;
+ case ZyppModel::PTR_COLUMN:
+ g_value_set_pointer (value, NULL);
+ break;
+ case ZyppModel::TOTAL_COLUMNS: break;
+ }
+}
+
+struct YGtkZyppModel : public YGtkTreeModel, Ypp::PkgList::Listener
+{
+ YGtkZyppModel()
+ {
+ if (!icons)
+ icons = new PackageIcons();
+ }
+
+ void append (const std::string &header, Ypp::PkgList list, const
std::string &applyAllLabel)
+ {
+ block.segments.push_back (Block::Segment (&block, header, list,
applyAllLabel));
+ list.setListener (this);
+ }
+
+protected:
+ struct Block {
+ struct Segment {
+ Segment (Block *block, const std::string &header,
Ypp::PkgList list, const std::string &applyAllLabel)
+ : block (block), header (header), applyAll
(applyAllLabel), list (list)
+ {}
+
+ int size()
+ {
+ int size = list.size();
+ if (size == 0) return 0;
+ return size + (header.empty() ? 0 : 1) +
(applyAll.empty() ? 0 : 1);
+ }
+
+ void signalChanged (int index, YGtkTreeModel::Listener
*listener)
+ {
+ int row = getRow() + index + (header.empty() ?
0 : 1);
+ listener->rowChanged (row);
+ }
+
+ void signalInserted (int index, YGtkTreeModel::Listener
*listener)
+ {
+ int row = getRow() + index + (header.empty() ?
0 : 1);
+ if (list.size() == 1) {
+ if (!header.empty())
+ listener->rowInserted (row-1);
+ if (!applyAll.empty())
+ listener->rowInserted (row+1);
+ }
+ listener->rowInserted (row);
+ }
+
+ void signalDelete (int index, YGtkTreeModel::Listener
*listener)
+ {
+ int row = getRow() + index + (header.empty() ?
0 : 1);
+ if (list.size() == 1) {
+ if (!header.empty())
+ listener->rowDeleted (row-1);
+ if (!applyAll.empty())
+ listener->rowDeleted (row+1);
+ }
+ listener->rowDeleted (row);
+ }
+
+ int getRow()
+ {
+ int row = 0;
+ for (std::list <Segment>::iterator it =
block->segments.begin();
+ it != block->segments.end(); it++) {
+ if (&(*it) == this)
+ break;
+ row += it->size();
+ }
+ return row;
+ }
+
+ Block *block;
+ std::string header, applyAll;
+ Ypp::PkgList list;
+ };
+
+ std::list <Segment> segments;
+
+ Segment *get (const Ypp::PkgList *list)
+ {
+ for (std::list <Segment>::iterator it =
segments.begin(); it != segments.end(); it++)
+ if (it->list == *list)
+ return &(*it);
+ return NULL;
+ }
+
+ bool get (int row, Segment **segment, int *index)
+ {
+ int size = 0;
+ for (std::list <Segment>::iterator it =
segments.begin(); it != segments.end(); it++) {
+ int _size = it->size();
+ if (size+_size > row) {
+ *segment = &(*it);
+ *index = row - size -
(it->header.empty() ? 0 : 1);
+ if (!it->applyAll.empty() && *index ==
_size-1)
+ *index = -2;
+ return true;
+ }
+ size += _size;
+ }
+ return false;
+ }
+
+ int sumSize()
+ {
+ int size = 0;
+ for (std::list <Segment>::iterator it =
segments.begin(); it != segments.end(); it++)
+ size += it->size();
+ return size;
+ }
+ };
+
+ Block block;
+
+ virtual int rowsNb()
+ { return block.sumSize(); }
+
+ virtual int columnsNb() const
+ { return ZyppModel::TOTAL_COLUMNS; }
+
+ virtual bool showEmptyEntry() const
+ { return true; }
+
+ virtual GType columnType (int col) const
+ { return _columnType (col); }
+
+ virtual void getValue (int row, int col, GValue *value)
+ {
+ if (row == -1) {
+ switch (col) {
+ case ZyppModel::NAME_COLUMN:
+ g_value_set_string (value, g_strdup
(_("(No entries.)")));
+ break;
+ case ZyppModel::STYLE_COLUMN:
+ g_value_set_int (value,
PANGO_STYLE_ITALIC);
+ break;
+ case ZyppModel::CHECK_VISIBLE_COLUMN:
+ g_value_set_boolean (value, FALSE);
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ return;
+ }
+
+ Block::Segment *segment = 0;
+ int index = 0;
+ block.get (row, &segment, &index);
+
+ if (index == -1) { // header
+ switch (col) {
+ case ZyppModel::NAME_COLUMN:
+ g_value_set_string (value, g_strdup
(segment->header.c_str()));
+ break;
+ case ZyppModel::NAME_SUMMARY_COLUMN: {
+ std::string header (segment->header);
+ header = "<big>" + header + "</big>";
+ g_value_set_string (value, g_strdup
(header.c_str()));
+ break;
+ }
+ case ZyppModel::WEIGHT_COLUMN:
+ g_value_set_int (value,
PANGO_WEIGHT_BOLD);
+ break;
+ case ZyppModel::CHECK_VISIBLE_COLUMN:
+ g_value_set_boolean (value, FALSE);
+ break;
+ case ZyppModel::FOREGROUND_COLUMN:
+ g_value_set_string (value, g_strdup
("darkgray"));
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ return;
+ }
+ if (index == -2) { // apply all label
+ switch (col) {
+ case ZyppModel::NAME_COLUMN:
+ g_value_set_string (value, g_strdup
(segment->applyAll.c_str()));
+ break;
+ case ZyppModel::BACKGROUND_COLUMN:
+ g_value_set_string (value, g_strdup
("lightblue"));
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ return;
+ }
+
+ Ypp::Package *package = segment->list.get (index);
+ switch (col) {
+ case ZyppModel::ICON_COLUMN: {
+ if (!icons)
+ icons = new PackageIcons();
+
+ GdkPixbuf *pixbuf = 0;
+ switch (package->type()) {
+ case Ypp::Package::PATTERN_TYPE: {
+ std::string filename
(package->icon());
+ GtkIconTheme *icons =
gtk_icon_theme_get_default();
+ pixbuf =
gtk_icon_theme_load_icon (icons,
+ filename.c_str(), 32,
GtkIconLookupFlags (0), NULL);
+ break;
+ }
+ default:
+ break;
+ }
+ if (pixbuf) {
+ if (!package->isInstalled()) {
+ GdkPixbuf *_pixbuf = pixbuf;
+ pixbuf = YGUtils::setOpacity
(_pixbuf, 50, true);
+ g_object_unref (_pixbuf);
+ }
+ }
+ else {
+ bool locked = package->isLocked();
+ bool auto_ = package->isAuto();
+ if (package->toInstall()) {
+ if (auto_)
+ pixbuf =
icons->to_auto_install;
+ else {
+ pixbuf =
icons->to_install;
+ if
(package->isInstalled())
+ pixbuf =
icons->to_install_upgrade;
+ }
+ }
+ else if (package->toRemove()) {
+ if (auto_)
+ pixbuf =
icons->to_auto_remove;
+ else
+ pixbuf =
icons->to_remove;
+ }
+ else if (package->hasUpgrade()) {
+ if (locked)
+ pixbuf =
icons->installed_upgradable_locked;
+ else
+ pixbuf =
icons->installed_upgradable;
+ }
+ else if (package->isInstalled()) {
+ if (locked)
+ pixbuf =
icons->installed_locked;
+ else
+ pixbuf =
icons->installed;
+ }
+ else {
+ if (locked)
+ pixbuf =
icons->available_locked;
+ else
+ pixbuf =
icons->available;
+ }
+ }
+ g_value_set_object (value, (GObject *) pixbuf);
+ break;
+ }
+ case ZyppModel::NAME_COLUMN: {
+ std::string str (package->name());
+ g_value_set_string (value, g_strdup
(str.c_str()));
+ break;
+ }
+ case ZyppModel::SUMMARY_COLUMN: {
+ std::string str (package->summary());
+ g_value_set_string (value, g_strdup
(str.c_str()));
+ break;
+ }
+ case ZyppModel::NAME_SUMMARY_COLUMN: {
+ std::string str = package->name();
+ std::string summary = package->summary();
+ if (!summary.empty()) {
+ YGUtils::escapeMarkup (summary);
+ str += "\n<small>" + summary +
"</small>";
+ }
+ g_value_set_string (value, g_strdup
(str.c_str()));
+ break;
+ }
+ case ZyppModel::REPOSITORY_COLUMN: {
+ const Ypp::Package::Version *version = 0;
+ if (package->toInstall (&version)) ;
+ if (!version)
+ version =
package->getInstalledVersion();
+ std::string repo;
+ if (version && version->repo)
+ repo = version->repo->name;
+ g_value_set_string (value, g_strdup
(repo.c_str()));
+ break;
+ }
+ case ZyppModel::SUPPORT_COLUMN:
+ g_value_set_string (value, g_strdup
(package->support().c_str()));
+ break;
+ case ZyppModel::INSTALLED_VERSION_COLUMN: {
+ const Ypp::Package::Version *version =
package->getInstalledVersion();
+ g_value_set_string (value, g_strdup
(version->number.c_str()));
+ break;
+ }
+ case ZyppModel::AVAILABLE_VERSION_COLUMN: {
+ const Ypp::Package::Version *version =
package->getAvailableVersion (0);
+ g_value_set_string (value, g_strdup
(version->number.c_str()));
+ break;
+ }
+ case ZyppModel::TO_INSTALL_COLUMN:
+ g_value_set_boolean (value,
package->toInstall());
+ break;
+ case ZyppModel::TO_UPGRADE_COLUMN: {
+ const Ypp::Package::Version *version = 0;
+ if (package->toInstall (&version))
+ g_value_set_boolean (value,
version->cmp > 0);
+ break;
+ }
+ case ZyppModel::NOT_TO_REMOVE_COLUMN:
+ g_value_set_boolean (value,
!package->toRemove());
+ break;
+ case ZyppModel::TO_MODIFY_COLUMN:
+ g_value_set_boolean (value,
package->toModify());
+ break;
+ case ZyppModel::SENSITIVE_COLUMN:
+ g_value_set_boolean (value,
!package->isLocked());
+ break;
+ case ZyppModel::WEIGHT_COLUMN: {
+ bool highlight = segment->list.highlight
(index);
+ int weight = highlight ? PANGO_WEIGHT_BOLD :
PANGO_WEIGHT_NORMAL;
+ g_value_set_int (value, weight);
+ break;
+ }
+ case ZyppModel::PTR_COLUMN:
+ g_value_set_pointer (value, (void *) package);
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ }
+
+ virtual void entryChanged (const Ypp::PkgList list, int index,
Ypp::Package *package)
+ {
+ Block::Segment *seg = block.get (&list);
+ seg->signalChanged (index, listener);
+ }
+
+ virtual void entryInserted (const Ypp::PkgList list, int index,
Ypp::Package *package)
+ {
+ Block::Segment *seg = block.get (&list);
+ seg->signalInserted (index, listener);
+ }
+
+ virtual void entryDeleted (const Ypp::PkgList list, int index,
Ypp::Package *package)
+ {
+ Block::Segment *seg = block.get (&list);
+ seg->signalDelete (index, listener);
+ }
+};
+
+GtkTreeModel *ygtk_zypp_model_new()
+{ return ygtk_tree_model_new (new YGtkZyppModel()); }
+
+void ygtk_zypp_model_append (GtkTreeModel *model,
+ const std::string &header, Ypp::PkgList list, const std::string
&applyAllLabel)
+{
+ YGtkZyppModel *zmodel = (YGtkZyppModel *) ygtk_tree_model_get_model
(model);
+ zmodel->append (header, list, applyAllLabel);
+}
+
+// model to show "loading..." on query
+struct EmptyModel : public YGtkTreeModel
+{
+ virtual bool showEmptyEntry() const { return false; }
+ virtual int rowsNb() { return 1; }
+ virtual int columnsNb() const { return ZyppModel::TOTAL_COLUMNS; }
+ virtual GType columnType (int col) const { return _columnType (col); }
+
+ virtual void getValue (int row, int col, GValue *value)
+ {
+ switch (col) {
+ case ZyppModel::NAME_COLUMN:
+ g_value_set_string (value, g_strdup
(_("Query...")));
+ break;
+ case ZyppModel::STYLE_COLUMN:
+ g_value_set_int (value, PANGO_STYLE_ITALIC);
+ break;
+ case ZyppModel::CHECK_VISIBLE_COLUMN:
+ g_value_set_boolean (value, FALSE);
+ break;
+ default:
+ _getValueDefault (col, value);
+ break;
+ }
+ }
+
+ virtual void setListener (YGtkTreeModel::Listener *listener) {}
+};
+
+//** View
+
+struct PackagesView::Impl
+{
+ Impl (bool descriptiveTooltip)
+ : m_listener (NULL), m_popup_hack (NULL), m_descriptiveTooltip
(descriptiveTooltip),
+ m_model (NULL), m_modelId (0)
+ {
+ m_scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ g_object_ref_sink (G_OBJECT (m_scroll));
+
+ GtkTreeView *view = GTK_TREE_VIEW (m_view =
ygtk_tree_view_new());
+ gtk_tree_view_set_search_column (view, ZyppModel::NAME_COLUMN);
+ gtk_tree_view_set_fixed_height_mode (view, TRUE);
+ gtk_tree_view_set_headers_visible (view, FALSE);
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection
(view);
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (G_OBJECT (selection), "changed",
+ G_CALLBACK (packages_selected_cb), this);
+ gtk_tree_selection_set_select_function (selection,
can_select_row_cb,
+ this, NULL);
+
+ g_signal_connect (G_OBJECT (m_view), "row-activated",
+ G_CALLBACK (package_activated_cb), this);
+ g_signal_connect (G_OBJECT (m_view), "right-click",
+ G_CALLBACK (popup_menu_cb), this);
+ gtk_widget_set_has_tooltip (m_view, TRUE);
+ g_signal_connect (G_OBJECT (m_view), "query-tooltip",
+ G_CALLBACK (query_tooltip_cb), this);
+
+ gtk_container_add (GTK_CONTAINER (m_scroll), m_view);
+ gtk_widget_show_all (m_scroll);
+ clear();
+ }
+
+ ~Impl()
+ {
+ if (m_popup_hack) gtk_widget_destroy (m_popup_hack);
+ g_object_unref (G_OBJECT (m_scroll));
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+ }
+
+ // data
+ PackagesView::Listener *m_listener;
+ GtkWidget *m_scroll, *m_view, *m_popup_hack;
+ bool m_descriptiveTooltip;
+ GtkTreeModel *m_model;
+ guint m_modelId;
+
+ // methods
+ void setRows (Ypp::PkgList list, const char *applyAllLabel)
+ {
+ std::string _applyAllLabel = applyAllLabel ? applyAllLabel : "";
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+ m_model = ygtk_zypp_model_new();
+ ygtk_zypp_model_append (m_model, std::string (""), list,
_applyAllLabel);
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ gtk_tree_view_set_model (view, m_model);
+ }
+
+ void appendRows (const char *header, Ypp::PkgList list, const char
*applyAllLabel)
+ {
+ std::string _header = header ? header : "";
+ std::string _applyAllLabel = applyAllLabel ? applyAllLabel : "";
+ if (!m_model)
+ m_model = ygtk_zypp_model_new();
+ ygtk_zypp_model_append (m_model, _header, list, _applyAllLabel);
+ if (!m_modelId)
+ m_modelId = g_idle_add_full (G_PRIORITY_LOW,
set_model_cb, this, NULL);
+ }
+
+ void clear()
+ {
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+ m_model = 0;
+ static GtkTreeModel *empty = 0;
+ if (!empty)
+ empty = ygtk_tree_model_new (new EmptyModel());
+ gtk_tree_view_set_model (GTK_TREE_VIEW (m_view), empty);
+ }
+
+ GList *getSelectedPaths (GtkTreeModel **model)
+ { return gtk_tree_selection_get_selected_rows (getTreeSelection(),
model); }
+
+ void selectAll()
+ { gtk_tree_selection_select_all (getTreeSelection()); }
+
+ void unselectAll()
+ { gtk_tree_selection_unselect_all (getTreeSelection()); }
+
+ int countSelected()
+ { return gtk_tree_selection_count_selected_rows (getTreeSelection()); }
+
+ Ypp::PkgList getSelected()
+ {
+ GtkTreeModel *model;
+ GList *paths = getSelectedPaths (&model);
+ Ypp::PkgList packages;
+ for (GList *i = paths; i; i = i->next) {
+ Ypp::Package *package;
+ GtkTreePath *path = (GtkTreePath *) i->data;
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter,
ZyppModel::PTR_COLUMN, &package, -1);
+ gtk_tree_path_free (path);
+ if (package)
+ packages.append (package);
+ }
+ g_list_free (paths);
+ return packages;
+ }
+
+ void appendIconColumn (const char *header, int col)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ if (header)
+ gtk_tree_view_set_headers_visible (view, TRUE);
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
+ int height = MAX (34, YGUtils::getCharsHeight (m_view,
2));
+ gtk_cell_renderer_set_fixed_size (renderer, -1, height);
+ column = gtk_tree_view_column_new_with_attributes (
+ header, renderer, "pixbuf", col,
+ "cell-background", ZyppModel::BACKGROUND_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 (view, column);
+ }
+
+ void appendCheckColumn (int modelCol)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
+ GtkTreeViewColumn *column;
+ column = gtk_tree_view_column_new_with_attributes (NULL,
+ renderer, "active", modelCol, "visible",
ZyppModel::CHECK_VISIBLE_COLUMN,
+ "sensitive", ZyppModel::SENSITIVE_COLUMN,
+ "cell-background", ZyppModel::BACKGROUND_COLUMN, NULL);
+ g_object_set_data (G_OBJECT (renderer), "col", GINT_TO_POINTER
(modelCol));
+ g_signal_connect (G_OBJECT (renderer), "toggled",
+ G_CALLBACK (renderer_toggled_cb), this);
+ // it seems like GtkCellRendererToggle has no width at start,
so fixed doesn't work
+ gtk_tree_view_column_set_sizing (column,
GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_fixed_width (column, 25);
+ gtk_tree_view_append_column (view, column);
+ }
+
+ void appendTextColumn (const char *header, int col, int size)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_view);
+ if (header)
+ gtk_tree_view_set_headers_visible (view, TRUE);
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ g_object_set (G_OBJECT (renderer), "ellipsize",
+ size == -1 ? PANGO_ELLIPSIZE_END :
PANGO_ELLIPSIZE_MIDDLE, NULL);
+/* gboolean reverse = gtk_widget_get_default_direction() ==
GTK_TEXT_DIR_RTL;
+ if (reverse) { // work-around: Pango ignored alignment flag on
RTL
+ gtk_widget_set_direction (m_view, GTK_TEXT_DIR_LTR);
+ g_object_set (renderer, "alignment", PANGO_ALIGN_RIGHT,
NULL);
+ }*/
+ GtkTreeViewColumn *column;
+ column = gtk_tree_view_column_new_with_attributes (
+ header, renderer, "markup", col,
+ "sensitive", ZyppModel::SENSITIVE_COLUMN,
+ "style", ZyppModel::STYLE_COLUMN,
+ "weight", ZyppModel::WEIGHT_COLUMN,
+ "foreground", ZyppModel::FOREGROUND_COLUMN,
+ "cell-background", ZyppModel::BACKGROUND_COLUMN,
+ NULL);
+ gtk_tree_view_column_set_sizing (column,
GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_tree_view_column_set_resizable (column, TRUE);
+ if (size >= 0)
+ gtk_tree_view_column_set_fixed_width (column, size);
+ else
+ gtk_tree_view_column_set_expand (column, TRUE);
+// gtk_tree_view_insert_column (view, column, reverse ? 0 : -1);
+ gtk_tree_view_append_column (view, column);
+ }
+
+ GtkTreeSelection *getTreeSelection()
+ { return gtk_tree_view_get_selection (GTK_TREE_VIEW (m_view)); }
+
+ void signalSelected()
+ { if (m_listener) m_listener->packagesSelected (getSelected()); }
+
+ void signalPopup (int button, int event_time)
+ {
+ // GtkMenu emits "deactivate" before Items notifications, so
there isn't
+ // a better way to de-allocate the popup
+ if (m_popup_hack) gtk_widget_destroy (m_popup_hack);
+ GtkWidget *menu = m_popup_hack = gtk_menu_new();
+
+ struct inner {
+ static void appendItem (GtkWidget *menu, const char
*label,
+ const char *tooltip, const char *icon, bool
sensitive,
+ void (& callback) (GtkMenuItem *item, Impl
*pThis), Impl *pThis)
+ {
+ GtkWidget *item;
+ if (icon) {
+ if (label) {
+ item =
gtk_image_menu_item_new_with_mnemonic (label);
+ GtkWidget *image;
+ if (*icon == 'g')
+ image =
gtk_image_new_from_stock (icon, GTK_ICON_SIZE_MENU);
+ else {
+ std::string filename =
std::string (DATADIR) + "/" + icon;
+ image =
gtk_image_new_from_file (filename.c_str());
+ }
+ gtk_image_menu_item_set_image
(GTK_IMAGE_MENU_ITEM (item), image);
+ }
+ else
+ item =
gtk_image_menu_item_new_from_stock (icon, NULL);
+ }
+ else
+ item = gtk_menu_item_new_with_mnemonic
(label);
+ if (tooltip)
+ gtk_widget_set_tooltip_markup (item,
tooltip);
+ if (!sensitive)
+ gtk_widget_set_sensitive (item, FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu),
item);
+ g_signal_connect (G_OBJECT (item), "activate",
G_CALLBACK (callback), pThis);
+ }
+ static void install_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().install(); }
+ static void remove_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().remove(); }
+ static void undo_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().undo(); }
+ static void lock_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().lock (true); }
+ static void unlock_cb (GtkMenuItem *item, Impl *pThis)
+ { pThis->getSelected().lock (false); }
+ static void select_all_cb (GtkMenuItem *item, Impl
*pThis)
+ { pThis->selectAll(); }
+ };
+
+ Ypp::PkgList packages = getSelected();
+ bool empty = true, canLock = packages.canLock(), unlocked =
packages.unlocked();
+ bool locked = !unlocked && canLock;
+ if (packages.notInstalled())
+ inner::appendItem (menu, _("_Install"), 0,
GTK_STOCK_SAVE,
+ !locked, inner::install_cb, this),
empty = false;
+ if (packages.upgradable())
+ inner::appendItem (menu, _("_Upgrade"), 0,
GTK_STOCK_GOTO_TOP,
+ !locked, inner::install_cb, this),
empty = false;
+ if (packages.installed())
+ inner::appendItem (menu, _("_Remove"), 0,
GTK_STOCK_DELETE,
+ !locked, inner::remove_cb, this),
empty = false;
+ if (packages.modified())
+ inner::appendItem (menu, _("_Undo"), 0, GTK_STOCK_UNDO,
+ true, inner::undo_cb, this), empty =
false;
+ if (canLock) {
+ static const char *lock_tooltip =
+ "<b>Package lock:</b> prevents the package
status from being modified by "
+ "the solver (that is, it won't honour
dependencies or collections ties.)";
+ if (packages.locked())
+ inner::appendItem (menu, _("_Unlock"),
_(lock_tooltip), "pkg-unlocked.png",
+ true, inner::unlock_cb,
this), empty = false;
+ if (unlocked)
+ inner::appendItem (menu, _("_Lock"),
_(lock_tooltip), "pkg-locked.png",
+ true, inner::lock_cb, this),
empty = false;
+ }
+ if (!empty)
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu),
gtk_separator_menu_item_new());
+ inner::appendItem (menu, 0, 0, GTK_STOCK_SELECT_ALL,
+ true, inner::select_all_cb, this);
+
+ gtk_menu_attach_to_widget (GTK_MENU (menu), m_view, NULL);
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
button, event_time);
+ gtk_widget_show_all (menu);
+ }
+
+ // callbacks
+ static gboolean set_model_cb (gpointer data)
+ {
+ Impl *pThis = (Impl *) data;
+ GtkTreeView *view = GTK_TREE_VIEW (pThis->m_view);
+ if (gtk_tree_view_get_model (view) == pThis->m_model)
+ gtk_tree_view_set_model (view, NULL);
+ gtk_tree_view_set_model (view, pThis->m_model);
+ pThis->m_modelId = 0;
+ return FALSE;
+ }
+
+ static void packages_selected_cb (GtkTreeSelection *selection, Impl
*pThis)
+ { if (GTK_WIDGET_REALIZED (pThis->m_view)) pThis->signalSelected(); }
+
+ static void popup_menu_cb (YGtkTreeView *view, gboolean outreach, Impl
*pThis)
+ { if (!outreach) pThis->signalPopup(3, gtk_get_current_event_time()); }
+
+ static gboolean can_select_row_cb (GtkTreeSelection *selection,
GtkTreeModel *model,
+ GtkTreePath *path, gboolean path_currently_selected, gpointer
data)
+ {
+ void *package;
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, ZyppModel::PTR_COLUMN,
&package, -1);
+ return package != NULL;
+ }
+
+ static void apply (Ypp::Package *package, int col)
+ {
+ if (package->toModify())
+ package->undo();
+ else switch (col) {
+ case ZyppModel::TO_INSTALL_COLUMN:
+ case ZyppModel::TO_UPGRADE_COLUMN:
+ package->install (0);
+ break;
+ case ZyppModel::NOT_TO_REMOVE_COLUMN:
+ package->remove();
+ break;
+ default: break;
+ }
+ }
+
+ static gboolean apply_iter_cb (GtkTreeModel *model,
+ GtkTreePath *path, GtkTreeIter *iter, gpointer col)
+ {
+ Ypp::Package *package;
+ gtk_tree_model_get (model, iter, ZyppModel::PTR_COLUMN,
&package, -1);
+ if (package)
+ apply (package, GPOINTER_TO_INT (col));
+ return FALSE;
+ }
+
+ static void renderer_toggled_cb (GtkCellRendererToggle *renderer, gchar
*path_str,
+ Impl *pThis)
+ {
+ Ypp::Package *package = 0;
+ GtkTreeView *view = GTK_TREE_VIEW (pThis->m_view);
+ GtkTreeModel *model = gtk_tree_view_get_model (view);
+ GtkTreeIter iter;
+ gtk_tree_model_get_iter_from_string (model, &iter, path_str);
+ gtk_tree_model_get (model, &iter, ZyppModel::PTR_COLUMN,
&package, -1);
+
+ //gboolean active = gtk_cell_renderer_toggle_get_active
(renderer);
+ int col = GPOINTER_TO_INT (g_object_get_data (G_OBJECT
(renderer), "col"));
+ if (package)
+ apply (package, col);
+ else {
+ if (!gtk_tree_model_iter_next (model, &iter)) { // on
apply-all
+ Ypp::get()->startTransactions();
+ gtk_tree_model_foreach (model, apply_iter_cb,
GINT_TO_POINTER (col));
+ Ypp::get()->finishTransactions();
+ }
+ }
+ }
+
+ static void package_activated_cb (GtkTreeView *view, GtkTreePath *path,
+ GtkTreeViewColumn *column, Impl
*pThis)
+ {
+ Ypp::PkgList packages = pThis->getSelected();
+ if (packages.notInstalled() || packages.upgradable())
+ packages.install();
+ }
+
+ static gboolean query_tooltip_cb (GtkWidget *widget, gint x, gint y,
+ gboolean keyboard_mode, GtkTooltip *tooltip, Impl *pThis)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (widget);
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ if (gtk_tree_view_get_tooltip_context (view,
+ &x, &y, keyboard_mode, &model, &path, &iter)) {
+ gtk_tree_view_set_tooltip_row (view, tooltip, path);
+ gtk_tree_path_free (path);
+
+ Ypp::Package *package = 0;
+ gtk_tree_model_get (model, &iter,
ZyppModel::PTR_COLUMN, &package, -1);
+ if (!package) return FALSE;
+
+ std::string text;
+ text.reserve (64);
+ if (!pThis->m_descriptiveTooltip) {
+ GtkTreeViewColumn *column;
+ int bx, by;
+
gtk_tree_view_convert_widget_to_bin_window_coords (
+ view, x, y, &bx, &by);
+ gtk_tree_view_get_path_at_pos (
+ view, x, y, NULL, &column, NULL, NULL);
+ int status_col =
+ gtk_widget_get_default_direction() ==
GTK_TEXT_DIR_RTL ? 1 : 0;
+ if (column == gtk_tree_view_get_column (view,
status_col)) {
+ if (package->toInstall()) {
+ if (package->isInstalled())
+ text = _("To re-install
a different version");
+ else
+ text = _("To install");
+ }
+ else if (package->toRemove())
+ text = _("To remove");
+ else if (package->isInstalled()) {
+ text = _("Installed");
+ if (package->hasUpgrade())
+ text += _(" (upgrade
available)");
+ }
+ else
+ text = _("Not installed");
+ if (package->isAuto())
+ text += _("\n<i>status changed
by the dependency solver</i>");
+ }
+ if (package->isLocked()) {
+ if (!text.empty()) text += "\n";
+ text += _("<i>locked: right-click to
unlock</i>");
+ }
+ }
+ else {
+ text = std::string ("<b>") + package->name() +
"</b>\n";
+ text += package->description (GTK_MARKUP);
+ }
+ if (text.empty())
+ return FALSE;
+ gtk_tooltip_set_markup (tooltip, text.c_str());
+
+ if (pThis->m_descriptiveTooltip) {
+ GdkPixbuf *pixbuf = 0;
+ std::string filename (package->icon());
+ if (!filename.empty())
+ pixbuf = YGUtils::loadPixbuf
(filename.c_str());
+ if (!pixbuf)
+ gtk_tree_model_get (model, &iter,
ZyppModel::ICON_COLUMN, &pixbuf, -1);
+ if (pixbuf) {
+ gtk_tooltip_set_icon (tooltip, pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+ }
+};
+
+PackagesView::PackagesView (bool descriptiveTooltip)
+: impl (new Impl (descriptiveTooltip))
+{}
+
+PackagesView::~PackagesView()
+{ delete impl; }
+
+GtkWidget *PackagesView::getWidget()
+{ return impl->m_scroll; }
+
+void PackagesView::setRows (Ypp::PkgList list, const char *applyAllLabel)
+{ impl->setRows (list, applyAllLabel); }
+
+void PackagesView::appendRows (const char *header, Ypp::PkgList list, const
char *applyAllLabel)
+{ impl->appendRows (header, list, applyAllLabel); }
+
+void PackagesView::clear()
+{ impl->clear(); }
+
+void PackagesView::appendIconColumn (const char *header, int col)
+{ impl->appendIconColumn (header, col); }
+
+void PackagesView::appendCheckColumn (int col)
+{ impl->appendCheckColumn (col); }
+
+void PackagesView::appendTextColumn (const char *header, int col, int size)
+{ impl->appendTextColumn (header, col, size); }
+
+void PackagesView::setFrame (bool show)
+{
+ GtkShadowType shadow = show ? GTK_SHADOW_IN : GTK_SHADOW_NONE;
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW
(impl->m_scroll), shadow);
+}
+
+void PackagesView::setListener (Listener *listener)
+{ impl->m_listener = listener; }
+
+Ypp::PkgList PackagesView::getSelected()
+{ return impl->getSelected(); }
+
+//** Detail & control
+
+class PackageDetails::Impl
+{
+private:
+ struct Versions {
+ GtkWidget *m_box, *m_versions_box, *m_button, *m_undo_button;
+ Ypp::PkgList m_packages; // we keep a copy to test against
modified...
+
+ GtkWidget *getWidget() { return m_box; }
+
+ Versions()
+ {
+ GtkWidget *label = gtk_label_new (_("Versions:"));
+ YGUtils::setWidgetFont (label, PANGO_STYLE_NORMAL,
PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+
+ m_versions_box = gtk_vbox_new (FALSE, 2);
+ m_button = gtk_button_new_with_label ("");
+ g_signal_connect (G_OBJECT (m_button), "clicked",
G_CALLBACK (button_clicked_cb), this);
+ m_undo_button = gtk_button_new_with_label ("");
+ gtk_button_set_image (GTK_BUTTON (m_undo_button),
+ gtk_image_new_from_stock (GTK_STOCK_UNDO,
GTK_ICON_SIZE_BUTTON));
+ g_signal_connect (G_OBJECT (m_undo_button), "clicked",
G_CALLBACK (undo_clicked_cb), this);
+ GtkWidget *button_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (button_box),
gtk_label_new(""), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (button_box), m_button,
FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (button_box),
m_undo_button, FALSE, TRUE, 0);
+
+ m_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (m_box), label, FALSE,
TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), m_versions_box,
TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), button_box, FALSE,
TRUE, 0);
+ }
+
+ void setPackages (Ypp::PkgList packages)
+ {
+ m_packages = packages;
+ m_packages.refreshProps();
+
+ GList *children = gtk_container_get_children
(GTK_CONTAINER (m_versions_box));
+ for (GList *i = children; i; i = i->next)
+ gtk_container_remove (GTK_CONTAINER
(m_versions_box), (GtkWidget *) i->data);
+ g_list_free (children);
+
+ if (packages.size() == 0) {
+ gtk_widget_hide (m_box);
+ return;
+ }
+ gtk_widget_show (m_box);
+ if (packages.size() == 1) {
+ Ypp::Package *package = packages.get (0);
+
+ int children = 0;
+ GtkWidget *radio = 0;
+ const Ypp::Package::Version *version;
+ if ((version = package->getInstalledVersion()))
{
+ std::string _version =
YGUtils::truncate (version->number, 20, 0);
+
+ bool italic = package->toRemove();
+ char *text = g_strdup_printf ("%s%s
<small>(%s)</small>\n%s%s",
+ italic ? "<i>" : "",
+ _version.c_str(),
version->arch.c_str(), _("Installed"),
+ italic ? "</i>" : "");
+ radio = gtk_radio_button_new_with_label
(NULL, text);
+ gtk_label_set_use_markup (GTK_LABEL
(GTK_BIN (radio)->child), TRUE);
+ if (version->number.size() > 20) {
+ char *text = g_strdup_printf
("%s <small>(%s)</small>\n%s",
+
version->number.c_str(), version->arch.c_str(), _("Installed"));
+ gtk_widget_set_tooltip_markup
(radio, text);
+ g_free (text);
+ }
+ gtk_box_pack_start (GTK_BOX
(m_versions_box), radio, FALSE, TRUE, 0);
+ g_free (text);
+ gtk_toggle_button_set_active
(GTK_TOGGLE_BUTTON (radio), TRUE);
+ g_object_set_data (G_OBJECT (radio),
"version", (void *) version);
+ g_signal_connect (G_OBJECT (radio),
"toggled",
+ G_CALLBACK
(version_toggled_cb), this);
+ children++;
+ }
+ bool activeSet = package->toRemove();
+ const Ypp::Package::Version *toInstall = 0;
+ if (!package->toInstall (&toInstall))
+ toInstall = 0;
+ const Ypp::Repository *favoriteRepo =
Ypp::get()->favoriteRepository();
+ for (int i = 0; (version =
package->getAvailableVersion (i)); i++) {
+ std::string _version =
YGUtils::truncate (version->number, 20, 0);
+ std::string repo;
+ if (version->repo)
+ repo = YGUtils::truncate
(version->repo->name, 22, 0);
+
+ bool italic = toInstall == version;
+ char *text = g_strdup_printf ("%s%s
<small>(%s)</small>\n%s%s",
+ italic ? "<i>" : "",
+ _version.c_str(),
version->arch.c_str(), repo.c_str(),
+ italic ? "</i>" : "");
+ radio =
gtk_radio_button_new_with_label_from_widget (
+ GTK_RADIO_BUTTON (radio), text);
+ gtk_label_set_use_markup (GTK_LABEL
(GTK_BIN (radio)->child), TRUE);
+ g_free (text);
+ if (version->number.size() > 20 ||
+ (version->repo &&
version->repo->name.size() > 22)) {
+ char *text = g_strdup_printf
("%s <small>(%s)</small>\n%s",
+
version->number.c_str(), version->arch.c_str(),
+ version->repo ?
version->repo->name.c_str() : "");
+ gtk_widget_set_tooltip_markup
(radio, text);
+ g_free (text);
+ }
+ gtk_box_pack_start (GTK_BOX
(m_versions_box), radio, FALSE, TRUE, 0);
+ if (!activeSet) {
+ if (toInstall == version) {
+
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ activeSet = true;
+ }
+ else if (i == 0)
+
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ else if (version->repo ==
favoriteRepo) {
+
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
+ favoriteRepo = 0; //
select only the 1st hit
+ }
+ }
+ g_object_set_data (G_OBJECT (radio),
"version", (void *) version);
+ g_signal_connect (G_OBJECT (radio),
"toggled",
+ G_CALLBACK
(version_toggled_cb), this);
+ if ((children % 2) == 1)
+ g_signal_connect (G_OBJECT
(radio), "expose-event", G_CALLBACK (draw_gray_cb), this);
+ children++;
+ }
+ gtk_widget_show_all (m_versions_box);
+ }
+
+ // is locked
+ if (packages.locked() || packages.unlocked())
+ gtk_widget_set_sensitive (m_button,
!packages.locked());
+ else
+ gtk_widget_set_sensitive (m_button, TRUE);
+ syncButton();
+ }
+
+ private:
+ static gboolean draw_gray_cb (GtkWidget *widget, GdkEventExpose
*event, Versions *pThis)
+ {
+ GtkAllocation *alloc = &widget->allocation;
+ int x = alloc->x, y = alloc->y, w = alloc->width, h =
alloc->height;
+
+ cairo_t *cr = gdk_cairo_create (widget->window);
+ cairo_rectangle (cr, x, y, w, h);
+ cairo_set_source_rgb (cr, 245/255.0, 245/255.0,
245/255.0);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ return FALSE;
+ }
+
+ const Ypp::Package::Version *getVersion()
+ {
+ GtkWidget *radio = 0;
+ GList *children = gtk_container_get_children
(GTK_CONTAINER (m_versions_box));
+ for (GList *i = children; i; i = i->next)
+ if (gtk_toggle_button_get_active
(GTK_TOGGLE_BUTTON (i->data))) {
+ radio = (GtkWidget *) i->data;
+ break;
+ }
+ g_list_free (children);
+ if (radio)
+ return (Ypp::Package::Version *)
g_object_get_data (G_OBJECT (radio), "version");
+ return NULL;
+ }
+
+ void syncButton()
+ {
+ gtk_widget_hide (m_undo_button);
+ const char *label = 0, *stock = 0;
+ if (m_packages.size() == 1) {
+ Ypp::Package *package = m_packages.get (0);
+ const Ypp::Package::Version *version =
getVersion();
+ const Ypp::Package::Version *installed =
package->getInstalledVersion();
+ if (installed == version) {
+ label = _("Remove");
+ stock = GTK_STOCK_DELETE;
+ if (package->toRemove())
+ gtk_widget_show (m_undo_button);
+ }
+ else {
+ if (installed) {
+ if (version->cmp > 0) {
+ label = _("Upgrade");
+ stock = GTK_STOCK_GO_UP;
+ }
+ else if (version->cmp < 0) {
+ label = _("Downgrade");
+ stock =
GTK_STOCK_GO_DOWN;
+ }
+ else {
+ label = _("Re-install");
+ stock =
GTK_STOCK_REFRESH;
+ }
+ }
+ else {
+ label = _("Install");
+ stock = GTK_STOCK_SAVE;
+ }
+
+ const Ypp::Package::Version *toInstall
= 0;
+ if (!package->toInstall (&toInstall))
+ toInstall = 0;
+ if (toInstall == version)
+ gtk_widget_show (m_undo_button);
+ }
+ }
+ else {
+ if (m_packages.modified())
+ gtk_widget_show (m_undo_button);
+ if (m_packages.upgradable()) {
+ label = _("Upgrade");
+ stock = GTK_STOCK_GO_UP;
+ }
+ else if (m_packages.installed()) {
+ label = _("Remove");
+ stock = GTK_STOCK_DELETE;
+ }
+ else if (m_packages.notInstalled()) {
+ label = _("Install");
+ stock = GTK_STOCK_SAVE;
+ }
+ else if (m_packages.modified()) {
+ label = _("Undo");
+ stock = GTK_STOCK_UNDO;
+ gtk_widget_hide (m_undo_button);
+ }
+ }
+ if (label) {
+ gtk_button_set_label (GTK_BUTTON (m_button),
label);
+ GtkWidget *image = gtk_image_new_from_stock (
+ stock, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (m_button),
image);
+ gtk_widget_show (m_button);
+ }
+ else
+ gtk_widget_hide (m_button);
+ }
+
+ static void version_toggled_cb (GtkToggleButton *radio,
Versions *pThis)
+ { if (gtk_toggle_button_get_active (radio))
pThis->syncButton(); }
+
+ static void button_clicked_cb (GtkButton *button, Versions
*pThis)
+ {
+ if (pThis->m_packages.size() == 1) {
+ Ypp::Package *package = pThis->m_packages.get
(0);
+ const Ypp::Package::Version *version =
pThis->getVersion();
+ const Ypp::Package::Version *installed =
package->getInstalledVersion();
+ if (installed == version)
+ pThis->m_packages.remove();
+ else
+ package->install (version);
+ }
+ else {
+ if (pThis->m_packages.upgradable())
+ pThis->m_packages.install();
+ else if (pThis->m_packages.installed())
+ pThis->m_packages.remove();
+ else if (pThis->m_packages.notInstalled())
+ pThis->m_packages.install();
+ else if (pThis->m_packages.modified())
+ pThis->m_packages.undo();
+ }
+ pThis->setPackages (pThis->m_packages); // refresh
+ }
+
+ static void undo_clicked_cb (GtkButton *button, Versions *pThis)
+ {
+ pThis->m_packages.undo();
+ pThis->setPackages (pThis->m_packages); // refresh
+ }
+
+#if 0
+ void packageModified (Ypp::Package *package)
+ {
+ // GTK+ doesn't fire selection change when a selected
row changes, so we need
+ // to re-load Versions in that occasions.
+ if (m_packages.contains (package)) {
+ m_packages.clearCache();
+ setPackages (m_packages);
+ }
+ }
+#endif
+ };
+
+GtkWidget *m_widget, *m_icon, *m_icon_frame, *m_description, *m_filelist,
*m_changelog,
+ *m_authors, *m_support, *m_requires, *m_provides;
+Versions *m_versions;
+PackagesView *m_contents;
+
+public:
+ GtkWidget *getWidget() { return m_widget; }
+
+ Impl (bool onlineUpdate)
+ {
+ m_versions = new Versions();
+ GtkWidget *vbox;
+ m_widget = createWhiteViewPort (&vbox);
+
+ GtkWidget *versions_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (versions_box),
+ createIconWidget (&m_icon, &m_icon_frame), FALSE, TRUE,
0);
+ gtk_box_pack_start (GTK_BOX (versions_box),
m_versions->getWidget(), FALSE, TRUE, 0);
+
+ m_description = ygtk_rich_text_new();
+ g_signal_connect (G_OBJECT (m_description), "link-clicked",
+ G_CALLBACK (link_pressed_cb), this);
+
+ GtkWidget *description_box = gtk_hbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (description_box), m_description,
TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (description_box), versions_box,
FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), description_box, FALSE,
TRUE, 0);
+
+ if (!onlineUpdate) {
+ m_filelist = ygtk_rich_text_new();
+ m_changelog = ygtk_rich_text_new();
+ m_authors = ygtk_rich_text_new();
+ m_support = ygtk_rich_text_new();
+ m_requires = ygtk_rich_text_new();
+ m_provides = ygtk_rich_text_new();
+ GtkWidget *dependencies_box = gtk_hbox_new (TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (dependencies_box),
m_requires, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (dependencies_box),
m_provides, TRUE, TRUE, 0);
+
+ appendExpander (vbox, _("File List"), m_filelist);
+ appendExpander (vbox, _("Changelog"), m_changelog);
+ appendExpander (vbox, _("Authors"), m_authors);
+ appendExpander (vbox, _("Dependencies"),
dependencies_box);
+ appendExpander (vbox, _(""), m_support);
+ m_contents = NULL;
+ if (CAN_OPEN_URIS())
+ g_signal_connect (G_OBJECT (m_filelist),
"link-clicked",
+ G_CALLBACK
(link_pressed_cb), this);
+ }
+ else {
+ m_filelist = m_changelog = m_authors = m_support =
m_requires = m_provides = NULL;
+ m_contents = new PackagesView (false);
+ m_contents->appendTextColumn (_("Name"),
ZyppModel::NAME_COLUMN, 150);
+ m_contents->appendTextColumn (_("Summary"),
ZyppModel::SUMMARY_COLUMN);
+ appendExpander (vbox, _("Applies to"),
m_contents->getWidget());
+ }
+ gtk_widget_show_all (vbox);
+ }
+
+ ~Impl()
+ {
+ delete m_contents;
+ delete m_versions;
+ }
+
+ void setPackages (Ypp::PkgList packages)
+ {
+ gtk_widget_hide (m_icon_frame);
+ if (packages.size() == 1) {
+ Ypp::Package *package = packages.get (0);
+ std::string description = "<b>" + package->name() +
"</b><br>";
+ description += package->description (HTML_MARKUP);
+ setText (m_description, description);
+ if (m_filelist) setText (m_filelist, package->filelist
(true));
+ if (m_changelog) setText (m_changelog,
package->changelog());
+ if (m_authors) setText (m_authors, package->authors
(true));
+ if (m_support) {
+ GtkWidget *expander = gtk_widget_get_ancestor
(m_support, GTK_TYPE_EXPANDER);
+ std::string label ("<b>" + std::string
(_("Support:")) + "</b> ");
+ label += package->support();
+ gtk_expander_set_label (GTK_EXPANDER
(expander), label.c_str());
+ setText (m_support, package->supportText
(true));
+ }
+ if (m_requires && m_provides) {
+ std::string requires_str = _("Requires:");
+ std::string provides_str = _("Provides:");
+ requires_str += "<br><blockquote>";
+ requires_str += package->requires (true);
+ YGUtils::replace (provides_str, "\n", 1,
"<br>");
+ requires_str += "</blockquote>";
+ provides_str += "<br><blockquote>";
+ provides_str += package->provides (true);
+ YGUtils::replace (requires_str, "\n", 1,
"<br>");
+ provides_str += "</blockquote>";
+ setText (m_requires, requires_str);
+ setText (m_provides, provides_str);
+ }
+
+ if (m_contents) { // patches -- "apply to"
+ Ypp::PkgQuery::Query *query = new
Ypp::PkgQuery::Query();
+ query->addCollection (package);
+ m_contents->clear();
+ m_contents->appendRows (0, Ypp::PkgQuery
(Ypp::Package::PACKAGE_TYPE, query), 0);
+ }
+
+ gtk_image_clear (GTK_IMAGE (m_icon));
+ GtkIconTheme *icons = gtk_icon_theme_get_default();
+ GdkPixbuf *pixbuf = gtk_icon_theme_load_icon (icons,
+ package->name().c_str(), 32, GtkIconLookupFlags
(0), NULL);
+ if (pixbuf) {
+ gtk_image_set_from_pixbuf (GTK_IMAGE (m_icon),
pixbuf);
+ g_object_unref (G_OBJECT (pixbuf));
+ gtk_widget_show (m_icon_frame);
+ }
+ }
+ else {
+ std::string description;
+ if (packages.size() > 0) {
+ description = "Selected:";
+ description += "<ul>";
+ for (int i = 0; packages.get (i); i++)
+ description += "<li>" + packages.get
(i)->name() + "</li>";
+ description += "</ul>";
+ }
+ setText (m_description, description);
+ if (m_filelist) setText (m_filelist, "");
+ if (m_changelog) setText (m_changelog, "");
+ if (m_authors) setText (m_authors, "");
+ if (m_support) setText (m_support, "");
+ if (m_requires) setText (m_requires, "");
+ if (m_provides) setText (m_provides, "");
+ if (m_contents) {
+ gtk_widget_hide (gtk_widget_get_ancestor
(m_contents->getWidget(), GTK_TYPE_EXPANDER));
+ m_contents->clear();
+ }
+ }
+
+ m_versions->setPackages (packages);
+ scrollTop();
+ }
+
+ void setPackage (Ypp::Package *package)
+ {
+ Ypp::PkgList packages;
+ packages.append (package);
+ setPackages (packages);
+ }
+
+private:
+ void scrollTop()
+ {
+ GtkScrolledWindow *scroll = GTK_SCROLLED_WINDOW (m_widget);
+ YGUtils::scrollWidget (gtk_scrolled_window_get_vadjustment
(scroll), true);
+ }
+
+ // utilities:
+ static GtkWidget *createIconWidget (GtkWidget **icon_widget, GtkWidget
**icon_frame)
+ {
+ *icon_widget = gtk_image_new();
+
+ GtkWidget *box, *align, *frame;
+ box = gtk_event_box_new();
+ gtk_container_add (GTK_CONTAINER (box), *icon_widget);
+ gtk_container_set_border_width (GTK_CONTAINER (box), 2);
+
+ frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (frame), box);
+
+ align = gtk_alignment_new (0, 0, 0, 0);
+ gtk_container_add (GTK_CONTAINER (align), frame);
+ gtk_container_set_border_width (GTK_CONTAINER (align), 6);
+ *icon_frame = align;
+ return align;
+ }
+ static GtkWidget *createWhiteViewPort (GtkWidget **vbox)
+ {
+ struct inner {
+ static gboolean expose_cb (GtkWidget *widget,
GdkEventExpose *event)
+ {
+ cairo_t *cr = gdk_cairo_create (widget->window);
+ GdkColor color = { 0, 255 << 8, 255 << 8, 255
<< 8 };
+ gdk_cairo_set_source_color (cr, &color);
+ cairo_rectangle (cr, event->area.x,
event->area.y,
+ event->area.width,
event->area.height);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ return FALSE;
+ }
+ };
+
+ *vbox = gtk_vbox_new (FALSE, 0);
+ g_signal_connect (G_OBJECT (*vbox), "expose-event",
+ G_CALLBACK (inner::expose_cb), NULL);
+
+ GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW
(scroll), *vbox);
+ return scroll;
+ }
+ static void appendExpander (GtkWidget *box, const char *label,
GtkWidget *child)
+ {
+ std::string str = std::string ("<b>") + label + "</b>";
+ GtkWidget *expander = gtk_expander_new (str.c_str());
+ gtk_expander_set_use_markup (GTK_EXPANDER (expander), TRUE);
+ gtk_container_add (GTK_CONTAINER (expander), child);
+ gtk_box_pack_start (GTK_BOX (box), expander, FALSE, TRUE, 0);
+ }
+ static void setText (GtkWidget *text, const std::string &str)
+ {
+ ygtk_rich_text_set_text (YGTK_RICH_TEXT (text), str.c_str(),
FALSE);
+ GtkWidget *expander = gtk_widget_get_ancestor (text,
GTK_TYPE_EXPANDER);
+ if (expander)
+ str.empty() ? gtk_widget_hide (expander) :
gtk_widget_show (expander);
+ }
+
+ // callbacks
+ static void link_pressed_cb (GtkWidget *text, const gchar *link, Impl
*pThis)
+ {
+ if (!strncmp (link, "pkg://", 6)) {
+ const gchar *pkg_name = link + 6;
+ Ypp::Package *pkg = Ypp::get()->getPackages
(Ypp::Package::PACKAGE_TYPE).find (pkg_name);
+ if (pkg)
+ pThis->setPackage (pkg);
+ else {
+ GtkWidget *dialog = gtk_message_dialog_new
(YGDialog::currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK, _("Package '%s' was not
found."), pkg_name);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
+ }
+ else
+ OPEN_URI (link);
+ }
+};
+
+PackageDetails::PackageDetails (bool onlineUpdate)
+: impl (new Impl (onlineUpdate))
+{}
+
+PackageDetails::~PackageDetails()
+{ delete impl; }
+
+GtkWidget *PackageDetails::getWidget()
+{ return impl->getWidget(); }
+
+void PackageDetails::setPackages (Ypp::PkgList packages)
+{ impl->setPackages (packages); }
+
+void PackageDetails::setPackage (Ypp::Package *package)
+{ impl->setPackage (package); }
+

Added: trunk/gtk/src/ygtkzyppview.h
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkzyppview.h?rev=58481&view=auto
==============================================================================
--- trunk/gtk/src/ygtkzyppview.h (added)
+++ trunk/gtk/src/ygtkzyppview.h Thu Sep 3 03:35:38 2009
@@ -0,0 +1,79 @@
+/********************************************************************
+ * YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
+ ********************************************************************/
+
+/* A view for Zypp wrapper query results.
+*/
+
+#ifndef YGTK_ZYPP_WRAPPER_H
+#define YGTK_ZYPP_WRAPPER_H
+
+#include "yzyppwrapper.h"
+
+namespace ZyppModel {
+ enum Columns {
+ // pixbuf
+ ICON_COLUMN,
+ // text
+ NAME_COLUMN, SUMMARY_COLUMN, NAME_SUMMARY_COLUMN,
REPOSITORY_COLUMN, SUPPORT_COLUMN,
+ INSTALLED_VERSION_COLUMN, AVAILABLE_VERSION_COLUMN,
+ // checks
+ TO_INSTALL_COLUMN, TO_UPGRADE_COLUMN, NOT_TO_REMOVE_COLUMN,
TO_MODIFY_COLUMN,
+ // internal
+ STYLE_COLUMN, WEIGHT_COLUMN, SENSITIVE_COLUMN,
CHECK_VISIBLE_COLUMN,
+ FOREGROUND_COLUMN, BACKGROUND_COLUMN,
+ // misc
+ PTR_COLUMN, TOTAL_COLUMNS
+ };
+};
+
+GtkTreeModel *ygtk_zypp_model_new();
+void ygtk_zypp_model_append (GtkTreeModel *model,
+ const char *header, Ypp::PkgList list, const char *applyAllLabel);
+
+struct PackagesView
+{
+ PackagesView (bool descriptiveTooltip);
+ ~PackagesView();
+ GtkWidget *getWidget();
+
+ void setRows (Ypp::PkgList list, const char *applyAllLabel); // tiny
bit optimized
+ // pack multiple lists:
+ void appendRows (const char *header, Ypp::PkgList list, const char
*applyAllLabel);
+ void clear();
+
+ void appendCheckColumn (int col);
+ void appendIconColumn (const char *header, int col);
+ void appendTextColumn (const char *header, int col, int size = -1);
+ // (set all column headers to NULL in order to hide them.)
+
+ void setFrame (bool show);
+
+ struct Listener {
+ virtual void packagesSelected (Ypp::PkgList packages) = 0;
+ };
+ void setListener (Listener *listener);
+ Ypp::PkgList getSelected();
+
+ struct Impl;
+ Impl *impl;
+};
+
+struct PackageDetails
+{
+ PackageDetails (bool onlineUpdate);
+ ~PackageDetails();
+ GtkWidget *getWidget();
+
+ void setPackages (Ypp::PkgList packages);
+ void setPackage (Ypp::Package *package); // convenience
+
+ struct Impl;
+ Impl *impl;
+};
+
+// calls Ypp::finish() for cleaning, and it cleans our stuff as well
+void ygtk_zypp_finish (void);
+
+#endif /*YGTK_ZYPP_WRAPPER_H*/
+

Modified: trunk/gtk/src/yzyppwrapper.cc
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/yzyppwrapper.cc?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/yzyppwrapper.cc (original)
+++ trunk/gtk/src/yzyppwrapper.cc Thu Sep 3 03:35:38 2009
@@ -15,6 +15,8 @@
#include "yzypptags.h"
#include <string.h>
#include <string>
+#include <algorithm>
+#include <vector>
#include <sstream>
#define YUILogComponent "gtk-pkg"
#include <YUILog.h>
@@ -201,7 +203,7 @@
friend class Ypp;
PkgList *packages [Package::TOTAL_TYPES]; // primitive pools
StringTree *categories [Package::TOTAL_TYPES], *categories2;
- GSList *repos;
+ std::vector <Repository *> repos;
const Repository *favoriteRepo;
int favoriteRepoPriority;
Disk *disk;
@@ -918,14 +920,10 @@
}

virtual bool toRemove()
- {
- return m_sel->toDelete();
- }
+ { return m_sel->toDelete(); }

virtual bool toModify()
- {
- return m_sel->toModify();
- }
+ { return m_sel->toModify(); }

virtual bool isAuto()
{
@@ -1294,43 +1292,38 @@
Ypp::PkgList *Ypp::Impl::getPackages (Ypp::Package::Type type)
{
if (!packages[type]) {
+ interface->loading (0);
+
PkgList *list = new PkgList();
struct inner {
- static gint compare (gconstpointer _a, gconstpointer _b)
+ // slower -- don't use for packages -- only for
languages
+ static bool utf8_order (const Package *a, const Package
*b)
+ { return g_utf8_collate (a->name().c_str(),
b->name().c_str()) < 0; }
+ static bool pattern_order (const Package *a, const
Package *b)
{
- Package *a = (Package *) _a;
- Package *b = (Package *) _b;
- return strcasecmp (a->name().c_str(),
b->name().c_str());
- }
- static gint compare_utf8 (gconstpointer _a,
gconstpointer _b)
- { // slower -- don't use for packages -- only for
patterns and languages
- Package *a = (Package *) _a;
- Package *b = (Package *) _b;
- return g_utf8_collate (a->name().c_str(),
b->name().c_str());
- }
- static gint compare_pattern (gconstpointer a,
gconstpointer b)
- {
- ZyppPattern pattern1 = tryCastToZyppPattern
(((PackageSel *) ((Package *) a)->impl)->m_sel->theObj());
- ZyppPattern pattern2 = tryCastToZyppPattern
(((PackageSel *) ((Package *) b)->impl)->m_sel->theObj());
- return strcmp (pattern1->order().c_str(),
pattern2->order().c_str());
+ ZyppPattern pattern1 = tryCastToZyppPattern
(((PackageSel *) a->impl)->m_sel->theObj());
+ ZyppPattern pattern2 = tryCastToZyppPattern
(((PackageSel *) b->impl)->m_sel->theObj());
+ return strcmp (pattern1->order().c_str(),
pattern2->order().c_str()) < 0;
}
};

if (type == Package::LANGUAGE_TYPE) {
zypp::LocaleSet locales =
zypp::getZYpp()->pool().getAvailableLocales();
+ list->reserve (locales.size());
for (zypp::LocaleSet::const_iterator it =
locales.begin();
it != locales.end(); it++) {
Package *package = new Package (new PackageLang
(type, *it));
- list->prepend (package);
+ list->append (package);
}
}
else { // Pool Selectables
ZyppPool::const_iterator it, end;
+ int size = 0;
switch (type) {
case Package::PACKAGE_TYPE:
it = zyppPool().byKindBegin
<zypp::Package>();
end = zyppPool().byKindEnd
<zypp::Package>();
-
+ size =
zyppPool().size(zypp::ResKind::package);
// for the categories
bindtextdomain ("rpm-groups",
LOCALEDIR);
bind_textdomain_codeset ("rpm-groups",
"utf8");
@@ -1338,14 +1331,18 @@
case Package::PATTERN_TYPE:
it = zyppPool().byKindBegin
<zypp::Pattern>();
end = zyppPool().byKindEnd
<zypp::Pattern>();
+ size =
zyppPool().size(zypp::ResKind::pattern);
break;
case Package::PATCH_TYPE:
it = zyppPool().byKindBegin
<zypp::Patch>();
end = zyppPool().byKindEnd
<zypp::Patch>();
+ size =
zyppPool().size(zypp::ResKind::patch);
break;
default:
break;
}
+ list->reserve (size);
+
for (; it != end; it++) {
Ypp::Node *category = 0, *category2 = 0;
ZyppSelectable sel = *it;
@@ -1393,19 +1390,24 @@
}

Package *package = new Package (new PackageSel
(type, sel, category, category2));
- list->prepend (package);
+ list->append (package);
+
+ int i = list->size();
+ if ((i % 500) == 0)
+ interface->loading (i / (float) size);
}
}
- list->reverse(); // lets reverse before sorting, as they are
somewhat sorted already
// a sort merge. Don't use g_slist_insert_sorted() -- its linear
if (type == Ypp::Package::PATTERN_TYPE)
- list->sort (inner::compare_pattern);
+ list->sort (inner::pattern_order);
else if (type == Ypp::Package::LANGUAGE_TYPE)
- list->sort (inner::compare_utf8);
+
+ list->sort (inner::utf8_order);
else
- list->sort (inner::compare);
+ list->sort();
packages[type] = list;
polishCategories (type);
+ interface->loading (1);
}
return packages[type];
}
@@ -1415,7 +1417,7 @@
struct Ypp::PkgList::Impl : public Ypp::PkgListener
{
PkgList::Listener *listener;
-GSList *list;
+std::vector <Ypp::Package *> pool;
guint inited : 2, _allInstalled : 2, _allNotInstalled : 2, _allUpgradable : 2,
_allModified : 2, _allLocked : 2, _allUnlocked : 2, _allCanLock : 2;
int refcount;
@@ -1426,7 +1428,7 @@
{ return (_id + 'a' > 'z') ? (_id - ('z'-'a') + '0') : (_id + 'a'); }

Impl() : PkgListener()
- , listener (NULL), list (NULL), inited (false), refcount (1)
+ , listener (NULL), inited (false), refcount (1)
{
static int _idTotal = 0;
_id = _idTotal++;
@@ -1435,16 +1437,23 @@

~Impl()
{
- Ypp::get()->removePkgListener (this);
- g_slist_free (list);
- }
+Ypp::get()->removePkgListener (this); }

// implementations
- Iter find (const Package *package) const
- { return (Iter) g_slist_find (list, (gconstpointer) package); }
+ int find (const Package *package) const
+ {
+ for (unsigned int i = 0; i < pool.size(); i++)
+ if (pool[i] == package)
+ return i;
+ return -1;
+ }

- void setListener (Ypp::PkgList::Listener *listener) const
- { const_cast <Impl *> (this)->listener = listener; }
+ void remove (int i)
+ {
+ std::vector <Package *>::iterator it = pool.begin();
+ it += i;
+ pool.erase (it);
+ }

void buildProps() const
{ if (!inited) const_cast <Impl *> (this)->_buildProps(); }
@@ -1452,19 +1461,18 @@
void _buildProps()
{
inited = true;
- if (list) {
+ if (!pool.empty()) {
_allInstalled = _allNotInstalled = _allUpgradable =
_allModified =
_allLocked = _allUnlocked = _allCanLock = true;
- for (GSList *i = list; i; i = i->next) {
- Package *pkg = (Package *) i->data;
+ for (unsigned int i = 0; i < pool.size(); i++) {
+ Package *pkg = pool[i];
if (!pkg->isInstalled()) {
_allInstalled = false;
_allUpgradable = false;
}
else {
_allNotInstalled = false;
- const Ypp::Package::Version *version =
pkg->getAvailableVersion(0);
- if (!version || version->cmp <= 0)
+ if (!pkg->hasUpgrade())
_allUpgradable = false;
}
if (pkg->toModify()) {
@@ -1492,63 +1500,56 @@
bool live = liveList();
if (!live && !listener)
return;
+
+ PkgList list (this);
+ refcount++;
bool match = this->match (package);
- Iter iter = find (package);
+ int index = find (package);
+
if (live) {
-fprintf (stderr, "match package: %s - matched? %d - found? %d\n",
package->name().c_str(), match, iter != 0);
- if (iter) { // is on the pool
+ if (index >= 0) { // is on the pool
if (match) { // modified
if (listener)
- listener->entryChanged (iter,
package);
+ listener->entryChanged (list,
index, package);
}
else { // removed
-fprintf (stderr, "\tremove!\n");
if (listener)
- listener->entryDeleted (iter,
package);
- list = g_slist_delete_link (list,
(GSList *) iter);
+ listener->entryDeleted (list,
index, package);
+ remove (index);
}
}
else { // not on pool
if (match) { // inserted
- list = g_slist_append (list, (gpointer)
package);
- iter = (Iter) g_slist_last (list);
+ pool.push_back (package);
if (listener)
- listener->entryInserted (iter,
package);
+ listener->entryInserted (list,
pool.size()-1, package);
}
}
}
- else if (iter)
- listener->entryChanged (iter, package);
+ else if (index >= 0)
+ listener->entryChanged (list, index, package);
}

// for sub-classes to implement live lists
virtual bool liveList() const { return false; }
virtual bool match (Package *pkg) const { return true; }
- virtual bool highlight (Iter it) const { return false; }
+ virtual bool highlight (int index) const { return false; }
};

Ypp::PkgList::PkgList()
: impl (new Impl())
-{
-fprintf (stderr, "create blank PkgList: %c\n", impl->getId());
-}
+{}

Ypp::PkgList::PkgList (Ypp::PkgList::Impl *impl) // sub-class
: impl (impl)
-{
-fprintf (stderr, "create PkgList sub-class: %c\n", impl->getId());
-}
+{}

Ypp::PkgList::PkgList (const Ypp::PkgList &other)
: impl (other.impl)
-{ impl->refcount++;
-fprintf (stderr, "ref PkgList %c: %d\n", impl->getId(), impl->refcount);
-}
+{ impl->refcount++; }

Ypp::PkgList & Ypp::PkgList::operator = (const Ypp::PkgList &other)
{
-fprintf (stderr, "set %c PkgList = %c: %d\n", impl->getId(),
other.impl->getId(), other.impl->refcount+1);
-fprintf (stderr, "\tunref PkgList %c: %d%s\n", impl->getId(),
impl->refcount-1, impl->refcount-1<=0 ? " -- free!" : "");
if (--impl->refcount <= 0) delete impl;
impl = other.impl;
impl->refcount++;
@@ -1556,82 +1557,79 @@
}

Ypp::PkgList::~PkgList()
-{
-fprintf (stderr, "\t~PkgList %c: %d%s\n", impl->getId(), impl->refcount-1,
impl->refcount-1<=0 ? " -- free!" : "");
-if (--impl->refcount <= 0) delete impl;
-}
+{ if (--impl->refcount <= 0) delete impl; }

-Ypp::PkgList::Iter Ypp::PkgList::first() const
-{ if (!this) return 0; return (Ypp::PkgList::Iter) impl->list; }
+Ypp::Package *Ypp::PkgList::get (int i) const
+{ return i >= (signed) impl->pool.size() ? NULL : impl->pool.at (i); }

-Ypp::PkgList::Iter Ypp::PkgList::next (Ypp::PkgList::Iter it) const
-{ return (Ypp::PkgList::Iter) ((GSList *) it)->next; }
-
-Ypp::Package *Ypp::PkgList::get (Ypp::PkgList::Iter it) const
-{ return (Ypp::Package *) ((GSList *) it)->data; }
-
-bool Ypp::PkgList::highlight (Ypp::PkgList::Iter it) const
-{ return impl->highlight (it); }
-
-bool Ypp::PkgList::empty() const
-{ return !first(); }
-
-bool Ypp::PkgList::single() const
-{
- if (first())
- if (!next (first()))
- return true;
- return false;
-}
+bool Ypp::PkgList::highlight (int i) const
+{ return impl->highlight (i); }

int Ypp::PkgList::size() const
-{
- int size = 0;
- for (Iter iter = first(); iter; iter = next (iter)) size++;
- return size;
-}
+{ return impl->pool.size(); }

-void Ypp::PkgList::prepend (Ypp::Package *package)
-{ impl->list = g_slist_prepend (impl->list, package); }
+void Ypp::PkgList::reserve (int size)
+{ impl->pool.reserve (size); }

void Ypp::PkgList::append (Ypp::Package *package)
-{ impl->list = g_slist_append (impl->list, package); }
+{ impl->pool.push_back (package); }

-void Ypp::PkgList::reverse()
-{ impl->list = g_slist_reverse (impl->list); }
+static bool pkgorder (const Ypp::Package *a, const Ypp::Package *b)
+{ return strcasecmp (a->name().c_str(), b->name().c_str()) < 0; }

-void Ypp::PkgList::sort (int (* compare) (const void *, const void *))
-{ impl->list = g_slist_sort (impl->list, compare); }
+void Ypp::PkgList::sort (bool (* compare) (const Package *, const Package *))
+{
+ std::sort (impl->pool.begin(), impl->pool.end(), compare ? compare :
pkgorder);
+}

-void Ypp::PkgList::remove (Ypp::PkgList::Iter it)
-{ impl->list = g_slist_delete_link (impl->list, (GSList *) it); }
+void Ypp::PkgList::remove (int i)
+{ impl->remove (i); }

void Ypp::PkgList::copy (const Ypp::PkgList list)
{
- for (Iter it = list.first(); it; it = list.next (it)) {
- Package *pkg = list.get (it);
+ bool showProgress = false;
+ GTimeVal then;
+ g_get_current_time (&then);
+
+ for (int i = 0; i < list.size(); i++) {
+ Package *pkg = list.get (i);
if (impl->match (pkg))
- prepend (pkg);
+ append (pkg);
+
+ if (showProgress) {
+ if ((i % 500) == 0)
+ ypp->impl->interface->loading (i / (float)
list.size());
+ }
+ else if (i == 499) { // show progress if it takes more than 1
sec to drive 'N' loops
+ GTimeVal now;
+ g_get_current_time (&now);
+ if (now.tv_usec - then.tv_usec >= 50*1000 || now.tv_sec
- then.tv_sec >= 1) {
+ showProgress = true;
+ ypp->impl->interface->loading (0);
+ }
+ }
}
- reverse();
+ if (showProgress)
+ ypp->impl->interface->loading (1);
}

bool Ypp::PkgList::contains (const Ypp::Package *package) const
-{ return find (package); }
+{ return find (package) != -1; }

-Ypp::PkgList::Iter Ypp::PkgList::find (const Ypp::Package *package) const
+int Ypp::PkgList::find (const Ypp::Package *package) const
{ return impl->find (package); }

Ypp::Package *Ypp::PkgList::find (const std::string &name) const
{
- for (Iter it = first(); it; it = next (it)) {
- Ypp::Package *pkg = get (it);
- if (name == pkg->name())
- return pkg;
- }
+ for (int i = 0; i < size(); i++)
+ if (name == get (i)->name())
+ return get (i);
return NULL;
}

+bool Ypp::PkgList::operator == (const Ypp::PkgList &other) const
+{ return this->impl == other.impl; }
+
bool Ypp::PkgList::installed() const
{ impl->buildProps(); return impl->_allInstalled; }

@@ -1659,37 +1657,37 @@
void Ypp::PkgList::install()
{
Ypp::get()->startTransactions();
- for (Iter it = first(); it; it = next (it))
- get (it)->install (0);
+ for (int i = 0; get (i); i++)
+ get (i)->install (0);
Ypp::get()->finishTransactions();
}

void Ypp::PkgList::remove()
{
Ypp::get()->startTransactions();
- for (Iter it = first(); it; it = next (it))
- get (it)->remove();
+ for (int i = 0; get (i); i++)
+ get (i)->remove();
Ypp::get()->finishTransactions();
}

void Ypp::PkgList::lock (bool toLock)
{
Ypp::get()->startTransactions();
- for (Iter it = first(); it; it = next (it))
- get (it)->lock (toLock);
+ for (int i = 0; get (i); i++)
+ get (i)->lock (toLock);
Ypp::get()->finishTransactions();
}

void Ypp::PkgList::undo()
{
Ypp::get()->startTransactions();
- for (Iter it = first(); it; it = next (it))
- get (it)->undo();
+ for (int i = 0; get (i); i++)
+ get (i)->undo();
Ypp::get()->finishTransactions();
}

-void Ypp::PkgList::setListener (Ypp::PkgList::Listener *listener) const
-{ impl->setListener (listener); }
+void Ypp::PkgList::setListener (Ypp::PkgList::Listener *listener)
+{ impl->listener = listener; }

//** Query

@@ -1743,9 +1741,8 @@
Keys <const Repository *> repositories;
Key <bool> isInstalled;
Key <bool> hasUpgrade;
- Key <bool> toModify;
- Key <bool> isRecommended;
- Key <bool> isSuggested;
+ Key <bool> toModify, toInstall, toRemove;
+ Key <bool> isRecommended, isSuggested;
Key <int> buildAge;
Key <bool> isUnsupported;
bool clear;
@@ -1794,6 +1791,10 @@
}
if (match && toModify.defined)
match = toModify.is (package->toModify());
+ if (match && toInstall.defined)
+ match = toInstall.is (package->toInstall());
+ if (match && toRemove.defined)
+ match = toRemove.is (package->toRemove());
if (match && isRecommended.defined)
match = isRecommended.is (package->isRecommended());
if (match && isSuggested.defined)
@@ -1932,6 +1933,10 @@
{ impl->hasUpgrade.set (value); }
void Ypp::PkgQuery::Query::setToModify (bool value)
{ impl->toModify.set (value); }
+void Ypp::PkgQuery::Query::setToInstall (bool value)
+{ impl->toInstall.set (value); }
+void Ypp::PkgQuery::Query::setToRemove (bool value)
+{ impl->toRemove.set (value); }
void Ypp::PkgQuery::Query::setIsRecommended (bool value)
{ impl->isRecommended.set (value); }
void Ypp::PkgQuery::Query::setIsSuggested (bool value)
@@ -1960,70 +1965,26 @@
{ return true; }

virtual bool match (Package *pkg) const
- { return query->impl->match (pkg); }
+ { return query ? query->impl->match (pkg) : true; }

- virtual bool highlight (Iter it) const
- { return query->impl->highlight == (Package *) ((GSList *) it)->data; }
+ virtual bool highlight (int index) const
+ { return query ? query->impl->highlight == pool [index] : false; }
};

Ypp::PkgQuery::PkgQuery (const Ypp::PkgList list, Ypp::PkgQuery::Query *query)
-: PkgList ((impl = new Impl (query)))
+: PkgList ((impl = new PkgQuery::Impl (query)))
{ copy (list); }

Ypp::PkgQuery::PkgQuery (Ypp::Package::Type type, Ypp::PkgQuery::Query *query)
-: PkgList ((impl = new Impl (query)))
+: PkgList ((impl = new PkgQuery::Impl (query)))
{ copy (Ypp::get()->getPackages (type)); }

-//** PkgTree
-
-Ypp::PkgTree::PkgTree (Ypp::Package::Type type) : PkgList()
-{
- Ypp::Node *category = Ypp::get()->getFirstCategory (type);
- for (; category; category = category->next()) {
- impl->list = g_slist_append (impl->list, (gpointer) category);
- const PkgList list = Ypp::get()->getPackages (type);
- for (Iter it = list.first(); it; it = list.next (it))
- impl->list = g_slist_append (impl->list, (gpointer)
list.get (it));
- }
-}
-
-/*
-Ypp::Package *Ypp::PkgTree::get (Ypp::PkgList::Iter it) const
-{
- return Ypp::PkgList::get (it);
-}
-
-std::string Ypp::PkgTree::getName (Ypp::PkgList::Iter it) const
-{
- gpointer data = ((GSList *) it)->data;
- Package *pkg = (Package *) data;
- if (pkg) return pkg->name();
- return ((Node *) data)->name;
-}
-*/
-
-/*
-Ypp::Package *Ypp::TreePool::get (Ypp::Pool::Iter iter)
-{
- GNode *node = (GNode *) iter;
- return node->children ? NULL : (Ypp::Package *) node->data;
-}
-
-std::string Ypp::TreePool::getName (Ypp::Pool::Iter iter)
-{
- Ypp::Package *package = get (iter);
- if (package)
- return package->name();
- return ((Ypp::Node *) ((GNode *) iter)->data)->name;
-}
-*/
-
//** Misc

struct Ypp::Disk::Impl
{
Ypp::Disk::Listener *listener;
-GSList *partitions;
+std::vector <Disk::Partition *> partitions;

Impl()
: partitions (NULL)
@@ -2047,20 +2008,20 @@

void clearPartitions()
{
- for (GSList *i = partitions; i; i = i->next)
- delete ((Partition *) i->data);
- g_slist_free (partitions);
- partitions = NULL;
+ for (unsigned int i = 0; i < partitions.size(); i++)
+ delete partitions[i];
+ partitions.clear();
}

const Partition *getPartition (int nb)
{
- if (!partitions) {
+ if (partitions.empty()) {
typedef zypp::DiskUsageCounter::MountPoint ZyppDu;
typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet;
typedef zypp::DiskUsageCounter::MountPointSet::iterator
ZyppDuSetIterator;

ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
+ partitions.reserve (diskUsage.size());
for (ZyppDuSetIterator it = diskUsage.begin(); it !=
diskUsage.end(); it++) {
const ZyppDu &point = *it;
if (!point.readonly) {
@@ -2076,11 +2037,13 @@
zypp::ByteCount
(partition->delta, zypp::ByteCount::K).asString() + "B";
partition->total_str =
zypp::ByteCount
(partition->total, zypp::ByteCount::K).asString() + "B";
- partitions = g_slist_append
(partitions, (gpointer) partition);
+ partitions.push_back (partition);
}
}
}
- return (Partition *) g_slist_nth_data (partitions, nb);
+ if (nb >= (signed) partitions.size())
+ return NULL;
+ return partitions[nb];
}
};

@@ -2212,8 +2175,8 @@
// Packages must be on leaves. If not, create a "Other" leaf, and put
it there.
if (type == Package::PACKAGE_TYPE) {
PkgList *list = ypp->impl->getPackages (type);
- for (PkgList::Iter it = list->first(); it; it = list->next
(it)) {
- Package *pkg = list->get (it);
+ for (int i = 0; list->get (i); i++) {
+ Package *pkg = list->get (i);
PackageSel *sel = (PackageSel *) pkg->impl;
Ypp::Node *ynode = pkg->category();
if (ynode->child()) {
@@ -2239,7 +2202,7 @@
//** Ypp top methods & internal connections

Ypp::Impl::Impl()
-: repos (NULL), favoriteRepo (NULL), disk (NULL), interface (NULL),
+: favoriteRepo (NULL), disk (NULL), interface (NULL),
pkg_listeners (NULL), inTransaction (false), transactions (NULL)
{
for (int i = 0; i < Package::TOTAL_TYPES; i++) {
@@ -2257,15 +2220,15 @@
};

for (int t = 0; t < Package::TOTAL_TYPES; t++) {
- for (Ypp::PkgList::Iter it = packages[t]->first(); it; it =
packages[t]->next (it))
- delete packages[t]->get (it);
+ if (packages [t])
+ for (int p = 0; p < packages[t]->size(); p++)
+ delete packages[t]->get (p);
delete packages [t];
delete categories[t];
}
delete categories2;
-
- g_slist_foreach (repos, inner::free_repo, NULL);
- g_slist_free (repos);
+ for (unsigned int i = 0; i < repos.size(); i++)
+ delete repos[i];

// don't delete pools as they don't actually belong to Ypp, just
listeners
g_slist_free (pkg_listeners);
@@ -2274,7 +2237,7 @@

const Ypp::Repository *Ypp::Impl::getRepository (int nb)
{
- if (!repos) {
+ if (repos.empty()) {
struct inner {
static void addRepo (Ypp::Impl *impl, const
zypp::RepoInfo &info)
{
@@ -2284,9 +2247,17 @@
repo->url =
info.baseUrlsBegin()->asString();
repo->alias = info.alias();
repo->enabled = info.enabled();
- impl->repos = g_slist_append (impl->repos,
repo);
+ impl->repos.push_back (repo);
}
};
+
+ int size;
+ zypp::RepoManager manager;
+ std::list <zypp::RepoInfo> known_repos =
manager.knownRepositories();
+ size = known_repos.size();
+ size += zyppPool().knownRepositoriesSize();
+ repos.reserve (size);
+
for (zypp::ResPoolProxy::repository_iterator it =
zyppPool().knownRepositoriesBegin();
it != zyppPool().knownRepositoriesEnd(); it++) {
const zypp::Repository &zrepo = *it;
@@ -2296,8 +2267,6 @@
}
// zyppPool::knownRepositories is more accurate, but it doesn't
feature disabled
// repositories. Add them with the following API.
- zypp::RepoManager manager;
- std::list <zypp::RepoInfo> known_repos =
manager.knownRepositories();
for (std::list <zypp::RepoInfo>::const_iterator it =
known_repos.begin();
it != known_repos.end(); it++) {
const zypp::RepoInfo info = *it;
@@ -2306,7 +2275,9 @@
inner::addRepo (this, info);
}
}
- return (Repository *) g_slist_nth_data (repos, nb);
+ if (nb >= (signed) repos.size())
+ return NULL;
+ return repos[nb];
}

const Ypp::Repository *Ypp::Impl::getRepository (const std::string &alias)
@@ -2439,20 +2410,21 @@
const Repository *repo = ypp->favoriteRepository();
PkgList confirmPkgs;
const PkgList *list = packages [Ypp::Package::PACKAGE_TYPE];
- for (PkgList::Iter it = list->first(); it; it = list->next
(it)) {
- Ypp::Package *pkg = list->get (it);
+ for (int i = 0; list->get (i); i++) {
+ Ypp::Package *pkg = list->get (i);
if (pkg->impl->isTouched()) {
const Ypp::Package::Version *version = 0;
if (pkg->toInstall (&version)) {
if (version->repo != repo)
- confirmPkgs.prepend (pkg);
+ confirmPkgs.append (pkg);
}
}
}
- if (!confirmPkgs.empty())
+ if (confirmPkgs.size() != 0)
cancel = (interface->allowRestrictedRepo (confirmPkgs)
== false);
}

+ interface->loading (0);
if (cancel) {
// user canceled resolver -- undo all
for (GSList *i = transactions; i; i = i->next)
@@ -2464,17 +2436,27 @@
for (int order = 0; order < 2; order++)
for (int type = 0; type < Ypp::Package::TOTAL_TYPES;
type++) {
const PkgList *list = packages [type];
- for (PkgList::Iter it = list->first(); it; it =
list->next (it)) {
- Ypp::Package *pkg = list->get (it);
- if (pkg->impl->isTouched()) {
- bool isAuto = pkg->isAuto();
- if ((order == 0 && !isAuto) ||
(order == 1 && isAuto)) {
- for (GSList *i =
pkg_listeners; i; i = i->next)
- ((PkgListener
*) i->data)->packageModified (pkg);
-
pkg->impl->setNotTouched();
+ if (list)
+ for (int i = 0; i < list->size(); i++) {
+ Ypp::Package *pkg = list->get
(i);
+ if (pkg->impl->isTouched()) {
+ bool isAuto =
pkg->isAuto();
+ if ((order == 0 &&
!isAuto) || (order == 1 && isAuto)) {
+ for (GSList *i
= pkg_listeners; i; i = i->next) {
+
PkgListener *listener = (PkgListener *) i->data;
+
listener->packageModified (pkg);
+ }
+
pkg->impl->setNotTouched();
+ }
+ }
+#if 0
+ if ((i % 500) == 0) {
+ float total =
2*Ypp::Package::TOTAL_TYPES*list->size();
+ float progress =
(i*order*type) / total;
+ interface->loading
(progress);
}
+#endif
}
- }
}
}
g_slist_free (transactions);
@@ -2482,14 +2464,15 @@
inTransaction = false;
if (disk)
disk->impl->packageModified();
+ interface->loading (1);
}

Ypp::Ypp()
{
impl = new Impl();
- zyppPool().saveState<zypp::Package >();
- zyppPool().saveState<zypp::Pattern >();
- zyppPool().saveState<zypp::Patch >();
+ zyppPool().saveState <zypp::Package>();
+ zyppPool().saveState <zypp::Pattern>();
+ zyppPool().saveState <zypp::Patch >();
}

Ypp::~Ypp()
@@ -2540,9 +2523,9 @@

bool Ypp::isModified()
{
- return zyppPool().diffState<zypp::Package >() ||
- zyppPool().diffState<zypp::Pattern >() ||
- zyppPool().diffState<zypp::Patch >();
+ return zyppPool().diffState<zypp::Package>() ||
+ zyppPool().diffState<zypp::Pattern>() ||
+ zyppPool().diffState<zypp::Patch >();
}

void Ypp::startTransactions()

Modified: trunk/gtk/src/yzyppwrapper.h
URL:
http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/yzyppwrapper.h?rev=58481&r1=58480&r2=58481&view=diff
==============================================================================
--- trunk/gtk/src/yzyppwrapper.h (original)
+++ trunk/gtk/src/yzyppwrapper.h Thu Sep 3 03:35:38 2009
@@ -4,19 +4,16 @@

/* A simplification of libzypp's API.

- To get a list of packages, setup a Query object and create a Pool with
+ To get a list of packages, setup a Query object and create a PkgQuery with
it. Package has a set of manipulation methods, the results of which are
- then reported to Pool listeners, which you can choose to act on your
+ then reported to PkgList listeners, which you can choose to act on your
interface, if you want them reflected on the viewer.
- Iterate the pool using Pool::Iter. If you want to keep references to them
- around for the UI, you probably want to look at paths.
+ Iterate PkgList using integers (it's actually a vector).

You must register an object that implements Interface, as some transactions
are bound by user decisions. Ypp is a singleton; first call to get() will
initialize it; you should call finish() when you're done to de-allocate
caches.
- The only thing you should free is Pool objects. A Query will be freed by
- the Pool object you pass it to.
*/

#ifndef ZYPP_WRAPPER_H
@@ -115,29 +112,24 @@

// Listing
// this class and all proper subclassed are refcounted
- struct PkgList {
- typedef void * Iter;
- Iter first() const;
- Iter next (Iter it) const;
- Package *get (Iter it) const;
- bool highlight (Iter it) const; // applicable to some
subclasses only
-
- bool empty() const;
- bool single() const;
+ struct PkgList { // NOTE: this is actually implemented as a vector
+ Package *get (int index) const;
+ bool highlight (int index) const; // applicable to some
subclasses only
int size() const;

- // for construction, it's faster to prepend & reverse than
append
- void prepend (Package *package);
+ void reserve (int size);
void append (Package *package);
- void reverse();
- void sort (int (* compare) (const void *, const void *));
- void remove (Iter it);
+ void sort (bool (* order) (const Package *, const Package *) =
0);
+ void remove (int index);
void copy (const PkgList list); // will only copy entry for
which match() == true

bool contains (const Package *package) const;
- Iter find (const Package *package) const;
+ int find (const Package *package) const; // -1 if not found
Package *find (const std::string &name) const;

+ // NOTE: checks if both lists point to the same memory space,
not equal contents
+ bool operator == (const PkgList &other) const;
+
// common properties
// NOTE: there is a hit first time one of these methods is used
bool installed() const;
@@ -159,11 +151,11 @@
// a Listener can be plugged for when an entry gets modified
// -- Inserted and Deleted are only available for particular
subclasses
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 (const PkgList list, int
index, Package *package) = 0;
+ virtual void entryInserted (const PkgList list, int
index, Package *package) = 0;
+ virtual void entryDeleted (const PkgList list, int
index, Package *package) = 0;
};
- void setListener (Listener *listener) const;
+ void setListener (Listener *listener);

struct Impl;
Impl *impl;
@@ -189,6 +181,8 @@
void setIsInstalled (bool installed);
void setHasUpgrade (bool upgradable);
void setToModify (bool modify);
+ void setToInstall (bool install);
+ void setToRemove (bool remove);
void setIsRecommended (bool recommended);
void setIsSuggested (bool suggested);
void setBuildAge (int days);
@@ -207,13 +201,7 @@
Impl *impl;
};

- // list 1D categories intertwined with its constituent packages
- struct PkgTree : public PkgList {
- // FIXME: currently broken
- PkgTree (Package::Type type);
- };
-
- // List primitives
+ // list primitives
const PkgList getPackages (Package::Type type);

struct PkgListener {
@@ -244,6 +232,7 @@
// resolveProblems = false to cancel the action that had that
effect
virtual bool resolveProblems (const std::list <Problem *>
&problems) = 0;
virtual bool allowRestrictedRepo (const PkgList list) = 0;
+ virtual void loading (float progress) = 0;
};
void setInterface (Interface *interface);


--
To unsubscribe, e-mail: yast-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: yast-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread
  • No further messages