13 #include "ygtkpkghistorydialog.h"
16 #include "YGPackageSelector.h"
17 #include "ygtkpkglistview.h"
19 #include "ygtktreeview.h"
20 #include "ygtkcellrenderertext.h"
22 #include <zypp/parser/HistoryLogReader.h>
23 #define FILENAME "/var/log/zypp/history"
25 static std::string reqbyTreatment (
const std::string &reqby)
28 return _(
"automatic");
29 if (reqby.compare (0, 4,
"root", 4) == 0) {
30 std::string str (_(
"user:"));
39 virtual void date (
const std::string &str,
bool first) = 0;
40 virtual void item (
const std::string &action,
const std::string &name,
41 const std::string &description,
const std::string &repositoryName,
42 const std::string &repositoryUrl,
const std::string &reqby,
bool autoReq) = 0;
49 enum Column { ICON_COLUMN, NAME_COLUMN, VERSION_URL_COLUMN, REPOSITORY_COLUMN,
50 REQBY_COLUMN, REPOSITORY_ICON_COLUMN, REPOSITORY_URL_COLUMN, SHORTCUT_COLUMN,
51 COLOR_COLUMN, XPAD_COLUMN, TOTAL_COLUMNS };
55 store = gtk_list_store_new (TOTAL_COLUMNS, G_TYPE_STRING, G_TYPE_STRING,
56 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
57 G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
61 { g_object_unref (G_OBJECT (store)); }
63 GtkTreeModel *getModel()
64 {
return GTK_TREE_MODEL (store); }
66 void addRow (GtkTreeIter *iter)
68 gtk_list_store_append (store, iter);
69 gtk_list_store_set (store, iter, ICON_COLUMN, NULL, NAME_COLUMN, NULL,
70 VERSION_URL_COLUMN, NULL, REPOSITORY_COLUMN, NULL, REQBY_COLUMN, NULL,
71 REPOSITORY_ICON_COLUMN, NULL, REPOSITORY_URL_COLUMN, NULL,
72 SHORTCUT_COLUMN, NULL, COLOR_COLUMN, NULL, XPAD_COLUMN, 0, -1);
75 int date (
const std::string &str,
bool first)
78 if (!first) addRow (&iter);
79 std::string _date = std::string (
"<b>\u26ab ") + str +
"</b>";
81 gtk_list_store_set (store, &iter, NAME_COLUMN, _date.c_str(), -1);
83 GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
84 int row = gtk_tree_path_get_indices (path)[0];
85 gtk_tree_path_free (path);
89 void item (
const std::string &action,
const std::string &name,
90 const std::string &description,
const std::string &repositoryName,
91 const std::string &repositoryUrl,
const std::string &reqby,
bool autoReq)
95 std::string shortcut (name);
96 if (action == _(
"install"))
98 else if (action == _(
"upgrade"))
99 icon = GTK_STOCK_GO_UP;
100 else if (action == _(
"remove"))
101 icon = GTK_STOCK_REMOVE;
102 else if (action == _(
"downgrade"))
103 icon = GTK_STOCK_GO_DOWN;
104 else if (action == _(
"re-install"))
105 icon = GTK_STOCK_REFRESH;
107 icon = getRepositoryStockIcon (name);
112 _name.reserve (action.size() + name.size() + 64);
114 _name += action +
"</b> " + name;
117 const char *repo_icon = 0, *color = 0;
118 bool is_patch =
false;
119 if (action == _(
"upgrade") && !repositoryUrl.empty()) {
121 repo_icon = getRepositoryStockIcon (repositoryUrl);
122 if (repositoryUrl.find (
"update") != std::string::npos) {
126 tag =
"<small><span color=\"#999999\">"; tag += _(
"patch"); tag +=
"</span></small>";
127 _name +=
" "; _name += tag;
131 if (autoReq && !is_patch) {
134 tag =
"<small><span color=\"#999999\">"; tag += _(
"auto"); tag +=
"</span></small>";
135 _name +=
" "; _name += tag;
138 gtk_list_store_append (store, &iter);
139 gtk_list_store_set (store, &iter, ICON_COLUMN, icon, NAME_COLUMN, _name.c_str(),
140 VERSION_URL_COLUMN, description.c_str(), REPOSITORY_COLUMN, repositoryName.c_str(),
141 REPOSITORY_ICON_COLUMN, repo_icon, REPOSITORY_URL_COLUMN, repositoryUrl.c_str(),
142 REQBY_COLUMN, reqby.c_str(), SHORTCUT_COLUMN, shortcut.c_str(),
143 COLOR_COLUMN, color, XPAD_COLUMN, xpad, -1);
151 enum Column { TEXT_COLUMN, LOG_ROW_COLUMN, TOTAL_COLUMNS };
154 { store = gtk_list_store_new (TOTAL_COLUMNS, G_TYPE_STRING, G_TYPE_INT); }
157 { g_object_unref (G_OBJECT (store)); }
159 GtkTreeModel *getModel()
160 {
return GTK_TREE_MODEL (store); }
162 void date (
const std::string &str,
bool first,
int log_row)
165 gtk_list_store_append (store, &iter);
166 gtk_list_store_set (store, &iter, TEXT_COLUMN, str.c_str(),
167 LOG_ROW_COLUMN, log_row, -1);
183 {
delete log_handler;
delete date_handler; }
185 virtual void date (
const std::string &str,
bool first)
187 int row = log_handler->date (str, first);
188 date_handler->date (str, first, row);
191 virtual void item (
const std::string &a,
const std::string &n,
192 const std::string &d,
const std::string &rn,
193 const std::string &ru,
const std::string &rb,
bool ar)
194 { log_handler->item (a, n, d, rn, ru, rb, ar); }
202 { file = fopen (filename,
"w"); }
208 { (void) fwrite (
"\n",
sizeof (
char), 1, file); }
210 virtual void date (
const std::string &str,
bool first)
214 (void) fwrite (str.c_str(),
sizeof (char), str.size(), file);
215 addSpace(); addSpace();
218 virtual void item (
const std::string &action,
const std::string &name,
219 const std::string &description,
const std::string &repositoryName,
220 const std::string &repositoryUrl,
const std::string &reqby,
bool autoReq)
223 str.reserve (action.size() + name.size() + description.size() + 4);
224 str = std::string (
"\t") + action +
" " + name +
" " + description +
"\n";
225 (void) fwrite (str.c_str(),
sizeof (char), str.size(), file);
233 std::map <std::string, zypp::Edition> installed;
238 zypp::parser::HistoryLogReader parser (FILENAME, zypp::parser::HistoryLogReader::Options(), boost::ref (*
this));
242 catch (
const zypp::Exception &ex) {
243 yuiWarning () <<
"Error: Could not load log file" << FILENAME <<
": "
244 << ex.asUserHistory() << std::endl;
248 bool operator() (
const zypp::HistoryLogData::Ptr &item)
250 std::string date (item->date().form (
"%d %B %Y"));
252 handler->date (date, _date.empty());
256 std::string action, name, descrpt, repoName, repoUrl, reqby, t;
257 bool autoreq =
false;
258 switch (item->action().toEnum()) {
259 case zypp::HistoryActionID::NONE_e:
261 case zypp::HistoryActionID::INSTALL_e: {
262 zypp::HistoryLogDataInstall *_item =
263 static_cast <zypp::HistoryLogDataInstall *> (item.get());
264 name = _item->name();
265 descrpt = _item->edition().version();
266 Ypp::getRepositoryFromAlias (_item->repoAlias(), repoName, repoUrl);
267 reqby = _item->reqby(); autoreq = reqby.empty();
268 reqby = reqbyTreatment (reqby);
269 zypp::Edition edition = _item->edition();
270 std::map <std::string, zypp::Edition>::iterator it;
271 it = installed.find (name);
272 if (it == installed.end())
273 action = _(
"install");
275 zypp::Edition prev_edition = it->second;
276 if (edition > prev_edition)
277 action = _(
"upgrade");
278 else if (edition < prev_edition)
279 action = _(
"downgrade");
281 action = _(
"re-install");
283 installed[name] = edition;
286 case zypp::HistoryActionID::REMOVE_e: {
287 zypp::HistoryLogDataRemove *_item =
288 static_cast <zypp::HistoryLogDataRemove *> (item.get());
289 action = _(
"remove");
290 name = _item->name();
291 descrpt = _item->edition().version();
292 reqby = _item->reqby(); autoreq = reqby.empty();
293 reqby = reqbyTreatment (reqby);
294 std::map <std::string, zypp::Edition>::iterator it;
295 it = installed.find (name);
296 if (it != installed.end())
297 installed.erase (it);
300 case zypp::HistoryActionID::REPO_ADD_e: {
301 zypp::HistoryLogDataRepoAdd *_item =
302 static_cast <zypp::HistoryLogDataRepoAdd *> (item.get());
303 action = _(
"add repository");
304 Ypp::getRepositoryFromAlias (_item->alias(), name, t);
305 descrpt = _item->url().asString();
308 case zypp::HistoryActionID::REPO_REMOVE_e: {
309 zypp::HistoryLogDataRepoRemove *_item =
310 static_cast <zypp::HistoryLogDataRepoRemove *> (item.get());
311 action = _(
"remove repository");
312 name = _item->alias();
315 case zypp::HistoryActionID::REPO_CHANGE_ALIAS_e: {
316 zypp::HistoryLogDataRepoAliasChange *_item =
317 static_cast <zypp::HistoryLogDataRepoAliasChange *> (item.get());
318 action = _(
"change repository alias");
319 name = _item->oldAlias() +
" -> " + _item->newAlias();
322 case zypp::HistoryActionID::REPO_CHANGE_URL_e: {
323 zypp::HistoryLogDataRepoUrlChange *_item =
324 static_cast <zypp::HistoryLogDataRepoUrlChange *> (item.get());
325 action = _(
"change repository url");
326 Ypp::getRepositoryFromAlias (_item->alias(), name, t);
327 descrpt = _item->newUrl().asString();
332 handler->item (action, name, descrpt, repoName, repoUrl, reqby, autoreq);
337 static void goto_clicked (GtkTreeView *log_view)
339 GtkTreeSelection *selection = gtk_tree_view_get_selection (log_view);
342 if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
344 gtk_tree_model_get (model, &iter, LogListHandler::SHORTCUT_COLUMN, &shortcut, -1);
345 if (!strcmp (shortcut,
"_repo"))
346 YGPackageSelector::get()->showRepoManager();
348 YGPackageSelector::get()->searchFor (Ypp::PoolQuery::NAME, shortcut);
351 GtkWidget *dialog = gtk_widget_get_toplevel (GTK_WIDGET (log_view));
352 gtk_widget_hide (dialog);
356 static void log_selection_changed_cb (GtkTreeSelection *selection, GtkDialog *dialog)
358 bool selected = gtk_tree_selection_count_selected_rows (selection) > 0;
359 gtk_dialog_set_response_sensitive (dialog, 1, selected);
362 static void log_row_activated_cb (GtkTreeView *view, GtkTreePath *path,
363 GtkTreeViewColumn *column)
364 { goto_clicked (view); }
366 static gboolean log_can_select_cb (GtkTreeSelection *selection, GtkTreeModel *model,
367 GtkTreePath *path, gboolean path_currently_selected, gpointer data)
370 gtk_tree_model_get_iter (model, &iter, path);
372 gtk_tree_model_get (model, &iter, LogListHandler::SHORTCUT_COLUMN, &shortcut, -1);
373 bool can_select = shortcut != NULL;
374 if (shortcut) g_free (shortcut);
378 static void date_selection_changed_cb (GtkTreeSelection *selection, GtkTreeView *log_view)
382 if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
384 gtk_tree_model_get (model, &iter, 1, &log_row, -1);
386 GtkTreePath *path = gtk_tree_path_new_from_indices (log_row, -1);
387 gtk_tree_view_scroll_to_cell (log_view, path, NULL, TRUE, 0, 0);
388 gtk_tree_path_free (path);
392 static void save_to_file (GtkWindow *parent)
394 GtkWidget *dialog = gtk_file_chooser_dialog_new (_(
"Save to"), parent,
395 GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
396 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL);
397 gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
398 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
400 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
401 gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
406 gtk_widget_destroy (dialog);
409 static void response_cb (GtkDialog *dialog, gint response, GtkTreeView *log_view)
412 case 1: goto_clicked (log_view);
break;
413 case 2: save_to_file (GTK_WINDOW (dialog));
break;
414 default: gtk_widget_hide (GTK_WIDGET (dialog));
break;
418 static gboolean query_tooltip_cb (GtkWidget *widget, gint x, gint y,
421 GtkTreeView *view = GTK_TREE_VIEW (widget);
425 if (gtk_tree_view_get_tooltip_context (view,
426 &x, &y, keyboard_mode, &model, &path, &iter)) {
427 gtk_tree_view_set_tooltip_row (view, tooltip, path);
428 gtk_tree_path_free (path);
430 GtkTreeViewColumn *column;
432 gtk_tree_view_convert_widget_to_bin_window_coords (
433 view, x, y, &bx, &by);
434 gtk_tree_view_get_path_at_pos (
435 view, x, y, NULL, &column, NULL, NULL);
439 const char *icon = 0;
441 if (column == ygtk_tree_view_get_column (YGTK_TREE_VIEW (view), 2)) {
443 gtk_tree_model_get (model, &iter, LogListHandler::REPOSITORY_COLUMN, &name,
444 LogListHandler::REPOSITORY_URL_COLUMN, &url, -1);
448 text +=
"\n<small>"; text += url; text +=
"</small>";
449 icon = getRepositoryStockIcon (url);
459 gtk_tooltip_set_markup (tooltip, text.c_str());
460 gtk_tooltip_set_icon_from_icon_name (tooltip,
461 icon, GTK_ICON_SIZE_BUTTON);
468 static void goto_activate_cb (GtkMenuItem *item, GtkTreeView *view)
469 { goto_clicked (view); }
471 static void right_click_cb (YGtkTreeView *view, gboolean outreach)
473 GtkWidget *menu = gtk_menu_new();
475 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
476 bool selected = gtk_tree_selection_get_selected (selection, NULL, NULL);
478 GtkWidget *item = gtk_image_menu_item_new_from_stock (GTK_STOCK_JUMP_TO, NULL);
479 gtk_widget_set_sensitive (item, selected);
480 gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
481 g_signal_connect (G_OBJECT (item),
"activate", G_CALLBACK (goto_activate_cb), view);
484 ygtk_tree_view_append_show_columns_item (view, menu);
485 ygtk_tree_view_popup_menu (view, menu);
488 static gboolean read_logs_idle_cb (
void *data)
490 GtkWidget **views = (GtkWidget **) data;
491 GtkWidget *dialog = views[0];
492 GtkTreeView *log_view = GTK_TREE_VIEW (views[1]);
493 GtkTreeView *date_view = GTK_TREE_VIEW (views[2]);
498 gtk_tree_view_set_model (date_view, handler.date_handler->getModel());
499 gtk_tree_view_set_model (log_view, handler.log_handler->getModel());
501 GtkTreeSelection *selection = gtk_tree_view_get_selection (date_view);
503 if (gtk_tree_model_get_iter_first (
504 gtk_tree_view_get_model (date_view), &iter))
505 gtk_tree_selection_select_iter (selection, &iter);
507 gdk_window_set_cursor (gtk_widget_get_window(GTK_WIDGET(dialog)), NULL);
511 YGtkPkgHistoryDialog::YGtkPkgHistoryDialog()
513 GtkCellRenderer *renderer, *pix_renderer;
514 GtkTreeViewColumn *column;
516 GtkWidget *log_view = ygtk_tree_view_new (_(
"No entries."));
517 gtk_tree_view_set_search_column (GTK_TREE_VIEW (log_view), LogListHandler::SHORTCUT_COLUMN);
518 gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (log_view), TRUE);
519 gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (log_view), TRUE);
520 gtk_widget_set_has_tooltip (log_view, TRUE);
521 g_signal_connect (G_OBJECT (log_view),
"query-tooltip",
522 G_CALLBACK (query_tooltip_cb),
this);
523 g_signal_connect (G_OBJECT (log_view),
"right-click",
524 G_CALLBACK (right_click_cb),
this);
526 bool reverse = gtk_widget_get_default_direction() == GTK_TEXT_DIR_RTL;
528 column = gtk_tree_view_column_new();
529 gtk_tree_view_column_set_title (column, _(
"Action"));
530 gtk_tree_view_column_set_spacing (column, 6);
532 pix_renderer = gtk_cell_renderer_pixbuf_new();
534 gtk_tree_view_column_pack_start (column, pix_renderer, FALSE);
536 renderer = ygtk_cell_renderer_text_new();
537 gtk_tree_view_column_pack_start (column, renderer, TRUE);
538 gtk_tree_view_column_set_attributes (column, renderer,
539 "markup", LogListHandler::NAME_COLUMN,
"xpad", LogListHandler::XPAD_COLUMN,
540 "foreground", LogListHandler::COLOR_COLUMN, NULL);
541 g_object_set (G_OBJECT (renderer),
"ellipsize", PANGO_ELLIPSIZE_MIDDLE, NULL);
544 gtk_tree_view_column_pack_start (column, pix_renderer, FALSE);
545 gtk_tree_view_column_set_attributes (column, pix_renderer,
546 "icon-name", LogListHandler::ICON_COLUMN, NULL);
548 gtk_tree_view_column_set_resizable (column, TRUE);
549 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
550 gtk_tree_view_column_set_expand (column, TRUE);
551 ygtk_tree_view_append_column (YGTK_TREE_VIEW (log_view), column);
553 renderer = gtk_cell_renderer_text_new();
554 column = gtk_tree_view_column_new_with_attributes (_(
"Version / URL"), renderer,
555 "text", LogListHandler::VERSION_URL_COLUMN,
"xpad", LogListHandler::XPAD_COLUMN,
556 "foreground", LogListHandler::COLOR_COLUMN, NULL);
557 g_object_set (G_OBJECT (renderer),
"ellipsize", PANGO_ELLIPSIZE_END, NULL);
558 gtk_tree_view_column_set_resizable (column, TRUE);
559 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
560 gtk_tree_view_column_set_fixed_width (column, 120);
561 ygtk_tree_view_append_column (YGTK_TREE_VIEW (log_view), column);
563 column = gtk_tree_view_column_new();
564 gtk_tree_view_column_set_title (column, _(
"Repository"));
565 gtk_tree_view_column_set_spacing (column, 2);
567 pix_renderer = gtk_cell_renderer_pixbuf_new();
569 gtk_tree_view_column_pack_start (column, pix_renderer, FALSE);
571 renderer = gtk_cell_renderer_text_new();
572 gtk_tree_view_column_pack_start (column, renderer, TRUE);
573 gtk_tree_view_column_set_attributes (column, renderer,
574 "text", LogListHandler::REPOSITORY_COLUMN, NULL);
577 gtk_tree_view_column_pack_start (column, pix_renderer, FALSE);
578 gtk_tree_view_column_set_attributes (column, pix_renderer,
579 "icon-name", LogListHandler::REPOSITORY_ICON_COLUMN, NULL);
581 gtk_tree_view_column_set_resizable (column, TRUE);
582 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
583 gtk_tree_view_column_set_fixed_width (column, 140);
584 gtk_tree_view_column_set_visible (column, FALSE);
585 ygtk_tree_view_append_column (YGTK_TREE_VIEW (log_view), column);
587 renderer = gtk_cell_renderer_text_new();
588 column = gtk_tree_view_column_new_with_attributes (_(
"Requested by"), renderer,
589 "text", LogListHandler::REQBY_COLUMN, NULL);
590 g_object_set (G_OBJECT (renderer),
"ellipsize", PANGO_ELLIPSIZE_END, NULL);
591 gtk_tree_view_column_set_resizable (column, TRUE);
592 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
593 gtk_tree_view_column_set_fixed_width (column, 100);
594 gtk_tree_view_column_set_visible (column, FALSE);
595 ygtk_tree_view_append_column (YGTK_TREE_VIEW (log_view), column);
597 GtkWidget *log_scroll = gtk_scrolled_window_new (NULL, NULL);
598 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (log_scroll),
599 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
600 gtk_scrolled_window_set_shadow_type (
601 GTK_SCROLLED_WINDOW (log_scroll), GTK_SHADOW_IN);
602 gtk_container_add (GTK_CONTAINER (log_scroll), log_view);
604 GtkWidget *date_view = gtk_tree_view_new();
605 gtk_tree_view_set_search_column (GTK_TREE_VIEW (date_view), DateListHandler::TEXT_COLUMN);
606 gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (date_view), TRUE);
608 renderer = gtk_cell_renderer_text_new();
609 column = gtk_tree_view_column_new_with_attributes (_(
"Date"), renderer,
610 "text", DateListHandler::TEXT_COLUMN, NULL);
611 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED);
612 gtk_tree_view_append_column (GTK_TREE_VIEW (date_view), column);
614 GtkWidget *date_scroll = gtk_scrolled_window_new (NULL, NULL);
615 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (date_scroll),
616 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
617 gtk_scrolled_window_set_shadow_type (
618 GTK_SCROLLED_WINDOW (date_scroll), GTK_SHADOW_IN);
619 gtk_container_add (GTK_CONTAINER (date_scroll), date_view);
621 GtkWidget *dialog = gtk_message_dialog_new (YGDialog::currentWindow(),
622 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_OTHER, GTK_BUTTONS_NONE,
623 _(
"Show History (%s)"), FILENAME);
624 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_JUMP_TO, 1);
625 gtk_dialog_add_button (GTK_DIALOG (dialog), _(
"Save to File"), 2);
626 gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
627 gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), 1, FALSE);
628 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
629 gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
630 gtk_window_set_default_size (GTK_WINDOW (dialog), 650, 600);
631 g_signal_connect (G_OBJECT (dialog),
"response",
632 G_CALLBACK (response_cb), log_view);
633 g_signal_connect (G_OBJECT (dialog),
"delete-event",
634 G_CALLBACK (gtk_true), log_view);
636 GtkWidget *hpaned = gtk_hpaned_new();
637 gtk_paned_pack1 (GTK_PANED (hpaned), date_scroll, FALSE, FALSE);
638 gtk_paned_pack2 (GTK_PANED (hpaned), log_scroll, TRUE, FALSE);
639 YGUtils::setPaneRelPosition (hpaned, .30);
640 gtk_widget_set_vexpand (hpaned, TRUE);
641 GtkContainer *content = GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog)));
642 gtk_container_add (content, hpaned);
644 gtk_widget_show_all (dialog);
647 GtkTreeSelection *selection;
648 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (log_view));
649 g_signal_connect (G_OBJECT (selection),
"changed",
650 G_CALLBACK (log_selection_changed_cb), dialog);
651 g_signal_connect (G_OBJECT (log_view),
"row-activated",
652 G_CALLBACK (log_row_activated_cb), NULL);
653 gtk_tree_selection_set_select_function (selection, log_can_select_cb, NULL, NULL);
654 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (date_view));
655 g_signal_connect (G_OBJECT (selection),
"changed",
656 G_CALLBACK (date_selection_changed_cb), log_view);
658 GdkCursor *cursor = gdk_cursor_new (GDK_WATCH);
659 gdk_window_set_cursor (gtk_widget_get_window(GTK_WIDGET(dialog)), cursor);
660 gdk_cursor_unref (cursor);
662 GtkWidget **views = g_new (GtkWidget *, 3);
663 views[0] = dialog; views[1] = log_view; views[2] = date_view;
664 g_idle_add_full (G_PRIORITY_LOW, read_logs_idle_cb, views, g_free);
667 YGtkPkgHistoryDialog::~YGtkPkgHistoryDialog()
668 { gtk_widget_destroy (m_dialog); }
670 void YGtkPkgHistoryDialog::popup()
671 { gtk_window_present (GTK_WINDOW (m_dialog)); }