11 #define YUILogComponent "gtk"
16 #include "YGPackageSelector.h"
17 #include "ygtkpkglistview.h"
18 #include "ygtktreeview.h"
19 #include "ygtktreemodel.h"
20 #include "ygtkcellrenderertext.h"
21 #include "ygtkcellrendererbutton.h"
22 #include "ygtkcellrenderersidebutton.h"
26 #define GRAY_COLOR "#727272"
32 HAS_UPGRADE_PROP = TOTAL_PROPS, TO_UPGRADE_PROP, CAN_TOGGLE_INSTALL_PROP,
33 MANUAL_MODIFY_PROP, IS_LOCKED_PROP,
37 FOREGROUND_PROP, BACKGROUND_PROP, REPOSITORY_STOCK_PROP,
44 static GType _columnType (
int col)
47 case NAME_PROP:
case ACTION_NAME_PROP:
case NAME_SUMMARY_PROP:
48 case VERSION_PROP:
case SINGLE_VERSION_PROP:
case REPOSITORY_PROP:
49 case SUPPORT_PROP:
case SIZE_PROP:
case STATUS_ICON_PROP:
50 case ACTION_BUTTON_PROP:
case ACTION_ICON_PROP:
case FOREGROUND_PROP:
51 case BACKGROUND_PROP:
case REPOSITORY_STOCK_PROP:
53 case INSTALLED_CHECK_PROP:
54 case HAS_UPGRADE_PROP:
case TO_UPGRADE_PROP:
case CAN_TOGGLE_INSTALL_PROP:
55 case MANUAL_MODIFY_PROP:
case IS_LOCKED_PROP:
56 return G_TYPE_BOOLEAN;
60 return G_TYPE_POINTER;
71 { addSelListener (
this); }
74 { removeSelListener (
this); }
76 void setHighlight (std::list <std::string> keywords)
77 { m_keywords = keywords; }
81 std::list <std::string> m_keywords;
83 virtual int rowsNb() {
return m_list.size(); }
84 virtual int columnsNb()
const {
return TOTAL_IMPL_PROPS; }
85 virtual bool showEmptyEntry()
const {
return false; }
87 virtual GType columnType (
int col)
const
88 {
return _columnType (col); }
90 virtual void getValue (
int row,
int col, GValue *value)
95 std::string str (sel.name());
96 highlightMarkupSpan (str, m_keywords);
97 g_value_set_string (value, str.c_str());
100 case ACTION_NAME_PROP: {
101 std::string str (
"<b>"), name (sel.name());
102 str.reserve (name.size() + 35);
103 str += getStatusAction (&sel);
106 g_value_set_string (value, str.c_str());
109 case NAME_SUMMARY_PROP: {
110 std::string name (sel.name()), summary (sel.summary()), str;
111 summary = YGUtils::escapeMarkup (summary);
112 highlightMarkupSpan (name, m_keywords);
113 highlightMarkupSpan (summary, m_keywords);
114 str.reserve (name.size() + summary.size() + 64);
116 if (!summary.empty()) {
118 str +=
"<span color=\"" GRAY_COLOR
"\">";
119 str +=
"<small>" + summary +
"</small>";
122 g_value_set_string (value, str.c_str());
125 case REPOSITORY_PROP: {
127 if (sel.hasCandidateVersion()) {
129 str = getRepositoryLabel (repo);
134 str = getRepositoryLabel (repo);
137 g_value_set_string (value, str.c_str());
140 case REPOSITORY_STOCK_PROP: {
141 const char *stock = 0;
142 if (sel.hasCandidateVersion()) {
144 stock = getRepositoryStockIcon (repo);
149 stock = getRepositoryStockIcon (repo);
152 g_value_set_string (value, stock);
156 if (sel.type() == Ypp::Selectable::PACKAGE) {
158 std::string str (Ypp::Package::supportSummary (pkg.support()));
159 g_value_set_string (value, str.c_str());
164 Size_t size = sel.anyVersion().size();
165 g_value_set_string (value, size.asString().c_str());
172 bool hasCandidate = sel.hasCandidateVersion();
176 if (sel.isInstalled()) {
178 if (candidate > installed)
180 if (candidate < installed)
185 str +=
"<span color=\"blue\">";
187 if (sel.type() == Ypp::Selectable::PACKAGE) {
189 patch = pkg.isCandidatePatch();
193 str +=
"<span color=\"red\">";
196 if (sel.isInstalled()) {
198 str +=
"<span color=\"red\">";
199 str += sel.installed().number();
204 str += sel.candidate().number();
207 str += sel.candidate().number();
209 { str +=
" <small>"; str += _(
"patch"); str +=
"</small>"; }
210 str +=
"</span>\n<small>";
211 str += sel.installed().number();
214 g_value_set_string (value, str.c_str());
217 case SINGLE_VERSION_PROP: {
220 if (sel.hasCandidateVersion() && !sel.toRemove())
221 str = sel.candidate().number();
223 str = sel.installed().number();
224 g_value_set_string (value, str.c_str());
227 case INSTALLED_CHECK_PROP: {
231 else if (sel.toRemove())
234 installed = sel.isInstalled();
235 g_value_set_boolean (value, installed);
238 case HAS_UPGRADE_PROP:
239 g_value_set_boolean (value, sel.hasUpgrade());
241 case TO_UPGRADE_PROP:
242 g_value_set_boolean (value, sel.hasUpgrade() && sel.toInstall());
244 case CAN_TOGGLE_INSTALL_PROP:
245 g_value_set_boolean (value, !sel.isInstalled() || sel.canRemove());
247 case MANUAL_MODIFY_PROP:
248 g_value_set_boolean (value, sel.toModify() && !sel.toModifyAuto());
251 g_value_set_boolean (value, !sel.isLocked());
253 case BACKGROUND_PROP: {
254 const char *color = 0;
257 g_value_set_string (value, color);
260 case FOREGROUND_PROP: {
261 const char *color = 0;
262 if (sel.toModifyAuto())
264 g_value_set_string (value, color);
268 int xpad = sel.toModifyAuto() ? 20 : 0;
269 g_value_set_int (value, xpad);
272 case STATUS_ICON_PROP:
273 g_value_set_string (value, getStatusStockIcon (sel));
275 case ACTION_ICON_PROP: {
278 stock = GTK_STOCK_UNDO;
279 else if (sel.isInstalled())
280 stock = GTK_STOCK_REMOVE;
282 stock = GTK_STOCK_ADD;
283 g_value_set_string (value, stock);
286 case ACTION_BUTTON_PROP: {
290 else if (sel.isInstalled())
294 g_value_set_string (value, text);
298 g_value_set_pointer (value, (
void *) &sel);
303 virtual void selectableModified()
305 for (
int i = 0; i < rowsNb(); i++)
306 listener->rowChanged (i);
310 static Ypp::Selectable *ygtk_zypp_model_get_sel (GtkTreeModel *model, gchar *path_str)
313 gtk_tree_model_get_iter_from_string (model, &iter, path_str);
315 gtk_tree_model_get (model, &iter, PTR_PROP, &sel, -1);
319 static Ypp::Selectable *ygtk_zypp_model_get_sel (GtkTreeModel *model, GtkTreePath *path)
322 gtk_tree_model_get_iter (model, &iter, path);
324 gtk_tree_model_get (model, &iter, PTR_PROP, &sel, -1);
331 GtkWidget *scroll, *view;
334 bool descriptiveTooltip;
335 int sort_attrb, ascendent : 2;
337 std::list <std::string> m_keywords;
338 bool indentAuto, colorModified;
340 Impl (
bool descriptiveTooltip,
int default_sort_attrb,
bool indentAuto,
bool colorModified)
341 : listener (NULL), list (0), descriptiveTooltip (descriptiveTooltip),
342 sort_attrb (default_sort_attrb), ascendent (
true), userModified (
false),
343 indentAuto (indentAuto), colorModified (colorModified) {}
345 void setList (
Ypp::List _list,
int _attrb,
bool _ascendent,
bool userSorted,
const std::list <std::string> &keywords)
347 if (userSorted) userModified =
true;
348 if (_list != list || sort_attrb != _attrb || ascendent != _ascendent) {
350 if (_list == list && sort_attrb == _attrb)
353 _list.sort ((Ypp::List::SortAttribute) _attrb, _ascendent);
357 ascendent = _ascendent;
360 GtkTreeModel *model = ygtk_tree_model_new (
new YGtkZyppModel (list));
361 gtk_tree_view_set_model (GTK_TREE_VIEW (view), model);
362 g_object_unref (G_OBJECT (model));
363 setHighlight (keywords);
366 GList *columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
367 for (GList *i = columns; i; i = i->next) {
368 GtkTreeViewColumn *column = (GtkTreeViewColumn *) i->data;
369 bool v = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (column),
"attrb")) == _attrb;
370 gtk_tree_view_column_set_sort_indicator (column, v);
372 gtk_tree_view_column_set_sort_order (column,
373 ascendent ? GTK_SORT_ASCENDING : GTK_SORT_DESCENDING);
375 g_list_free (columns);
379 gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), NAME_PROP);
382 void setHighlight (
const std::list <std::string> &keywords)
384 if (m_keywords.empty() && keywords.empty())
return;
385 m_keywords = keywords;
386 GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
388 zmodel->setHighlight (keywords);
389 gtk_widget_queue_draw (view);
393 static void right_click_cb (YGtkTreeView *view, gboolean outreach,
YGtkPkgListView *pThis)
396 static void appendItem (GtkWidget *menu,
const char *_label,
397 const char *tooltip,
const char *stock,
bool sensitive,
403 label = YGUtils::mapKBAccel (_label);
406 item = gtk_image_menu_item_new_with_mnemonic (label.c_str());
407 GtkWidget *image = gtk_image_new_from_stock (stock, GTK_ICON_SIZE_MENU);
408 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
411 item = gtk_image_menu_item_new_from_stock (stock, NULL);
414 item = gtk_menu_item_new_with_mnemonic (label.c_str());
416 gtk_widget_set_tooltip_markup (item, tooltip);
417 gtk_widget_set_sensitive (item, sensitive);
418 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
419 g_signal_connect (G_OBJECT (item),
"activate", G_CALLBACK (callback), pThis);
422 { pThis->getSelected().install(); }
424 { reinstall (pThis->getSelected()); }
426 { pThis->getSelected().remove(); }
428 { pThis->getSelected().undo(); }
430 { pThis->getSelected().lock (
true); }
432 { pThis->getSelected().lock (
false); }
434 { pThis->selectAll(); }
436 static bool canReinstall (
Ypp::List list)
438 for(
int i = 0; i < list.size(); i++) {
440 if (sel.hasInstalledVersion()) {
443 for (j = 0; j < sel.totalVersions(); j++) {
445 if (!version.isInstalled() && version == installedVersion)
448 if(j == sel.totalVersions())
458 for(
int i = 0; i < list.size(); i++) {
461 for (
int j = 0; j < sel.totalVersions(); j++) {
463 if (!version.isInstalled() && version == installedVersion) {
464 sel.setCandidate (version);
473 GtkWidget *menu = gtk_menu_new();
475 Ypp::Selectable::Type type = Ypp::Selectable::PACKAGE;
477 type = list.get(0).type();
482 bool canLock = props.canLock(), unlocked = props.isUnlocked();
483 bool modified = props.toModify();
484 bool locked = !unlocked && canLock;
485 if (props.isNotInstalled() && !modified)
486 inner::appendItem (menu, _(
"&Install"), 0, GTK_STOCK_SAVE,
487 !locked, inner::install_cb, pThis);
488 if (props.hasUpgrade() && !modified)
489 inner::appendItem (menu, _(
"&Upgrade"), 0, GTK_STOCK_GO_UP,
490 !locked, inner::install_cb, pThis);
491 if (type == Ypp::Selectable::PACKAGE && inner::canReinstall(list) && !modified)
492 inner::appendItem (menu, _(
"&Re-install"), 0, GTK_STOCK_REFRESH,
493 !locked, inner::reinstall_cb, pThis);
494 if (props.isInstalled() && !modified)
495 inner::appendItem (menu, _(
"&Remove"), 0, GTK_STOCK_DELETE,
496 !locked && props.canRemove(), inner::remove_cb, pThis);
498 inner::appendItem (menu, _(
"&Undo"), 0, GTK_STOCK_UNDO,
499 true, inner::undo_cb, pThis);
501 static const char *lock_tooltip =
502 "<b>Package lock:</b> prevents the package status from being modified by "
503 "the dependencies resolver.";
504 if (props.isLocked())
505 inner::appendItem (menu, _(
"&Unlock"), _(lock_tooltip),
506 GTK_STOCK_DIALOG_AUTHENTICATION,
true, inner::unlock_cb, pThis);
508 inner::appendItem (menu, _(
"&Lock"), _(lock_tooltip),
509 GTK_STOCK_DIALOG_AUTHENTICATION, !modified,
510 inner::lock_cb, pThis);
514 if (type == Ypp::Selectable::PACKAGE || type == Ypp::Selectable::PATCH) {
515 GList *items = gtk_container_get_children (GTK_CONTAINER (menu));
519 gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new());
520 inner::appendItem (menu, NULL, NULL, GTK_STOCK_SELECT_ALL,
521 true, inner::select_all_cb, pThis);
522 ygtk_tree_view_append_show_columns_item (YGTK_TREE_VIEW (pThis->impl->view), menu);
524 ygtk_tree_view_popup_menu (YGTK_TREE_VIEW (pThis->impl->view), menu);
527 static void selection_changed_cb (GtkTreeSelection *selection,
YGtkPkgListView *pThis)
529 if (gtk_widget_get_realized (pThis->impl->view) && pThis->impl->listener)
530 pThis->impl->listener->selectionChanged();
533 static void row_activated_cb (GtkTreeView *view, GtkTreePath *path,
536 YGUI::ui()->busyCursor();
537 if (YGPackageSelector::get()->yield())
return;
539 GtkTreeModel *model = gtk_tree_view_get_model (view);
543 else if (sel->isInstalled())
548 YGUI::ui()->normalCursor();
551 static void check_toggled_cb (GtkCellRendererToggle *renderer, gchar *path_str,
554 YGUI::ui()->busyCursor();
555 if (YGPackageSelector::get()->yield())
return;
557 GtkTreeView *view = GTK_TREE_VIEW (pThis->impl->view);
558 GtkTreeModel *model = gtk_tree_view_get_model (view);
561 gboolean active = gtk_cell_renderer_toggle_get_active (renderer);
565 active ? sel->remove() : sel->install();
567 YGUI::ui()->normalCursor();
573 YGUI::ui()->busyCursor();
574 if (YGPackageSelector::get()->yield())
return;
576 GtkTreeView *view = GTK_TREE_VIEW (pThis->impl->view);
577 GtkTreeModel *model = gtk_tree_view_get_model (view);
579 sel->toInstall() ? sel->undo() : sel->install();
581 YGUI::ui()->normalCursor();
587 GtkTreeView *view = GTK_TREE_VIEW (pThis->impl->view);
588 GtkTreeModel *model = gtk_tree_view_get_model (view);
596 GtkTreeView *view = GTK_TREE_VIEW (pThis->impl->view);
597 GtkTreeModel *model = gtk_tree_view_get_model (view);
601 else if (sel->isInstalled())
607 static gboolean query_tooltip_cb (GtkWidget *widget, gint x, gint y,
610 GtkTreeView *view = GTK_TREE_VIEW (widget);
614 if (gtk_tree_view_get_tooltip_context (view,
615 &x, &y, keyboard_mode, &model, &path, &iter)) {
616 gtk_tree_view_set_tooltip_row (view, tooltip, path);
619 gtk_tree_path_free (path);
622 const char *icon = 0;
624 GtkTreeViewColumn *column;
626 gtk_tree_view_convert_widget_to_bin_window_coords (
627 view, x, y, &bx, &by);
628 gtk_tree_view_get_path_at_pos (
629 view, x, y, NULL, &column, NULL, NULL);
631 GtkIconSize icon_size = GTK_ICON_SIZE_MENU;
632 if (column == ygtk_tree_view_get_column (YGTK_TREE_VIEW (view), 0)) {
633 text = getStatusSummary (*sel);
634 icon = getStatusStockIcon (*sel);
636 else if (pThis->impl->descriptiveTooltip) {
637 text = std::string (
"<b>") + sel->name() +
"</b>\n\n";
638 text += sel->description (
false);
639 switch (sel->type()) {
640 case Ypp::Selectable::PATTERN: {
641 ZyppPattern pattern = castZyppPattern (sel->zyppSel()->theObj());
642 icon = pattern->icon().asString().c_str();
644 icon =
"pattern-generic";
647 case Ypp::Selectable::PACKAGE:
648 icon = getStatusStockIcon (*sel);
652 icon_size = GTK_ICON_SIZE_DIALOG;
657 gtk_tooltip_set_markup (tooltip, text.c_str());
659 gtk_tooltip_set_icon_from_icon_name (tooltip, icon, icon_size);
665 static void column_clicked_cb (GtkTreeViewColumn *column,
YGtkPkgListView *pThis)
667 int attrb = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (column),
"attrb"));
668 bool ascendent =
true;
669 if (gtk_tree_view_column_get_sort_indicator (column))
670 ascendent = gtk_tree_view_column_get_sort_order (column) == GTK_SORT_DESCENDING;
671 pThis->impl->setList (pThis->impl->list, attrb, ascendent,
true, pThis->impl->m_keywords);
674 static void set_sort_column (
YGtkPkgListView *pThis, GtkTreeViewColumn *column,
int property)
678 case INSTALLED_CHECK_PROP: attrb = Ypp::List::IS_INSTALLED_SORT;
break;
679 case NAME_PROP:
case ACTION_NAME_PROP:
case NAME_SUMMARY_PROP:
680 attrb = Ypp::List::NAME_SORT;
break;
681 case REPOSITORY_PROP: attrb = Ypp::List::REPOSITORY_SORT;
break;
682 case SUPPORT_PROP: attrb = Ypp::List::SUPPORT_SORT;
break;
683 case SIZE_PROP: attrb = Ypp::List::SIZE_SORT;
break;
686 gtk_tree_view_column_set_clickable (column,
true);
687 g_object_set_data (G_OBJECT (column),
"attrb", GINT_TO_POINTER (attrb));
689 g_signal_connect (G_OBJECT (column),
"clicked",
690 G_CALLBACK (column_clicked_cb), pThis);
693 YGtkPkgListView::YGtkPkgListView (
bool descriptiveTooltip,
int default_sort,
bool indentAuto,
bool colorModified,
bool variableHeight)
694 : impl (new Impl (descriptiveTooltip, default_sort, indentAuto, colorModified))
696 impl->scroll = gtk_scrolled_window_new (NULL, NULL);
697 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (impl->scroll),
698 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
699 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (impl->scroll),
702 GtkTreeView *view = GTK_TREE_VIEW (impl->view = ygtk_tree_view_new (_(
"No matches.")));
704 gtk_tree_view_set_fixed_height_mode (view, TRUE);
705 gtk_tree_view_set_headers_visible (view, FALSE);
707 GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
708 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
709 g_signal_connect (G_OBJECT (selection),
"changed",
710 G_CALLBACK (selection_changed_cb),
this);
712 g_signal_connect (G_OBJECT (view),
"row-activated",
713 G_CALLBACK (row_activated_cb),
this);
714 g_signal_connect (G_OBJECT (view),
"right-click",
715 G_CALLBACK (right_click_cb),
this);
716 gtk_widget_set_has_tooltip (impl->view, TRUE);
717 g_signal_connect (G_OBJECT (view),
"query-tooltip",
718 G_CALLBACK (query_tooltip_cb),
this);
720 gtk_container_add (GTK_CONTAINER (impl->scroll), impl->view);
721 gtk_widget_show_all (impl->scroll);
724 YGtkPkgListView::~YGtkPkgListView()
727 GtkWidget *YGtkPkgListView::getWidget()
728 {
return impl->scroll; }
730 GtkWidget *YGtkPkgListView::getView()
731 {
return impl->view; }
733 void YGtkPkgListView::setQuery (
Ypp::Query &query)
736 void YGtkPkgListView::setList (
Ypp::List list)
738 std::list <std::string> keywords;
739 impl->setList (list, impl->sort_attrb, impl->ascendent,
false, keywords);
742 void YGtkPkgListView::setHighlight (
const std::list <std::string> &keywords)
744 impl->setHighlight (keywords);
746 int index = keywords.size() == 1 ? impl->list.find (keywords.front()) : -1;
748 GtkTreeView *view = GTK_TREE_VIEW (impl->view);
749 GtkTreePath *path = gtk_tree_path_new_from_indices (index, -1);
750 gtk_tree_view_scroll_to_cell (view, path, NULL, TRUE, .5, 0);
752 GtkTreeSelection *selection = gtk_tree_view_get_selection (view);
753 gtk_tree_selection_select_path (selection, path);
754 gtk_tree_path_free (path);
756 else if (gtk_widget_get_realized (impl->view))
757 gtk_tree_view_scroll_to_point (GTK_TREE_VIEW (impl->view), -1, 0);
760 void YGtkPkgListView::addTextColumn (
const char *header,
int property,
bool visible,
int size)
762 GtkTreeView *view = GTK_TREE_VIEW (impl->view);
764 gtk_tree_view_set_headers_visible (view, TRUE);
765 GtkTreeViewColumn *column = gtk_tree_view_column_new();
766 gtk_tree_view_column_set_title (column, header);
768 GtkCellRenderer *renderer;
769 if (property == REPOSITORY_PROP) {
770 renderer = gtk_cell_renderer_pixbuf_new();
771 if (gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL)
772 gtk_tree_view_column_pack_end (column, renderer, FALSE);
774 gtk_tree_view_column_pack_start (column, renderer, FALSE);
775 gtk_tree_view_column_set_attributes (column, renderer,
776 "icon-name", REPOSITORY_STOCK_PROP, NULL);
779 if (property == VERSION_PROP) {
780 renderer = ygtk_cell_renderer_side_button_new();
781 g_object_set (G_OBJECT (renderer),
"stock-id", GTK_STOCK_GO_UP, NULL);
782 g_signal_connect (G_OBJECT (renderer),
"toggled",
783 G_CALLBACK (upgrade_toggled_cb),
this);
786 renderer = ygtk_cell_renderer_text_new();
788 gtk_tree_view_column_pack_start (column, renderer, TRUE);
789 gtk_tree_view_column_set_attributes (column, renderer,
790 "markup", property,
"sensitive", IS_LOCKED_PROP, NULL);
792 if (impl->colorModified)
793 gtk_tree_view_column_add_attribute (column, renderer,
794 "cell-background", BACKGROUND_PROP);
795 if (impl->indentAuto) {
796 gtk_tree_view_column_add_attribute (column, renderer,
"xpad", XPAD_PROP);
797 gtk_tree_view_column_add_attribute (column, renderer,
"foreground", FOREGROUND_PROP);
800 PangoEllipsizeMode ellipsize = PANGO_ELLIPSIZE_END;
801 if (size >= 0 && property != NAME_SUMMARY_PROP)
802 ellipsize = PANGO_ELLIPSIZE_MIDDLE;
803 g_object_set (G_OBJECT (renderer),
"ellipsize", ellipsize, NULL);
805 if (property == VERSION_PROP) {
806 gtk_tree_view_column_add_attribute (column, renderer,
807 "button-visible", HAS_UPGRADE_PROP);
808 gtk_tree_view_column_add_attribute (column, renderer,
809 "active", TO_UPGRADE_PROP);
813 gtk_tree_view_set_rules_hint (view, TRUE);
814 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
815 gtk_tree_view_column_set_resizable (column, TRUE);
817 gtk_tree_view_column_set_fixed_width (column, size);
819 gtk_tree_view_column_set_expand (column, TRUE);
820 gtk_tree_view_column_set_visible (column, visible);
821 set_sort_column (
this, column, property);
822 ygtk_tree_view_append_column (YGTK_TREE_VIEW (view), column);
825 void YGtkPkgListView::addCheckColumn (
int property)
827 GtkTreeView *view = GTK_TREE_VIEW (impl->view);
828 GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
829 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (NULL,
830 renderer,
"active", property,
"sensitive", IS_LOCKED_PROP, NULL);
831 if (impl->colorModified)
832 gtk_tree_view_column_add_attribute (column, renderer,
833 "cell-background", BACKGROUND_PROP);
834 if (property == INSTALLED_CHECK_PROP)
835 gtk_tree_view_column_add_attribute (column, renderer,
836 "activatable", CAN_TOGGLE_INSTALL_PROP);
837 g_signal_connect (G_OBJECT (renderer),
"toggled",
838 G_CALLBACK (check_toggled_cb),
this);
841 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
842 gtk_tree_view_column_set_fixed_width (column, 25);
843 set_sort_column (
this, column, property);
844 gtk_tree_view_append_column (view, column);
847 void YGtkPkgListView::addImageColumn (
const char *header,
int property,
bool onlyManualModified)
849 GtkTreeView *view = GTK_TREE_VIEW (impl->view);
850 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
851 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (
852 header, renderer,
"icon-name", property, NULL);
853 if (impl->colorModified)
854 gtk_tree_view_column_add_attribute (column, renderer,
855 "cell-background", BACKGROUND_PROP);
856 if (onlyManualModified)
857 gtk_tree_view_column_add_attribute (column, renderer,
858 "visible", MANUAL_MODIFY_PROP);
860 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
861 int height = MAX (32, YGUtils::getCharsHeight (impl->view, 1));
862 gtk_cell_renderer_set_fixed_size (renderer, -1, height);
863 gtk_tree_view_column_set_fixed_width (column, 38);
864 gtk_tree_view_append_column (view, column);
867 void YGtkPkgListView::addButtonColumn (
const char *header,
int property)
869 GtkCellRenderer *renderer = ygtk_cell_renderer_button_new();
870 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes (
871 header, renderer,
"sensitive", IS_LOCKED_PROP, NULL);
872 if (impl->colorModified)
873 gtk_tree_view_column_add_attribute (column, renderer,
874 "cell-background", BACKGROUND_PROP);
877 g_object_get (G_OBJECT (gtk_settings_get_default()),
"gtk-button-images", &show_icon, NULL);
880 if (property == UNDO_BUTTON_PROP) {
882 g_object_set (G_OBJECT (renderer),
"text", text, NULL);
884 g_object_set (G_OBJECT (renderer),
"stock-id", GTK_STOCK_UNDO, NULL);
885 gtk_tree_view_column_add_attribute (column, renderer,
886 "visible", MANUAL_MODIFY_PROP);
887 g_signal_connect (G_OBJECT (renderer),
"toggled",
888 G_CALLBACK (undo_toggled_cb),
this);
892 gtk_tree_view_column_add_attribute (column, renderer,
895 gtk_tree_view_column_add_attribute (column, renderer,
896 "stock-id", ACTION_ICON_PROP);
897 g_signal_connect (G_OBJECT (renderer),
"toggled",
898 G_CALLBACK (action_button_toggled_cb),
this);
903 PangoLayout *layout = gtk_widget_create_pango_layout (impl->view,
904 strlen (header) > strlen (text) ? header : text);
905 pango_layout_get_pixel_extents (layout, NULL, &rect);
906 width = MAX (width, rect.width);
907 g_object_unref (G_OBJECT (layout));
911 gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (impl->view),
912 GTK_ICON_SIZE_MENU, &icon_width, NULL);
916 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
917 gtk_tree_view_column_set_fixed_width (column, width);
918 gtk_tree_view_append_column (GTK_TREE_VIEW (impl->view), column);
922 { impl->listener = listener; }
925 {
return impl->list; }
930 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->view));
931 GList *rows = gtk_tree_selection_get_selected_rows (selection, &model);
934 for (GList *i = rows; i; i = i->next) {
936 GtkTreePath *path = (GtkTreePath *) i->data;
937 gtk_tree_model_get_iter (model, &iter, path);
940 gtk_tree_model_get (model, &iter, PTR_PROP, &sel, -1);
941 gtk_tree_path_free (path);
948 void YGtkPkgListView::selectAll()
950 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->view));
951 gtk_tree_selection_select_all (selection);
958 const char *action = 0;
959 if (sel->toInstall()) {
960 action = _(
"install");
961 if (sel->type() == Ypp::Selectable::PACKAGE) {
962 if (sel->isInstalled()) {
963 Ypp::Version candidate = sel->candidate(), installed = sel->installed();
964 if (candidate > installed)
965 action = _(
"upgrade");
966 else if (candidate < installed)
967 action = _(
"downgrade");
969 action = _(
"re-install");
973 else if (sel->toRemove())
974 action = _(
"remove");
976 action = _(
"modify");
984 text = _(
"locked: right-click to unlock");
985 else if (sel.toInstall()) {
987 text = _(
"To install") + std::string (
" ") + candidate.number();
989 else if (sel.toRemove())
990 text = _(
"To remove");
991 else if (sel.isInstalled()) {
992 text = _(
"Installed");
993 if (sel.hasUpgrade()) {
995 text += _(
"(upgrade available)");
999 text = _(
"Not installed");
1000 if (sel.toModifyAuto()) {
1002 text += _(
"status changed by the dependencies resolver");
1012 icon = GTK_STOCK_DIALOG_AUTHENTICATION;
1013 else if (sel.toInstall()) {
1014 icon = GTK_STOCK_ADD;
1015 if (sel.type() == Ypp::Selectable::PACKAGE) {
1017 if (sel.isInstalled()) {
1019 if (candidate > installed)
1020 icon = GTK_STOCK_GO_UP;
1021 else if (candidate < installed)
1022 icon = GTK_STOCK_GO_DOWN;
1024 icon = GTK_STOCK_REFRESH;
1028 else if (sel.toRemove())
1029 icon = GTK_STOCK_REMOVE;
1030 else if (sel.isInstalled())
1031 icon = GTK_STOCK_HARDDISK;
1039 std::string name (repo.name()), url, str;
1040 url = repo.isSystem() ? _(
"Installed packages") : repo.url();
1041 str.reserve (name.size() + url.size() + 64);
1043 str +=
"<span color=\"" GRAY_COLOR
"\">";
1044 str +=
"<small>" + url +
"</small>";
1049 const char *getRepositoryStockIcon (
const std::string &url)
1052 return GTK_STOCK_MISSING_IMAGE;
1053 if (url.compare (0, 2,
"cd", 2) == 0 || url.compare (0, 3,
"dvd", 3) == 0)
1054 return GTK_STOCK_CDROM;
1055 if (url.compare (0, 3,
"iso", 3) == 0)
1056 return GTK_STOCK_FILE;
1057 if (url.find (
"KDE") != std::string::npos)
1058 return "pattern-kde";
1059 if (url.find (
"GNOME") != std::string::npos)
1060 return "pattern-gnome";
1061 if (url.find (
"update") != std::string::npos)
1062 return "yast-update";
1063 if (url.find (
"home") != std::string::npos)
1064 return "yast-users";
1065 return GTK_STOCK_NETWORK;
1070 if (repo.isSystem())
1072 return getRepositoryStockIcon (repo.url());
1075 void highlightMarkup (std::string &text,
const std::list <std::string> &keywords,
1076 const char *openTag,
const char *closeTag,
int openTagLen,
int closeTagLen)
1078 if (keywords.empty())
return;
1079 text.reserve ((openTagLen + closeTagLen + 2) * 6);
1080 const char *i = text.c_str();
1082 std::list <std::string>::const_iterator it;
1083 for (it = keywords.begin(); it != keywords.end(); it++) {
1084 const std::string &keyword = *it;
1085 int len = keyword.size();
1086 if (strncasecmp (i, keyword.c_str(), len) == 0) {
1087 int pos = i - text.c_str();
1088 text.insert (pos+len, closeTag);
1089 text.insert (pos, openTag);
1090 i = text.c_str() + pos + len + openTagLen + closeTagLen - 2;
1094 if (it == keywords.end())
1099 void highlightMarkupSpan (std::string &text,
const std::list <std::string> &keywords)
1101 static const char openTag[] =
"<span fgcolor=\"#000000\" bgcolor=\"#ffff00\">";
1102 static const char closeTag[] =
"</span>";
1103 highlightMarkup (text, keywords, openTag, closeTag,
sizeof (openTag),
sizeof (closeTag));