Author: rpmcruz
Date: Thu Dec 20 21:36:55 2007
New Revision: 43212
URL: http://svn.opensuse.org/viewcvs/yast?rev=43212&view=rev
Log:
Moving unstable-libyui to main.
Modified:
trunk/gtk/src/Makefile.am
trunk/gtk/src/YGComboBox.cc
trunk/gtk/src/YGImage.cc
trunk/gtk/src/YGLayout.cc
trunk/gtk/src/YGMultiLineEdit.cc
trunk/gtk/src/YGPackageSelector.cc
trunk/gtk/src/YGProgressBar.cc
trunk/gtk/src/YGPushButton.cc
trunk/gtk/src/YGUI.cc
trunk/gtk/src/YGUtils.cc
trunk/gtk/src/YGUtils.h
trunk/gtk/src/YGWizard.cc
trunk/gtk/src/ygdkmngloader.c
trunk/gtk/src/ygtkratiobox.h
trunk/gtk/src/ygtkwizard.c
trunk/gtk/src/ygtkwizard.h
Modified: trunk/gtk/src/Makefile.am
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/Makefile.am?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/Makefile.am (original)
+++ trunk/gtk/src/Makefile.am Thu Dec 20 21:36:55 2007
@@ -46,11 +46,13 @@
ygtkfieldentry.c \
ygtkmenubutton.c \
ygtkwizard.c \
- ygtkcellrendererarrow.c \
ygtkfindentry.c \
ygdkmngloader.c \
+ ygtkimage.c \
ygtkhtmlwrap.c \
- ygtkrichtext.c
+ ygtkrichtext.c \
+ yzyppwrapper.cc \
+ ygtkzyppwrapper.cc
# should only append ygtkrichtext.c if USE_GTKHTML is set
dummy_SOURCES = dummy.cc
Modified: trunk/gtk/src/YGComboBox.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGComboBox.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGComboBox.cc (original)
+++ trunk/gtk/src/YGComboBox.cc Thu Dec 20 21:36:55 2007
@@ -26,8 +26,9 @@
gtk_combo_box_set_model (GTK_COMBO_BOX (getWidget()), GTK_TREE_MODEL (store));
g_object_unref (store);
- if(opt.isEditable.value())
+ if(opt.isEditable.value()) {
gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (getWidget()), 0);
+ }
else {
GtkCellRenderer* cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_end (GTK_CELL_LAYOUT (getWidget()), cell, TRUE);
Modified: trunk/gtk/src/YGImage.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGImage.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGImage.cc (original)
+++ trunk/gtk/src/YGImage.cc Thu Dec 20 21:36:55 2007
@@ -5,266 +5,57 @@
#include "ygdkmngloader.h"
#include
#include
-#include
-#include "YEvent.h"
+#include "YGUI.h"
#include "YGWidget.h"
#include "YImage.h"
+#include "ygtkimage.h"
class YGImage : public YImage, public YGWidget
{
- bool m_hasZeroWidth, m_hasZeroHeight, m_isScaled, m_isTiled, m_isAnimation;
- bool m_imageLoaded;
-
- struct Animation {
- GdkPixbufAnimation *pixbuf;
- GdkPixbufAnimationIter *frame;
- guint timeout_id;
- };
- union {
- GdkPixbuf *m_pixbuf;
- Animation *m_animation;
- };
- gchar *alt_text;
-
- void initOptions (const YWidgetOpt &opt)
+ void setProps (const YWidgetOpt &opt, const YCPString &alt_text)
{
- IMPL
- m_imageLoaded = false;
- m_hasZeroWidth = opt.zeroWidth.value();
- m_hasZeroHeight = opt.zeroHeight.value();
- m_isAnimation = opt.animated.value();
- m_isScaled = opt.scaleToFit.value();
- m_isTiled = opt.tiled.value();
+ bool scale = opt.scaleToFit.value(), tile = opt.tiled.value();
+ YGtkImageAlign align = CENTER_IMAGE_ALIGN;
+ if (tile)
+ align = TILE_IMAGE_ALIGN;
+ if (scale)
+ align = SCALE_IMAGE_ALIGN;
+ if (scale && tile)
+ y2warning ("YImage can't be scaled and tiled at the same time");
+ ygtk_image_set_props (YGTK_IMAGE (getWidget()), align, alt_text->value_cstr());
- if (m_hasZeroWidth || m_isScaled || m_isTiled)
+ bool zeroWidth = opt.zeroWidth.value(), zeroHeight = opt.zeroHeight.value();
+ if (zeroWidth || scale || tile)
setStretchable (YD_HORIZ, true);
- if (m_hasZeroHeight || m_isScaled || m_isTiled)
+ if (zeroHeight || scale || tile)
setStretchable (YD_VERT, true);
-
- if (m_isScaled && m_isTiled) {
- y2warning ("YImage can't be scaled and tiled at the same time");
- m_isTiled = false;
- }
-
- if (m_isAnimation)
- m_animation = NULL;
- else
- m_pixbuf = NULL;
-
- g_signal_connect (G_OBJECT (getWidget()), "expose-event",
- G_CALLBACK (expose_event_cb), this);
- gtk_widget_queue_draw (getWidget());
- }
-
- void loadImage (GdkPixbuf *pixbuf, const char *error_msg)
- {
- IMPL
- if (pixbuf == NULL) {
- g_warning ("Couldn't load image - %s", error_msg);
- return;
- }
-
- m_imageLoaded = true;
- m_pixbuf = pixbuf;
- gtk_widget_set_size_request (getWidget(), m_hasZeroWidth ? -1 : gdk_pixbuf_get_width (pixbuf),
- m_hasZeroHeight ? -1 : gdk_pixbuf_get_height (pixbuf));
- }
-
- void loadAnimation (GdkPixbufAnimation *pixbuf, const char *error_msg)
- {
- IMPL
- if (pixbuf == NULL) {
- g_warning ("Couldn't load animation - %s", error_msg);
- return;
- }
-
- m_imageLoaded = true;
- m_animation = new Animation;
- m_animation->pixbuf = pixbuf;
-
- m_animation->frame = NULL;
- advance_frame_cb (this);
-
- g_signal_connect (G_OBJECT (getWidget()), "expose-event",
- G_CALLBACK (expose_event_cb), this);
- gtk_widget_queue_draw (getWidget());
+ gtk_widget_set_size_request (getWidget(), zeroWidth ? 1 : -1, zeroHeight ? 1 : -1);
}
public:
YGImage (const YWidgetOpt &opt, YGWidget *parent,
const YCPString &filename_str, const YCPString &text)
: YImage (opt),
- YGWidget (this, parent, true, GTK_TYPE_DRAWING_AREA, NULL)
+ YGWidget (this, parent, true, YGTK_TYPE_IMAGE, NULL)
{
IMPL
- alt_text = g_strdup (text->value_cstr());
- initOptions (opt);
-
+ setProps (opt, text);
const char *filename = filename_str->value_cstr();
- GError *error = 0;
- if (m_isAnimation) {
- GdkPixbufAnimation *pixbuf;
- if (ygdk_mng_pixbuf_is_file_mng (filename))
- pixbuf = ygdk_mng_pixbuf_new_from_file (filename, &error);
- else
- pixbuf = gdk_pixbuf_animation_new_from_file (filename, &error);
- loadAnimation (pixbuf, error ? error->message : "(undefined)");
- }
- else {
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, &error);
- loadImage (pixbuf, error ? error->message : "(undefined)");
- }
+ bool animated = opt.animated.value();
+ ygtk_image_set_from_file (YGTK_IMAGE (getWidget()), filename, animated);
}
YGImage (const YWidgetOpt &opt, YGWidget *parent,
const YCPByteblock &byteblock, const YCPString &text)
: YImage (opt),
- YGWidget (this, parent, true, GTK_TYPE_DRAWING_AREA, NULL)
- {
- IMPL
- alt_text = g_strdup (text->value_cstr());
- initOptions (opt);
-
- GError *error = 0;
- if (m_isAnimation && ygdk_mng_pixbuf_is_data_mng (byteblock->value(), byteblock->size()))
- {
- GdkPixbufAnimation *pixbuf;
- pixbuf = ygdk_mng_pixbuf_new_from_data (byteblock->value(), byteblock->size(), &error);
- loadAnimation (pixbuf, error ? error->message : "(undefined)");
- }
- else
- {
- GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
- g_signal_connect (G_OBJECT (loader), "area-prepared",
- G_CALLBACK (image_loaded_cb), this);
-
- if (!gdk_pixbuf_loader_write (loader,
- byteblock->value(), byteblock->size(), &error))
- g_warning ("Could not load image from data blocks: %s", error->message);
- gdk_pixbuf_loader_close (loader, &error);
- }
- }
-
- virtual ~YGImage()
- {
- IMPL
- if (m_imageLoaded) {
- if (m_isAnimation) {
- g_object_unref (G_OBJECT (m_animation->pixbuf));
- if (m_animation->timeout_id)
- g_source_remove (m_animation->timeout_id);
- delete m_animation;
- }
- else
- g_object_unref (G_OBJECT (m_pixbuf));
- }
- g_free (alt_text);
- }
-
- // callback for image loading
- static void image_loaded_cb (GdkPixbufLoader *loader, YGImage *pThis)
- {
- IMPL
- if (pThis->m_isAnimation) {
- if (pThis->m_animation) {
- // a new frame loaded -- just redraw the widget
- if (gdk_pixbuf_animation_iter_on_currently_loading_frame
- (pThis->m_animation->frame))
- gtk_widget_queue_draw (pThis->getWidget());
- }
- else {
- GdkPixbufAnimation *pixbuf = gdk_pixbuf_loader_get_animation (loader);
- g_object_ref (G_OBJECT (pixbuf));
- pThis->loadAnimation (pixbuf, " on block data reading callback");
- }
- }
- else {
- GdkPixbuf *pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
- g_object_ref (G_OBJECT (pixbuf));
- pThis->loadImage (pixbuf, " on block data reading callback");
- }
- }
-
- // callback for image displaying
- static gboolean advance_frame_cb (void *pData)
- {
- IMPL
- YGImage *pThis = (YGImage *) pData;
- Animation *animation = pThis->m_animation;
-
- if (!animation->frame) // no frame yet loaded
- animation->frame = gdk_pixbuf_animation_get_iter (animation->pixbuf, NULL);
- else
- if (gdk_pixbuf_animation_iter_advance (animation->frame, NULL))
- gtk_widget_queue_draw (pThis->getWidget());
-
- // shedule next frame
- int delay = gdk_pixbuf_animation_iter_get_delay_time (animation->frame);
- if (delay != -1)
- animation->timeout_id = g_timeout_add (delay, advance_frame_cb, pThis);
-
- GdkPixbuf *pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (pThis->m_animation->frame);
- gtk_widget_set_size_request (pThis->getWidget(), gdk_pixbuf_get_width (pixbuf),
- gdk_pixbuf_get_height (pixbuf));
- return FALSE;
- }
-
- static gboolean expose_event_cb (GtkWidget *widget, GdkEventExpose *event,
- YGImage *pThis)
+ YGWidget (this, parent, true, YGTK_TYPE_IMAGE, NULL)
{
IMPL
- int x, y, width, height;
- x = widget->allocation.x + 6;
- y = widget->allocation.y + 6;
- width = widget->allocation.width;
- height = widget->allocation.height;
-
- cairo_t *cr = gdk_cairo_create (widget->window);
-
- if (!pThis->m_imageLoaded) {
- // show default text if no image was loaded
- PangoLayout *layout;
- layout = gtk_widget_create_pango_layout (widget, pThis->alt_text);
-
- int text_width, text_height;
- pango_layout_get_size (layout, &text_width, &text_height);
- text_width /= PANGO_SCALE;
- text_height /= PANGO_SCALE;
-
- x += (width - text_width) / 2;
- y += (height - text_height) / 2;
-
- cairo_move_to (cr, x, y);
- pango_cairo_show_layout (cr, layout);
-
- g_object_unref (layout);
- cairo_destroy (cr);
- return TRUE;
- }
-
- GdkPixbuf *pixbuf;
- if (pThis->m_isAnimation)
- pixbuf = gdk_pixbuf_animation_iter_get_pixbuf (pThis->m_animation->frame);
- else
- pixbuf = pThis->m_pixbuf;
- gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
-
- if (pThis->m_isTiled)
- cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
-
- if (pThis->m_isScaled) {
- double scale_x = (double) gdk_pixbuf_get_width (pixbuf) / width;
- double scale_y = (double) gdk_pixbuf_get_height (pixbuf) / height;
- cairo_matrix_t matrix;
- cairo_matrix_init_scale (&matrix, scale_x, scale_y);
- cairo_pattern_set_matrix (cairo_get_source (cr), &matrix);
- }
-
- cairo_rectangle (cr, 0, 0, width, height);
- cairo_fill (cr);
-
- cairo_destroy (cr);
- return TRUE;
+ setProps (opt, text);
+ const guint8 *data = byteblock->value();
+ long data_size = byteblock->size();
+ bool animated = opt.animated.value();
+ ygtk_image_set_from_data (YGTK_IMAGE (getWidget()), data, data_size, animated);
}
YGWIDGET_IMPL_COMMON
Modified: trunk/gtk/src/YGLayout.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGLayout.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGLayout.cc (original)
+++ trunk/gtk/src/YGLayout.cc Thu Dec 20 21:36:55 2007
@@ -96,7 +96,7 @@
YGWidget::sync_stretchable();
}
- virtual void moveChild (YWidget *, long, long) {}; // ignore
+ virtual void moveChild (YWidget *, long, long) {} // ignore
};
YContainerWidget *
Modified: trunk/gtk/src/YGMultiLineEdit.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGMultiLineEdit.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGMultiLineEdit.cc (original)
+++ trunk/gtk/src/YGMultiLineEdit.cc Thu Dec 20 21:36:55 2007
@@ -245,3 +245,146 @@
return new YGRichText (opt, YGWidget::get (parent), text);
}
+#if 0
+/* Wrote this code, in order to allow the user to print a package license.
+ But they are written in HTML, so that was too much for me. Anyway, might
+ be needed in the future -- it prints text okay. Maybe we could adapt it to
+ YGtkRichText, so that it just iterates through its tags (its a GtkTextView
+ afterall), rather than doing html parsing. ugh. Maybe we could somehow re-use
+ GtkTextView GtkLayouts...*/
+
+typedef struct {
+ gchar *title, *text;
+ PangoLayout *title_layout, *text_layout;
+ gint cur_line;
+} PrintData;
+
+
+static void free_print_data_cb (gpointer _data, GClosure *closure)
+{
+ PrintData *data = _data;
+fprintf (stderr, "freeing print data '%s'\n", data->title);
+ g_free (data->title);
+ g_free (data->text);
+ if (data->title_layout)
+ g_object_unref (G_OBJECT (data->title_layout));
+ if (data->text_layout)
+ g_object_unref (G_OBJECT (data->text_layout));
+ g_free (data);
+}
+
+static void print_begin_cb (GtkPrintOperation *print, GtkPrintContext *context, PrintData *data)
+{
+ int width = gtk_print_context_get_width (context);
+ int height = gtk_print_context_get_height (context);
+
+ PangoFontDescription *desc;
+ desc = pango_font_description_from_string ("Sans 12");
+
+ data->text_layout = gtk_print_context_create_pango_layout (context);
+ pango_layout_set_font_description (data->text_layout, desc);
+ pango_layout_set_width (data->text_layout, width * PANGO_SCALE);
+ pango_layout_set_text (data->text_layout, data->text, -1);
+
+ data->title_layout = gtk_print_context_create_pango_layout (context);
+ pango_layout_set_font_description (data->title_layout, desc);
+ pango_layout_set_width (data->title_layout, width * PANGO_SCALE);
+ pango_layout_set_text (data->title_layout, data->title, -1);
+
+ pango_font_description_free (desc);
+
+ int title_height, text_height;
+ pango_layout_get_pixel_size (data->title_layout, NULL, &title_height);
+ title_height += 10;
+ pango_layout_get_pixel_size (data->text_layout, NULL, &text_height);
+
+ int pages_nb, page_height = height - title_height;
+ pages_nb = text_height / page_height;
+ if (text_height % page_height != 0)
+ pages_nb++;
+ data->cur_line = 0;
+fprintf (stderr, "print begin: will use %d pages\n", pages_nb);
+ gtk_print_operation_set_n_pages (print, pages_nb);
+}
+
+static void print_draw_page_cb (GtkPrintOperation *print, GtkPrintContext *context,
+ gint page_nb, PrintData *data)
+{
+ int title_height;
+ pango_layout_get_pixel_size (data->title_layout, NULL, &title_height);
+ title_height += 10;
+
+ cairo_t *cr = gtk_print_context_get_cairo_context (context);
+ cairo_set_source_rgb (cr, 0, 0, 0);
+
+ cairo_move_to (cr, 6, 3);
+ pango_cairo_show_layout (cr, data->title_layout);
+
+ cairo_move_to (cr, 0, title_height-4);
+ cairo_line_to (cr, gtk_print_context_get_width (context), title_height-4);
+ cairo_stroke (cr);
+
+ int y = title_height, page_height = 0;
+ for (;; data->cur_line++) {
+fprintf (stderr, "printing line: %d\n", data->cur_line);
+ PangoLayoutLine *line = pango_layout_get_line_readonly (data->text_layout,
+ data->cur_line);
+ if (!line)
+{
+fprintf (stderr, "no more lines\n");
+ break;
+}
+ PangoRectangle rect;
+ pango_layout_line_get_pixel_extents (line, NULL, &rect);
+fprintf (stderr, "paragraph rect: %d x %d , %d x %d\n", rect.x, rect.y, rect.width, rect.height);
+ page_height += rect.height;
+ if (page_height >= gtk_print_context_get_height (context))
+{
+fprintf (stderr, "end of page: %f x %d\n", gtk_print_context_get_height (context), page_height);
+ break;
+}
+
+ cairo_move_to (cr, rect.x, y + rect.height);
+ pango_cairo_show_layout_line (cr, line);
+ y += rect.height;
+ }
+}
+
+void ygtk_html_print_text (GtkWindow *parent_window, const gchar *title, const gchar *text)
+{
+ PrintData *data = g_new (PrintData, 1);
+ data->title = g_strdup (title);
+ data->text = g_strdup (text);
+ data->title_layout = data->text_layout = NULL;
+
+ GtkPrintOperation *print = gtk_print_operation_new();
+
+ static GtkPrintSettings *print_settings = NULL;
+ if (print_settings)
+ gtk_print_operation_set_print_settings (print, print_settings);
+
+ g_signal_connect (G_OBJECT (print), "begin-print", G_CALLBACK (print_begin_cb), data);
+ g_signal_connect_data (G_OBJECT (print), "draw-page", G_CALLBACK (print_draw_page_cb),
+ data, free_print_data_cb, 0);
+
+ GError *error;
+ GtkPrintOperationResult res;
+ res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ parent_window, &error);
+ if (res == GTK_PRINT_OPERATION_RESULT_ERROR) {
+ GtkWidget *dialog;
+ dialog = gtk_message_dialog_new (parent_window, GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
+ "<b>Print error</b>\n%s", error->message);
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ g_error_free (error);
+ }
+ if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
+ if (print_settings)
+ g_object_unref (print_settings);
+ print_settings = g_object_ref (gtk_print_operation_get_print_settings (print));
+ }
+}
+#endif
+
Modified: trunk/gtk/src/YGPackageSelector.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGPackageSelector.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGPackageSelector.cc (original)
+++ trunk/gtk/src/YGPackageSelector.cc Thu Dec 20 21:36:55 2007
@@ -2,2419 +2,1382 @@
* YaST2-GTK - http://en.opensuse.org/YaST2-GTK *
********************************************************************/
-/*
- Textdomain "yast2-gtk"
-*/
-
#include
#include
-#include
+
+#include "YGUI.h"
#include "YGUtils.h"
#include "YGi18n.h"
#include "YGDialog.h"
-#include "YPackageSelector.h"
-#include "ygtkhtmlwrap.h"
+
#include "ygtkwizard.h"
-#include "ygtkcellrendererarrow.h"
-#include "ygtkratiobox.h"
#include "ygtkfindentry.h"
+#include "ygtkhtmlwrap.h"
+#include "ygtkzyppwrapper.h"
-#include <map>
-
-//#define DISABLE_PACKAGE_SELECTOR
-
-#ifndef DISABLE_PACKAGE_SELECTOR
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifdef PRE_ZYPP_3
-#include
-#include
-#else
-#include
-#include
-#endif
+// utilities
+static GtkWidget *createImageFromXPM (const char **xpm)
+{
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (xpm);
+ GtkWidget *image = gtk_image_new_from_pixbuf (pixbuf);
+ gtk_widget_show (image);
+ g_object_unref (pixbuf);
+ return image;
+}
-/* We should consider linking to libgnome and use gnome_url_show(url) here,
- or at least do some path finding. */
#define FILEMANAGER_EXEC "/usr/bin/nautilus"
-inline bool FILEMANAGER_PRESENT()
-{ return g_file_test (FILEMANAGER_EXEC, G_FILE_TEST_IS_EXECUTABLE); }
inline void FILEMANAGER_LAUNCH (const char *path)
-{ system ((string (FILEMANAGER_EXEC) + " " + path + " &").c_str()); }
+{ system ((std::string (FILEMANAGER_EXEC) + " -n --no-desktop " + path + " &").c_str()); }
-// some typedefs and functions to short Zypp names
-typedef zypp::ResPoolProxy ZyppPool;
-inline ZyppPool zyppPool() { return zypp::getZYpp()->poolProxy(); }
-typedef zypp::ui::Selectable::Ptr ZyppSelectable;
-typedef zypp::ui::Selectable* ZyppSelectablePtr;
-typedef zypp::ResObject::constPtr ZyppObject;
-typedef zypp::Package::constPtr ZyppPackage;
-typedef zypp::Patch::constPtr ZyppPatch;
-typedef zypp::Pattern::constPtr ZyppPattern;
-typedef zypp::Language::constPtr ZyppLanguage;
-inline ZyppPackage tryCastToZyppPkg (ZyppObject obj)
- { return zypp::dynamic_pointer_cast <const zypp::Package> (obj); }
-inline ZyppPatch tryCastToZyppPatch (ZyppObject obj)
- { return zypp::dynamic_pointer_cast <const zypp::Patch> (obj); }
-inline ZyppPattern tryCastToZyppPattern (ZyppObject obj)
- { return zypp::dynamic_pointer_cast <const zypp::Pattern> (obj); }
-inline ZyppLanguage tryCastToZyppLanguage (ZyppObject obj)
- { return zypp::dynamic_pointer_cast <const zypp::Language> (obj); }
-
-static zypp::Text
-fastGetSummary (ZyppObject obj)
+static void busyCursor()
{
- static std::map name_to_summary;
- std::string &summary = name_to_summary[ obj->name() ];
- if (summary.length() <= 0)
- summary = obj->summary();
- return summary;
+ YGUI::ui()->busyCursor();
+ // so that the cursor is actually set...
+ while (g_main_context_iteration (NULL, FALSE)) ;
}
+static void normalCursor()
+{ YGUI::ui()->normalCursor(); }
-// Computer icon comes from Tango, but may not be installed, or not initialized.
-#include "computer.xpm"
+#include "icons/pkg-list-mode.xpm"
+#include "icons/pkg-tiles-mode.xpm"
-static bool acceptLicense (ZyppSelectablePtr sel)
+class PackagesView
{
- if (sel->hasLicenceConfirmed())
- return true;
-
- ZyppObject object = sel->candidateObj();
- ZyppPackage package = tryCastToZyppPkg (object);
- if (!package)
- return true;
-
- const string &license = package->licenseToConfirm();
- if (license.empty()) {
- sel->setLicenceConfirmed (true);
- return true;
- }
-
- GtkWidget *dialog = gtk_dialog_new_with_buttons (_("License Agreement"),
- YGUI::ui()->currentWindow(), GTK_DIALOG_MODAL,
- _("_Reject"), GTK_RESPONSE_REJECT, _("_Accept"), GTK_RESPONSE_ACCEPT, NULL);
-
- GtkWidget *license_view, *license_window;
-
- license_view = ygtk_html_wrap_new();
- ygtk_html_wrap_set_text (license_view, license.c_str());
-
- license_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (license_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type
- (GTK_SCROLLED_WINDOW (license_window), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (license_window), license_view);
-
- GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox);
- gtk_box_pack_start (vbox, license_window, TRUE, TRUE, 6);
-
- const char *print_text = _("If you would like to print this license, check the EULA.txt file on the first media");
- GtkLabel *print_label = GTK_LABEL (gtk_label_new (print_text));
- gtk_box_pack_start (vbox, GTK_WIDGET (print_label), FALSE, TRUE, 2);
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 400);
- gtk_widget_show_all (dialog);
-
- bool confirmed = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT;
- gtk_widget_destroy (dialog);
-
- sel->setLicenceConfirmed (confirmed);
- return confirmed;
-}
+public:
+ struct Listener {
+ virtual void packagesSelected (const std::list &selection) = 0;
+ };
+ void setListener (Listener *listener)
+ { m_listener = listener; }
-// install / remove convinience wrapper. You only need to specify an object
-// if you want that particular version to be installed.
-// returns true on sucess
-static bool mark_selectable (ZyppSelectablePtr selectable, bool install /*or remove*/)
-{
- zypp::ui::Status status = selectable->status();
+private:
+Listener *m_listener;
- if (install) {
- if (!selectable->hasCandidateObj()) {
- y2warning ("YGPackageSelector: no package on repository to install");
- return false;
- }
- if (!acceptLicense (selectable))
- return false;
- if (status == zypp::ui::S_Del)
- status = zypp::ui::S_KeepInstalled;
- else {
- if (status == zypp::ui::S_KeepInstalled)
- status = zypp::ui::S_Update;
- else
- status = zypp::ui::S_Install;
+ void packagesSelected (const std::list &selection)
+ {
+ if (m_listener) {
+ busyCursor();
+ m_listener->packagesSelected (selection);
+ normalCursor();
}
}
- else /*remove*/ {
- if (status == zypp::ui::S_NoInst)
- ; // do nothing
- else if (status == zypp::ui::S_Install)
- status = zypp::ui::S_NoInst;
- else if (status == zypp::ui::S_Update)
- status = zypp::ui::S_KeepInstalled;
- else
- status = zypp::ui::S_Del;
- }
-
-#if 0 // debug
- const char *name = selectable->name().c_str();
- switch (status) {
- case zypp::ui::S_KeepInstalled:
- y2milestone ("keep %s installed\n", name);
- break;
- case zypp::ui::S_Update:
- y2milestone ("update %s\n", name);
- break;
- case zypp::ui::S_Install:
- y2milestone ("install %s\n", name);
- break;
- case zypp::ui::S_Del:
- y2milestone ("remove %s\n", name);
- break;
- case zypp::ui::S_NoInst:
- y2milestone ("don't install %s\n", name);
- break;
- default:
- y2milestone ("error: unknown action: should not happen\n");
- break;
- }
-#endif
-
- return selectable->set_status (status);
-}
-// tries to solve possible dependencies problems and asks the user for
-// manual resolution if needed (there is not much space for interface
-// design here)
-static bool solveProblems()
-{
- IMPL
- zypp::Resolver_Ptr resolver = zypp::getZYpp()->resolver();
- if (resolver->resolvePool())
- return true;
- zypp::ResolverProblemList problems = resolver->problems();
- if (problems.empty())
- return true;
-
- GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Resolve Problems"),
- YGUI::ui()->currentWindow(), GTK_DIALOG_MODAL,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("C_onfirm"), GTK_RESPONSE_ACCEPT, NULL);
-
- GtkWidget *problems_view;
- problems_view = gtk_tree_view_new();
-
- GtkWidget *problems_window;
- problems_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (problems_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type
- (GTK_SCROLLED_WINDOW (problems_window), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (problems_window), problems_view);
-
- GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox);
- gtk_box_pack_start (vbox, problems_window, TRUE, TRUE, 0);
-
- // create model
- // the vairous columns are: radio button active (boolean), problem
- // or solution description (string), is radio button (boolean: always
- // true), show radio button (boolean; false for problems)
- GtkTreeStore *problems_store = gtk_tree_store_new (4,
- G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
- // install view
- GtkTreeViewColumn *column;
- GtkCellRenderer *radio_renderer = gtk_cell_renderer_toggle_new();
- column = gtk_tree_view_column_new_with_attributes ("",
- radio_renderer, "active", 0, "radio", 2, "visible", 3, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (problems_view), column);
- g_signal_connect (G_OBJECT (radio_renderer), "toggled",
- G_CALLBACK (YGUtils::tree_view_radio_toggle_cb),
- GTK_TREE_MODEL (problems_store));
-
- column = gtk_tree_view_column_new_with_attributes (_("Problems"),
- gtk_cell_renderer_text_new(), "text", 1, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (problems_view), column);
-
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (problems_view), FALSE);
- gtk_tree_view_set_model (GTK_TREE_VIEW (problems_view),
- GTK_TREE_MODEL (problems_store));
- g_object_unref (G_OBJECT (problems_store));
-
- // construct model
- GtkTreeIter piter, siter;
- map users_actions;
- for (zypp::ResolverProblemList::iterator it = problems.begin();
- it != problems.end(); it++) {
- zypp::ProblemSolutionList solutions = (*it)->solutions();
-
- gtk_tree_store_append (problems_store, &piter, NULL);
- gtk_tree_store_set (problems_store, &piter, 0, FALSE,
- 1, (*it)->description().c_str(), 2, TRUE, 3, FALSE, -1);
-
- for (zypp::ProblemSolutionList::iterator jt = solutions.begin();
- jt != solutions.end(); jt++) {
- gtk_tree_store_append (problems_store, &siter, &piter);
- gtk_tree_store_set (problems_store, &siter, 0, FALSE,
- 1, (*jt)->description().c_str(), 2, TRUE, 3, TRUE, -1);
- users_actions [gtk_tree_model_get_path (GTK_TREE_MODEL (
- problems_store), &siter)] = get_pointer (*jt);
- }
- }
-
- // set tree properties
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (
- GTK_TREE_VIEW (problems_view)), GTK_SELECTION_NONE);
- gtk_tree_view_expand_all (GTK_TREE_VIEW (problems_view));
-
- gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 400);
- gtk_widget_show_all (dialog);
-
- bool confirmed = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT;
-
- if (confirmed) {
- // apply user solutions
- zypp::ProblemSolutionList userChoices;
+ struct View {
+ PackagesView *m_parent;
+ GtkWidget *m_widget;
+ View (PackagesView *parent) : m_parent (parent)
+ {}
+ virtual void setModel (GtkTreeModel *model) = 0;
- GtkTreeIter iter;
- for (map ::iterator it
- = users_actions.begin(); it != users_actions.end(); it++) {
- gtk_tree_model_get_iter (GTK_TREE_MODEL (problems_store),
- &iter, it->first);
- gboolean state = FALSE;
- gtk_tree_model_get (GTK_TREE_MODEL (problems_store), &iter,
- 0, &state, -1);
- if (state)
- userChoices.push_back (it->second);
-
- gtk_tree_path_free (it->first);
- }
- resolver->applySolutions (userChoices);
- }
-
- gtk_widget_destroy (dialog);
- if (confirmed)
- // repeate the all process as things may not yet be solved
- return solveProblems();
- return false;
-}
+ void selectedPaths (GtkTreeModel *model, GList *paths)
+ {
+ std::list 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);
-#ifdef PRE_ZYPP_3
-static string getSourceName (zypp::Source_Ref source)
-{ // based on yast-qt's singleProduct()
- if (!source.enabled())
- // can't get name if disabled; strangely, source.resolvables().begin()
- // hangs
- return "";
- string ret;
- bool found = false;
- for (zypp::ResStore::iterator it = source.resolvables().begin();
- it != source.resolvables().end(); it++) {
- zypp::Product::Ptr product;
- product = zypp::dynamic_pointer_cast zypp::Product (*it);
- if (product) {
- if (found) {
- y2milestone ("Multiple products on installation source %s",
- source.alias().c_str());
- return "";
- }
- found = true;
- ret = fastGetSummary (product);
+ packages.push_back (package);
+ }
+ g_list_free (paths);
+ m_parent->packagesSelected (packages);
}
- }
-
- if (!found)
- y2milestone ("No product on installation source %s",
- source.alias().c_str());
- return ret;
-}
-#endif
-
-#define PACKAGE_INFO_HEIGHT 140
-#define ADVANCED_INFO_HEIGHT 80
-
-// Expander widget with the package information
-class PackageInformation
-{
- GtkWidget *m_widget, *m_notebook;
- // Information text
- GtkWidget *m_about_text, *m_authors_text, *m_filelist_text, *m_changelog_text;
- bool m_use_filemanager;
-
-public:
- PackageInformation (const char *expander_text, bool only_description)
+ };
+ struct ListView : public View
{
- m_widget = gtk_expander_new (expander_text);
- gtk_widget_set_sensitive (m_widget, FALSE);
-
- if (only_description) {
- GtkWidget *about_win = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (about_win),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- m_about_text = ygtk_html_wrap_new();
- gtk_container_add (GTK_CONTAINER (about_win), m_about_text);
- gtk_container_add (GTK_CONTAINER (m_widget), about_win);
- m_authors_text = m_filelist_text = m_changelog_text = NULL;
- m_notebook = NULL;
- }
- else {
- m_notebook = gtk_notebook_new();
- gtk_notebook_set_tab_pos (GTK_NOTEBOOK (m_notebook), GTK_POS_BOTTOM);
- gtk_container_add (GTK_CONTAINER (m_widget), m_notebook);
-
- m_about_text = add_text_tab (m_notebook, _("Description"));
- m_filelist_text = add_text_tab (m_notebook, _("File List"));
- if ((m_use_filemanager = FILEMANAGER_PRESENT()))
- ygtk_html_wrap_connect_link_clicked (m_filelist_text,
- G_CALLBACK (dir_pressed_cb), NULL);
- m_changelog_text = add_text_tab (m_notebook, _("Change Log"));
- m_authors_text = add_text_tab (m_notebook, _("Authors"));
+ ListView (PackagesView *parent)
+ : View (parent)
+ {
+ GtkTreeView *view = GTK_TREE_VIEW (m_widget = gtk_tree_view_new());
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), 1);
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ renderer = gtk_cell_renderer_pixbuf_new();
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "pixbuf", YGtkZyppModel::ICON_COLUMN, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "markup", YGtkZyppModel::NAME_DESCRIPTION_COLUMN, NULL);
+ gtk_tree_view_column_set_expand (column, TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ renderer = gtk_cell_renderer_pixbuf_new();
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "pixbuf", YGtkZyppModel::SPECIAL_ICON_COLUMN, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (G_OBJECT (selection), "changed",
+ G_CALLBACK (packages_selected_cb), this);
+ gtk_widget_show (m_widget);
}
- gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (m_widget)),
- -1, PACKAGE_INFO_HEIGHT);
- }
- GtkWidget *getWidget()
- { return m_widget; }
+ virtual void setModel (GtkTreeModel *model)
+ {
+ gtk_tree_view_set_model (GTK_TREE_VIEW (m_widget), model);
+ if (GTK_WIDGET_REALIZED (m_widget))
+ gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (m_widget), 0, 0);
+ }
- void setPackage (ZyppSelectablePtr selectable, ZyppObject object)
+ static void packages_selected_cb (GtkTreeSelection *selection, View *pThis)
+ {
+ GtkTreeModel *model;
+ GList *paths = gtk_tree_selection_get_selected_rows (selection, &model);
+ pThis->selectedPaths (model, paths);
+ }
+ };
+ struct IconView : public View
{
- if (!selectable || !object) {
- if (m_about_text)
- set_text (m_about_text, "");
- if (m_filelist_text)
- set_text (m_filelist_text, "");
- if (m_changelog_text)
- set_text (m_changelog_text, "");
- if (m_authors_text)
- set_text (m_authors_text, "");
- gtk_expander_set_expanded (GTK_EXPANDER (m_widget), FALSE);
- gtk_widget_set_sensitive (m_widget, FALSE);
- return;
+ IconView (PackagesView *parent)
+ : View (parent)
+ {
+ GtkIconView *view = GTK_ICON_VIEW (m_widget = gtk_icon_view_new());
+ gtk_icon_view_set_text_column (view, YGtkZyppModel::NAME_COLUMN);
+ gtk_icon_view_set_pixbuf_column (view, YGtkZyppModel::ICON_COLUMN);
+ gtk_icon_view_set_selection_mode (view, GTK_SELECTION_MULTIPLE);
+ g_signal_connect (G_OBJECT (m_widget), "selection-changed",
+ G_CALLBACK (packages_selected_cb), this);
+ gtk_widget_show (m_widget);
}
- /* Keep notebook on first page; but only when not visible to not
- annoy the user. */
- if (m_notebook && !gtk_expander_get_expanded (GTK_EXPANDER (m_widget)))
- gtk_notebook_set_current_page (GTK_NOTEBOOK (m_notebook), 0);
- gtk_widget_set_sensitive (m_widget, TRUE);
-
- ZyppPackage package = tryCastToZyppPkg (object);
- if (m_about_text) {
- string description = YGUtils::escape_markup (object->description(), true);
-
- // cut authors, since they have their own section
- string::size_type pos = description.find ("Authors:");
- if (pos != string::npos)
- description.erase (pos, string::npos);
-
- string str;
- if (package) {
- description += "<br>";
- str = package->url();
- if (!str.empty())
- description += _("Website: ") + str + "<br>";
- str = package->license();
- if (!str.empty())
- description += _("License: ") + str + "<br>";
- description += _("Size: ") + object->size().asString() + "b<br>";
- }
-
-#ifdef PRE_ZYPP_3
- zypp::Source_Ref source = object->source();
- str = getSourceName (source);
- if (str.empty())
- str = source.url().asString();
- else
- str = str + " (" + source.url().asString() + ")";
-#else
- zypp::Repository repo = object->repository();
- str = repo.info().name();
-#endif
- if (!str.empty())
- description += _("Repository: ") + str;
+ virtual void setModel (GtkTreeModel *model)
+ {
+ gtk_icon_view_set_model (GTK_ICON_VIEW (m_widget), model);
+ if (GTK_WIDGET_REALIZED (m_widget)) {
+ GtkTreePath *path = gtk_tree_path_new_first();
+ gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (m_widget),
+ path, FALSE, 0, 0);
+ gtk_tree_path_free (path);
+ }
+ }
- set_text (m_about_text, description);
+ static void packages_selected_cb (GtkIconView *view, View *pThis)
+ {
+ GtkTreeModel *model = gtk_icon_view_get_model (view);
+ GList *paths = gtk_icon_view_get_selected_items (view);
+ pThis->selectedPaths (model, paths);
}
- if (package) {
- if (m_filelist_text) {
- string filelist;
- const std::list <string> &filenames = package->filenames();
- for (std::list <string>::const_iterator it = filenames.begin();
- it != filenames.end(); it++) {
- string file (*it);
- // don't show created dirs
- if (g_file_test (file.c_str(), G_FILE_TEST_IS_DIR))
- continue;
- // set the path as a link
- if (m_use_filemanager) {
- string::size_type pos = file.find_last_of ('/');
- if (pos != string::npos) { // should be always true
- string dirname (file, 0, pos+1);
- string basename (file, pos+1, string::npos);
- file = "<a href=" + dirname + ">" + dirname + "</a>" + basename;
- }
- }
- filelist += file + "<br>";
- }
- set_text (m_filelist_text, filelist);
- }
- if (m_changelog_text) {
- string text;
- const std::list zypp::ChangelogEntry &changelog = package->changelog();
- for (std::list zypp::ChangelogEntry::const_iterator it = changelog.begin();
- it != changelog.end(); it++) {
- string t = "<blockquote>" + YGUtils::escape_markup (it->text(), true) +
- "</blockquote>";
- text += "<p>" + it->date().asString() + ""
- + YGUtils::escape_markup (it->author()) + ":<br>"
- + t + "</p>";
- }
- set_text (m_changelog_text, text);
- }
- if (m_authors_text) {
- string packager (YGUtils::escape_markup (package->packager())), authors;
+ };
- const std::list <string> &authors_list = package->authors();
- if (!authors_list.empty()) {
- for (std::list <string>::const_iterator it = authors_list.begin();
- it != authors_list.end(); it++)
- authors += *it;
- }
- else {
-// TODO: stuff changed on YGUtils, descript. and this needs to be reviewd
- /* authors() should be the proper way to get authors, but it seems to
- be rarely used, instead packagers list them on the description. */
- string description (object->description());
-//std::cerr << "description: " << description << std::endl;
- string::size_type pos = description.find ("Authors:");
- if (pos != string::npos) {
- pos = description.find_first_not_of (
- '-', pos + sizeof ("Authors:") + 1);
-//std::cerr << "copy string from " << pos << std::endl;
- authors = string (description, pos, string::npos);
- authors = YGUtils::escape_markup (authors, true);
-//std::cerr << "authors: " << authors << std::endl;
- }
- }
+GtkWidget *m_box, *m_bin, *m_list_button, *m_icon_button;
+GtkTreeModel *m_model;
+View *m_view;
- string text;
- if (!packager.empty())
- text = _("Packaged by:") + ("<blockquote>" + packager) +
- "</blockquote>";
- if (!authors.empty()) {
- if (!packager.empty())
- text += "<br><br>";
- text += _("Developed by:") + ("<blockquote>" + authors) +
- "</blockquote>";
- }
- set_text (m_authors_text, text);
- }
- }
- else {
- if (m_filelist_text)
- set_text (m_filelist_text, "");
- if (m_changelog_text)
- set_text (m_changelog_text, "");
- if (m_authors_text)
- set_text (m_authors_text, "");
- }
- }
+public:
+ GtkWidget *getWidget()
+ { return m_box; }
-private:
- // auxiliaries to cut down on code
- static GtkWidget *add_text_tab (GtkWidget *notebook, const char *label)
+ PackagesView() : m_listener (NULL), m_model (NULL), m_view (NULL)
{
- GtkWidget *widget, *scroll_win;
- scroll_win = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_win),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
- widget = ygtk_html_wrap_new();
- gtk_container_add (GTK_CONTAINER (scroll_win), widget);
+ m_bin = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (m_bin),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_bin),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_notebook_append_page (GTK_NOTEBOOK (notebook), scroll_win,
- gtk_label_new (label));
- return widget;
+ GtkWidget *buttons = gtk_vbox_new (FALSE, 0), *image;
+ image = createImageFromXPM (pkg_list_mode_xpm);
+ m_list_button = gtk_toggle_button_new();
+ gtk_button_set_image (GTK_BUTTON (m_list_button), image);
+ image = createImageFromXPM (pkg_tiles_mode_xpm);
+ m_icon_button = gtk_toggle_button_new();
+ gtk_button_set_image (GTK_BUTTON (m_icon_button), image);
+ gtk_box_pack_start (GTK_BOX (buttons), gtk_label_new(""), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (buttons), m_list_button, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (buttons), m_icon_button, FALSE, FALSE, 0);
+ g_signal_connect (G_OBJECT (m_list_button), "toggled",
+ G_CALLBACK (mode_toggled_cb), this);
+ g_signal_connect (G_OBJECT (m_icon_button), "toggled",
+ G_CALLBACK (mode_toggled_cb), this);
+
+ m_box = gtk_hbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX (m_box), m_bin, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), buttons, FALSE, TRUE, 0);
+
+ setMode (LIST_MODE);
+ }
+
+ ~PackagesView()
+ {
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+ delete m_view;
}
- static void set_text (GtkWidget *widget, const string &text)
+ enum ViewMode {
+ LIST_MODE, ICON_MODE
+ };
+ void setMode (ViewMode mode)
{
- const char *str = _("<i>(not available)</i>");
- if (!text.empty())
- str = text.c_str();
- ygtk_html_wrap_set_text (widget, str);
- ygtk_html_wrap_scroll (widget, TRUE); // scroll to the start
+ if (GTK_WIDGET_REALIZED (m_bin))
+ busyCursor();
+ g_signal_handlers_block_by_func (m_list_button, (gpointer) mode_toggled_cb, this);
+ g_signal_handlers_block_by_func (m_icon_button, (gpointer) mode_toggled_cb, this);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_list_button), mode == LIST_MODE);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_icon_button), mode == ICON_MODE);
+
+ g_signal_handlers_unblock_by_func (m_list_button, (gpointer) mode_toggled_cb, this);
+ g_signal_handlers_unblock_by_func (m_icon_button, (gpointer) mode_toggled_cb, this);
+
+ if (m_view)
+ gtk_container_remove (GTK_CONTAINER (m_bin), m_view->m_widget);
+ delete m_view;
+ if (mode == LIST_MODE)
+ m_view = new ListView (this);
+ else
+ m_view = new IconView (this);
+fprintf (stderr, "adding new view to container\n");
+ gtk_container_add (GTK_CONTAINER (m_bin), m_view->m_widget);
+ if (m_model)
+ m_view->setModel (m_model);
+ packagesSelected (std::list ());
+ normalCursor();
+ }
+
+ void query (Ypp::Query *query)
+ {
+ if (GTK_WIDGET_REALIZED (m_bin))
+ busyCursor();
+
+ if (m_model)
+ g_object_unref (G_OBJECT (m_model));
+
+ YGtkZyppModel *zmodel = ygtk_zypp_model_new (query);
+ m_model = GTK_TREE_MODEL (zmodel);
+ if (m_view) {
+ m_view->setModel (m_model);
+ packagesSelected (std::list ());
+ }
+ normalCursor();
}
- /* When a directory is pressed on the file list. */
- static void dir_pressed_cb (GtkWidget *text, const gchar *link)
- { FILEMANAGER_LAUNCH (link); }
+private:
+ static void mode_toggled_cb (GtkToggleButton *toggle, PackagesView *pThis)
+ {
+ bool active = gtk_toggle_button_get_active (toggle);
+ if (!active) {
+ // don't let the button be un-pressed
+ g_signal_handlers_block_by_func (toggle, (gpointer) mode_toggled_cb, pThis);
+ gtk_toggle_button_set_active (toggle, TRUE);
+ g_signal_handlers_unblock_by_func (toggle, (gpointer) mode_toggled_cb, pThis);
+ return;
+ }
+ ViewMode mode = GTK_WIDGET (toggle) == pThis->m_list_button ? LIST_MODE : ICON_MODE;
+ pThis->setMode (mode);
+ }
};
-// Table widget with package sources
- /* I don't like this, since it differs from the rest of the code, but to
- avoid declarations... */
- struct SourcesTableListener
- {
- virtual ~SourcesTableListener() {}
- virtual void sources_changed_cb() = 0;
- };
-class SourcesTable
+// TEMP: a window of modified packages
+class TrashWindow : PackagesView::Listener
{
- GtkWidget *m_widget;
- GtkTreeModel *m_model;
- SourcesTableListener *m_listener;
+GtkWidget *m_window, *m_undo_button;
+PackagesView *m_view;
public:
- SourcesTable (SourcesTableListener *listener)
- : m_listener (listener)
+ TrashWindow()
{
- /* 0 - source enabled?, 1 - source name (estimation), 2 - source URL,
- 3 - source id; what they call of alias. */
- GtkListStore *store = gtk_list_store_new (4, G_TYPE_BOOLEAN, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING);
- m_model = GTK_TREE_MODEL (store);
-
-#ifdef PRE_ZYPP_3
- zypp::SourceManager_Ptr manager = zypp::SourceManager::sourceManager();
- for (zypp::SourceManager::Source_const_iterator it = manager->Source_begin();
- it != manager->Source_end(); it++) {
- zypp::Source_Ref src = *it;
- if (src && src.enabled()) {
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, src.enabled(),
- 1, getSourceName (src).c_str(), 2, src.url().asString().c_str(),
- 3, src.alias().c_str(), -1);
- }
- }
-#else
- zypp::RepoManager manager;
- std::list zypp::RepoInfo repos = manager.knownRepositories();
- for (std::list zypp::RepoInfo::iterator it = repos.begin();
- it != repos.end(); it++) {
- if (it->enabled()) {
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, bool(it->enabled()),
- 1, it->name().c_str(), 2, it->alias().c_str(), -1);
- }
- }
-#endif
-
- GtkWidget *view = gtk_tree_view_new_with_model (m_model);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)),
- GTK_SELECTION_NONE);
- g_object_unref (G_OBJECT (m_model)); // tree view will take care of it
-
- // prepare the view
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
-
- renderer = gtk_cell_renderer_toggle_new();
- column = gtk_tree_view_column_new_with_attributes ("",
- renderer, "active", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
- g_signal_connect (G_OBJECT (renderer), "toggled",
- G_CALLBACK (source_toggled_cb), this);
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes ("",
- renderer, "text", 1, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
-
-#ifdef PRE_ZYPP_3
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes ("",
- renderer, "text", 2, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
-#endif
-
- m_widget = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_widget_set_size_request (m_widget, -1, ADVANCED_INFO_HEIGHT);
- gtk_container_add (GTK_CONTAINER (m_widget), view);
+ m_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title (GTK_WINDOW (m_window), "Changes");
+ gtk_window_set_default_size (GTK_WINDOW (m_window), 200, 250);
+
+ m_view = new PackagesView();
+ Ypp::Query *query = new Ypp::Query (Ypp::Package::PACKAGE_TYPE);
+ query->setIsModified (true);
+ m_view->query (query);
+ m_view->setListener (this);
+
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 6), *undo_align;
+ m_undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO);
+ gtk_widget_set_sensitive (m_undo_button, FALSE);
+ g_signal_connect (G_OBJECT (m_undo_button), "clicked",
+ G_CALLBACK (undo_clicked_cb), this);
+ undo_align = gtk_alignment_new (1, 0, 0, 0);
+ gtk_container_add (GTK_CONTAINER (undo_align), m_undo_button);
+
+ gtk_box_pack_start (GTK_BOX (vbox), m_view->getWidget(), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), undo_align, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (m_window), vbox);
+ gtk_widget_show_all (m_window);
}
- GtkWidget *getWidget()
- { return m_widget; }
-
-private:
- static void source_toggled_cb (GtkCellRendererToggle *renderer,
- gchar *path_str, SourcesTable *pThis)
+ ~TrashWindow()
{
- IMPL
- GtkTreeModel *model = pThis->m_model;
- GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
- GtkTreeIter iter;
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
-
-#ifdef PRE_ZYPP_3
- gchar *alias;
- gtk_tree_model_get (model, &iter, 3, &alias, -1);
-
- zypp::SourceManager_Ptr manager = zypp::SourceManager::sourceManager();
- zypp::Source_Ref source = manager->findSource (alias);
- g_free (alias);
-
- if (gtk_cell_renderer_toggle_get_active (renderer))
- source.disable();
- else
- source.enable();
- gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- 0, source.enabled(), -1);
-#else
- gchar *alias;
- gtk_tree_model_get (model, &iter, 2, &alias, -1);
-
- zypp::RepoManager manager;
- zypp::RepoInfo repo = manager.getRepositoryInfo (alias);
- g_free (alias);
+ delete m_view;
+ gtk_widget_destroy (m_window);
+ }
- bool enable = !gtk_cell_renderer_toggle_get_active (renderer);
- repo.setEnabled (enable);
+private:
+std::list m_selection;
- gtk_list_store_set (GTK_LIST_STORE (model), &iter,
- 0, bool (repo.enabled()), -1);
-#endif
+ virtual void packagesSelected (const std::list &selection)
+ {
+ gtk_widget_set_sensitive (m_undo_button, !selection.empty());
+ m_selection = selection;
+ }
- pThis->m_listener->sources_changed_cb();
+ static void undo_clicked_cb (GtkButton *button, TrashWindow *pThis)
+ {
+ for (std::list ::iterator it = pThis->m_selection.begin();
+ it != pThis->m_selection.end(); it++)
+ (*it)->undo();
}
};
-// Table widget to monitor disk partitions space-usage
-#define MIN_FREE_MB_WARN (80*1024)
+#include "icons/cat-development.xpm"
+#include "icons/cat-documentation.xpm"
+#include "icons/cat-emulators.xpm"
+#include "icons/cat-games.xpm"
+#include "icons/cat-hardware.xpm"
+#include "icons/cat-network.xpm"
+#include "icons/cat-multimedia.xpm"
+#include "icons/cat-office.xpm"
+#include "icons/cat-system.xpm"
+#include "icons/cat-utilities.xpm"
-class DiskTable
+class Filters
{
- GtkWidget *m_widget;
- GtkTreeModel *m_model;
- bool m_has_warned; // only warn once
-
- // evil long names
- typedef zypp::DiskUsageCounter::MountPoint ZyppDu;
- typedef zypp::DiskUsageCounter::MountPointSet ZyppDuSet;
- typedef zypp::DiskUsageCounter::MountPointSet::iterator ZyppDuSetIterator;
-
public:
- DiskTable()
- {
- m_has_warned = false;
- if (zypp::getZYpp()->diskUsage().empty())
- zypp::getZYpp()->setPartitions (
- zypp::DiskUsageCounter::detectMountPoints());
-
- /* 0 - mount point (also used as id), 1 - percentage of disk usage
- ([0, 100]), 2 - disk usage detail (i.e. "200Mb of 1Gb") */
- GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_INT,
- G_TYPE_STRING);
- m_model = GTK_TREE_MODEL (store);
- update();
-
- GtkWidget *view = gtk_tree_view_new_with_model (m_model);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)),
- GTK_SELECTION_NONE);
- g_object_unref (G_OBJECT (m_model)); // tree view will take care of it
-
- // prepare the view
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes (_("Mount Point"),
- renderer, "text", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
-
- renderer = gtk_cell_renderer_progress_new();
- column = gtk_tree_view_column_new_with_attributes (_("Usage"),
- renderer, "value", 1, "text", 2, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ struct Listener {
+ virtual void doQuery (Ypp::Query *query) = 0;
+ };
+ void setListener (Listener *listener)
+ { m_listener = listener; signalChanged(); }
- m_widget = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (m_widget),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_widget_set_size_request (m_widget, -1, ADVANCED_INFO_HEIGHT);
- gtk_container_add (GTK_CONTAINER (m_widget), view);
- }
+private:
+ GtkWidget *m_widget, *m_name, *m_status, *m_categories, *m_repos, *m_type,
+ *m_categories_expander, *m_repos_expander;
+ Listener *m_listener;
+ guint timeout_id;
+ int repoToggled; // how many repos are toggled? if 0, it can speed up query
+ int packageType;
+public:
GtkWidget *getWidget()
{ return m_widget; }
- static string sizeToString (long long size)
+ Filters()
+ : m_listener (NULL), timeout_id (0), repoToggled (0), packageType (-1)
{
- zypp::ByteCount count (size, zypp::ByteCount::K);
- return count.asString();
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+ GtkSizeGroup *size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ m_name = ygtk_find_entry_new();
+ g_signal_connect_after (G_OBJECT (m_name), "changed",
+ G_CALLBACK (entry_changed_cb), this);
+ gtk_box_pack_start (GTK_BOX (vbox),
+ labelWidget (_("Name: "), m_name, size_group), FALSE, TRUE, 0);
+
+ m_status = gtk_combo_box_new_text();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("All"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Installed"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Upgradable"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Available"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_status), _("Modified"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (m_status), 0);
+ g_signal_connect_after (G_OBJECT (m_status), "changed",
+ G_CALLBACK (combo_changed_cb), this);
+ gtk_box_pack_start (GTK_BOX (vbox),
+ labelWidget (_("Status: "), m_status, size_group), FALSE, TRUE, 0);
+
+ gtk_box_pack_start (GTK_BOX (vbox), buildCategories(), FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), buildRepos(), FALSE, TRUE, 0);
+
+ m_type = gtk_combo_box_new_text();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Packages"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Patterns"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (m_type), _("Languages"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (m_type), 0);
+ g_signal_connect_after (G_OBJECT (m_type), "changed",
+ G_CALLBACK (combo_changed_cb), this);
+ gtk_box_pack_start (GTK_BOX (vbox), gtk_label_new (""), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox),
+ labelWidget (_("Type: "), m_type, size_group), FALSE, TRUE, 0);
+
+ m_widget = gtk_notebook_new();
+ gtk_notebook_append_page (GTK_NOTEBOOK (m_widget), vbox,
+ gtk_label_new (_("Filters")));
+ g_object_unref (G_OBJECT (size_group));
}
- void update()
+ ~Filters()
{
- GtkListStore *store = GTK_LIST_STORE (m_model);
- gtk_list_store_clear (store);
-
- bool warning = false;
- ZyppDuSet diskUsage = zypp::getZYpp()->diskUsage();
- for (ZyppDuSetIterator it = diskUsage.begin(); it != diskUsage.end(); it++) {
- const ZyppDu &partition = *it;
- if (!partition.readonly) {
- // partition fields: dir, used_size, total_size (size on Kb)
- GtkTreeIter iter;
- gtk_list_store_append (store, &iter);
-
- long usage = (partition.pkg_size * 100) / (partition.total_size + 1);
- string usage_str = sizeToString (partition.pkg_size) + " (of " +
- sizeToString (partition.total_size) + ")";
- gtk_list_store_set (store, &iter, 0, partition.dir.c_str(),
- 1, usage, 2, usage_str.c_str(), -1);
-
- warning = warning ||
- (partition.total_size > 1024 &&
- partition.total_size - partition.pkg_size < MIN_FREE_MB_WARN);
- }
- }
- if (warning)
- warn();
+ if (timeout_id) g_source_remove (timeout_id);
}
- void warn()
+private:
+ static void entry_changed_cb (GtkEditable *editable, Filters *pThis)
+ { pThis->signalChangedDelay(); }
+ static void combo_changed_cb (GtkComboBox *combo, Filters *pThis)
+ { pThis->signalChanged(); }
+
+ void signalChanged()
{
- if (m_has_warned)
- return;
- m_has_warned = true;
+ if (!m_listener) return;
- GtkWidget *dialog, *view, *scroll_view;
- dialog = gtk_message_dialog_new_with_markup (YGUI::ui()->currentWindow(),
- GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
- GTK_BUTTONS_OK, _("<b>Disk Almost Full !</b>\n\n"
- "One of the partitions is reaching its limit of capacity. You may "
- "have to remove packages if you wish to install some."));
+ Ypp::Package::Type type;
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (m_type)))
+ {
+ case 0: default: type = Ypp::Package::PACKAGE_TYPE; break;
+ case 1: type = Ypp::Package::PATTERN_TYPE; break;
+ case 2: type = Ypp::Package::LANGUAGE_TYPE; break;
+
+ }
- view = gtk_tree_view_new_with_model (m_model);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE);
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)),
- GTK_SELECTION_NONE);
+ Ypp::Query *query = new Ypp::Query (type);
- GtkTreeViewColumn *column;
- column = gtk_tree_view_column_new_with_attributes (_("Mount Point"),
- gtk_cell_renderer_text_new(), "text", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
- column = gtk_tree_view_column_new_with_attributes (_("Usage"),
- gtk_cell_renderer_progress_new(),
- "value", 1, "text", 2, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ const char *name = gtk_entry_get_text (GTK_ENTRY (m_name));
+ if (*name)
+ query->setName (std::string (name));
+ switch (gtk_combo_box_get_active (GTK_COMBO_BOX (m_status)))
+ {
+ case 1: query->setIsInstalled (true); break;
+ case 2: query->setHasUpgrade (true); break;
+ case 3: query->setIsInstalled (false); break;
+ case 4: query->setIsModified (true); break;
+ case 0: default: break;
+
+ }
- scroll_view = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll_view),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
- gtk_widget_set_size_request (scroll_view, -1, 80);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll_view),
- GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (scroll_view), view);
- gtk_widget_show_all (scroll_view);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll_view);
+ {
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (m_categories));
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
+ Ypp::Node *category;
+ gtk_tree_model_get (model, &iter, 1, &category, -1);
+ if (category)
+ query->setCategory (category);
+ }
+ }
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- }
-};
+ if (repoToggled) {
+ std::list <int> reposQuery;
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_repos));
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ gboolean enabled;
+ gint repo;
+ gtk_tree_model_get (model, &iter, 0, &enabled, 2, &repo, -1);
+ if (enabled)
+ reposQuery.push_back (repo);
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+ query->setRepositories (reposQuery);
+ }
-// YOU patch selector
-class YGPatchSelector : public YPackageSelector, public YGWidget
-{
- GtkWidget *m_patches_view;
- GtkTreeModel *m_patches_model; // GtkListStore type
+ m_listener->doQuery (query);
+ updateCategories (type);
+ }
- // Package information widget
- PackageInformation *m_information_widget;
+ void signalChangedDelay()
+ {
+ struct inner {
+ static gboolean timeout_cb (gpointer data)
+ {
+ Filters *pThis = (Filters *) data;
+ pThis->timeout_id = 0;
+ pThis->signalChanged();
+ return FALSE;
+ }
+ };
+ if (timeout_id) g_source_remove (timeout_id);
+ timeout_id = g_timeout_add (500, inner::timeout_cb, this);
+ }
-public:
- YGPatchSelector (const YWidgetOpt &opt, YGWidget *parent)
- : YPackageSelector (opt),
- YGWidget (this, parent, true, YGTK_TYPE_WIZARD, NULL)
+ void updateCategories (Ypp::Package::Type type)
{
- setBorder (0);
- GtkWidget *main_vbox = gtk_vbox_new (FALSE, 0);
+ if (packageType == type)
+ return;
+ packageType = type;
- YGtkWizard *wizard = YGTK_WIZARD (getWidget());
- ygtk_wizard_set_child (YGTK_WIZARD (getWidget()), main_vbox);
- GtkWindow *window = YGUI::ui()->currentWindow();
- ygtk_wizard_set_header_text (wizard, window, _("Patch Selector"));
- ygtk_wizard_set_header_icon (wizard, window,
- THEMEDIR "/icons/32x32/apps/yast-software.png");
- ygtk_wizard_set_help_text (wizard,
- _("For information on a given patch, just press it and as well as the "
- "Package Information expander to make those informations visible.<br>"
- "To install a patch you just need to press the check button next to it "
- "and then the button Install when you are done.")
- );
- ygtk_wizard_set_next_button_label (wizard, _("_Install"));
- ygtk_wizard_set_next_button_id (wizard, g_strdup ("install"), g_free);
- ygtk_wizard_set_abort_button_label (wizard, _("_Cancel"));
- ygtk_wizard_set_abort_button_id (wizard, g_strdup ("cancel"), g_free);
- g_signal_connect (G_OBJECT (getWidget()), "action-triggered",
- G_CALLBACK (wizard_action_cb), this);
+ GtkTreeModel *model = NULL;
- m_patches_view = gtk_tree_view_new();
- GtkWidget *patches_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type
- (GTK_SCROLLED_WINDOW (patches_window), GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (patches_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_container_add (GTK_CONTAINER (patches_window), m_patches_view);
-
- m_information_widget = new PackageInformation (_("Patch Information"), true);
- GtkWidget *pkg_info_widget = m_information_widget->getWidget();
-
- gtk_box_pack_start (GTK_BOX (main_vbox), patches_window, TRUE, TRUE, 6);
- gtk_box_pack_start (GTK_BOX (main_vbox), pkg_info_widget, FALSE, FALSE, 6);
- gtk_widget_show_all (main_vbox);
-
- // Create a model for the patches lists
- // models' columns: selected radio button state (boolean),
- // package name (string), patch priority (string), selectable object (pointer)
- m_patches_model = GTK_TREE_MODEL (gtk_list_store_new
- (4, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
+ if (type == Ypp::Package::PACKAGE_TYPE) {
+ struct inner {
+ static void populate (GtkTreeStore *store, GtkTreeIter *parent,
+ Ypp::Node *category)
+ {
+ if (!category)
+ return;
+ GtkTreeIter iter;
+ gtk_tree_store_append (store, &iter, parent);
+ const std::string &name = category->name;
+ gtk_tree_store_set (store, &iter, 0, name.c_str(), 1, category, -1);
+ if (!parent) {
+ const char **icon = 0;
+ if (name == "Development")
+ icon = cat_development_xpm;
+ else if (name == "Documentation")
+ icon = cat_documentation_xpm;
+ else if (name == "Emulators")
+ icon = cat_emulators_xpm;
+ else if (name == "Games")
+ icon = cat_games_xpm;
+ else if (name == "Hardware")
+ icon = cat_hardware_xpm;
+ else if (name == "Multimedia")
+ icon = cat_multimedia_xpm;
+ else if (name == "Network")
+ icon = cat_network_xpm;
+ else if (name == "Office")
+ icon = cat_office_xpm;
+ else if (name == "System")
+ icon = cat_system_xpm;
+ else if (name == "Utilities")
+ icon = cat_utilities_xpm;
+ if (icon) {
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (icon);
+ gtk_tree_store_set (store, &iter, 2, pixbuf, -1);
+ }
+ }
+ populate (store, &iter, category->child());
+ populate (store, parent, category->next());
+ }
+ };
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
- column = gtk_tree_view_column_new_with_attributes ("", renderer,
- "active", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (m_patches_view), column);
- g_signal_connect (G_OBJECT (renderer), "toggled",
- G_CALLBACK (patch_toggled_cb), this);
+ GtkTreeStore *store = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_POINTER,
+ GDK_TYPE_PIXBUF);
+ model = GTK_TREE_MODEL (store);
- column = gtk_tree_view_column_new_with_attributes (_("Priority"),
- gtk_cell_renderer_text_new(), "text", 1, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (m_patches_view), column);
-
- column = gtk_tree_view_column_new_with_attributes (_("Name"),
- gtk_cell_renderer_text_new(), "text", 2, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (m_patches_view), column);
-
- for (ZyppPool::const_iterator it = zyppPool().byKindBegin zypp::Patch();
- it != zyppPool().byKindEnd zypp::Patch(); it++) {
- ZyppSelectable selectable = *it;
- ZyppPatch patch = tryCastToZyppPatch (selectable->theObj());
- if (!patch)
- continue;
- bool displayPatch = false;
-
- // These rules are taken from YQPkgPatchList::fillList() in the RelevantPatches case
- if (selectable->hasInstalledObj()) { // installed?
- if (selectable->installedPoolItem().status().isIncomplete()) { // patch broken?
- // The patch is broken: It had been installed, but the user somehow
- // downgraded individual packages belonging to the patch to older versions.
- displayPatch = true;
-
- y2warning( "Installed patch is broken: %s - %s",
- patch->name().c_str(),
- patch->summary().c_str() );
- }
- } else { // not installed
- if (selectable->hasCandidateObj() && selectable->candidatePoolItem().status().isSatisfied()) {
- // This is a pretty exotic case, but still it might happen:
- //
- // The patch itelf is not installed, but it is satisfied because the
- // user updated all the packages belonging to the patch to the versions
- // the patch requires. All that is missing now is to get the patch meta
- // data onto the system. So let's display the patch to give the user
- // a chance to install it (if he so chooses).
-
- displayPatch = true;
-
- y2milestone( "Patch satisfied, but not installed yet: %s - %s",
- patch->name().c_str(),
- patch->summary().c_str() );
- }
- }
+ GtkTreeIter iter;
+ gtk_tree_store_append (store, &iter, NULL);
+ gtk_tree_store_set (store, &iter, 0, _("All"), 1, NULL, -1);
- if (selectable->hasCandidateObj()) { // candidate available?
- // The most common case: There is a candidate patch, i.e. one that could be
- // installed, but either no version of that patch is installed or there is a
- // newer one to which the patch could be updated.
-
- if (selectable->candidatePoolItem().status().isNeeded()) { // patch really needed?
- // Patches are needed if any of the packages that belong to the patch
- // are installed on the system.
-
- displayPatch = true;
- } else {
- // None of the packages that belong to the patch is installed on the system.
-
- y2debug( "Patch not needed: %s - %s",
- patch->name().c_str(),
- patch->summary().c_str() );
- }
- }
+ inner::populate (store, NULL, Ypp::get()->getFirstCategory (type));
- if (displayPatch) {
- // select them all
- selectable->set_status (zypp::ui::S_Install);
+ }
+ else if (type == Ypp::Package::PATTERN_TYPE) {
+ GtkListStore *store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_POINTER,
+ GDK_TYPE_PIXBUF);
+ model = GTK_TREE_MODEL (store);
- GtkTreeIter iter;
- GtkListStore *store = GTK_LIST_STORE (m_patches_model);
+ GtkTreeIter iter;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, _("All"), 1, NULL, -1);
+
+ for (Ypp::Node *i = Ypp::get()->getFirstCategory (type); i; i = i->next()) {
gtk_list_store_append (store, &iter);
- gtk_list_store_set (store, &iter, 0, selectable->toInstall(),
- 1, patch->category().c_str(), 2, selectable->name().c_str(),
- 3, get_pointer (selectable), -1);
+ gtk_list_store_set (store, &iter, 0, i->name.c_str(), 1, i, -1);
}
}
- gtk_tree_view_set_model (GTK_TREE_VIEW (m_patches_view), m_patches_model);
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (m_categories));
+ g_signal_handlers_block_by_func (selection,
+ (gpointer) categories_selection_cb, this);
- // TODO: severity should be sort by severity, not alphabetically
- YGUtils::tree_view_set_sortable (GTK_TREE_VIEW (m_patches_view), 1);
+ gtk_tree_view_set_model (GTK_TREE_VIEW (m_categories), model);
+ if (model) {
+ g_object_unref (G_OBJECT (model));
+ gtk_widget_show (m_categories_expander);
- gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_patches_view), 2);
+ /* we use gtk_tree_view_set_cursor(), rather than gtk_tree_selection_select_iter()
+ because that one is buggy in that when the user first interacts with the treeview,
+ a change signal is sent, even if he was just expanding one node... */
+ GtkTreePath *path = gtk_tree_path_new_first();
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (m_categories), path, NULL, FALSE);
+ gtk_tree_path_free (path);
+ }
+ else
+ gtk_widget_hide (m_categories_expander);
- g_signal_connect (G_OBJECT (m_patches_view), "cursor-changed",
- G_CALLBACK (patch_clicked_cb), this);
+ g_signal_handlers_unblock_by_func (selection,
+ (gpointer) categories_selection_cb, this);
}
- virtual ~YGPatchSelector()
+ GtkWidget *buildCategories()
{
- IMPL
- g_object_unref (m_patches_model);
- delete m_information_widget;
+ GtkWidget *scroll;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ m_categories = gtk_tree_view_new();
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_categories), FALSE);
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_categories), 0);
+ renderer = gtk_cell_renderer_pixbuf_new();
+ column = gtk_tree_view_column_new_with_attributes ("",
+ renderer, "pixbuf", 2, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (m_categories), column);
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes ("",
+ renderer, "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (m_categories), column);
+
+ GtkTreeSelection *selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (m_categories));
+ gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+ g_signal_connect (G_OBJECT (selection), "changed",
+ G_CALLBACK (categories_selection_cb), this);
+
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_size_request (scroll, -1, 200);
+ gtk_container_add (GTK_CONTAINER (scroll), m_categories);
+
+ m_categories_expander = gtk_expander_new (_("Categories"));
+ gtk_container_add (GTK_CONTAINER (m_categories_expander), scroll);
+ gtk_expander_set_expanded (GTK_EXPANDER (m_categories_expander), TRUE);
+ return m_categories_expander;
}
- static ZyppSelectablePtr selectedPatch (GtkTreeView *tree_view)
+ GtkWidget *buildRepos()
{
- IMPL
- GtkTreePath *path;
+ GtkWidget *scroll;
+ GtkListStore *store;
GtkTreeViewColumn *column;
- gtk_tree_view_get_cursor (tree_view, &path, &column);
- if (path) {
- GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+ GtkCellRenderer *renderer;
- ZyppSelectablePtr selectable = 0;
+ // 0 - enabled, 1 - name, 2 - ptr
+ store = gtk_list_store_new (3, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_INT);
+ for (int i = 0; Ypp::get()->getRepository (i); i++) {
+ const Ypp::Repository *repo = Ypp::get()->getRepository (i);
GtkTreeIter iter;
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, 3, &selectable, -1);
-
- gtk_tree_path_free (path);
- return selectable;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, TRUE, 1, repo->name.c_str(), 2, i, -1);
}
- return NULL;
- }
+ m_repos = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (m_repos), FALSE);
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_repos), 1);
+ gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (m_repos)),
+ GTK_SELECTION_NONE);
+ g_object_unref (G_OBJECT (store));
+ renderer = gtk_cell_renderer_toggle_new();
+ column = gtk_tree_view_column_new_with_attributes ("", renderer, "active", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (m_repos), column);
+ g_signal_connect (G_OBJECT (renderer), "toggled",
+ G_CALLBACK (repo_toggled_cb), this);
+ g_signal_connect (G_OBJECT (m_repos), "row-activated",
+ G_CALLBACK (repo_clicked_cb), this);
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+ column = gtk_tree_view_column_new_with_attributes ("",
+ renderer, "text", 1, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (m_repos), column);
- // callbacks
- static void patch_clicked_cb (GtkTreeView *tree_view, YGPatchSelector *pThis)
- {
- IMPL
- ZyppSelectablePtr sel = selectedPatch (tree_view);
- pThis->m_information_widget->setPackage (sel, sel->theObj());
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_size_request (scroll, -1, 80);
+ gtk_container_add (GTK_CONTAINER (scroll), m_repos);
+
+ m_repos_expander = gtk_expander_new (_("Repositories"));
+ gtk_container_add (GTK_CONTAINER (m_repos_expander), scroll);
+ return m_repos_expander;
}
- static void wizard_action_cb (YGtkWizard *wizard, gpointer id,
- gint id_type, YGPatchSelector *pThis)
+ static void categories_selection_cb (GtkTreeSelection *selection, Filters *pThis)
{
- const gchar *action = (gchar *) id;
- if (!strcmp (action, "install")) {
- y2milestone ("Closing PackageSelector with 'accept'");
- if (solveProblems())
- YGUI::ui()->sendEvent (new YMenuEvent (YCPSymbol ("accept")));
- }
- else if (!strcmp (action, "cancel")) {
- y2milestone ("Closing PackageSelector with 'cancel'");
- YGUI::ui()->sendEvent (new YCancelEvent());
- }
+fprintf (stderr, "CATEGORIES SELECTED\n");
+ pThis->signalChanged();
}
- static void patch_toggled_cb (GtkCellRendererToggle *renderer,
- gchar *path_str, YGPatchSelector *pThis)
+ void toggle_repo (GtkTreePath *path)
{
IMPL
- GtkTreeModel *model = pThis->m_patches_model;
-
- // Toggle the box
- GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
- gint *column = (gint*) g_object_get_data (G_OBJECT (renderer), "column");
+ GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (m_repos));
+ GtkListStore *store = GTK_LIST_STORE (model);
GtkTreeIter iter;
gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_path_free (path);
- gboolean state;
- ZyppSelectablePtr selectable = 0;
- gtk_tree_model_get (model, &iter, 0, &state, 3, &selectable, -1);
-
- state = !state;
- if (mark_selectable (selectable, state))
- gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, state, -1);
+ gboolean enabled;
+ gtk_tree_model_get (model, &iter, 0, &enabled, -1);
+ gtk_list_store_set (store, &iter, 0, !enabled, -1);
+ if (enabled) repoToggled--; else repoToggled++;
+fprintf (stderr, "repoToggled count: %d\n", repoToggled);
+ signalChanged();
}
- YGWIDGET_IMPL_COMMON
-};
-
-// Package selector's widget
-class PackageSelector : public SourcesTableListener
-{
-
-enum package_columns
-{
- COL_SELECTABLE = 0, // selectable object (pointer)
- COL_INSTALLED_NAME, // installed name (string)
- COL_AVAILABLE_NAME, // available_name (string)
- COL_IS_INSTALLED, // is installed (boolean)
- COL_IS_AVAILABLE, // is available (boolean)
- COL_CAN_BE_UPGRADED, // can be upgraded (boolean)
- COL_CAN_BE_DOWNGRADED, // can be downgraded (boolean)
- COL_SHOW_UPGRADABLE_CONTROL, // show up/downgrade control (boolean)
- COL_HAS_CHILDREN, // has children
- COL_FONT_STYLE // font style; italic for modified (integer) = 10
-};
-
-friend class YGPackageSelector;
-
- GtkWidget *m_widget;
-
- // The GtkTreeView widgets
- GtkWidget *m_installed_view, *m_available_view;
- // Packages backend model
- GtkTreeModel *m_packages_model;
-
- // Package information widget
- PackageInformation *m_information_widget;
- SourcesTable *m_sources_table;
- DiskTable *m_disk_table;
-
- // Search gizmos
- GtkWidget *m_search_entry, *m_plain_view;
- guint search_timeout_id;
- bool name_opt, summary_opt, descr_opt, provides_opt, requires_opt;
- list <string> m_search_queries;
-
- // Interface tweak
- GtkWidget *m_install_label, *m_remove_label;
-
-public:
- PackageSelector (bool patterns_mode)
+ static void repo_toggled_cb (GtkCellRendererToggle *renderer,
+ gchar *path_str, Filters *pThis)
{
IMPL
- m_widget = gtk_vbox_new (FALSE, 0);
-
- GtkWidget *packages_hbox = gtk_hbox_new (FALSE, 0);
-
- GtkWidget *available_box, *installed_box;
- /* All views share a similar model structure. There is a common model for
- all packages, where filters are installed upon to split it on two, each
- installed on the tree view. The common model follows the following spec:
- 0 - selectable object (pointer), 1 - installed name (string), 2 - available
- name (string), 3 - is installed (boolean), 4 - is available (boolean),
- 5 - can be upgraded (boolean), 6 - can be downgraded (boolean),
- 7 - show up/downgrade control (boolean), 8 - has children,
- 9 - font style; italic for modified (integer) = 10
-
- Models are created at each view mode change (and the other freed). This
- allows for more than one model type be used and is also better for speed,
- since the filter and tree view then installed upon don't have to keep
- syncing at every item change. */
- installed_box = createListWidget (_("<b>Installed Software:</b>"),
- "computer", computer_xpm, m_installed_view,
- 1, false);
- available_box = createListWidget (_("<b>Available Software:</b>"),
- "gtk-cdrom", NULL, m_available_view,
- 2, true);
-
- /* FIXME: it seems (due to markup or something) search, this won't work.
- Not really a issue as we provide searching, but...
- gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_installed_view), 0);
- gtk_tree_view_set_search_column (GTK_TREE_VIEW (m_available_view), 0); */
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (m_installed_view), FALSE);
- gtk_tree_view_set_enable_search (GTK_TREE_VIEW (m_available_view), FALSE);
-
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (
- GTK_TREE_VIEW (m_installed_view)), GTK_SELECTION_MULTIPLE);
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (
- GTK_TREE_VIEW (m_available_view)), GTK_SELECTION_MULTIPLE);
-
- GtkWidget *buttons_minsize, *selection_buttons_vbox, *install_button,
- *remove_button;
- selection_buttons_vbox = gtk_vbox_new (TRUE, 80);
- // to avoid re-labeling glitches, let it only grow
- buttons_minsize = ygtk_adj_size_new();
- gtk_container_add (GTK_CONTAINER (buttons_minsize), selection_buttons_vbox);
- ygtk_adj_size_set_only_expand (YGTK_ADJ_SIZE (buttons_minsize), TRUE);
-
- install_button = createArrowButton (_("_install"), GTK_ARROW_RIGHT, &m_install_label);
- remove_button = createArrowButton (_("_remove"), GTK_ARROW_LEFT, &m_remove_label);
-
- GtkWidget *install_align = gtk_alignment_new (0, 1, 1, 0);
- gtk_container_add (GTK_CONTAINER (install_align), install_button);
- GtkWidget *remove_align = gtk_alignment_new (0, 0, 1, 0);
- gtk_container_add (GTK_CONTAINER (remove_align), remove_button);
-
- gtk_box_pack_start (GTK_BOX (selection_buttons_vbox), install_align,
- TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (selection_buttons_vbox), remove_align,
- TRUE, TRUE, 0);
- gtk_container_set_border_width (GTK_CONTAINER (selection_buttons_vbox), 6);
-
- gtk_box_pack_start (GTK_BOX (packages_hbox), available_box, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (packages_hbox), buttons_minsize,
- FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (packages_hbox), installed_box, TRUE, TRUE, 0);
-
- GtkWidget *view_box, *view_label, *view_categories, *view_patterns,
- *view_languages;
- view_label = gtk_label_new (_("View Packages:"));
- gtk_label_set_use_markup (GTK_LABEL (view_label), TRUE);
- gtk_misc_set_alignment (GTK_MISC (view_label), 0, 0.5);
- m_plain_view = gtk_radio_button_new_with_mnemonic (NULL, _("as _plain list"));
- view_categories = gtk_radio_button_new_with_mnemonic_from_widget
- (GTK_RADIO_BUTTON (m_plain_view), _("in _categories"));
- view_patterns = gtk_radio_button_new_with_mnemonic_from_widget
- (GTK_RADIO_BUTTON (m_plain_view), _("in _patterns"));
- view_languages = gtk_radio_button_new_with_mnemonic_from_widget
- (GTK_RADIO_BUTTON (m_plain_view), _("in _languages"));
- view_box = gtk_hbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (view_box), view_label, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (view_box), m_plain_view, FALSE, TRUE, 4);
- gtk_box_pack_start (GTK_BOX (view_box), view_categories, FALSE, TRUE, 4);
- gtk_box_pack_start (GTK_BOX (view_box), view_patterns, FALSE, TRUE, 4);
- gtk_box_pack_start (GTK_BOX (view_box), view_languages, FALSE, TRUE, 4);
- g_signal_connect (G_OBJECT (m_plain_view), "toggled",
- G_CALLBACK (view_plain_mode_cb), this);
- g_signal_connect (G_OBJECT (view_categories), "toggled",
- G_CALLBACK (view_categories_mode_cb), this);
- g_signal_connect (G_OBJECT (view_patterns), "toggled",
- G_CALLBACK (view_patterns_mode_cb), this);
- g_signal_connect (G_OBJECT (view_languages), "toggled",
- G_CALLBACK (view_languages_mode_cb), this);
-
- // default search fields
- name_opt = summary_opt = provides_opt = true;
- requires_opt = descr_opt = false;
-
- GtkWidget *search_hbox, *search_label;
- search_hbox = gtk_hbox_new (FALSE, 0);
- search_label = gtk_label_new_with_mnemonic (_("_Search:"));
- gtk_label_set_use_markup (GTK_LABEL (search_label), TRUE);
- gtk_misc_set_alignment (GTK_MISC (search_label), 0, 0.5);
- m_search_entry = ygtk_find_entry_new();
- gtk_label_set_mnemonic_widget (GTK_LABEL (search_label), m_search_entry);
- gtk_box_pack_start (GTK_BOX (search_hbox), search_label, FALSE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (search_hbox), m_search_entry, TRUE, TRUE, 4);
- search_timeout_id = 0;
- g_signal_connect (G_OBJECT (m_search_entry), "activate", // when Enter
- G_CALLBACK (search_activate_cb), this); // is pressed
- g_signal_connect_after (G_OBJECT (m_search_entry), "changed",
- G_CALLBACK (search_request_cb), this);
- ygtk_find_entry_attach_menu (YGTK_FIND_ENTRY (m_search_entry),
- create_search_menu());
-
- /* we want "View Packages" to be aligned to "Search"; we could use a
- GtkTable for that, but a GtkSizeGroup does the job with less hassle. */
- GtkSizeGroup *align_labels = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- gtk_size_group_add_widget (align_labels, view_label);
- gtk_size_group_add_widget (align_labels, search_label);
- g_object_unref (G_OBJECT (align_labels));
-
- m_information_widget = new PackageInformation (_("Package Information"), false);
- GtkWidget *pkg_info_widget = m_information_widget->getWidget();
-
- m_sources_table = new SourcesTable (this);
- m_disk_table = new DiskTable();
-
- GtkWidget *advanced_expander = gtk_expander_new (_("Advanced"));
- GtkWidget *advanced_notebook = gtk_notebook_new();
- GtkWidget *sources_vbox = gtk_vbox_new (FALSE, 4);
- GtkWidget *sources_label = gtk_label_new (
- _("<i>Use the Software Repositories tool to manage the sources.</i>"));
- gtk_misc_set_alignment (GTK_MISC (sources_label), 1, 0);
- gtk_label_set_use_markup (GTK_LABEL (sources_label), TRUE);
- gtk_box_pack_start (GTK_BOX (sources_vbox), m_sources_table->getWidget(),
- TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (sources_vbox), sources_label, TRUE, TRUE, 0);
- gtk_notebook_set_tab_pos (GTK_NOTEBOOK (advanced_notebook), GTK_POS_BOTTOM);
- gtk_notebook_append_page (GTK_NOTEBOOK (advanced_notebook),
- sources_vbox, gtk_label_new (_("Repositories")));
- gtk_notebook_append_page (GTK_NOTEBOOK (advanced_notebook),
- m_disk_table->getWidget(), gtk_label_new (_("Disk Usage")));
- gtk_container_add (GTK_CONTAINER (advanced_expander), advanced_notebook);
-
- gtk_box_pack_start (GTK_BOX (m_widget), packages_hbox, TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (m_widget), view_box, FALSE, FALSE, 12);
- gtk_box_pack_start (GTK_BOX (m_widget), search_hbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (m_widget), pkg_info_widget, FALSE, FALSE, 12);
- gtk_box_pack_start (GTK_BOX (m_widget), advanced_expander, FALSE, FALSE, 0);
- gtk_widget_show_all (m_widget);
-
- g_object_ref (G_OBJECT (m_widget));
- gtk_object_sink (GTK_OBJECT (m_widget));
-
- // interface sugar
- g_signal_connect (G_OBJECT (install_button), "clicked",
- G_CALLBACK (install_button_clicked_cb), this);
- g_signal_connect (G_OBJECT (remove_button), "clicked",
- G_CALLBACK (remove_button_clicked_cb), this);
-
- g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (
- m_installed_view))), "changed",
- G_CALLBACK (package_clicked_cb), this);
- g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (
- m_available_view))), "changed",
- G_CALLBACK (package_clicked_cb), this);
-
- // signal for default view
- if (patterns_mode)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view_patterns), TRUE);
- else
- g_signal_emit_by_name (G_OBJECT (m_plain_view), "toggled", this);
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+ pThis->toggle_repo (path);
+ gtk_tree_path_free (path);
}
- // create widgets functions to cut down on code
- GtkWidget *createListWidget (const char *header, const char *stock_icon,
- const char **xpm_icon, GtkWidget *&list, int package_name_col,
- bool has_version_col)
+ static void repo_clicked_cb (GtkTreeView *view, GtkTreePath *path,
+ GtkTreeViewColumn *column, Filters *pThis)
{
- GtkWidget *vbox, *header_hbox, *image, *label, *scrolled_window;
-
- vbox = gtk_vbox_new (FALSE, 0);
- scrolled_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_shadow_type
- (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
- GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
- list = gtk_tree_view_new();
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list), FALSE);
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (list), TRUE);
- gtk_tree_selection_set_select_function (gtk_tree_view_get_selection (
- GTK_TREE_VIEW (list)), dont_select_groups_cb, this, NULL);
- gtk_container_add (GTK_CONTAINER (scrolled_window), list);
-
- header_hbox = gtk_hbox_new (FALSE, 0);
- image = NULL;
- if (stock_icon)
- image = gtk_image_new_from_icon_name (stock_icon, GTK_ICON_SIZE_BUTTON);
- if ((!stock_icon || gtk_image_get_storage_type (GTK_IMAGE (image)) == GTK_IMAGE_EMPTY)
- && xpm_icon) {
- GdkPixbuf *pixbuf = gdk_pixbuf_new_from_xpm_data (xpm_icon);
- image = gtk_image_new_from_pixbuf (pixbuf);
- g_object_unref (G_OBJECT (pixbuf));
- }
- label = gtk_label_new_with_mnemonic (header);
- gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), list);
- if (image)
- gtk_box_pack_start (GTK_BOX (header_hbox), image, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (header_hbox), label, FALSE, FALSE, 4);
-
- gtk_box_pack_start (GTK_BOX (vbox), header_hbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), scrolled_window, TRUE, TRUE, 4);
-
- // The treeview model will be built according to the view... Columns
- // and renderers are common anyway...
- GtkCellRenderer *text_renderer = gtk_cell_renderer_text_new();
- g_object_set (G_OBJECT (text_renderer),
- "ellipsize", PANGO_ELLIPSIZE_END, NULL);
- GtkTreeViewColumn *column;
- column = gtk_tree_view_column_new_with_attributes (_("Packages"),
- text_renderer, "markup", package_name_col, "style", 9, NULL);
- gtk_tree_view_column_set_expand (column, TRUE);
- gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
- // versions combo column
- if (has_version_col) {
- GtkCellRenderer *arrow_renderer = ygtk_cell_renderer_arrow_new();
- column = gtk_tree_view_column_new_with_attributes (NULL,
- arrow_renderer, "can-go-up", 5, "can-go-down", 6, "visible", 7, NULL);
- gtk_tree_view_column_set_expand (column, FALSE);
- gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
- g_signal_connect (G_OBJECT (arrow_renderer), "pressed",
- G_CALLBACK (change_available_version_cb), this);
- }
- return vbox;
- }
-
- GtkWidget *createArrowButton (const char *label, GtkArrowType arrow_type,
- GtkWidget **label_widget)
- {
- GtkWidget *button, *box = gtk_hbox_new (FALSE, 0);
- GtkWidget *arrow = gtk_arrow_new (arrow_type, GTK_SHADOW_OUT);
- gtk_container_add (GTK_CONTAINER (box), arrow);
- *label_widget = gtk_label_new_with_mnemonic (label);
- gtk_container_add (GTK_CONTAINER (box), *label_widget);
- gtk_box_set_child_packing (GTK_BOX (box), arrow, FALSE, TRUE, 0,
- arrow_type == GTK_ARROW_LEFT ? GTK_PACK_START : GTK_PACK_END);
-
- button = gtk_button_new();
- gtk_container_add (GTK_CONTAINER (button), box);
- return button;
+ IMPL
+ pThis->toggle_repo (path);
}
- // Dynamic views support
- void load_packages_view (GtkTreeModel *(* build_model) (GtkProgressBar *))
- {
- GtkWidget *dialog, *label, *vbox, *progress = 0;
- dialog = gtk_dialog_new();
- gtk_window_set_title (GTK_WINDOW (dialog), "");
- gtk_window_set_transient_for (GTK_WINDOW (dialog),
- YGUI::ui()->currentWindow());
- gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
- gtk_window_set_default_size (GTK_WINDOW (dialog), 100, -1);
- gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
- vbox = GTK_DIALOG (dialog)->vbox;
-// gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
- label = gtk_label_new (_("Loading packages list..."));
- gtk_misc_set_alignment (GTK_MISC (label), 0, 0);
- gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 4);
- progress = gtk_progress_bar_new();
- gtk_box_pack_start (GTK_BOX (vbox), progress, TRUE, FALSE, 4);
- gtk_widget_show_all (dialog);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (m_installed_view), NULL);
- gtk_tree_view_set_model (GTK_TREE_VIEW (m_available_view), NULL);
- m_information_widget->setPackage (NULL, NULL);
-
- GtkProgressBar *progress_bar = GTK_PROGRESS_BAR (progress);
- // build it
- GtkTreeModel *model = (m_packages_model = build_model (progress_bar));
-
- GtkTreeModel *installed_model, *available_model;
- installed_model = gtk_tree_model_filter_new (model, NULL);
- available_model = gtk_tree_model_filter_new (model, NULL);
- g_object_unref (G_OBJECT (model));
-
- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (
- installed_model), is_package_installed, this, NULL);
- gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (
- available_model), is_package_available, this, NULL);
-
- gtk_tree_view_set_model (GTK_TREE_VIEW (m_installed_view), installed_model);
- gtk_tree_view_set_model (GTK_TREE_VIEW (m_available_view), available_model);
- g_object_unref (G_OBJECT (installed_model));
- g_object_unref (G_OBJECT (available_model));
-
- // use the "available" name to do the sorting
- GtkTreeSortable *sortable = GTK_TREE_SORTABLE (model);
- gtk_tree_sortable_set_sort_func (sortable, COL_AVAILABLE_NAME,
- YGUtils::sort_compare_cb,
- GINT_TO_POINTER (COL_AVAILABLE_NAME),
- NULL);
- gtk_tree_sortable_set_sort_column_id (sortable, COL_AVAILABLE_NAME,
- GTK_SORT_ASCENDING);
-
- gtk_widget_destroy (dialog);
+ // utility
+ static GtkWidget *labelWidget (const char *label_str, GtkWidget *widget,
+ GtkSizeGroup *group)
+ {
+ GtkWidget *hbox = gtk_hbox_new (FALSE, 0);
+ GtkWidget *label = gtk_label_new_with_mnemonic (label_str);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
+ gtk_size_group_add_widget (group, label);
+ return hbox;
}
+};
- // macros to handle progress bar
- #define SET_PROGRESS(_steps, _jump) int steps = _steps, step = 0, jump = _jump;
- #define PROGRESS() \
- if (progress && ((step++) % jump == 0)) { \
- gdouble fraction = steps > 0 ? ((gdouble) step) / steps : 0; \
- gtk_progress_bar_set_fraction (progress, fraction); \
- while (gtk_events_pending()) gtk_main_iteration(); }
-
- static GtkTreeModel *loadPackagesListAsPlain (GtkProgressBar *progress)
- {
- GtkListStore *store = gtk_list_store_new (10, G_TYPE_POINTER, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT);
- GtkTreeModel *model = GTK_TREE_MODEL (store);
- g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (1));
-
- SET_PROGRESS (zyppPool().size zypp::Package(), 200)
- GtkTreeIter iter;
- for (ZyppPool::const_iterator it = zyppPool().byKindBegin zypp::Package();
- it != zyppPool().byKindEnd zypp::Package(); it++)
- {
- ZyppSelectable selectable = *it;
- gtk_list_store_append (store, &iter);
- loadPackageRow (model, &iter, selectable);
- PROGRESS()
- }
- return model;
- }
+#include "icons/pkg-locked.xpm"
+#include "icons/pkg-unlocked.xpm"
- static GtkTreeModel *loadPackagesListByCategory (GtkProgressBar *progress)
- {
- GtkTreeStore *store = gtk_tree_store_new (10, G_TYPE_POINTER, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT);
- GtkTreeModel *model = GTK_TREE_MODEL (store);
- g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (1));
+class PackageControl
+{
+GtkWidget *m_vbox, *m_status, *m_lock_button, *m_locked_image, *m_unlocked_image,
+ *m_installed_box, *m_available_box, *m_remove_button, *m_install_button,
+ *m_undo_button, *m_versions_combo, *m_version_repo;
+GtkTreeModel *m_versions_model;
- // we need to create the categories tree as we iterate packages
- map tree;
+public:
+std::list m_packages;
- SET_PROGRESS (zyppPool().size zypp::Package(), 80)
- GtkTreeIter iter, parent_iter;
- for (ZyppPool::const_iterator it = zyppPool().byKindBegin zypp::Package();
- it != zyppPool().byKindEnd zypp::Package(); it++)
- {
- ZyppSelectable selectable = *it;
- ZyppObject object = selectable->theObj();
+ GtkWidget *getWidget()
+ { return m_vbox; }
- GtkTreePath *path = NULL;
- ZyppPackage package = tryCastToZyppPkg (object);
- if (package) {
- // group is a string like "Productivity/Networking/Email/Utilities"
- string group = package->group();
-
- // We will now retrieve the hierarchy of the package's group and
- // make sure a path has already been created on all nodes, as well
- // as get last node's GtkTreePath
- list <string> hierarchy = YGUtils::splitString (group, '/');
- while (!hierarchy.empty()) {
- string node = hierarchy.front();
- hierarchy.pop_front();
-
- map ::iterator it = tree.find (node);
- if (it == tree.end()) {
- if (path) {
- gtk_tree_model_get_iter (GTK_TREE_MODEL (store),
- &parent_iter, path);
- gtk_tree_store_append (store, &iter, &parent_iter);
- }
- else // create at root
- gtk_tree_store_append (store, &iter, NULL);
+ PackageControl()
+ {
+ GtkSizeGroup *size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ m_vbox = gtk_vbox_new (FALSE, 6);
+ GtkWidget *hbox, *label;
+
+ m_lock_button = gtk_toggle_button_new();
+ g_signal_connect (G_OBJECT (m_lock_button), "toggled",
+ G_CALLBACK (locked_toggled_cb), this);
+ m_undo_button = gtk_button_new_from_stock (GTK_STOCK_UNDO);
+ g_signal_connect (G_OBJECT (m_undo_button), "clicked",
+ G_CALLBACK (undo_clicked_cb), this);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ label = gtk_label_new (_("Status:"));
+ YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_size_group_add_widget (size_group, label);
+ m_status = gtk_label_new ("-");
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), m_status, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), m_undo_button, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new(0), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), m_lock_button, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_vbox), hbox, TRUE, TRUE, 0);
+
+ m_locked_image = createImageFromXPM (pkg_locked_xpm);
+ m_unlocked_image = createImageFromXPM (pkg_unlocked_xpm);
+ g_object_ref_sink (G_OBJECT (m_locked_image));
+ g_object_ref_sink (G_OBJECT (m_unlocked_image));
+
+ m_remove_button = createButton (_("_Remove"), GTK_STOCK_DELETE);
+ g_signal_connect (G_OBJECT (m_remove_button), "clicked",
+ G_CALLBACK (remove_clicked_cb), this);
+ m_install_button = createButton ("", GTK_STOCK_SAVE);
+ g_signal_connect (G_OBJECT (m_install_button), "clicked",
+ G_CALLBACK (install_clicked_cb), this);
+
+ m_installed_box = gtk_hbox_new (FALSE, 6);
+ label = gtk_label_new (_("Installed: "));
+ YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_size_group_add_widget (size_group, label);
+ gtk_box_pack_start (GTK_BOX (m_installed_box), label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_installed_box), m_remove_button, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_vbox), m_installed_box, TRUE, TRUE, 0);
+
+ m_versions_model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT));
+ m_versions_combo = gtk_combo_box_new_with_model (m_versions_model);
+ g_signal_connect (G_OBJECT (m_versions_combo), "changed",
+ G_CALLBACK (version_changed_cb), this);
+
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (m_versions_combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (m_versions_combo),
+ renderer, "text", 0, NULL);
+
+ m_available_box = gtk_hbox_new (FALSE, 6);
+ label = gtk_label_new (_("Available: "));
+ YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ gtk_size_group_add_widget (size_group, label);
+ gtk_box_pack_start (GTK_BOX (m_available_box), label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_available_box), m_versions_combo, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_available_box), m_install_button, FALSE, TRUE, 0);
+ label = gtk_label_new (_("(Repository:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+ m_version_repo = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (m_version_repo), 0, 0.5);
+ gtk_label_set_ellipsize (GTK_LABEL (m_version_repo), PANGO_ELLIPSIZE_END);
+ gtk_box_pack_start (GTK_BOX (m_available_box), label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_available_box), m_version_repo, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_vbox), m_available_box, TRUE, TRUE, 0);
+
+ g_object_unref (G_OBJECT (size_group));
+ }
+
+ ~PackageControl()
+ {
+ gtk_widget_destroy (m_locked_image);
+ g_object_unref (G_OBJECT (m_locked_image));
+ gtk_widget_destroy (m_unlocked_image);
+ g_object_unref (G_OBJECT (m_unlocked_image));
+ }
+
+ void setPackages (const std::list &packages)
+ {
+fprintf (stderr, "packages selected (%d)\n", packages.size());
+ // FIXME: we'll probably want to re-work the controls interface
+ // for now, let's just handle none-one-multiple selections separatadely
+ m_packages = packages;
+ if (packages.size() == 1) {
+ Ypp::Package *package = packages.front();
+ // status label
+ std::string status;
+ if (package->isInstalled())
+ status = _("Installed ") + package->getInstalledVersion()->number;
+ else
+ status = _("Not installed");
+ if (package->toInstall()) {
+ int nb;
+ const Ypp::Package::Version *version;
+ package->toInstall (&nb);
+ version = package->getAvailableVersion (nb);
+ status += _(" (to install");
+ if (version)
+ status += " " + version->number;
+ status += ")";
+ }
+ else if (package->toRemove())
+ status += _(" (to remove)");
+ gtk_label_set_text (GTK_LABEL (m_status), status.c_str());
+ if (package->isModified())
+ gtk_widget_show (m_undo_button);
+ else
+ gtk_widget_hide (m_undo_button);
- string name = "<big><b>" + node + "</b></big>";
- gtk_tree_store_set (store, &iter,
- 0, NULL, 1, name.c_str(), 2, name.c_str(), 3, TRUE,
- 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1);
+ // install version
+ if (package->isInstalled())
+ gtk_widget_show (m_installed_box);
+ else
+ gtk_widget_hide (m_installed_box);
- path = gtk_tree_model_get_path (model, &iter);
- tree [node] = path;
- }
- else // exists
- path = it->second;
+ // available versions
+ gtk_widget_show (m_versions_combo);
+ if (package->getAvailableVersion (0)) {
+ gtk_list_store_clear (GTK_LIST_STORE (m_versions_model));
+ for (int i = 0; package->getAvailableVersion (i); i++) {
+ const char *version = package->getAvailableVersion (i)->number.c_str();
+fprintf (stderr, "adding version: %s\n", version);
+ GtkTreeIter iter;
+ gtk_list_store_append (GTK_LIST_STORE (m_versions_model), &iter);
+ gtk_list_store_set (GTK_LIST_STORE (m_versions_model), &iter,
+ 0, version, 1, i, -1);
}
+ gtk_combo_box_set_active (GTK_COMBO_BOX (m_versions_combo), 0);
+ gtk_widget_show (m_available_box);
}
+ else
+ gtk_widget_hide (m_available_box);
- if (!path) // package has no group
- continue;
-
- gtk_tree_model_get_iter (model, &parent_iter, path);
- gtk_tree_store_append (store, &iter, &parent_iter);
- loadPackageRow (model, &iter, selectable);
- PROGRESS()
- }
-
- // free GtkTreePaths
- for (map ::iterator it = tree.begin();
- it != tree.end(); it++)
- gtk_tree_path_free (it->second);
- return model;
- }
-
- /* NOTE: Getting the packages under a pattern, language, etc is done
- differently, so code re-use would be limited. Probably doesn't worth
- the trouble and complexity of doing so. */
-
- static GtkTreeModel *loadPackagesListByPattern (GtkProgressBar *progress)
- {
- GtkTreeStore *store = gtk_tree_store_new (10, G_TYPE_POINTER, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT);
- GtkTreeModel *model = GTK_TREE_MODEL (store);
- g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (0));
-
- // we need to create a categories tree for the patterns
- map tree;
-
- SET_PROGRESS (zyppPool().size zypp::Pattern(), 5)
- for (ZyppPool::const_iterator it = zyppPool().byKindBegin zypp::Pattern();
- it != zyppPool().byKindEnd zypp::Pattern(); it++) {
- ZyppSelectable selectable = *it;
- ZyppObject object = selectable->theObj();
- ZyppPattern pattern = tryCastToZyppPattern (object);
- if (pattern && pattern->userVisible()) {
- GtkTreeIter category_iter, pattern_iter, package_iter;
- string category = pattern->category();
- map ::iterator cat_it = tree.find (category);
- if (cat_it == tree.end()) {
- string name = "<big><b>" + category + "</b></big>";
- gtk_tree_store_append (store, &category_iter, NULL);
- gtk_tree_store_set (store, &category_iter,
- 0, NULL, 1, name.c_str(), 2, name.c_str(), 3, TRUE,
- 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1);
- tree [category] = category_iter;
- }
+ // is locked
+ gtk_widget_show (m_lock_button);
+ bool locked = package->isLocked();
+ g_signal_handlers_block_by_func (m_lock_button, (gpointer) locked_toggled_cb, this);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_lock_button), locked);
+ g_signal_handlers_unblock_by_func (m_lock_button, (gpointer) locked_toggled_cb, this);
+ gtk_button_set_image (GTK_BUTTON (m_lock_button),
+ locked ? m_locked_image : m_unlocked_image);
+ gtk_widget_set_sensitive (m_install_button, !locked);
+ gtk_widget_set_sensitive (m_remove_button, !locked);
+
+ gtk_widget_show (m_vbox);
+ }
+ else if (packages.size()) {
+ bool allInstalled = true, allNotInstalled = true, allUpgradable = true,
+ allModified = true, allLocked = true, allUnlocked = true;
+ for (std::list ::const_iterator it = packages.begin();
+ it != packages.end(); it++) {
+ if (!(*it)->isInstalled()) {
+ allInstalled = false;
+ allUpgradable = false;
+ }
+ else {
+ allNotInstalled = false;
+ const Ypp::Package::Version *version = (*it)->getAvailableVersion(0);
+ if (!version || version->cmp <= 0)
+ allUpgradable = false;
+ }
+ if (!(*it)->isModified())
+ allModified = false;
+ if ((*it)->isLocked())
+ allUnlocked = false;
else
- category_iter = cat_it->second;
-
- string name = "<b>" + fastGetSummary (object) + "</b>";
- gtk_tree_store_append (store, &pattern_iter, &category_iter);
- loadPackageRow (model, &pattern_iter, selectable);
-
-/* gtk_tree_store_set (store, &pattern_iter,
- 0, get_pointer (selectable), 1, name.c_str(), 2, name.c_str(),
- 3, TRUE, 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1);*/
-
- // adding children packages
- const set <string> &packages = pattern->install_packages();
- for (ZyppPool::const_iterator pt2 =
- zyppPool().byKindBegin zypp::Package();
- pt2 != zyppPool().byKindEnd zypp::Package(); pt2++) {
- ZyppSelectable sel = *pt2;
- for (set <string>::iterator pt1 = packages.begin();
- pt1 != packages.end(); pt1++) {
- if (sel->name() == *pt1) {
- gtk_tree_store_append (store, &package_iter, &pattern_iter);
- loadPackageRow (model, &package_iter, sel);
- }
- }
- }
+ allLocked = false;
}
- PROGRESS()
- }
- return model;
- }
- static GtkTreeModel *loadPackagesListByLanguage (GtkProgressBar *progress)
- {
- GtkTreeStore *store = gtk_tree_store_new (10, G_TYPE_POINTER, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
- G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_INT);
- GtkTreeModel *model = GTK_TREE_MODEL (store);
- g_object_set_data (G_OBJECT (model), "detail-package", GINT_TO_POINTER (0));
-
- SET_PROGRESS (zyppPool().size zypp::Language(), 20)
- for (ZyppPool::const_iterator it = zyppPool().byKindBegin zypp::Language();
- it != zyppPool().byKindEnd zypp::Language(); it++) {
- ZyppSelectable langsel = *it;
- ZyppObject langobj = langsel->theObj();
- ZyppLanguage lang = tryCastToZyppLanguage (langobj);
- if (lang) {
- string langname = langsel->name();
- if (langname.empty() || langname == "C")
- continue;
-
- string descrpt = "<b>" + langobj->description() + "</b>";
- GtkTreeIter parent_iter, iter;
- gtk_tree_store_append (store, &parent_iter, NULL);
- loadPackageRow (model, &parent_iter, langsel);
-/* gtk_tree_store_set (store, &parent_iter,
- 0, get_pointer (langsel), 1, descrpt.c_str(), 2, descrpt.c_str(),
- 3, TRUE, 4, TRUE, 5, FALSE, 6, FALSE, 7, FALSE, 8, TRUE, -1);*/
-
- for (ZyppPool::const_iterator it =
- zyppPool().byKindBegin zypp::Package();
- it != zyppPool().byKindEnd zypp::Package(); it++) {
- ZyppSelectable pkgsel = *it;
- ZyppObject pkgobj = pkgsel->theObj();
-
- const zypp::CapSet &capSet = pkgobj->dep (zypp::Dep::FRESHENS);
- for (zypp::CapSet::const_iterator it = capSet.begin();
- it != capSet.end(); it++) {
- if (it->index() == lang->name()) {
- gtk_tree_store_append (store, &iter, &parent_iter);
- loadPackageRow (model, &iter, pkgsel);
- }
- }
- }
- }
- PROGRESS()
- }
- return model;
- }
- #undef SET_PROGRESS
- #undef PROGRESS
-
- static void induceObjects (ZyppSelectable selectable, ZyppObject &install_obj,
- ZyppObject &available_obj, bool *has_upgrade,
- bool *has_downgrade)
- {
- available_obj = (install_obj = NULL);
- if (!selectable)
- return;
- switch (selectable->status()) {
- case zypp::ui::S_Install:
- case zypp::ui::S_Update:
- install_obj = selectable->candidateObj();
- break;
- case zypp::ui::S_Del:
- available_obj = selectable->installedObj();
- break;
- default:
- available_obj = selectable->candidateObj();
- install_obj = selectable->installedObj();
- break;
- }
+ std::string status;
+ if (allInstalled)
+ status = _("Installed");
+ else if (allNotInstalled)
+ status = _("Not installed");
+ else
+ status = _("--");
- // zypp keeps on the pool objects whose sources we disabled, so we may
- // need to calculate the candidate object here.
-#ifdef PRE_ZYPP_3
- if (available_obj != NULL && !available_obj->source().enabled()) {
-#else
- // beware lurking tribool requires bool cast here.
- if (available_obj != NULL && !(bool)(available_obj->repository().info().enabled())) {
-#endif
- available_obj = NULL;
- for (zypp::ui::Selectable::available_iterator it = selectable->availableBegin();
- it != selectable->availableEnd(); it++) {
-#ifdef PRE_ZYPP_3
- if (!(*it)->source().enabled())
-#else
- if (!(*it)->repository().info().enabled())
-#endif
- ;
- else if (!available_obj)
- available_obj = *it;
- else if (zypp::Edition::compare ((*it)->edition(),
- available_obj->edition()) > 0)
- available_obj = *it;
+ if (allModified) {
+ status += _(" (modified)");
+ gtk_widget_show (m_undo_button);
}
- }
-
- bool has_up = false, has_down = false;
- if (available_obj != NULL && install_obj != NULL) {
- int res = zypp::Edition::compare (install_obj->edition(),
- available_obj->edition());
- if (res < 0)
- has_up = true;
- else if (res > 0)
- has_down = true;
- }
-
- if (has_upgrade)
- *has_upgrade = has_up;
- if (has_downgrade)
- *has_downgrade = has_down;
- }
-
- /* Must be called for the main model. */
- static void loadPackageRow (GtkTreeModel *model, GtkTreeIter *iter,
- ZyppSelectable selectable)
- {
- ZyppObject install_obj, available_obj;
- bool has_upgrade, has_downgrade, has_children = FALSE;
- induceObjects (selectable, install_obj, available_obj,
- &has_upgrade, &has_downgrade);
-
- bool detailed = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (model),
- "detail-package"));
- string availableName, installedName, name (YGUtils::escape_markup (selectable->name()));
- if (available_obj) {
- if (detailed)
- availableName = "<b>" + name + "</b> (" + available_obj->edition().version() +
- ")\n<small>" + YGUtils::escape_markup (fastGetSummary (available_obj)) +
- "</small>";
- else {
- ZyppPattern pattern = tryCastToZyppPattern (available_obj);
- ZyppLanguage lang = tryCastToZyppLanguage (available_obj);
- if (pattern) {
- availableName = "<b>" + fastGetSummary (available_obj) + "</b>";
- has_children = TRUE;
- } else if (lang) {
- availableName = "<b>" + available_obj->description() + "</b>";
- has_children = TRUE;
- } else
- availableName = name + " (" + available_obj->edition().version() + ")";
- }
- }
- if (install_obj) {
- if (detailed)
- installedName = "<b>" + name + "</b> (" + install_obj->edition().version() +
- ")\n<small>" + YGUtils::escape_markup (fastGetSummary (install_obj)) +
- "</small>";
- else {
- ZyppPattern pattern = tryCastToZyppPattern (install_obj);
- ZyppLanguage lang = tryCastToZyppLanguage (install_obj);
- if (pattern) {
- installedName = "<b>" + fastGetSummary (install_obj) + "</b>";
- has_children = TRUE;
- } else if (lang) {
- installedName = "<b>" + install_obj->description() + "</b>";
- has_children = TRUE;
- } else
- installedName = name + " (" + install_obj->edition().version() + ")";
- }
- }
-
- // Make sure that both the availableName and installedName
- // are filled. Occasionally, the names are empty, so the
- // following checks make sure these variable are filled.
- if (availableName.empty())
- availableName = installedName;
- else if (installedName.empty())
- installedName = availableName;
-
- PangoStyle style = PANGO_STYLE_NORMAL;
- if (selectable->toModify())
- style = PANGO_STYLE_ITALIC;
-
- // oh, would be nice to have a common set for tree models...
- if (GTK_IS_LIST_STORE (model))
- gtk_list_store_set (GTK_LIST_STORE (model), iter,
- COL_SELECTABLE, get_pointer (selectable),
- COL_INSTALLED_NAME, installedName.c_str(),
- COL_AVAILABLE_NAME, availableName.c_str(),
- COL_IS_INSTALLED, install_obj != 0,
- COL_IS_AVAILABLE, available_obj != 0,
- COL_CAN_BE_UPGRADED, has_upgrade,
- COL_CAN_BE_DOWNGRADED, has_downgrade,
- COL_SHOW_UPGRADABLE_CONTROL, detailed,
- COL_HAS_CHILDREN, has_children,
- COL_FONT_STYLE, style, -1);
- else /*if (GTK_IS_TREE_STORE (model))*/
- gtk_tree_store_set (GTK_TREE_STORE (model), iter,
- COL_SELECTABLE, get_pointer (selectable),
- COL_INSTALLED_NAME, installedName.c_str(),
- COL_AVAILABLE_NAME, availableName.c_str(),
- COL_IS_INSTALLED, install_obj != 0,
- COL_IS_AVAILABLE, available_obj != 0,
- COL_CAN_BE_UPGRADED, has_upgrade,
- COL_CAN_BE_DOWNGRADED, has_downgrade,
- COL_SHOW_UPGRADABLE_CONTROL, detailed,
- COL_HAS_CHILDREN, has_children,
- COL_FONT_STYLE, style, -1);
-/* y2milestone ("set %s: %d - %d\n", selectable->name().c_str(),
- available_obj != 0, install_obj != 0);*/
- }
+ else
+ gtk_widget_hide (m_undo_button);
+ gtk_label_set_text (GTK_LABEL (m_status), status.c_str());
- virtual ~PackageSelector()
- {
- IMPL
- if (search_timeout_id)
- g_source_remove (search_timeout_id);
+ // install version
+ if (allInstalled)
+ gtk_widget_show (m_installed_box);
+ else
+ gtk_widget_hide (m_installed_box);
- delete m_information_widget;
- delete m_sources_table;
- delete m_disk_table;
- gtk_widget_destroy (m_widget);
- g_object_unref (G_OBJECT (m_widget));
- }
+ // available versions
+ gtk_widget_hide (m_versions_combo);
+ if (allNotInstalled || allUpgradable) {
+ gtk_widget_show (m_available_box);
+ const char *installLabel = _("Install");
+ if (allUpgradable)
+ installLabel = _("Upgrade");
+ gtk_button_set_label (GTK_BUTTON (m_install_button), installLabel);
+ }
+ else
+ gtk_widget_hide (m_available_box);
- GtkWidget *getWidget()
- { return m_widget; }
+ // is locked
+ if (allLocked || allUnlocked) {
+ gtk_widget_show (m_lock_button);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_lock_button), allLocked);
+ gtk_button_set_image (GTK_BUTTON (m_lock_button),
+ allLocked ? m_locked_image : m_unlocked_image);
+ gtk_widget_set_sensitive (m_install_button, !allLocked);
+ gtk_widget_set_sensitive (m_remove_button, !allLocked);
+ }
+ else {
+ gtk_widget_hide (m_lock_button);
+ gtk_widget_set_sensitive (m_install_button, TRUE);
+ gtk_widget_set_sensitive (m_remove_button, TRUE);
+ }
+ gtk_widget_show (m_vbox);
+ }
+ else
+ gtk_widget_hide (m_vbox);
- static void view_plain_mode_cb (GtkToggleButton *button,
- PackageSelector *pThis)
- {
- if (!gtk_toggle_button_get_active (button)) return;
- pThis->load_packages_view (&loadPackagesListAsPlain);
+#if 0
+ m_package = package;
+ if (package) {
+ if (package->isInstalled()) {
+ gtk_widget_show (m_remove_button);
+ gtk_widget_hide (m_install_button);
+ }
+ else {
+ gtk_widget_show (m_install_button);
+ gtk_widget_hide (m_remove_button);
+ }
+ if (package && package->hasUpgrade())
+ gtk_widget_show (m_upgrade_button);
+ else
+ gtk_widget_hide (m_upgrade_button);
+ }
+ else {
+ gtk_widget_hide (m_install_button);
+ gtk_widget_hide (m_remove_button);
+ gtk_widget_hide (m_upgrade_button);
+ }
+#endif
}
- static void view_categories_mode_cb (GtkToggleButton *button,
- PackageSelector *pThis)
+private:
+ static void install_clicked_cb (GtkButton *button, PackageControl *pThis)
{
- if (!gtk_toggle_button_get_active (button)) return;
- pThis->clear_search_entry (true);
- pThis->load_packages_view (&loadPackagesListByCategory);
+ busyCursor();
+ Ypp::get()->startTransactions();
+ for (std::list ::iterator it = pThis->m_packages.begin();
+ it != pThis->m_packages.end(); it++) {
+ int version;
+ if (GTK_WIDGET_VISIBLE (pThis->m_versions_combo))
+ version = gtk_combo_box_get_active (GTK_COMBO_BOX (
+ pThis->m_versions_combo));
+ else
+ version = 0; // i.e. most recent (on multi-packages)
+ (*it)->install (version);
+ }
+ Ypp::get()->finishTransactions();
+ normalCursor();
}
- static void view_patterns_mode_cb (GtkToggleButton *button,
- PackageSelector *pThis)
+ static void remove_clicked_cb (GtkButton *button, PackageControl *pThis)
{
- if (!gtk_toggle_button_get_active (button)) return;
- pThis->clear_search_entry (true);
- pThis->load_packages_view (&loadPackagesListByPattern);
+ busyCursor();
+ Ypp::get()->startTransactions();
+ for (std::list ::iterator it = pThis->m_packages.begin();
+ it != pThis->m_packages.end(); it++)
+ (*it)->remove();
+ Ypp::get()->finishTransactions();
+ normalCursor();
}
- static void view_languages_mode_cb (GtkToggleButton *button,
- PackageSelector *pThis)
+ static void undo_clicked_cb (GtkButton *button, PackageControl *pThis)
{
- if (!gtk_toggle_button_get_active (button)) return;
- pThis->clear_search_entry (true);
- pThis->load_packages_view (&loadPackagesListByLanguage);
+ busyCursor();
+ Ypp::get()->startTransactions();
+ for (std::list ::iterator it = pThis->m_packages.begin();
+ it != pThis->m_packages.end(); it++)
+ (*it)->undo();
+ Ypp::get()->finishTransactions();
+ normalCursor();
}
- void sources_changed_cb()
+ static void locked_toggled_cb (GtkToggleButton *button, PackageControl *pThis)
{
- // reload view; FIXME: re-load the current view, not necessarly
- // the plain list; hacky anyway
- if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (m_plain_view)))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (m_plain_view), TRUE);
- else
- g_signal_emit_by_name (G_OBJECT (m_plain_view), "toggled", this);
+ busyCursor();
+ Ypp::get()->startTransactions();
+ for (std::list ::iterator it = pThis->m_packages.begin();
+ it != pThis->m_packages.end(); it++)
+ (*it)->lock (gtk_toggle_button_get_active (button));
+ Ypp::get()->finishTransactions();
+ normalCursor();
}
- void clear_search_entry (bool dont_load)
+ static void version_changed_cb (GtkComboBox *combo, PackageControl *pThis)
{
- if (dont_load)
- g_signal_handlers_block_by_func (m_search_entry,
- (gpointer) search_request_cb, this);
- gtk_entry_set_text (GTK_ENTRY (m_search_entry), "");
- if (dont_load)
- g_signal_handlers_unblock_by_func (m_search_entry,
- (gpointer) search_request_cb, this);
- }
+ fprintf (stderr, "version changed\n");
+ if (!pThis->m_packages.empty()) {
+ Ypp::Package *package = pThis->m_packages.front();
+ int nb;
+ GtkTreeIter iter;
+ if (gtk_combo_box_get_active_iter (combo, &iter)) {
+ gtk_tree_model_get (pThis->m_versions_model, &iter, 1, &nb, -1);
+ const Ypp::Package::Version *version;
+ fprintf (stderr, "get available version %d\n", nb);
+ version = package->getAvailableVersion (nb);
+ g_assert (version != NULL);
+
+ const Ypp::Repository *repo = Ypp::get()->getRepository (version->repo);
+ if (repo) {
+ std::string repo_str = repo->name + ")";
+ gtk_label_set_text (GTK_LABEL (pThis->m_version_repo), repo_str.c_str());
+ }
+ else
+ gtk_label_set_text (GTK_LABEL (pThis->m_version_repo),
+ "TODO: hide this for collections)");
- static void search_activate_cb (GtkEntry *entry, PackageSelector *pThis)
- {
- IMPL
- if (pThis->search_timeout_id)
- g_source_remove (pThis->search_timeout_id);
- search_cb (pThis);
+ const char *installLabel = _("Install");
+ if (package->isInstalled()) {
+ if (version->cmp > 0)
+ installLabel = _("Upgrade");
+ else if (version->cmp == 0)
+ installLabel = _("Re-install");
+ else //if (version->cmp < 0)
+ installLabel = _("Downgrade");
+ }
+ gtk_button_set_label (GTK_BUTTON (pThis->m_install_button), installLabel);
+ }
+ }
}
- static void search_request_cb (GtkEditable *editable, PackageSelector *pThis)
+ // utility
+ static GtkWidget *createButton (const char *label_str, const gchar *stock_id)
{
- IMPL
- // we'll make a delay for the actual search to wait for the user
- // to finish writting
- if (pThis->search_timeout_id)
- g_source_remove (pThis->search_timeout_id);
- pThis->search_timeout_id = g_timeout_add (500, search_cb, pThis);
+ GtkWidget *button, *image;
+ button = gtk_button_new_with_mnemonic (label_str);
+ if (stock_id) {
+ image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_BUTTON);
+ gtk_button_set_image (GTK_BUTTON (button), image);
+ }
+ return button;
}
+};
- struct FindClosure {
- bool found;
- GtkTreeView *view;
- PackageSelector *pThis;
- };
- static gboolean find_exact_match (GtkTreeModel *model, GtkTreePath *path,
- GtkTreeIter *iter, gpointer data)
- {
- FindClosure *cl = (FindClosure *) data;
-
- ZyppSelectablePtr sel = NULL;
-
- gtk_tree_model_get (model, iter, COL_SELECTABLE, &sel, -1);
-
- if (!sel)
- return FALSE;
-
- if (sel->name() == *cl->pThis->m_search_queries.begin()) {
- cl->found = true;
- gtk_tree_selection_select_iter
- (gtk_tree_view_get_selection (cl->view), iter);
- package_clicked_cb (gtk_tree_view_get_selection (cl->view), cl->pThis);
- return TRUE;
- }
- return FALSE;
- }
-
- void highlight_exact_matches ()
- {
- if (m_search_queries.empty() || !name_opt)
- return;
+class PackageInfo
+{
+GtkWidget *m_widget, *m_description, *m_filelist, *m_changelog, *m_authors;
- FindClosure cl;
- cl.found = false;
- cl.pThis = this;
- cl.view = GTK_TREE_VIEW (m_installed_view);
-
- gtk_tree_model_foreach (gtk_tree_view_get_model (cl.view),
- find_exact_match, &cl);
-
- if (!cl.found) {
- cl.view = GTK_TREE_VIEW (m_available_view);
- gtk_tree_model_foreach (gtk_tree_view_get_model (cl.view),
- find_exact_match, &cl);
- }
- }
+public:
+ GtkWidget *getWidget()
+ { return m_widget; }
- static gboolean search_cb (gpointer data)
+ PackageInfo()
{
- IMPL
-
- // This is potentially very slow ...
-#ifdef IMPL_DEBUG
- fprintf (stderr, "search start...\n");
-#endif
- PackageSelector *pThis = (PackageSelector *) data;
- pThis->search_timeout_id = 0;
-
- const gchar *query = gtk_entry_get_text (GTK_ENTRY (pThis->m_search_entry));
- bool plain_view = gtk_toggle_button_get_active (
- GTK_TOGGLE_BUTTON (pThis->m_plain_view));
- if (!plain_view)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (pThis->m_plain_view), TRUE);
- pThis->m_search_queries = YGUtils::splitString (query, ' ');
-
- // just re-filter
- GtkTreeModel *available_model =
- gtk_tree_view_get_model (GTK_TREE_VIEW (pThis->m_available_view));
- GtkTreeModel *installed_model =
- gtk_tree_view_get_model (GTK_TREE_VIEW (pThis->m_installed_view));
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (available_model));
- gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (installed_model));
-
- pThis->highlight_exact_matches ();
-
-#ifdef IMPL_DEBUG
- fprintf (stderr, "search done...\n");
-#endif
- return FALSE;
+ m_widget = gtk_notebook_new();
+ addPage (_("Description"), createHtmlWidget (&m_description));
+ addPage (_("File List"), createHtmlWidget (&m_filelist));
+ addPage (_("ChangeLog"), createHtmlWidget (&m_changelog));
+ addPage (_("Authors"), createHtmlWidget (&m_authors));
+ gtk_widget_set_size_request (m_widget, -1, 150);
+ ygtk_html_wrap_connect_link_clicked (m_filelist,
+ G_CALLBACK (path_pressed_cb), NULL);
}
- GtkMenu *create_search_menu()
+ void setPackage (Ypp::Package *package)
{
- GtkWidget *menu = gtk_menu_new();
- append_option_item (menu, _("Name"), &name_opt);
- append_option_item (menu, _("Summary"), &summary_opt);
- append_option_item (menu, _("Description"), &descr_opt);
- append_option_item (menu, _("RPM Provides"), &provides_opt);
- append_option_item (menu, _("RPM Requires"), &requires_opt);
- gtk_widget_show_all (menu);
- return GTK_MENU (menu);
+ if (package) {
+ setText (m_description, package->description());
+ setText (m_filelist, package->filelist());
+ setText (m_changelog, package->changelog());
+ setText (m_authors, package->authors());
+ if (!GTK_WIDGET_VISIBLE (m_widget)) {
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (m_widget), 0);
+ gtk_widget_show (m_widget);
+ }
+ }
+ else
+ gtk_widget_hide (m_widget);
}
- static void append_option_item (GtkWidget *menu, const char *label, bool *option)
+private:
+ static void path_pressed_cb (GtkWidget *text, const gchar *link)
+ { FILEMANAGER_LAUNCH (link); }
+
+ // utilities:
+ static GtkWidget *createHtmlWidget (GtkWidget **html_widget)
{
- GtkWidget *item = gtk_check_menu_item_new_with_label (label);
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), *option);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- g_signal_connect (G_OBJECT (item), "toggled",
- G_CALLBACK (search_option_change_cb), option);
+ *html_widget = ygtk_html_wrap_new();
+ GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (scroll), *html_widget);
+ return scroll;
}
- static void search_option_change_cb (GtkCheckMenuItem *item, bool *option)
- { *option = item->active; }
-
- inline static gboolean is_package_visible (GtkTreeModel *model, GtkTreeIter *iter,
- PackageSelector *pThis, int visible_col)
+ void addPage (const char *title, GtkWidget *content)
{
- gboolean visible, has_children;
- ZyppSelectablePtr selectable;
-
- gtk_tree_model_get (model, iter, visible_col, &visible,
- COL_HAS_CHILDREN, &has_children,
- COL_SELECTABLE, &selectable, -1);
-
-// fprintf (stderr, "is visible '%s'\n", selectable ? selectable->name().c_str() : "<noname>");
- if (has_children)
- visible = TRUE;
- else if (visible && !pThis->m_search_queries.empty())
- visible = pThis->does_package_match (selectable);
-
- return visible;
+ gtk_notebook_append_page (GTK_NOTEBOOK (m_widget), content, gtk_label_new (title));
}
- static gboolean is_package_installed (GtkTreeModel *model, GtkTreeIter *iter,
- gpointer data)
- { return is_package_visible (model, iter, (PackageSelector *) data, 3); }
-
- static gboolean is_package_available (GtkTreeModel *model, GtkTreeIter *iter,
- gpointer data)
+ void setText (GtkWidget *rtext, const std::string &text)
{
- gboolean is_installed, is_available, has_upgrade, has_children;
- gboolean visible = TRUE;
- ZyppSelectablePtr selectable;
- PackageSelector *pThis = (PackageSelector *) data;
-
- // only show the packages that aren't installed
- // unless there's an upgrade available
- gtk_tree_model_get (model, iter, COL_SELECTABLE, &selectable,
- COL_IS_INSTALLED, &is_installed,
- COL_IS_AVAILABLE, &is_available,
- COL_CAN_BE_UPGRADED, &has_upgrade,
- COL_HAS_CHILDREN, &has_children, -1);
- if (!has_children) {
- if (is_available && (!is_installed || has_upgrade)) {
- if (!pThis->m_search_queries.empty())
- visible = pThis->does_package_match (selectable);
- } else
- visible = FALSE;
+ if (text.empty()) {
+ const char *empty = _("<i>(only available for installed packages)</i>");
+ ygtk_html_wrap_set_text (rtext, empty);
}
-
- return visible;
+ else
+ ygtk_html_wrap_set_text (rtext, text.c_str());
+ ygtk_html_wrap_scroll (rtext, TRUE);
}
+};
- bool does_package_match_one (ZyppSelectablePtr sel, string key)
- {
- ZyppObject obj = NULL;
+class DiskView : public Ypp::Disk::Listener
+{
+GtkWidget *m_widget;
+bool m_hasWarn;
+GtkTreeModel *m_model;
- if (name_opt && YGUtils::contains (sel->name(), key))
- return TRUE;
-
- if (summary_opt || descr_opt || provides_opt || requires_opt)
- obj = sel->theObj();
-
- if (summary_opt && YGUtils::contains (fastGetSummary (obj), key))
- return TRUE;
- if (descr_opt && YGUtils::contains (obj->description(), key))
- return TRUE;
- if (provides_opt) {
- const zypp::CapSet &capSet = obj->dep (zypp::Dep::PROVIDES);
- for (zypp::CapSet::const_iterator it = capSet.begin();
- it != capSet.end(); it++)
- if (YGUtils::contains (it->asString(), key))
- return TRUE;
- }
- if (requires_opt) {
- const zypp::CapSet &capSet = obj->dep (zypp::Dep::REQUIRES);
- for (zypp::CapSet::const_iterator it = capSet.begin();
- it != capSet.end(); it++)
- if (YGUtils::contains (it->asString(), key))
- return TRUE;
- }
- return FALSE;
- }
+public:
+ GtkWidget *getWidget()
+ { return m_widget; }
- gboolean does_package_match (ZyppSelectablePtr sel)
+ DiskView()
+ : m_hasWarn (false)
{
- if (m_search_queries.empty())
- return true;
+ m_model = GTK_TREE_MODEL (gtk_list_store_new (
+ // 0 - mount point, 1 - usage percent, 2 - usage string
+ 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING));
+ m_widget = createCombo (m_model);
+ g_object_unref (G_OBJECT (m_model));
- bool and_results = true; // vs. or them ...
+ Ypp::get()->getDisk()->setListener (this);
+ update();
+ }
- bool result = and_results;
- for (list <string>::iterator it = m_search_queries.begin();
- it != m_search_queries.end(); it++) {
-
- // TODO: googlify more ...
- if (*it == "OR") {
- and_results = false;
- continue;
- }
- if (*it == "AND") {
- and_results = true;
- continue;
- }
- bool match = does_package_match_one (sel, *it);
- result = and_results ? result && match : result || match;
- }
- return result;
- }
-
- // callbacks
- static bool getSelectedPackage (GtkTreeView *tree_view,
- ZyppSelectablePtr *package_sel, GtkTreePath **_path = 0)
+private:
+ #define MIN_FREE_MB_WARN (80*1024)
+ virtual void update()
{
- IMPL
- GtkTreePath *path = 0;
- gtk_tree_view_get_cursor (tree_view, &path, NULL);
- if (path) {
- GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+ GtkListStore *store = GTK_LIST_STORE (m_model);
+ gtk_list_store_clear (store);
+
+ int warn_part = -1;
+ Ypp::Disk *disk = Ypp::get()->getDisk();
+ for (int i = 0; disk->getPartition (i); i++) {
+ const Ypp::Disk::Partition *part = disk->getPartition (i);
+ long usage = (part->used * 100) / (part->total + 1);
+ std::string usage_str = part->used_str + " (of " + part->total_str + ")";
GtkTreeIter iter;
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get (model, &iter, COL_SELECTABLE, package_sel, -1);
- if (_path)
- *_path = gtk_tree_model_filter_convert_path_to_child_path
- (GTK_TREE_MODEL_FILTER (model), path);
- gtk_tree_path_free (path);
- return true;
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, part->path.c_str(), 1, usage,
+ 2, usage_str.c_str(), -1);
+ if (warn_part < 0 && (part->total > 1024 && part->total - part->used < MIN_FREE_MB_WARN))
+ warn_part = i;
}
- return false;
+ if (warn_part >= 0) {
+ warn();
+ gtk_combo_box_set_active (GTK_COMBO_BOX (m_widget), warn_part);
+ }
+ else
+ gtk_combo_box_set_active (GTK_COMBO_BOX (m_widget), 0);
}
- // For SLED10 / older gtk+'s ...
- static bool compat_gtk_tree_model_filter_convert_child_iter_to_iter (GtkTreeModelFilter *filter,
- GtkTreeIter *filter_iter,
- GtkTreeIter *child_iter)
- {
-#if GTK_CHECK_VERSION(2,10,0)
- return gtk_tree_model_filter_convert_child_iter_to_iter (filter, filter_iter, child_iter);
-#else // cut/paste from gtk+ HEAD...
- gboolean ret;
- GtkTreePath *child_path, *path;
-
- memset (filter_iter, 0, sizeof (GtkTreeIter));
-
- GtkTreeModel *child_model;
- g_object_get (G_OBJECT (filter), "child-model", &child_model, NULL);
- child_path = gtk_tree_model_get_path (child_model, child_iter);
- g_return_val_if_fail (child_path != NULL, FALSE);
-
- path = gtk_tree_model_filter_convert_child_path_to_path (filter,
- child_path);
- gtk_tree_path_free (child_path);
-
- if (!path)
- return FALSE;
+ void warn()
+ {
+ if (m_hasWarn) return;
+ m_hasWarn = true;
- ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (filter), filter_iter, path);
- gtk_tree_path_free (path);
+ GtkWidget *dialog, *view;
+ dialog = gtk_message_dialog_new (YGUI::ui()->currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_OK, _("Disk Almost Full !"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ "One of the partitions is reaching its limit of capacity. You may "
+ "have to remove packages if you wish to install some.");
- return ret;
-#endif
- }
+ view = createView (m_model);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), view);
- static bool sync_tree_views_scroll (GtkTreeView *current_view, GtkTreeView *other_view,
- GtkTreePath *current_path, bool select_it)
- {
- /* What we do here is to scroll the other view to the correspondent
- package position. If the package isn't present in that view, we
- iterate it so we get the closest package (with respect to alphabetic
- sorting). */
-
- // converts the path from one model to the other
- GtkTreePath *_path, *other_path;
- _path = gtk_tree_model_filter_convert_path_to_child_path (
- GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (current_view)),
- current_path);
- if (!_path)
- return false;
-
- GtkTreeModel *base_model = gtk_tree_model_filter_get_model (
- GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (current_view)));
-
- GtkTreeIter iter, other_iter;
- gtk_tree_model_get_iter (base_model, &iter, _path);
- gtk_tree_path_free (_path);
-
- int timeout = 0;
- // Try to find a a similar item in the other view to synchronise with
- while (!compat_gtk_tree_model_filter_convert_child_iter_to_iter (
- GTK_TREE_MODEL_FILTER (gtk_tree_view_get_model (other_view)),
- &other_iter, &iter))
- {
- if (!gtk_tree_model_iter_next (base_model, &iter))
- return false;
- // This turns into N^3 very quickly if we search too hard
- if (timeout++ > 10)
- return false;
- select_it = false; // not the same package -- dont select it then
- }
-
- other_path = gtk_tree_model_get_path (gtk_tree_view_get_model (other_view),
- &other_iter);
-
- GdkRectangle cell_rect, visible_rect;
- gtk_tree_view_get_cell_area (other_view, other_path, NULL, &cell_rect);
- gtk_tree_view_get_visible_rect (other_view, &visible_rect);
- int y = visible_rect.y + cell_rect.y;
-
- gtk_tree_view_get_cell_area (current_view, current_path, NULL, &cell_rect);
- y -= cell_rect.y; // offset
-
- gtk_tree_view_expand_to_path (other_view, other_path);
- YGUtils::tree_view_smooth_scroll_to_point (other_view, 0, y);
- if (select_it)
- gtk_tree_selection_select_path (gtk_tree_view_get_selection (other_view),
- other_path);
- gtk_tree_path_free (other_path);
- return true;
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
}
- static void package_clicked_cb (GtkTreeSelection *selection, PackageSelector *pThis)
+ // utilities
+#if 1
+ static GtkWidget *createView (GtkTreeModel *model)
{
- IMPL
- int selected_rows = gtk_tree_selection_count_selected_rows (selection);
- if (selected_rows == 0)
- return;
-
- static bool safeguard = false;
- if (safeguard)
- return;
- safeguard = true;
+ GtkWidget *view = gtk_tree_view_new_with_model (model), *scroll;
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
+ gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)),
+ GTK_SELECTION_NONE);
- GtkTreeView *tree_view = gtk_tree_selection_get_tree_view (selection);
- bool install_view = tree_view == GTK_TREE_VIEW (pThis->m_installed_view);
- GtkTreeView *other_view = GTK_TREE_VIEW (install_view ?
- pThis->m_available_view : pThis->m_installed_view);
-
- // unselect the other view
- gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (other_view));
-
- // select and scroll to the package in the other view (if it's listed there)
- GtkTreePath *path = 0;
- gtk_tree_view_get_cursor (tree_view, &path, NULL);
- if (path) {
- // function can be called to set some package visible
- gtk_tree_view_scroll_to_cell (tree_view, path, NULL, FALSE, 0, 0);
+ GtkTreeViewColumn *column;
+ column = gtk_tree_view_column_new_with_attributes (_("Mount Point"),
+ gtk_cell_renderer_text_new(), "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ column = gtk_tree_view_column_new_with_attributes (_("Usage"),
+ gtk_cell_renderer_progress_new(), "value", 1, "text", 2, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
- sync_tree_views_scroll (tree_view, other_view, path, selected_rows == 1);
- gtk_tree_path_free (path);
- }
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+ GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+// gtk_widget_set_size_request (scroll, -1, 50);
+ gtk_container_add (GTK_CONTAINER (scroll), view);
+ gtk_widget_show_all (scroll);
+ return scroll;
+ }
+#endif
+ static GtkWidget *createCombo (GtkTreeModel *model)
+ {
+ GtkWidget *combo = gtk_combo_box_new_with_model (model);
+ GtkCellRenderer *renderer;
+ renderer = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo),
+ renderer, "text", 0, NULL);
+ // let's put all columns to the same width, to make it look like a table
+ g_object_set (G_OBJECT (renderer), "width-chars", 14, NULL);
+ renderer = gtk_cell_renderer_progress_new();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo),
+ renderer, "value", 1, "text", 2, NULL);
+ return combo;
+ }
+};
- // show package information
- ZyppSelectablePtr sel = 0;
- getSelectedPackage (tree_view, &sel);
-
- ZyppObject install_obj, available_obj;
- induceObjects (sel, install_obj, available_obj, NULL, NULL);
-
- ZyppObject &obj = install_view ? install_obj : available_obj;
- pThis->m_information_widget->setPackage (sel, obj);
-
- // change the install/remove button label to upgrade, or etc
- GtkLabel *install_label = GTK_LABEL (pThis->m_install_label),
- *remove_label = GTK_LABEL (pThis->m_remove_label);
- if (selected_rows > 1) {
- gtk_label_set_text (install_label, _("_install"));
- gtk_label_set_text (remove_label, _("_remove"));
- }
- else { // personalize
- // remove label
- if (sel && sel->toInstall())
- gtk_label_set_text (remove_label, _("_undo"));
- else
- gtk_label_set_text (remove_label, _("_remove"));
- // install label
- if (sel && sel->toDelete())
- gtk_label_set_text (install_label, _("_undo"));
- else if (!install_obj)
- gtk_label_set_text (install_label, _("_install"));
- else if (available_obj) {
- int res = zypp::Edition::compare (install_obj->edition(),
- available_obj->edition());
- if (res < 0)
- gtk_label_set_text (install_label, _("_upgrade"));
- else if (res > 0)
- gtk_label_set_text (install_label, _("_downgrade"));
- else
- gtk_label_set_text (install_label, _("re-_install"));
- }
- }
- gtk_label_set_use_underline (install_label, TRUE);
- gtk_label_set_use_underline (remove_label, TRUE);
+class PackageSelector : public Filters::Listener, public PackagesView::Listener
+{
+PackagesView *m_packages;
+Filters *m_filters;
+PackageInfo *m_info;
+PackageControl *m_control;
+DiskView *m_disk;
+GtkWidget *m_box;
+TrashWindow *m_trashWin;
- safeguard = false;
- }
+public:
+ GtkWidget *getWidget()
+ { return m_box; }
- // install/remove/update/... selected packages
- void markSelectedPackage (GtkTreeView *view, bool available, bool installed)
+ PackageSelector()
{
- IMPL
- /* Since the filter model gets changed, get paths for the base model and
- then do our stuff. */
- GList *selected = gtk_tree_selection_get_selected_rows (
- gtk_tree_view_get_selection (view), NULL);
-
- int selected_len = g_list_length (selected);
- GtkTreeIter iters [selected_len];
-
- GtkTreeModel *filter_model = gtk_tree_view_get_model (view);
- GtkTreeModelFilter *filter = GTK_TREE_MODEL_FILTER (filter_model);
- GtkTreeModel *model = gtk_tree_model_filter_get_model (filter);
-
- int i = 0;
- for (GList *it = selected; it; it = it->next, i++) {
- GtkTreePath *path = (GtkTreePath *) it->data;
+ m_packages = new PackagesView();
+ m_packages->setListener (this);
- GtkTreeIter filter_iter, iter;
- gtk_tree_model_get_iter (filter_model, &filter_iter, path);
- gtk_tree_path_free (path);
+ m_control = new PackageControl();
+ m_info = new PackageInfo();
- gtk_tree_model_filter_convert_iter_to_child_iter (filter, &iter, &filter_iter);
- iters[i] = iter;
- }
- g_list_free (selected);
- for (i = 0; i < selected_len; i++) {
- GtkTreeIter *iter = &iters[i];
- ZyppSelectablePtr sel = 0;
- gtk_tree_model_get (model, iter, COL_SELECTABLE, &sel, -1);
- if (sel && mark_selectable (sel, installed) /* install/remove */) {
- loadPackageRow (model, iter, sel); // update model
-
- // mark also children (eg. for patterns and languages)
- GtkTreeIter child;
- if (gtk_tree_model_iter_children (model, &child, iter)) {
- do {
- gtk_tree_model_get (model, &child, COL_SELECTABLE, &sel, -1);
- if (sel && mark_selectable (sel, installed))
- loadPackageRow (model, &child, sel);
- } while (gtk_tree_model_iter_next (model, &child));
+ GtkWidget *vbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), m_packages->getWidget(), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), m_control->getWidget(), FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), m_info->getWidget(), FALSE, TRUE, 0);
- }
- }
- }
+ m_filters = new Filters();
+ m_filters->setListener (this);
+ m_disk = new DiskView();
- m_disk_table->update();
+ GtkWidget *left_box = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (left_box), m_filters->getWidget(), TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (left_box), m_disk->getWidget(), FALSE, TRUE, 0);
- // select path, so the buttons get updated and all (hacky)
- GtkTreeView *other_view = GTK_TREE_VIEW (
- GTK_WIDGET (view) == m_installed_view ? m_available_view : m_installed_view);
- package_clicked_cb (gtk_tree_view_get_selection (other_view), this);
+ m_box = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (m_box), left_box, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (m_box), vbox, TRUE, TRUE, 0);
+ gtk_widget_show_all (m_box);
+
+ m_control->setPackages (std::list Ypp::Package* ());
+ m_info->setPackage (NULL);
+
+ m_trashWin = new TrashWindow();
}
- static void install_button_clicked_cb (GtkButton *button, PackageSelector *pThis)
+ ~PackageSelector()
{
- IMPL
- pThis->markSelectedPackage (GTK_TREE_VIEW (pThis->m_available_view), false, true);
- gtk_widget_grab_focus (pThis->m_available_view);
+ delete m_packages;
+ delete m_control;
+ delete m_info;
+ delete m_filters;
+ delete m_disk;
+ delete m_trashWin;
}
- static void remove_button_clicked_cb (GtkButton *button, PackageSelector *pThis)
+ virtual void doQuery (Ypp::Query *query)
{
- IMPL
- pThis->markSelectedPackage (GTK_TREE_VIEW (pThis->m_installed_view), true, false);
- gtk_widget_grab_focus (pThis->m_installed_view);
+ m_packages->query (query);
}
- static void change_available_version_cb (YGtkCellRendererArrow *renderer,
- guint arrow_type, const gchar *_path, PackageSelector *pThis)
+ virtual void packagesSelected (const std::list &packages)
{
- GtkTreeModel *model = gtk_tree_view_get_model (
- GTK_TREE_VIEW (pThis->m_available_view));
- GtkTreePath *path = gtk_tree_path_new_from_string (_path);
- GtkTreeIter it;
- gtk_tree_model_get_iter (model, &it, path);
- gtk_tree_path_free (path);
-
- GtkTreeIter iter;
- gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (model),
- &iter, &it);
- model = pThis->m_packages_model;
-
- ZyppSelectablePtr selectable;
- gtk_tree_model_get (model, &iter, COL_SELECTABLE, &selectable, -1);
-
- ZyppObject candidate = selectable->candidateObj();
- for (zypp::ui::Selectable::available_iterator it = selectable->availableBegin();
- it != selectable->availableEnd(); it++) {
- int cmp = zypp::Edition::compare ((*it)->edition(), candidate->edition());
- if (arrow_type == GTK_ARROW_UP) { // upgrade
- if (cmp > 0)
- candidate = *it;
- }
- else /*if (arrow_type == GTK_ARROW_DOWN)*/ { // downgrade
- if (cmp < 0)
- candidate = *it;
- }
- }
- if (!selectable->setCandidate (candidate))
- y2warning ("Error: Could not %sgrade\n", arrow_type == GTK_ARROW_UP ? "up" : "down");
- pThis->loadPackageRow (model, &iter, selectable);
+ m_control->setPackages (packages);
+ if (packages.size() == 1)
+ m_info->setPackage (packages.front());
+ else
+ m_info->setPackage (NULL);
}
- static gboolean dont_select_groups_cb (GtkTreeSelection *selection, GtkTreeModel *model,
- GtkTreePath *path, gboolean selected, gpointer data)
+ void packageModified (Ypp::Package *package)
{
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter (model, &iter, path)) {
- ZyppSelectablePtr selectable;
- gtk_tree_model_get (model, &iter, COL_SELECTABLE, &selectable, -1);
- return selectable != NULL;
- }
- return FALSE;
+ // GTK+ doesn't fire selection change when a selected row changes, so we need
+ // to re-load PackageControl in that occasions.
+ std::list ::iterator it;
+ for (it = m_control->m_packages.begin(); it != m_control->m_packages.end(); it++)
+ if (*it == package)
+ break;
+ if (it != m_control->m_packages.end())
+ m_control->setPackages (m_control->m_packages);
}
};
-// The ordinary package selector that displays all packages
-class YGPackageSelector : public YPackageSelector, public YGWidget
-{
- PackageSelector *m_package_selector;
-
- static bool confirm_cb (void *pThis)
- {
- return ((YGPackageSelector *)pThis)->checkDelete();
- }
-
- bool checkDelete()
- {
- bool changed =
- zyppPool().diffState() ||
- zyppPool().diffState() ||
- zyppPool().diffStatezypp::Selection() ||
- zyppPool().diffState() ||
- zyppPool().diffState();
- if (!changed)
- return true;
+#include "YPackageSelector.h"
- GtkWidget *dialog;
- dialog = gtk_message_dialog_new_with_markup
- (YGUI::ui()->currentWindow(),
- GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
- GTK_BUTTONS_NONE, _("<b>Abandon all changes?</b>"));
- gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
- GTK_STOCK_QUIT, GTK_RESPONSE_YES, NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog),
- GTK_RESPONSE_NO);
- bool ok = gtk_dialog_run (GTK_DIALOG (dialog)) ==
- GTK_RESPONSE_YES;
- gtk_widget_destroy (dialog);
- return ok;
- }
+class YGPackageSelector : public YPackageSelector, public YGWidget, public Ypp::Interface
+{
+PackageSelector *m_package_selector;
public:
YGPackageSelector (const YWidgetOpt &opt, YGWidget *parent)
@@ -2422,27 +1385,19 @@
YGWidget (this, parent, true, YGTK_TYPE_WIZARD, NULL)
{
setBorder (0);
-
YGDialog *dialog = YGUI::ui()->currentYGDialog();
dialog->setCloseCallback (confirm_cb, this);
- GtkWindow *window = dialog->getWindow();
- gtk_window_resize (window, MAX (680, GTK_WIDGET (window)->allocation.width),
+
+ GtkWindow *window = dialog->getWindow();
+ gtk_window_resize (window, GTK_WIDGET (window)->allocation.width,
MAX (580, GTK_WIDGET (window)->allocation.height));
YGtkWizard *wizard = YGTK_WIZARD (getWidget());
-
ygtk_wizard_set_header_icon (wizard, window,
THEMEDIR "/icons/32x32/apps/yast-software.png");
- ygtk_wizard_set_header_text (wizard, window, "Package Selector");
+ ygtk_wizard_set_header_text (wizard, window, _("Package Selector"));
ygtk_wizard_set_help_text (wizard,
- _("Two pools are presented; one with the available software, the other "
- "with the installed one. To install software you choose a package "
- "from the install pool and press Install. Similar method for removal "
- "of software. When you are done press the Accept button.<br>"
- "Information on a given package is displayed on the Package Information "
- "expander at the bottom which may be enlarged.<br>"
- "A categories view of the software is possible, as well as searching "
- "for a given package.")
+ _("TO WRITE")
);
ygtk_wizard_set_abort_button_label (wizard, _("_Cancel"));
@@ -2453,15 +1408,16 @@
g_signal_connect (G_OBJECT (getWidget()), "action-triggered",
G_CALLBACK (wizard_action_cb), this);
- m_package_selector = new PackageSelector (!opt.searchMode.value());
+ m_package_selector = new PackageSelector();
gtk_container_add (GTK_CONTAINER (wizard), m_package_selector->getWidget());
+
+ Ypp::get()->setInterface (this);
}
virtual ~YGPackageSelector()
{
- YGDialog *dialog = YGUI::ui()->currentYGDialog();
- dialog->unsetCloseCallback();
delete m_package_selector;
+ ygtk_zypp_model_finish();
}
protected:
@@ -2472,201 +1428,334 @@
const gchar *action = (gchar *) id;
if (!strcmp (action, "accept")) {
- if (zyppPool().diffState zypp::Package ()) {
- // in case of changes, check problems, ask for confirmation and JFDI.
- if (pThis->confirmChanges() && solveProblems()) {
- y2milestone ("Closing PackageSelector with 'accept'");
- YGUI::ui()->sendEvent (new YMenuEvent (YCPSymbol ("accept")));
- }
- }
- else
- YGUI::ui()->sendEvent (new YCancelEvent());
+ y2milestone ("Closing PackageSelector with 'accept'");
+ YGUI::ui()->sendEvent (new YMenuEvent (YCPSymbol ("accept")));
}
else if (!strcmp (action, "cancel")) {
y2milestone ("Closing PackageSelector with 'cancel'");
- if (pThis->checkDelete())
- YGUI::ui()->sendEvent (new YCancelEvent());
+ if (pThis->confirmExit())
+ YGUI::ui()->sendEvent (new YCancelEvent());
}
}
- // helper function for confirmChanges
- static bool isInstalled (const string &package)
- {
- for (ZyppPool::const_iterator it = zyppPool().byKindBegin zypp::Package();
- it != zyppPool().byKindEnd zypp::Package(); it++) {
- if ((*it)->hasInstalledObj() || (*it)->toInstall()) {
- if (package == (*it)->name())
- return true;
- ZyppObject obj = (*it)->theObj();
- const zypp::CapSet &caps = obj->dep (zypp::Dep::PROVIDES);
- for (zypp::CapSet::const_iterator jt = caps.begin();
- jt != caps.end(); jt++)
- if (package == jt->asString())
- return true;
- }
- }
- return false; // doesn't even exist
- }
+ bool confirmExit()
+ {
+ if (!Ypp::get()->isModified())
+ return true;
+
+ GtkWidget *dialog;
+ dialog = gtk_message_dialog_new
+ (YGUI::ui()->currentWindow(),
+ GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE, _("Changes not saved!"));
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+ _("Quit anyway?"));
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_NO,
+ GTK_STOCK_QUIT, GTK_RESPONSE_YES, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES);
+
+ bool ok = gtk_dialog_run (GTK_DIALOG (dialog)) ==
+ GTK_RESPONSE_YES;
+ gtk_widget_destroy (dialog);
+ return ok;
+ }
+ static bool confirm_cb (void *pThis)
+ { return ((YGPackageSelector *)pThis)->confirmExit(); }
- bool confirmChanges()
+ virtual bool acceptLicense (Ypp::Package *package, const std::string &license)
{
- IMPL
- if (zyppPool().empty zypp::Package ())
- return false;
+ std::string title = package->name() + _(" License Agreement");
+ GtkWidget *dialog = gtk_dialog_new_with_buttons (title.c_str(),
+ YGUI::ui()->currentWindow(), GTK_DIALOG_NO_SEPARATOR,
+ _("_Reject"), GTK_RESPONSE_REJECT, _("_Accept"), GTK_RESPONSE_ACCEPT, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
- GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Changes Summary"),
- YGUI::ui()->currentWindow(),
- GtkDialogFlags (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, _("C_onfirm"), GTK_RESPONSE_ACCEPT, NULL);
-
- GtkWidget *install_label, *remove_label, *install_view, *remove_view;
- install_label = gtk_label_new (_("To install:"));
- remove_label = gtk_label_new (_("To remove:"));
- install_view = gtk_tree_view_new();
- remove_view = gtk_tree_view_new();
-
- GtkWidget *install_window, *remove_window;
- install_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (install_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type
- (GTK_SCROLLED_WINDOW (install_window), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (install_window), install_view);
- remove_window = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (remove_window),
- GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ GtkWidget *license_view, *license_window;
+
+ license_view = ygtk_html_wrap_new();
+ ygtk_html_wrap_set_text (license_view, license.c_str());
+
+ license_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (license_window),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type
- (GTK_SCROLLED_WINDOW (remove_window), GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (remove_window), remove_view);
+ (GTK_SCROLLED_WINDOW (license_window), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (license_window), license_view);
GtkBox *vbox = GTK_BOX (GTK_DIALOG(dialog)->vbox);
- gtk_box_pack_start (vbox, install_label, FALSE, FALSE, 6);
- gtk_box_pack_start (vbox, install_window, TRUE, TRUE, 6);
- gtk_box_pack_start (vbox, remove_label, FALSE, FALSE, 6);
- gtk_box_pack_start (vbox, remove_window, TRUE, TRUE, 6);
+ gtk_box_pack_start (vbox, license_window, TRUE, TRUE, 6);
- // create model
- {
- GtkTreeStore *install_store = gtk_tree_store_new (1, G_TYPE_STRING);
- GtkTreeStore *remove_store = gtk_tree_store_new (1, G_TYPE_STRING);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
+ gtk_widget_show_all (dialog);
- // install view
- GtkTreeViewColumn *column;
- column = gtk_tree_view_column_new_with_attributes (_("Install packages"),
- gtk_cell_renderer_text_new(), "text", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (install_view), column);
-
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (install_view), FALSE);
- gtk_tree_view_set_model (GTK_TREE_VIEW (install_view),
- GTK_TREE_MODEL (install_store));
- g_object_unref (G_OBJECT (install_store));
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (
- GTK_TREE_VIEW (install_view)), GTK_SELECTION_NONE);;
-
- // remove view
- column = gtk_tree_view_column_new_with_attributes (_("Remove packages"),
- gtk_cell_renderer_text_new(), "text", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (remove_view), column);
-
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (remove_view), FALSE);
- gtk_tree_view_set_model (GTK_TREE_VIEW (remove_view),
- GTK_TREE_MODEL (remove_store));
- g_object_unref (G_OBJECT (remove_store));
- gtk_tree_selection_set_mode (gtk_tree_view_get_selection (
- GTK_TREE_VIEW (remove_view)), GTK_SELECTION_NONE);;
-
- // construct model
- for (ZyppPool::const_iterator it = zyppPool().byKindBegin zypp::Package();
- it != zyppPool().byKindEnd zypp::Package(); it++)
+ gint ret = gtk_dialog_run (GTK_DIALOG (dialog));
+ bool confirmed = (ret == GTK_RESPONSE_ACCEPT);
+
+ gtk_widget_destroy (dialog);
+ return confirmed;
+ }
+
+ virtual bool resolveProblems (std::list problems)
+ {
+fprintf (stderr, "resolving %d problems\n", problems.size());
+ // we can't use ordinary radio buttons, as gtk+ enforces that in a group
+ // one must be selected...
+
+ enum ColumnAlias {
+ SHOW_TOGGLE_COL, ACTIVE_TOGGLE_COL, TEXT_COL, WEIGHT_TEXT_COL,
+ APPLY_PTR_COL, TOOLTIP_TEXT_COL
+ };
+
+ struct inner {
+ static void solution_toggled (GtkTreeModel *model, GtkTreePath *path)
{
- ZyppSelectable selectable = *it;
- if (!selectable)
- continue;
-
- GtkTreeStore *store;
- if (selectable->toInstall())
- store = install_store;
- else if (selectable->toDelete())
- store = remove_store;
- else continue;
+ GtkTreeStore *store = GTK_TREE_STORE (model);
+ GtkTreeIter iter, parent;
- GtkTreeIter iter;
- gtk_tree_store_append (store, &iter, NULL);
- gtk_tree_store_set (store, &iter, 0, selectable->name().c_str(), -1);
+ gboolean enabled;
+ bool *apply;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, ACTIVE_TOGGLE_COL, &enabled,
+ APPLY_PTR_COL, &apply, -1);
+
+ // disable all the other radios on the group, setting current
+ gtk_tree_model_get_iter (model, &iter, path);
+ if (gtk_tree_model_iter_parent (model, &parent, &iter)) {
+ gtk_tree_model_iter_children (model, &iter, &parent);
+ do {
+ gtk_tree_store_set (store, &iter, ACTIVE_TOGGLE_COL, FALSE, -1);
+ bool *apply;
+ gtk_tree_model_get (model, &iter, APPLY_PTR_COL, &apply, -1);
+ *apply = false;
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
- // show dependencies -- we just ask Zypp for dependencies in the form
- // of a string (which is the only way to do it anyway).
- if (store == install_store) {
- GtkTreeIter dep_iter;
- ZyppObject object = selectable->theObj();
- const zypp::CapSet &capSet = object->dep (zypp::Dep::REQUIRES);
- for (zypp::CapSet::const_iterator it = capSet.begin();
- it != capSet.end(); it++) {
- // don't show if it is already installed
- if (isInstalled (it->asString()))
- continue;
-
- gtk_tree_store_append (store, &dep_iter, &iter);
- gtk_tree_store_set (store, &dep_iter,
- 0, it->asString().c_str(), -1);
- }
+ enabled = !enabled;
+ if (apply)
+ *apply = enabled;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_store_set (store, &iter, ACTIVE_TOGGLE_COL, enabled, -1);
+ }
+#if 0
+ static void renderer_toggled_cb (GtkCellRenderer *render, gchar *path_str,
+ GtkTreeModel *model)
+ {
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+ solution_toggled (model, path);
+ gtk_tree_path_free (path);
+ }
+#endif
+ static void cursor_changed_cb (GtkTreeView *view, GtkTreeModel *model)
+ {
+ GtkTreePath *path;
+ gtk_tree_view_get_cursor (view, &path, NULL);
+ solution_toggled (model, path);
+ gtk_tree_path_free (path);
+ }
+ static gboolean query_tooltip_cb (GtkWidget *view, gint x, gint y,
+ gboolean keyboard_mode, GtkTooltip *tooltip, gpointer data)
+ {
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ if (gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (view),
+ &x, &y, keyboard_mode, &model, &path, &iter)) {
+ gchar *tooltip_str;
+ gtk_tree_model_get (model, &iter, TOOLTIP_TEXT_COL,
+ &tooltip_str, -1);
+ gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (view), tooltip, path);
+ gtk_tree_path_free (path);
+ if (tooltip_str) {
+ gtk_tooltip_set_text (tooltip, tooltip_str);
+ g_free (tooltip_str);
+ return TRUE;
}
+ }
+ return FALSE;
- // show packages that require this -- we will need to iterate through
- // all the packages... (not very accurate)
- else {
- GtkTreeIter req_iter;
-
- for (ZyppPool::const_iterator it =
- zyppPool().byKindBegin zypp::Package();
- it != zyppPool().byKindEnd zypp::Package(); it++) {
- // only show if it is installed
- if ((*it)->hasInstalledObj() || (*it)->toInstall()) {
- ZyppSelectable dep_selectable = *it;
- ZyppObject dep_object = dep_selectable->theObj();
-
- const zypp::CapSet &capSet = dep_object->dep (zypp::Dep::REQUIRES);
- for (zypp::CapSet::const_iterator it = capSet.begin();
- it != capSet.end(); it++) {
- if (it->asString() == selectable->name()) {
- gtk_tree_store_append (store, &req_iter, &iter);
- gtk_tree_store_set (store, &req_iter,
- 0, dep_selectable->name().c_str(), -1);
- break;
- }
- }
- }
- }
+
+/*
+ GtkTreePath *path;
+ if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), x, y,
+ &path, NULL, NULL, NULL)) {
+ GtkTreeIter iter;
+ gchar *tooltip_text;
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_path_free (path);
+ gtk_tree_model_get (model, &iter,
+ TOOLTIP_TEXT_COL, &tooltip_text, -1);
+ // some strings are just " ", so we need to check that
+ // now,
+ bool empty = true;
+ for (int i = 0; tooltip_text[i] && empty; i++)
+ if (tooltip_text[i] != ' ')
+ empty = false;
+ if (empty)
+ gtk_tooltip_set_text (tooltip, "(no details)");
+ else
+ gtk_tooltip_set_text (tooltip, tooltip_text);
+ g_free (tooltip_text);
+ return TRUE;
}
+ return FALSE;
+*/
+ }
+ };
+
+ // model
+ GtkTreeStore *store = gtk_tree_store_new (6, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
+ G_TYPE_STRING, G_TYPE_INT, G_TYPE_POINTER, G_TYPE_STRING);
+ for (std::list ::iterator it = problems.begin();
+ it != problems.end(); it++) {
+ GtkTreeIter problem_iter;
+ gtk_tree_store_append (store, &problem_iter, NULL);
+ gtk_tree_store_set (store, &problem_iter, SHOW_TOGGLE_COL, FALSE,
+ TEXT_COL, (*it)->description.c_str(),
+ WEIGHT_TEXT_COL, PANGO_WEIGHT_BOLD, APPLY_PTR_COL, NULL,
+ TOOLTIP_TEXT_COL, (*it)->details.c_str(), -1);
+
+ for (int i = 0; (*it)->getSolution (i); i++) {
+ Ypp::Problem::Solution *solution = (*it)->getSolution (i);
+ GtkTreeIter solution_iter;
+ const gchar *tooltip_text = solution->details.c_str();
+ if (solution->details.empty())
+ tooltip_text = NULL;
+ gtk_tree_store_append (store, &solution_iter, &problem_iter);
+ gtk_tree_store_set (store, &solution_iter, SHOW_TOGGLE_COL, TRUE,
+ ACTIVE_TOGGLE_COL, FALSE, TEXT_COL, solution->description.c_str(),
+ APPLY_PTR_COL, &solution->apply,
+ TOOLTIP_TEXT_COL, tooltip_text, -1);
+ }
+ }
+
+ // interface
+ GtkWidget *dialog = gtk_message_dialog_new (YGUI::ui()->currentWindow(),
+ GtkDialogFlags (0), GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE,
+ _("There are some conflicts on the transaction that must be "
+ "solved manually."));
+ gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY);
+
+ GtkWidget *view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
+ g_object_unref (G_OBJECT (store));
+ gtk_tree_selection_set_mode (gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (view)), GTK_SELECTION_NONE);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (view), FALSE);
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), TEXT_COL);
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ renderer = gtk_cell_renderer_toggle_new();
+ gtk_cell_renderer_toggle_set_radio (
+ GTK_CELL_RENDERER_TOGGLE (renderer), TRUE);
+/* g_signal_connect (G_OBJECT (renderer), "toggled",
+ G_CALLBACK (inner::renderer_toggled_cb), store);*/
+ // we should not connect the actual toggle button, as we toggle on row press
+ g_signal_connect (G_OBJECT (view), "cursor-changed",
+ G_CALLBACK (inner::cursor_changed_cb), store);
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "visible", SHOW_TOGGLE_COL, "active", ACTIVE_TOGGLE_COL, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes ("", renderer,
+ "text", TEXT_COL, "weight", WEIGHT_TEXT_COL, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view), column);
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+ gtk_widget_set_has_tooltip (view, TRUE);
+ g_signal_connect (G_OBJECT (view), "query-tooltip",
+ G_CALLBACK (inner::query_tooltip_cb), store);
+
+ GtkWidget *scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll),
+ GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (scroll), view);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll);
+
+
+#if 0
+ // version that uses viewport, labels and radio buttons -- unfortunately,
+ // gtk+ enforces that one radio button per group to be selected -- we don't
+ // want that as the user may decide to do nothing for a certain action.
+ // We also don't want to add a "Do nothing" radio, as that would imply would
+ // dismiss the conflict. No, we just want to let the user try to resolve current
+ // conflicts...
+ struct inner {
+ static void solution_toggled (GtkToggleButton *toggle, bool *apply)
+ { *apply = gtk_toggle_button_get_active (toggle); }
+ };
+
+ GtkWidget *dialog = gtk_dialog_new_with_buttons (_("Problem Resolver"),
+ YGUI::ui()->currentWindow(), GtkDialogFlags (0),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL);
+
+ GtkWidget *view_port = gtk_viewport_new (NULL, NULL);
+ gtk_viewport_set_shadow_type (GTK_VIEWPORT (view_port), GTK_SHADOW_NONE);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), view_port,
+ TRUE, TRUE, 0);
+ GtkWidget *main_box = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (view_port), main_box);
+
+fprintf (stderr, "populating main box\n");
+ for (std::list ::iterator it = problems.begin();
+ it != problems.end(); it++) {
+ GtkWidget *label, *box;
+fprintf (stderr, "creating label: %s\n", (*it)->description.c_str());
+ label = gtk_label_new ((*it)->description.c_str());
+ YGUtils::setWidgetFont (label, PANGO_WEIGHT_BOLD, PANGO_SCALE_MEDIUM);
+fprintf (stderr, "setting tooltyp: %s\n", (*it)->details.c_str());
+ if (!(*it)->details.empty())
+ gtk_widget_set_tooltip_text (label, (*it)->details.c_str());
+
+ GSList *group = NULL;
+ box = gtk_vbox_new (FALSE, 6);
+ for (int i = 0; (*it)->getSolution (i); i++) {
+ Ypp::Problem::Solution *solution = (*it)->getSolution (i);
+fprintf (stderr, "creating radio: %s\n", solution->description.c_str());
+ GtkWidget *radio = gtk_radio_button_new_with_label (
+ group, solution->description.c_str());
+fprintf (stderr, "setting tooltip: %s\n", (*it)->details.c_str());
+ if (!solution->details.empty())
+ gtk_widget_set_tooltip_text (radio, solution->details.c_str());
+ group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio));
+ gtk_box_pack_start (GTK_BOX (box), radio, FALSE, TRUE, 0);
+ g_signal_connect (G_OBJECT (radio), "toggled",
+ G_CALLBACK (inner::solution_toggled), &solution->apply);
}
+
+ gtk_box_pack_start (GTK_BOX (main_box), label, FALSE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (main_box), box, FALSE, TRUE, 0);
}
+#endif
- gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 400);
+ gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 480);
gtk_widget_show_all (dialog);
- bool confirmed = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT;
+ bool apply = (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_APPLY);
gtk_widget_destroy (dialog);
+ return apply;
+ }
- return confirmed;
+ virtual void packageModified (Ypp::Package *package)
+ {
+ m_package_selector->packageModified (package);
}
YGWIDGET_IMPL_COMMON
};
-#endif /*DISABLE_PACKAGE_SELECTOR*/
YWidget *
YGUI::createPackageSelector (YWidget *parent, YWidgetOpt &opt,
const YCPString &floppyDevice)
{
- // TODO: floppyDevice really needed?
-#ifndef DISABLE_PACKAGE_SELECTOR
- if (opt.youMode.value())
+/* if (opt.youMode.value())
return new YGPatchSelector (opt, YGWidget::get (parent));
- else
+ else*/
return new YGPackageSelector (opt, YGWidget::get (parent));
-#else
- return NULL;
-#endif
}
YWidget *
Modified: trunk/gtk/src/YGProgressBar.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGProgressBar.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGProgressBar.cc (original)
+++ trunk/gtk/src/YGProgressBar.cc Thu Dec 20 21:36:55 2007
@@ -120,8 +120,7 @@
{
// ygtk_ratio_box_set_homogeneous (YGTK_RATIO_BOX (getWidget()), TRUE);
ygtk_ratio_box_set_spacing (YGTK_RATIO_BOX (getWidget()), 2);
-
- for (int i = segments()-1; i >= 0; i--) {
+ for (int s = 0; s < segments(); s++) {
GtkWidget* bar = gtk_progress_bar_new();
gtk_progress_bar_set_orientation (GTK_PROGRESS_BAR (bar),
horizontal ? GTK_PROGRESS_LEFT_TO_RIGHT : GTK_PROGRESS_BOTTOM_TO_TOP);
@@ -132,7 +131,7 @@
else
gtk_widget_set_size_request (bar, -1, min_size);
ygtk_ratio_box_pack (YGTK_RATIO_BOX (getWidget()), bar,
- maxValue (i), TRUE, TRUE, 0);
+ getSegmentWeight (s), TRUE, TRUE, 0);
}
ygtk_adj_size_set_max (YGTK_ADJ_SIZE (m_adj_size), horizontal ? 200 : 0,
@@ -143,17 +142,29 @@
virtual void doUpdate()
{
GList* children = gtk_container_get_children (GTK_CONTAINER (getWidget()));
- int n = segments()-1;
- for (GList *i = children; i && n >= 0; i = i->next, n--) {
+ int s = 0;
+ for (GList *i = children; i && s < segments(); i = i->next, s++) {
GtkProgressBar *bar = GTK_PROGRESS_BAR (i->data);
- gfloat fraction = 0;
- if (currentValue (n) != -1)
- fraction = 1.0 - ((gfloat) currentValue(n) / maxValue(n));
- gtk_progress_bar_set_fraction (bar, fraction);
+ gtk_progress_bar_set_fraction (bar, getSegmentValue (s));
}
g_list_free (children);
}
+ int getSegmentWeight (int n)
+ {
+ if (vertical())
+ n = (segments() - n) - 1;
+ return maxValue (n);
+ }
+ float getSegmentValue (int n)
+ {
+ if (vertical())
+ n = (segments() - n) - 1;
+ if (currentValue (n) == -1)
+ return 0;
+ return 1.0 - (((float) currentValue (n)) / maxValue (n));
+ }
+
YGWIDGET_IMPL_COMMON
};
Modified: trunk/gtk/src/YGPushButton.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGPushButton.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGPushButton.cc (original)
+++ trunk/gtk/src/YGPushButton.cc Thu Dec 20 21:36:55 2007
@@ -30,8 +30,6 @@
G_CALLBACK (set_default_cb), this);
}
- virtual ~YGPushButton() {}
-
// YPushButton
virtual void setLabel (const YCPString &label)
{
Modified: trunk/gtk/src/YGUI.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUI.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGUI.cc (original)
+++ trunk/gtk/src/YGUI.cc Thu Dec 20 21:36:55 2007
@@ -644,9 +644,7 @@
// debug dialogs
-static void destroy_dialog (GtkDialog *dialog, gint arg)
-{ IMPL; gtk_widget_destroy (GTK_WIDGET (dialog)); }
-
+//#define IS_VALID_COL
void dumpYastTree (YWidget *widget)
{
IMPL
@@ -667,7 +665,11 @@
gchar *weight = g_strdup_printf ("%ld x %ld",
widget->weight (YD_HORIZ), widget->weight (YD_VERT));
gtk_tree_store_set (store, &iter, 0, widget->widgetClass(),
- 1, ygwidget->getDebugLabel().c_str(), 2, stretch, 3, weight, -1);
+ 1, ygwidget->getDebugLabel().c_str(), 2, stretch, 3, weight,
+#ifdef IS_VALID_COL
+ 4, widget->isValid(),
+#endif
+ -1);
g_free (stretch);
g_free (weight);
@@ -675,14 +677,37 @@
for (int i = 0; i < container->numChildren(); i++)
dumpYastTree (container->child (i), store, &iter);
}
+ static void dialog_response_cb (GtkDialog *dialog, gint response, YWidget *ywidget)
+ {
+ if (response == 1) {
+ GtkTreeStore *store;
+ GtkTreeView *view;
+ store = (GtkTreeStore *) g_object_get_data (G_OBJECT (dialog), "store");
+ view = (GtkTreeView *) g_object_get_data (G_OBJECT (dialog), "view");
+ gtk_tree_store_clear (store);
+ dumpYastTree (ywidget, store, NULL);
+ gtk_tree_view_expand_all (view);
+ }
+ else
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+ }
};
- GtkTreeStore *store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING);
- inner::dumpYastTree (widget, store, NULL);
+ int cols = 4;
+#ifdef IS_VALID_COL
+ cols++;
+#endif
+ GtkTreeStore *store = gtk_tree_store_new (cols,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING
+#ifdef IS_VALID_COL
+ , G_TYPE_BOOLEAN
+#endif
+ );
GtkWidget *dialog = gtk_dialog_new_with_buttons ("YWidgets Tree", NULL,
- GtkDialogFlags (GTK_DIALOG_NO_SEPARATOR), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
+ GtkDialogFlags (GTK_DIALOG_NO_SEPARATOR), GTK_STOCK_REFRESH, 1,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
gtk_window_set_default_size (GTK_WINDOW (dialog), -1, 400);
GtkWidget *view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
@@ -692,13 +717,19 @@
gtk_tree_view_append_column (GTK_TREE_VIEW (view),
gtk_tree_view_column_new_with_attributes ("Label",
gtk_cell_renderer_text_new(), "text", 1, NULL));
+ gtk_tree_view_column_set_expand (gtk_tree_view_get_column (
+ GTK_TREE_VIEW (view), 1), TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW (view),
gtk_tree_view_column_new_with_attributes ("Stretch",
gtk_cell_renderer_text_new(), "text", 2, NULL));
gtk_tree_view_append_column (GTK_TREE_VIEW (view),
gtk_tree_view_column_new_with_attributes ("Weight",
gtk_cell_renderer_text_new(), "text", 3, NULL));
- gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+#ifdef IS_VALID_COL
+ gtk_tree_view_append_column (GTK_TREE_VIEW (view),
+ gtk_tree_view_column_new_with_attributes ("Valid",
+ gtk_cell_renderer_toggle_new(), "active", 4, NULL));
+#endif
gtk_tree_view_set_enable_tree_lines (GTK_TREE_VIEW (view), TRUE);
GtkWidget *scroll_win = gtk_scrolled_window_new (NULL, NULL);
@@ -709,10 +740,16 @@
gtk_container_add (GTK_CONTAINER (scroll_win), view);
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scroll_win);
- gtk_widget_show_all (dialog);
+ inner::dumpYastTree (widget, store, NULL);
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+
+ g_object_set_data (G_OBJECT (dialog), "view", view);
+ g_object_set_data (G_OBJECT (dialog), "store", store);
g_signal_connect (G_OBJECT (dialog), "response",
- G_CALLBACK (destroy_dialog), 0);
+ G_CALLBACK (inner::dialog_response_cb), widget);
+
+ gtk_widget_show_all (dialog);
}
#include
@@ -754,6 +791,8 @@
for (int i = 0; i < container->numChildren(); i++)
dumpYastHtml (container->child (i), box);
}
+ static void destroy_dialog (GtkDialog *dialog, gint arg)
+ { gtk_widget_destroy (GTK_WIDGET (dialog)); }
};
IMPL
@@ -765,6 +804,6 @@
gtk_widget_show_all (dialog);
g_signal_connect (G_OBJECT (dialog), "response",
- G_CALLBACK (destroy_dialog), 0);
+ G_CALLBACK (inner::destroy_dialog), 0);
}
Modified: trunk/gtk/src/YGUtils.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUtils.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGUtils.cc (original)
+++ trunk/gtk/src/YGUtils.cc Thu Dec 20 21:36:55 2007
@@ -66,6 +66,8 @@
void YGUtils::replace (string &str, const char *mouth, int mouth_len, const char *food)
{
+ if (mouth_len < 0)
+ mouth_len = strlen (mouth);
unsigned int i = 0;
while ((i = str.find (mouth, i)) != string::npos)
{
@@ -87,83 +89,27 @@
gtk_text_buffer_delete_mark (buffer, end_mark);
}
-/* Strings can ask for not being escape with the comment
- <!-- DT:Rich --> */
-static bool dont_escape (const string &str)
-{
- const char *comment = "<!-- DT:Rich -->";
- if (str.length() < sizeof (comment))
- return false;
- for (unsigned int i = 0; i < sizeof (comment); i++)
- if (str[i] != comment[i])
- return false;
- return true;
-}
-
-string YGUtils::escape_markup (const string &str, bool break_lines)
+void YGUtils::escapeMarkup (string &str)
{
- if (dont_escape (str))
- return string (str);
-
- string ret;
- ret.reserve (str.length());
for (unsigned int i = 0; i < str.length(); i++) {
- char ch = str[i];
- switch (ch) {
+ switch (str[i]) {
case '<':
- ret += "<";
+ str.erase (i, 1);
+ str.insert (i, "<");
break;
case '>':
- ret += ">";
+ str.erase (i, 1);
+ str.insert (i, ">");
break;
case '&':
- ret += "&";
- break;
- case '\n':
- ret += "<br/>";
+ str.erase (i, 1);
+ str.insert (i, "&");
break;
default:
- ret += ch;
break;
}
}
-
- return ret;
-}
-
-#if 0
-string YGUtils::escape_break_lines (const string &str, bool paragraph_mode)
-{
- if (dont_escape (str))
- return str;
- string res;
- res.reserve (str.length() + 6);
- if (paragraph_mode)
- res = "<p>";
- /* on paragraph mode, dont break when there is no text on the paragraph.
- otherwise, just dont break at the start of the text. */
- bool dont_break = true;
- for (unsigned int i = 0; i != str.length(); i++) {
- char ch = str[i];
- if (paragraph_mode && ch == '\n' && str[i-1] == '\n') {
- if (!dont_break)
- res += "</p><p>";
- dont_break = true;
- }
- else if (!paragraph_mode && ch == '\n') {
- if (!dont_break)
- res += "<br>";
- }
- else {
- res += ch;
- dont_break = false;
- }
- }
- if (paragraph_mode)
- res += "</p>";
- return res;
}
-#endif
#define PROD_ENTITY "&product;"
@@ -503,7 +449,9 @@
{
std::list <string> parts;
unsigned int i, j;
- for (j = 0, i = 0; i < str.length(); i++)
+ // ignore first character, if separator
+ i = j = (str[0] == separator) ? 1 : 0;
+ for (; i < str.length(); i++)
if (str[i] == separator) {
parts.push_back (str.substr (j, i - j));
j = ++i;
Modified: trunk/gtk/src/YGUtils.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGUtils.h?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGUtils.h (original)
+++ trunk/gtk/src/YGUtils.h Thu Dec 20 21:36:55 2007
@@ -9,6 +9,14 @@
#include <list>
#include
#include
+#include
+#include
+#include
+
+// TODO: do a cleanup here. We should probably split string, gtk and stuff
+// Some GtkTreeView should probably go to their own files
+// Let's avoid GTK+ stuff, better to replicate that, if needed, than leave in
+// this general purpose utils.
/* YGUtils.h/cc have some functionality that is shared between different parts
of the code. */
@@ -16,13 +24,13 @@
namespace YGUtils
{
/* Replaces Yast's '&' accelerator by Gnome's '_' (and proper escaping). */
- string mapKBAccel (const char *src);
+ std::string mapKBAccel (const char *src);
/* Filters characters that are not on the valids_chars array from the text string
Length is used to tell the length of text, in case it isn't NUL
terminated (you may pass -1, if it is).
Use the compare string member if you want to see if there was any change. */
- string filterText (const char* text, int length, const char* valid_chars);
+ std::string filterText (const char* text, int length, const char* valid_chars);
/* Convenience call for widgets that implement GtkEditable interface.
This function inserts and deletes text, if needed, so you may want
@@ -31,11 +39,10 @@
const char *valid_chars);
/* Replaces every 'mouth' by 'food' in 'str'. */
- void replace (string &str, const char *mouth, int mouth_len, const char *food);
+ void replace (std::string &str, const char *mouth, int mouth_len, const char *food);
- /* Escapes markup text (eg. changes '<' by '\<').
- If break_line is true, the break line character will be transformed in <br/> */
- string escape_markup (const string &str, bool break_line = false);
+ /* Escapes markup text (eg. changes '<' by '\<'). */
+ void escapeMarkup (std::string &str);
/* Adds functionality to GtkTextView to scroll to bottom. */
void scrollTextViewDown(GtkTextView *text_view);
@@ -52,11 +59,11 @@
int strcmp (const char *str1, const char *str2);
/* Checks if a std::string contains some other string (case insensitive). */
- bool contains (const string &haystack, const string &needle);
+ bool contains (const std::string &haystack, const std::string &needle);
/* Splits a string into parts as separated by the separator characters.
eg: splitString ("Office/Writer", '/') => { "Office", "Writer" } */
- std::list <string> splitString (const string &str, char separator);
+ std::list std::string splitString (const std::string &str, char separator);
/* Prints a GtkTreeModel for debugging purposes. */
void print_model (GtkTreeModel *model, int string_col);
Modified: trunk/gtk/src/YGWizard.cc
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/YGWizard.cc?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/YGWizard.cc (original)
+++ trunk/gtk/src/YGWizard.cc Thu Dec 20 21:36:55 2007
@@ -128,11 +128,9 @@
G_CALLBACK (action_triggered_cb), this);
}
- ~YGWizard()
+ virtual ~YGWizard()
{
- delete m_back_button;
- delete m_abort_button;
- delete m_next_button;
+ // m_back/abort/next_button are added as children and will be freed by ~YContainerWidget
}
/* The purpose of this function is to do some sanity checks, besides
Modified: trunk/gtk/src/ygdkmngloader.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygdkmngloader.c?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/ygdkmngloader.c (original)
+++ trunk/gtk/src/ygdkmngloader.c Thu Dec 20 21:36:55 2007
@@ -113,7 +113,8 @@
return ret;
is_file_mng_failed:
- fclose (file);
+ if (file)
+ fclose (file);
return FALSE;
}
Modified: trunk/gtk/src/ygtkratiobox.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkratiobox.h?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/ygtkratiobox.h (original)
+++ trunk/gtk/src/ygtkratiobox.h Thu Dec 20 21:36:55 2007
@@ -96,8 +96,6 @@
gboolean *yfill, guint *padding,
gboolean *expandable);
-void ygtk_ratio_box_set_force_min_weight (YGtkRatioBox *box, gboolean force);
-
/* RatioHBox */
#define YGTK_TYPE_RATIO_HBOX (ygtk_ratio_hbox_get_type ())
Modified: trunk/gtk/src/ygtkwizard.c
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkwizard.c?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/ygtkwizard.c (original)
+++ trunk/gtk/src/ygtkwizard.c Thu Dec 20 21:36:55 2007
@@ -312,7 +312,7 @@
wizard->m_title_image = gtk_image_new();
wizard->m_title_label = gtk_label_new("");
gtk_label_set_ellipsize (GTK_LABEL (wizard->m_title_label), PANGO_ELLIPSIZE_END);
- gtk_misc_set_alignment (GTK_MISC (wizard->m_title_label), 0, 0);
+ gtk_misc_set_alignment (GTK_MISC (wizard->m_title_label), 0, 0.5);
// setup label look
gtk_widget_modify_fg (wizard->m_title_label, GTK_STATE_NORMAL,
@@ -366,7 +366,7 @@
gtk_size_group_add_widget (buttons_group, wizard->m_abort_button);
g_object_unref (G_OBJECT (buttons_group));
- //** The menu and the navigation widget will be created when requested.
+ //** The menu and the navigation widgets will be created when requested.
//** Help dialog will be build on realize so we can give it a parent window.
}
@@ -413,8 +413,9 @@
DESTROY_WIDGET (wizard->m_title)
DESTROY_WIDGET (wizard->m_buttons)
DESTROY_WIDGET (wizard->m_menu)
- DESTROY_WIDGET (wizard->m_navigation)
+ DESTROY_WIDGET (wizard->m_steps)
DESTROY_WIDGET (wizard->m_title)
+ DESTROY_WIDGET (wizard->m_pane)
#undef DESTROY_WIDGET
if (wizard->m_help_dialog) {
@@ -445,56 +446,75 @@
void ygtk_wizard_enable_steps (YGtkWizard *wizard)
{
- if (wizard->m_navigation) {
- g_error ("YGtkWizard: a tree or steps widgets have already been enabled.");
- return;
- }
- wizard->m_navigation_widget = ygtk_steps_new();
- wizard->m_navigation = wizard->m_navigation_widget;
- gtk_widget_modify_text (wizard->m_navigation_widget, GTK_STATE_NORMAL,
- &wizard->m_navigation_widget->style->fg [GTK_STATE_SELECTED]);
+ g_return_if_fail (wizard->m_steps == NULL);
- gtk_widget_set_parent (wizard->m_navigation, GTK_WIDGET (wizard));
- gtk_widget_show_all (wizard->m_navigation);
+ wizard->m_steps = ygtk_steps_new();
+ gtk_widget_modify_text (wizard->m_steps, GTK_STATE_NORMAL,
+ &wizard->m_steps->style->fg [GTK_STATE_SELECTED]);
+
+ gtk_widget_set_parent (wizard->m_steps, GTK_WIDGET (wizard));
+ gtk_widget_show (wizard->m_steps);
+ gtk_widget_queue_resize (GTK_WIDGET (wizard));
}
void ygtk_wizard_enable_tree (YGtkWizard *wizard)
{
- if (wizard->m_navigation) {
- g_error ("YGtkWizard: a tree or steps widgets have already been enabled.");
- return;
- }
+ g_return_if_fail (wizard->m_tree == NULL);
- wizard->m_navigation_widget = gtk_tree_view_new_with_model
+ wizard->m_tree_view = gtk_tree_view_new_with_model
(GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING)));
- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (wizard->m_navigation_widget),
- 0, "(no title)", gtk_cell_renderer_text_new(), "text", 0, NULL);
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (wizard->m_navigation_widget), FALSE);
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (wizard->m_tree_view),
+ 0, "", gtk_cell_renderer_text_new(), "text", 0, NULL);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (wizard->m_tree_view), FALSE);
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (
- GTK_TREE_VIEW (wizard->m_navigation_widget)), GTK_SELECTION_BROWSE);
+ GTK_TREE_VIEW (wizard->m_tree_view)), GTK_SELECTION_BROWSE);
- g_signal_connect (G_OBJECT (wizard->m_navigation_widget), "cursor-changed",
+ g_signal_connect (G_OBJECT (wizard->m_tree_view), "cursor-changed",
G_CALLBACK (tree_item_selected_cb), wizard);
- wizard->m_navigation = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wizard->m_navigation),
+ wizard->m_tree = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (wizard->m_tree),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (wizard->m_navigation),
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (wizard->m_tree),
GTK_SHADOW_IN);
- gtk_container_add (GTK_CONTAINER (wizard->m_navigation), wizard->m_navigation_widget);
- gtk_widget_set_size_request (wizard->m_navigation, 180, -1);
+ gtk_container_add (GTK_CONTAINER (wizard->m_tree), wizard->m_tree_view);
+ gtk_widget_set_size_request (wizard->m_tree, 180, -1);
- gtk_widget_set_parent (wizard->m_navigation, GTK_WIDGET (wizard));
- gtk_widget_show_all (wizard->m_navigation);
- gtk_widget_queue_draw (GTK_WIDGET (wizard));
+ GtkWidget *child = wizard->m_child, *pane;
+ pane = gtk_hpaned_new();
+ gtk_paned_pack1 (GTK_PANED (pane), wizard->m_tree, TRUE, TRUE);
+ gtk_widget_show_all (pane);
+ ygtk_wizard_set_child (wizard, pane);
+ wizard->m_pane = pane;
+ if (child)
+ gtk_container_add (GTK_CONTAINER (wizard), child);
+}
+
+static void ygtk_wizard_add_child (GtkContainer *container, GtkWidget *child)
+{
+ YGtkWizard *wizard = YGTK_WIZARD (container);
+ wizard->m_child = child;
+ if (wizard->m_pane)
+ gtk_paned_pack2 (GTK_PANED (wizard->m_pane), child, TRUE, FALSE);
+ else
+ GTK_CONTAINER_CLASS (ygtk_wizard_parent_class)->add (container, child);
+}
+
+static void ygtk_wizard_remove_child (GtkContainer *container, GtkWidget *child)
+{
+ YGtkWizard *wizard = YGTK_WIZARD (container);
+ wizard->m_child = NULL;
+ if (wizard->m_pane)
+ gtk_container_remove (GTK_CONTAINER (wizard->m_pane), child);
+ else
+ GTK_CONTAINER_CLASS (ygtk_wizard_parent_class)->remove (container, child);
}
void ygtk_wizard_set_child (YGtkWizard *wizard, GtkWidget *new_child)
{
- GtkWidget *child = GTK_BIN (wizard)->child;
- if (child)
- gtk_container_remove (GTK_CONTAINER (wizard), child);
+ if (wizard->m_child)
+ gtk_container_remove (GTK_CONTAINER (wizard), wizard->m_child);
if (new_child)
gtk_container_add (GTK_CONTAINER (wizard), new_child);
}
@@ -520,7 +540,7 @@
const char *text, const char *id)
{
GtkTreeModel *model = gtk_tree_view_get_model
- (GTK_TREE_VIEW (wizard->m_navigation_widget));
+ (GTK_TREE_VIEW (wizard->m_tree_view));
GtkTreeIter iter;
if (!parent_id || !*parent_id)
@@ -552,7 +572,7 @@
void ygtk_wizard_clear_tree (YGtkWizard *wizard)
{
- GtkTreeView *tree = GTK_TREE_VIEW (wizard->m_navigation_widget);
+ GtkTreeView *tree = GTK_TREE_VIEW (wizard->m_tree_view);
gtk_tree_store_clear (GTK_TREE_STORE (gtk_tree_view_get_model (tree)));
yg_hash_table_remove_all (wizard->tree_ids);
}
@@ -563,17 +583,17 @@
if (path == NULL)
return FALSE;
- g_signal_handlers_block_by_func (wizard->m_navigation_widget,
+ g_signal_handlers_block_by_func (wizard->m_tree_view,
(gpointer) tree_item_selected_cb, wizard);
- GtkWidget *widget = wizard->m_navigation_widget;
+ GtkWidget *widget = wizard->m_tree_view;
gtk_tree_view_expand_to_path (GTK_TREE_VIEW (widget), path);
gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget), path,
NULL, FALSE);
gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (widget), path, NULL,
TRUE, 0.5, 0.5);
- g_signal_handlers_unblock_by_func (wizard->m_navigation_widget,
+ g_signal_handlers_unblock_by_func (wizard->m_tree_view,
(gpointer) tree_item_selected_cb, wizard);
return TRUE;
}
@@ -766,15 +786,15 @@
void ygtk_wizard_add_step_header (YGtkWizard *wizard, const char *text)
{
- g_return_if_fail (wizard->m_navigation_widget != NULL);
- ygtk_steps_append_heading (YGTK_STEPS (wizard->m_navigation_widget), text);
+ g_return_if_fail (wizard->m_steps != NULL);
+ ygtk_steps_append_heading (YGTK_STEPS (wizard->m_steps), text);
}
void ygtk_wizard_add_step (YGtkWizard *wizard, const char* text, const char *id)
{
guint step_nb;
- g_return_if_fail (wizard->m_navigation_widget != NULL);
- step_nb = ygtk_steps_append (YGTK_STEPS (wizard->m_navigation_widget), text);
+ g_return_if_fail (wizard->m_steps != NULL);
+ step_nb = ygtk_steps_append (YGTK_STEPS (wizard->m_steps), text);
g_hash_table_insert (wizard->steps_ids, g_strdup (id), GINT_TO_POINTER (step_nb));
}
@@ -783,14 +803,13 @@
gpointer step_nb = g_hash_table_lookup (wizard->steps_ids, id);
if (!step_nb)
return FALSE;
- ygtk_steps_set_current (YGTK_STEPS (wizard->m_navigation_widget),
- GPOINTER_TO_INT (step_nb));
+ ygtk_steps_set_current (YGTK_STEPS (wizard->m_steps), GPOINTER_TO_INT (step_nb));
return TRUE;
}
void ygtk_wizard_clear_steps (YGtkWizard *wizard)
{
- ygtk_steps_clear (YGTK_STEPS (wizard->m_navigation_widget));
+ ygtk_steps_clear (YGTK_STEPS (wizard->m_steps));
yg_hash_table_remove_all (wizard->steps_ids);
}
@@ -809,7 +828,7 @@
const gchar *ygtk_wizard_get_tree_selection (YGtkWizard *wizard)
{
GtkTreePath *path;
- gtk_tree_view_get_cursor (GTK_TREE_VIEW (wizard->m_navigation_widget),
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (wizard->m_tree_view),
&path, NULL);
if (path == NULL)
return NULL;
@@ -825,7 +844,7 @@
void ygtk_wizard_set_sensitive (YGtkWizard *wizard, gboolean sensitive)
{
- // FIXME: check if this chains through
+ // TODO: check if this chains through
gtk_widget_set_sensitive (GTK_WIDGET (wizard), sensitive);
if (ygtk_wizard_is_next_button_protected (wizard))
@@ -862,8 +881,8 @@
{
GtkRequisition nav_req, child_req;
- if (wizard->m_navigation) {
- gtk_widget_size_request (wizard->m_navigation, &nav_req);
+ if (wizard->m_steps) {
+ gtk_widget_size_request (wizard->m_steps, &nav_req);
nav_req.width += content_padding * 2;
nav_req.height += content_padding * 2;
}
@@ -951,8 +970,8 @@
nav_area.x = child_area.x;
nav_area.y = child_area.y;
nav_area.height = child_area.height;
- if (wizard->m_navigation) {
- gtk_widget_get_child_requisition (wizard->m_navigation, &req);
+ if (wizard->m_steps) {
+ gtk_widget_get_child_requisition (wizard->m_steps, &req);
nav_area.width = req.width + content_padding*2;
child_area.x += nav_area.width;
@@ -981,9 +1000,9 @@
}
// navigation pane
- if (wizard->m_navigation) {
+ if (wizard->m_steps) {
apply_allocation_padding (&nav_area, content_padding);
- gtk_widget_size_allocate (wizard->m_navigation, &nav_area);
+ gtk_widget_size_allocate (wizard->m_steps, &nav_area);
}
// buttons
@@ -1025,10 +1044,10 @@
w -= content_padding*2;
y += wizard->m_title->allocation.height + header_padding*2 + content_padding;
h -= wizard->m_title->allocation.height + header_padding*2 + content_padding*2;
- if (wizard->m_navigation) {
- int navigation_w = wizard->m_navigation->allocation.width;
- x += navigation_w + content_padding;
- w -= navigation_w + content_padding;
+ if (wizard->m_steps) {
+ int steps_w = wizard->m_steps->allocation.width;
+ x += steps_w + content_padding;
+ w -= steps_w + content_padding;
}
gdk_cairo_set_source_color (cr, &widget->style->bg [GTK_STATE_NORMAL]);
@@ -1042,8 +1061,8 @@
if (wizard->m_menu)
gtk_container_propagate_expose (container, wizard->m_menu, event);
gtk_container_propagate_expose (container, wizard->m_title, event);
- if (wizard->m_navigation)
- gtk_container_propagate_expose (container, wizard->m_navigation, event);
+ if (wizard->m_steps)
+ gtk_container_propagate_expose (container, wizard->m_steps, event);
gtk_container_propagate_expose (container, wizard->m_buttons, event);
if (GTK_BIN (container)->child)
gtk_container_propagate_expose (container, GTK_BIN (container)->child, event);
@@ -1059,8 +1078,8 @@
(*callback) (wizard->m_buttons, callback_data);
if (wizard->m_menu)
(*callback) (wizard->m_menu, callback_data);
- if (wizard->m_navigation)
- (*callback) (wizard->m_navigation, callback_data);
+ if (wizard->m_steps)
+ (*callback) (wizard->m_steps, callback_data);
}
GtkWidget *containee = GTK_BIN (container)->child;
@@ -1068,150 +1087,6 @@
(*callback) (containee, callback_data);
}
-/* Accessibility support */
-
-static gint ygtk_wizard_accessible_get_n_children (AtkObject *accessible)
-{
- return 1 /* content*/ + 5 /* buttons*/;
-}
-
-static AtkObject *ygtk_wizard_accessible_ref_child (AtkObject *accessible,
- gint index)
-{
- GtkWidget *widget = GTK_ACCESSIBLE (accessible)->widget;
- if (!widget)
- return NULL;
- YGtkWizard *wizard = YGTK_WIZARD (widget);
-
- if (index == 0) {
- GtkWidget *child = GTK_BIN (wizard)->child;
- if (child)
- return g_object_ref (G_OBJECT (child));
- return NULL;
- }
-
- if (index >= 1 && index <= 5) {
- GtkWidget *buttons[5] = { wizard->m_back_button, wizard->m_abort_button,
- wizard->m_next_button, wizard->m_help_button,
- wizard->m_release_notes_button };
- GtkWidget *button = buttons [index-1];
-
- if (GTK_WIDGET_VISIBLE (button))
- return g_object_ref (G_OBJECT (button));
- return NULL;
- }
- // out of range
- return NULL;
-}
-
-static void ygtk_wizard_accessible_class_init (AtkObjectClass *class)
-{
- class->get_n_children = ygtk_wizard_accessible_get_n_children;
- class->ref_child = ygtk_wizard_accessible_ref_child;
-}
-
-static GType ygtk_wizard_accessible_get_type (void)
-{
- static GType type = 0;
- if (!type) {
- AtkObjectFactory *factory;
- GType derived_type;
- GTypeQuery query;
- GType derived_atk_type;
-
- derived_type = g_type_parent (YGTK_TYPE_WIZARD);
- factory = atk_registry_get_factory (atk_get_default_registry (), derived_type);
- derived_atk_type = atk_object_factory_get_accessible_type (factory);
- g_type_query (derived_atk_type, &query);
-
- GTypeInfo type_info = { 0 };
- type_info.class_size = query.class_size;
- type_info.class_init = (GClassInitFunc) ygtk_wizard_accessible_class_init;
- type_info.instance_size = query.instance_size;
-
- type = g_type_register_static (derived_atk_type, "YGtkWizardAccessible",
- &type_info, 0);
-
-/*
- type = g_type_register_static_simple (derived_atk_type,
- "YGtkWizardAccessible", query.class_size,
- (GClassInitFunc) ygtk_wizard_accessible_class_init,
- query.instance_size, NULL, 0);
-*/
- }
- return type;
-}
-
-static AtkObject *ygtk_wizard_accessible_new (GObject *obj)
-{
- AtkObject *accessible;
- g_return_val_if_fail (YGTK_IS_WIZARD (obj), NULL);
-
- accessible = g_object_new (ygtk_wizard_accessible_get_type (), NULL);
- atk_object_initialize (accessible, obj);
- return accessible;
-}
-
-static GType ygtk_wizard_accessible_factory_get_accessible_type()
-{
- return ygtk_wizard_accessible_get_type ();
-}
-
-static AtkObject*ygtk_wizard_accessible_factory_create_accessible (GObject *obj)
-{
- return ygtk_wizard_accessible_new (obj);
-}
-
-static void ygtk_wizard_accessible_factory_class_init (AtkObjectFactoryClass *class)
-{
- class->create_accessible = ygtk_wizard_accessible_factory_create_accessible;
- class->get_accessible_type = ygtk_wizard_accessible_factory_get_accessible_type;
-}
-
-static GType ygtk_wizard_accessible_factory_get_type (void)
-{
- static GType type = 0;
- if (!type) {
- GTypeInfo type_info = { 0 };
- type_info.class_size = sizeof (AtkObjectFactoryClass);
- type_info.class_init = (GClassInitFunc) ygtk_wizard_accessible_factory_class_init;
- type_info.instance_size = sizeof (AtkObjectFactory);
-
- type = g_type_register_static (ATK_TYPE_OBJECT_FACTORY,
- "YGtkWizardAccessibleFactory", &type_info, 0);
-
-/*
- type = g_type_register_static_simple (ATK_TYPE_OBJECT_FACTORY,
- "YGtkWizardAccessibleFactory", sizeof (AtkObjectFactoryClass),
- (GClassInitFunc) ygtk_wizard_accessible_factory_class_init,
- sizeof (AtkObjectFactory), NULL, 0);
-*/
- }
- return type;
-}
-
-static AtkObject *ygtk_wizard_get_accessible (GtkWidget *widget)
-{
- static gboolean first_time = TRUE;
- if (first_time) {
- AtkObjectFactory *factory;
- AtkRegistry *registry;
- GType derived_type;
- GType derived_atk_type;
-
- derived_type = g_type_parent (YGTK_TYPE_WIZARD);
- registry = atk_get_default_registry ();
- factory = atk_registry_get_factory (registry, derived_type);
- derived_atk_type = atk_object_factory_get_accessible_type (factory);
- if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE)) {
- atk_registry_set_factory_type (registry, YGTK_TYPE_WIZARD,
- ygtk_wizard_accessible_factory_get_type ());
- }
- first_time = FALSE;
- }
- return GTK_WIDGET_CLASS (ygtk_wizard_parent_class)->get_accessible (widget);
-}
-
static void ygtk_wizard_class_init (YGtkWizardClass *klass)
{
ygtk_wizard_parent_class = g_type_class_peek_parent (klass);
@@ -1222,10 +1097,11 @@
widget_class->realize = ygtk_wizard_realize;
widget_class->size_request = ygtk_wizard_size_request;
widget_class->size_allocate = ygtk_wizard_size_allocate;
- widget_class->get_accessible = ygtk_wizard_get_accessible;
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
container_class->forall = ygtk_wizard_forall;
+ container_class->add = ygtk_wizard_add_child;
+ container_class->remove = ygtk_wizard_remove_child;
GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass);
gtkobject_class->destroy = ygtk_wizard_destroy;
Modified: trunk/gtk/src/ygtkwizard.h
URL: http://svn.opensuse.org/viewcvs/yast/trunk/gtk/src/ygtkwizard.h?rev=43212&r1=43211&r2=43212&view=diff
==============================================================================
--- trunk/gtk/src/ygtkwizard.h (original)
+++ trunk/gtk/src/ygtkwizard.h Thu Dec 20 21:36:55 2007
@@ -81,11 +81,12 @@
GHashTable *steps_ids; /* gchar* -> guint */
/* Widgets for layout. */
- GtkWidget *m_menu, *m_title, *m_navigation, *m_buttons;
+ GtkWidget *m_menu, *m_title, *m_steps, *m_tree, *m_buttons;
+ GtkWidget *m_child, *m_pane;
// containee can be accessed via GTK_BIN (wizard)->child
/* Widgets we need to have access to. */
- GtkWidget *m_title_label, *m_title_image, *m_navigation_widget,
+ GtkWidget *m_title_label, *m_title_image, *m_tree_view,
*m_back_button, *m_abort_button, *m_next_button, *m_help_button,
*m_release_notes_button;
--
To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org
For additional commands, e-mail: yast-commit+help@opensuse.org