summaryrefslogtreecommitdiff
path: root/portato/gui/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'portato/gui/gtk')
-rw-r--r--portato/gui/gtk/__init__.py13
-rw-r--r--portato/gui/gtk/dialogs.py66
-rw-r--r--portato/gui/gtk/glade/geneticone.glade1028
-rw-r--r--portato/gui/gtk/windows.py892
-rw-r--r--portato/gui/gtk/wrapper.py105
5 files changed, 2104 insertions, 0 deletions
diff --git a/portato/gui/gtk/__init__.py b/portato/gui/gtk/__init__.py
new file mode 100644
index 0000000..85938b4
--- /dev/null
+++ b/portato/gui/gtk/__init__.py
@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/gui/gtk/__init__.py
+# This file is part of the Portato-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2006 René 'Necoro' Neumann
+# This is free software. You may redistribute copies of it under the terms of
+# the GNU General Public License version 2.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Written by René 'Necoro' Neumann <necoro@necoro.net>
+
+from windows import MainWindow
diff --git a/portato/gui/gtk/dialogs.py b/portato/gui/gtk/dialogs.py
new file mode 100644
index 0000000..68cd629
--- /dev/null
+++ b/portato/gui/gtk/dialogs.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/gui/gtk/dialogs.py
+# This file is part of the Portato-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2006 René 'Necoro' Neumann
+# This is free software. You may redistribute copies of it under the terms of
+# the GNU General Public License version 2.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Written by René 'Necoro' Neumann <necoro@necoro.net>
+
+import gtk
+
+def io_ex_dialog (io_ex):
+ string = io_ex.strerror
+ if io_ex.filename:
+ string = string+": "+io_ex.filename
+
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, string)
+ ret = dialog.run()
+ dialog.destroy()
+ return ret
+
+def blocked_dialog (blocked, blocks):
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, blocked+" is blocked by "+blocks+".\nPlease unmerge the blocking package.")
+ ret = dialog.run()
+ dialog.destroy()
+ return ret
+
+def not_root_dialog ():
+ errorMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "You are not root.")
+ ret = errorMB.run()
+ errorMB.destroy()
+ return ret
+
+def unmask_dialog (cpv):
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, cpv+" seems to be masked.\nDo you want to unmask it and its dependencies?.\n")
+ ret = dialog.run()
+ dialog.destroy()
+ return ret
+
+def nothing_found_dialog ():
+ dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Package not found!")
+ ret = dialog.run()
+ dialog.destroy()
+ return ret
+
+def changed_flags_dialog (what = "flags"):
+ hintMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
+ "You have changed %s. Portato will write these changes into the appropriate files. Please backup them if you think it is necessairy." % what)
+ ret = hintMB.run()
+ hintMB.destroy()
+ return ret
+
+def remove_deps_dialog ():
+ infoMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "You cannot remove dependencies. :)")
+ ret = infoMB.run()
+ infoMB.destroy()
+ return ret
+
+def remove_queue_dialog ():
+ askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, "Do you really want to clear the whole queue?")
+ ret = askMB.run()
+ askMB.destroy()
+ return ret
diff --git a/portato/gui/gtk/glade/geneticone.glade b/portato/gui/gtk/glade/geneticone.glade
new file mode 100644
index 0000000..cf187c7
--- /dev/null
+++ b/portato/gui/gtk/glade/geneticone.glade
@@ -0,0 +1,1028 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--*- mode: xml -*-->
+<glade-interface>
+ <widget class="GtkWindow" id="MainWindow">
+ <property name="border_width">2</property>
+ <property name="window_position">GTK_WIN_POS_CENTER</property>
+ <signal name="destroy" handler="cb_destroy"/>
+ <child>
+ <widget class="GtkVBox" id="mainVB">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuBar" id="menubar">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="fileMenu">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_File</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="prefItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Preferences</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_preferences_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="reloadItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Reload Portage</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_reload_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="closeItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Close</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_destroy"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="emergeMenu">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Emerge</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu2">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="emergeItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Emerge</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_emerge_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="unmergeItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Unmerge</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_unmerge_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="updateItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Update _World</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_update_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="syncItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Sync</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_sync_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="saveFlagsItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Save _Flags</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_save_flags_clicked"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkMenuItem" id="helpMenu">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_?</property>
+ <property name="use_underline">True</property>
+ <child>
+ <widget class="GtkMenu" id="menu3">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="aboutItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_About</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="cb_about_clicked"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="searchHB">
+ <property name="visible">True</property>
+ <property name="border_width">3</property>
+ <child>
+ <widget class="GtkEntry" id="searchEntry">
+ <property name="visible">True</property>
+ <signal name="activate" handler="cb_search_clicked" object="searchEntry"/>
+ </widget>
+ <packing>
+ <property name="padding">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="searchButton">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Search</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_search_clicked" object="searchEntry"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVPaned" id="vpaned">
+ <property name="visible">True</property>
+ <property name="position">300</property>
+ <child>
+ <widget class="GtkFrame" id="listFrame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="label_yalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_IN</property>
+ <child>
+ <widget class="GtkHBox" id="listHB">
+ <property name="visible">True</property>
+ <property name="spacing">5</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="catScroll">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTreeView" id="catList">
+ <property name="visible">True</property>
+ <property name="search_column">0</property>
+ <signal name="cursor_changed" handler="cb_cat_list_selection"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="pkgScroll">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTreeView" id="pkgList">
+ <property name="visible">True</property>
+ <property name="search_column">0</property>
+ <signal name="cursor_changed" handler="cb_pkg_list_selection"/>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <placeholder/>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="resize">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkNotebook" id="notebook">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <widget class="GtkTable" id="PackageTable">
+ <property name="visible">True</property>
+ <property name="n_rows">4</property>
+ <property name="n_columns">2</property>
+ <child>
+ <widget class="GtkHBox" id="checkHB">
+ <property name="visible">True</property>
+ <property name="spacing">1</property>
+ <property name="homogeneous">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="installedCheck">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">Installed</property>
+ <property name="draw_indicator">True</property>
+ <signal name="button_press_event" handler="cb_button_pressed"/>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="maskedCheck">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">Masked</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="cb_masked_toggled"/>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="testingCheck">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">Testing</property>
+ <property name="draw_indicator">True</property>
+ <signal name="toggled" handler="cb_testing_toggled"/>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHButtonBox" id="buttonBB">
+ <property name="visible">True</property>
+ <property name="border_width">5</property>
+ <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+ <child>
+ <widget class="GtkButton" id="pkgEmergeBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Emerge</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_package_emerge_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="pkgUnmergeBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Unmerge</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_package_unmerge_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="pkgRevertBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Re_vert</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_package_revert_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="notInSysLabel">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Installed, but not in portage anymore&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="missingLabel">
+ <property name="visible">True</property>
+ <property name="no_show_all">True</property>
+ <property name="label" translatable="yes">&lt;span foreground='red'&gt;&lt;b&gt;MISSING KEYWORD&lt;/b&gt;&lt;/span&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="descLabel">
+ <property name="visible">True</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ <property name="y_padding">10</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkVBox" id="comboVB">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options">GTK_FILL</property>
+ <property name="x_padding">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkScrolledWindow" id="useListScroll">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTreeView" id="useList">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_padding">5</property>
+ <property name="y_padding">5</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Package</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="queueHB">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkScrolledWindow" id="queueScroll">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <child>
+ <widget class="GtkTreeView" id="queueList">
+ <property name="visible">True</property>
+ <property name="headers_visible">False</property>
+ <property name="enable_search">False</property>
+ <signal name="button_press_event" handler="cb_queue_right_click"/>
+ <signal name="row_activated" handler="cb_row_activated"/>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkVButtonBox" id="queueBB">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+ <child>
+ <widget class="GtkButton" id="emergeBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">E_merge</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_emerge_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="unmergeBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Unmerge</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_unmerge_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="updateBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Update _World</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_update_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="removeBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Remove</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_remove_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ <property name="tab_expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Queue</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">1</property>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHBox" id="termHB">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ <property name="tab_expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Console</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="type">tab</property>
+ <property name="position">2</property>
+ <property name="tab_expand">False</property>
+ <property name="tab_fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkAlignment" id="alignment4">
+ <property name="visible">True</property>
+ <property name="top_padding">5</property>
+ <child>
+ <widget class="GtkLabel" id="statusLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="yalign">0</property>
+ <property name="label" translatable="yes">Portato - A Portage GUI</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="AboutWindow">
+ <property name="title" translatable="yes">About</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="default_width">1</property>
+ <property name="default_height">1</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="skip_taskbar_hint">True</property>
+ <child>
+ <widget class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="aboutLabel">
+ <property name="visible">True</property>
+ <property name="use_markup">True</property>
+ <property name="justify">GTK_JUSTIFY_CENTER</property>
+ <property name="wrap">True</property>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="okBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_OK</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="close"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="SearchWindow">
+ <property name="title" translatable="yes">Search</property>
+ <property name="resizable">False</property>
+ <property name="modal">True</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="default_width">1</property>
+ <property name="default_height">1</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="skip_taskbar_hint">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </widget>
+ <widget class="GtkWindow" id="PreferenceWindow">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Preferences</property>
+ <property name="modal">True</property>
+ <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+ <property name="destroy_with_parent">True</property>
+ <property name="skip_taskbar_hint">True</property>
+ <child>
+ <widget class="GtkVBox" id="mainVB">
+ <property name="visible">True</property>
+ <property name="spacing">5</property>
+ <child>
+ <widget class="GtkFrame" id="generalFrame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment1">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkCheckButton" id="debugCheck">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Debug</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;General Options&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="syncFrame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment5">
+ <property name="visible">True</property>
+ <property name="bottom_padding">5</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">5</property>
+ <child>
+ <widget class="GtkHBox" id="syncHB">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkLabel" id="syncLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Sync command: </property>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="syncCommandEdit">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Sync Options&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="updateFrame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment2">
+ <property name="visible">True</property>
+ <property name="left_padding">12</property>
+ <child>
+ <widget class="GtkVBox" id="updateVB">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkCheckButton" id="deepCheck">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">--deep</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="newUseCheck">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">--newuse</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label4">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Update World Options&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkFrame" id="keywordFrame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <widget class="GtkAlignment" id="alignment3">
+ <property name="visible">True</property>
+ <property name="bottom_padding">5</property>
+ <property name="left_padding">12</property>
+ <property name="right_padding">5</property>
+ <child>
+ <widget class="GtkTable" id="keywordTable">
+ <property name="visible">True</property>
+ <property name="n_rows">10</property>
+ <property name="n_columns">2</property>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="useFileEdit">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="useEditLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">File name to use, if package.use is a directory: </property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="usePerVersionCheck">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add only exact version to package.use</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="testPerVersionCheck">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add only exact version to package.keywords</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="testEditLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">File name to use, if package.keywords is a directory: </property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="testFileEdit">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">6</property>
+ <property name="bottom_attach">7</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEntry" id="maskFileEdit">
+ <property name="visible">True</property>
+ </widget>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">9</property>
+ <property name="bottom_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="maskEditLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">File name to use, if package.mask/package.unmask is a directory: </property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">9</property>
+ <property name="bottom_attach">10</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkCheckButton" id="maskPerVersionCheck">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Add only exact version to package.mask/package.unmask</property>
+ <property name="draw_indicator">True</property>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ <property name="top_attach">8</property>
+ <property name="bottom_attach">9</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkEventBox" id="hintEB">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkFrame" id="hintFrame">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_OUT</property>
+ <child>
+ <widget class="GtkLabel" id="hintLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">&lt;u&gt;You may use the following placeholders:&lt;/u&gt;
+
+&lt;i&gt;$(cat)&lt;/i&gt;: category
+&lt;i&gt;$(pkg)&lt;/i&gt;: package name
+&lt;i&gt;$(cat-1)/$(cat-2)&lt;/i&gt;: first/second part of the category</property>
+ <property name="use_markup">True</property>
+ </widget>
+ </child>
+ <child>
+ <placeholder/>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="useLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">5</property>
+ <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Use-Flags&lt;/i&gt;&lt;/u&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_padding">6</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="testLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">5</property>
+ <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Testing Keywords&lt;/i&gt;&lt;/u&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_padding">5</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="maskLabel">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="xpad">5</property>
+ <property name="label" translatable="yes">&lt;u&gt;&lt;i&gt;Masking Keywords&lt;/i&gt;&lt;/u&gt;</property>
+ <property name="use_markup">True</property>
+ <property name="single_line_mode">True</property>
+ </widget>
+ <packing>
+ <property name="top_attach">7</property>
+ <property name="bottom_attach">8</property>
+ <property name="y_padding">5</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">&lt;b&gt;Use Flag and Keyword Options&lt;/b&gt;</property>
+ <property name="use_markup">True</property>
+ </widget>
+ <packing>
+ <property name="type">label_item</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkHButtonBox" id="buttonBox">
+ <property name="visible">True</property>
+ <property name="homogeneous">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_SPREAD</property>
+ <child>
+ <widget class="GtkButton" id="okBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_OK</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_ok_clicked"/>
+ </widget>
+ </child>
+ <child>
+ <widget class="GtkButton" id="cancelBtn">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">_Cancel</property>
+ <property name="use_underline">True</property>
+ <signal name="clicked" handler="cb_cancel_clicked"/>
+ </widget>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <widget class="GtkMenu" id="queuePopup">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkMenuItem" id="oneShotItem">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">oneshot</property>
+ <signal name="activate" handler="cb_oneshot_clicked"/>
+ </widget>
+ </child>
+ </widget>
+</glade-interface>
diff --git a/portato/gui/gtk/windows.py b/portato/gui/gtk/windows.py
new file mode 100644
index 0000000..f4a37fe
--- /dev/null
+++ b/portato/gui/gtk/windows.py
@@ -0,0 +1,892 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/gui/gtk/windows.py
+# This file is part of the Portato-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2006 René 'Necoro' Neumann
+# This is free software. You may redistribute copies of it under the terms of
+# the GNU General Public License version 2.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Written by René 'Necoro' Neumann <necoro@necoro.net>
+
+# gtk stuff
+import pygtk
+pygtk.require("2.0")
+import gtk
+import gtk.glade
+import gobject
+
+#our backend stuff
+from portato.helper import *
+from portato.constants import CONFIG_LOCATION, VERSION, DATA_DIR
+from portato import backend
+from portato.backend import flags
+from portato.backend.exceptions import *
+
+# more GUI stuff
+from portato.gui.gui_helper import Database, Config, EmergeQueue
+from dialogs import *
+from wrapper import GtkTree, GtkConsole
+
+# for the terminal
+import vte
+
+# other
+from portage_util import unique_array
+
+class Window:
+ def __init__ (self):
+ self.tree = gtk.glade.XML(DATA_DIR+"portato.glade", root = self.__class__.__name__)
+ self.tree.signal_autoconnect(self)
+ self.window = self.tree.get_widget(self.__class__.__name__)
+
+ @staticmethod
+ def watch_cursor (func):
+ """This is a decorator for functions being so time consuming, that it is appropriate to show the watch-cursor.
+ @attention: this function relies on the gtk.Window-Object being stored as self.window"""
+ def wrapper (self, *args, **kwargs):
+ ret = None
+ def cb_idle():
+ try:
+ ret = func(self, *args, **kwargs)
+ finally:
+ self.window.window.set_cursor(None)
+ return False
+
+ watch = gtk.gdk.Cursor(gtk.gdk.WATCH)
+ self.window.window.set_cursor(watch)
+ gobject.idle_add(cb_idle)
+ return ret
+ return wrapper
+
+class AbstractDialog (Window):
+ """A class all our dialogs get derived from. It sets useful default vars and automatically handles the ESC-Button."""
+
+ def __init__ (self, parent):
+ """Constructor.
+
+ @param parent: the parent window
+ @type parent: gtk.Window"""
+
+ Window.__init__(self)
+
+ # set parent
+ self.window.set_transient_for(parent)
+
+ # catch the ESC-key
+ self.window.connect("key-press-event", self.cb_key_pressed)
+
+ def cb_key_pressed (self, widget, event):
+ """Closes the window if ESC is pressed."""
+ keyname = gtk.gdk.keyval_name(event.keyval)
+ if keyname == "Escape":
+ self.close()
+ return True
+ else:
+ return False
+
+ def close (self, *args):
+ self.window.destroy()
+
+class AboutWindow (AbstractDialog):
+ """A window showing the "about"-informations."""
+
+ def __init__ (self, parent):
+ """Constructor.
+
+ @param parent: the parent window
+ @type parent: gtk.Window"""
+
+ AbstractDialog.__init__(self, parent)
+
+ label = self.tree.get_widget("aboutLabel")
+ label.set_markup("""
+<big><b>Portato v.%s</b></big>
+A Portage-GUI
+
+This software is licensed under the terms of the GPLv2.
+Copyright (C) 2006 René 'Necoro' Neumann &lt;necoro@necoro.net&gt;
+
+<small>Thanks to Fred for support and ideas :P</small>
+""" % VERSION)
+
+ self.window.show_all()
+
+class SearchWindow (AbstractDialog):
+ """A window showing the results of a search process."""
+
+ def __init__ (self, parent, list, jump_to):
+ """Constructor.
+
+ @param parent: parent-window
+ @type parent: gtk.Window
+ @param list: list of results to show
+ @type list: string[]
+ @param jump_to: function to call if "OK"-Button is hit
+ @type jump_to: function(string)"""
+
+ AbstractDialog.__init__(self, parent)
+
+ self.list = list # list to show
+ self.jump_to = jump_to # function to call for jumping
+
+ # combo box
+ self.combo = gtk.combo_box_new_text()
+ for x in list:
+ self.combo.append_text(x)
+ self.combo.set_active(0) # first item
+ self.combo.connect("key-press-event", self.cb_key_pressed_combo)
+
+ self.window.add(self.combo)
+
+ # finished --> show
+ self.window.show_all()
+
+ def cb_key_pressed_combo (self, widget, event):
+ """Emulates a ok-button-click."""
+ keyname = gtk.gdk.keyval_name(event.keyval)
+ if keyname == "Return": # take it as an "OK" if Enter is pressed
+ self.window.destroy()
+ self.jump_to(self.list[self.combo.get_active()])
+ return True
+ else:
+ return False
+
+class PreferenceWindow (AbstractDialog):
+ """Window displaying some preferences."""
+
+ # all checkboxes in the window
+ # widget name -> option name
+ checkboxes = {
+ "debugCheck" : "debug_opt",
+ "deepCheck" : "deep_opt",
+ "newUseCheck" : "newuse_opt",
+ "maskPerVersionCheck" : "maskPerVersion_opt",
+ "usePerVersionCheck" : "usePerVersion_opt",
+ "testPerVersionCheck" : "testingPerVersion_opt"
+ }
+
+ # all edits in the window
+ # widget name -> option name
+ edits = {
+ "maskFileEdit" : "maskFile_opt",
+ "testFileEdit" : "testingFile_opt",
+ "useFileEdit" : "useFile_opt",
+ "syncCommandEdit" : "syncCmd_opt"
+ }
+
+ def __init__ (self, parent, cfg):
+ """Constructor.
+
+ @param parent: parent window
+ @type parent: gtk.Window
+ @param cfg: configuration object
+ @type cfg: gui_helper.Config"""
+
+ AbstractDialog.__init__(self, parent)
+
+ # our config
+ self.cfg = cfg
+
+ # set the bg-color of the hint
+ hintEB = self.tree.get_widget("hintEB")
+ hintEB.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#f3f785"))
+
+ for box in self.checkboxes:
+ self.tree.get_widget(box).\
+ set_active(self.cfg.get_boolean(self.checkboxes[box]))
+
+ for edit in self.edits:
+ self.tree.get_widget(edit).\
+ set_text(self.cfg.get(self.edits[edit]))
+
+ self.window.show_all()
+
+ def _save(self):
+ """Sets all options in the Config-instance."""
+
+ for box in self.checkboxes:
+ self.cfg.set_boolean(self.checkboxes[box], self.tree.get_widget(box).get_active())
+
+ for edit in self.edits:
+ self.cfg.set(self.edits[edit],self.tree.get_widget(edit).get_text())
+
+ def cb_ok_clicked(self, button):
+ """Saves, writes to config-file and closes the window."""
+ self._save()
+ try:
+ self.cfg.write()
+ except IOError, e:
+ io_ex_dialog(e)
+
+ self.window.destroy()
+
+ def cb_cancel_clicked (self, button):
+ """Just closes - w/o saving."""
+ self.window.destroy()
+
+class PackageTable:
+ """A window with data about a specfic package."""
+
+ def __init__ (self, main):
+ """Build up window contents.
+
+ @param main: the main window
+ @type main: MainWindow"""
+
+ self.main = main
+ self.tree = main.tree
+ self.window = main.window
+ self.tree.signal_autoconnect(self)
+
+ # the table
+ self.table = self.tree.get_widget("PackageTable")
+
+ # chechboxes
+ self.installedCheck = self.tree.get_widget("installedCheck")
+ self.maskedCheck = self.tree.get_widget("maskedCheck")
+ self.testingCheck = self.tree.get_widget("testingCheck")
+
+ # labels
+ self.notInSysLabel = self.tree.get_widget("notInSysLabel")
+ self.missingLabel = self.tree.get_widget("missingLabel")
+
+ # buttons
+ self.emergeBtn = self.tree.get_widget("pkgEmergeBtn")
+ self.unmergeBtn = self.tree.get_widget("pkgUnmergeBtn")
+ self.cancelBtn = self.tree.get_widget("pkgCancelBtn")
+
+ # useList
+ self.useListScroll = self.tree.get_widget("useListScroll")
+ self.useList = None
+
+ def update (self, cp, queue = None, version = None, doEmerge = True, instantChange = False):
+ """Updates the table to show the contents for the package.
+
+ @param cp: the selected package
+ @type cp: string (cp)
+ @param queue: emerge-queue (if None the emerge-buttons are disabled)
+ @type queue: EmergeQueue
+ @param version: if not None, specifies the version to select
+ @type version: string
+ @param doEmerge: if False, the emerge buttons are disabled
+ @type doEmerge: False
+ @param instantChange: if True the changed keywords are updated instantly
+ @type instantChange: boolean"""
+
+ self.cp = cp # category/package
+ self.version = version # version - if not None this is used
+ self.queue = queue
+ self.doEmerge = doEmerge
+ self.instantChange = instantChange
+
+ # packages and installed packages
+ self.packages = backend.sort_package_list(backend.get_all_versions(cp))
+ self.instPackages = backend.sort_package_list(backend.get_all_installed_versions(cp))
+
+ # version-combo-box
+ self.vCombo = self.build_vers_combo()
+ if not self.doEmerge: self.vCombo.set_sensitive(False)
+ vb = self.tree.get_widget("comboVB")
+ children = vb.get_children()
+ if children:
+ for c in children: vb.remove(c)
+ vb.pack_start(self.vCombo)
+
+ # the label (must be here, because it depends on the combo box)
+ desc = self.actual_package().get_env_var("DESCRIPTION").replace("&","&amp;")
+ if not desc:
+ desc = "<no description>"
+ use_markup = False
+ else:
+ desc = "<b>"+desc+"</b>"
+ use_markup = True
+ desc = "<i><u>"+self.actual_package().get_cp()+"</u></i>\n\n"+desc
+ self.descLabel = self.tree.get_widget("descLabel")
+ self.descLabel.set_use_markup(use_markup)
+ self.descLabel.set_label(desc)
+
+ if not self.queue or not self.doEmerge:
+ self.emergeBtn.set_sensitive(False)
+ self.unmergeBtn.set_sensitive(False)
+
+ # current status
+ self.cb_combo_changed(self.vCombo)
+ self.table.show_all()
+
+ def fill_use_list(self, store):
+ """Fills a given ListStore with the use-flag data.
+
+ @param store: the store to fill
+ @type store: gtk.ListStore"""
+
+ pkg = self.actual_package()
+ pkg_flags = pkg.get_all_use_flags()
+ pkg_flags.sort()
+ for use in pkg_flags:
+ if pkg.is_installed() and use in pkg.get_actual_use_flags(): # flags set during install
+ enabled = True
+ elif (not pkg.is_installed()) and use in pkg.get_settings("USE").split() and not flags.invert_use_flag(use) in pkg.get_new_use_flags(): # flags that would be set
+ enabled = True
+ elif use in pkg.get_new_use_flags():
+ enabled = True
+ else:
+ enabled = False
+ store.append([enabled, use, backend.get_use_desc(use, self.cp)])
+
+ return store
+
+ def build_use_list (self):
+ """Builds the useList."""
+ store = gtk.ListStore(bool, str, str)
+ self.fill_use_list(store)
+
+ # build view
+ view = gtk.TreeView(store)
+ cell = gtk.CellRendererText()
+ tCell = gtk.CellRendererToggle()
+ tCell.set_property("activatable", True)
+ tCell.connect("toggled", self.cb_use_flag_toggled, store)
+ view.append_column(gtk.TreeViewColumn("Enabled", tCell, active = 0))
+ view.append_column(gtk.TreeViewColumn("Flags", cell, text = 1))
+ view.append_column(gtk.TreeViewColumn("Description", cell, text = 2))
+
+ if store.iter_n_children(None) == 0: # if there are no nodes in the list ...
+ view.set_child_visible(False) # ... do not show the list
+ else:
+ view.set_child_visible(True)
+ return view
+
+ def build_vers_combo (self):
+ """Creates the combo box with the different versions."""
+ combo = gtk.combo_box_new_text()
+
+ # append versions
+ for s in [x.get_version() for x in self.packages]:
+ combo.append_text(s)
+
+ # activate the first one
+ try:
+ best_version = ""
+ if self.version:
+ best_version = self.version
+ else:
+ best_version = backend.find_best_match(self.packages[0].get_cp(), (self.instPackages != [])).get_version()
+ for i in range(len(self.packages)):
+ if self.packages[i].get_version() == best_version:
+ combo.set_active(i)
+ break
+ except AttributeError: # no package found
+ debug('catched AttributeError => no "best package" found. Selected first one.')
+ combo.set_active(0)
+
+ combo.connect("changed", self.cb_combo_changed)
+
+ return combo
+
+ def actual_package (self):
+ """Returns the actual selected package.
+
+ @returns: the actual selected package
+ @rtype: backend.Package"""
+
+ return self.packages[self.vCombo.get_active()]
+
+ def _update_keywords (self, emerge, update = False):
+ if emerge:
+ try:
+ try:
+ self.queue.append(self.actual_package().get_cpv(), unmerge = False, update = update)
+ except backend.PackageNotFoundException, e:
+ if unmask_dialog(e[0]) == gtk.RESPONSE_YES:
+ self.queue.append(self.actual_package().get_cpv(), unmerge = False, unmask = True, update = update)
+ except BlockedException, e:
+ blocked_dialog(e[0], e[1])
+ else:
+ try:
+ self.queue.append(self.actual_package().get_cpv(), unmerge = True)
+ except backend.PackageNotFoundException, e:
+ masked_dialog(e[0])
+
+ def cb_combo_changed (self, combo):
+ """Callback for the changed ComboBox.
+ It then rebuilds the useList and the checkboxes."""
+
+ # remove old useList
+ w = self.useListScroll.get_child()
+ if w:
+ self.useListScroll.remove(w)
+
+ # build new
+ self.useList = self.build_use_list()
+ self.useListScroll.add(self.useList)
+ pkg = self.actual_package()
+
+ #
+ # rebuild the buttons and checkboxes in all the different manners which are possible
+ #
+ if (not pkg.is_in_system()) or pkg.is_missing_keyword():
+ if not pkg.is_in_system():
+ self.missingLabel.hide()
+ self.notInSysLabel.show()
+ else: # missing keyword
+ self.missingLabel.show()
+ self.notInSysLabel.hide()
+
+ self.installedCheck.hide()
+ self.maskedCheck.hide()
+ self.testingCheck.hide()
+ self.emergeBtn.set_sensitive(False)
+ else:
+ self.missingLabel.hide()
+ self.notInSysLabel.hide()
+ self.installedCheck.show()
+ self.maskedCheck.show()
+ self.testingCheck.show()
+ if self.doEmerge:
+ self.emergeBtn.set_sensitive(True)
+ self.installedCheck.set_active(pkg.is_installed())
+ self.maskedCheck.set_active(pkg.is_masked())
+ if pkg.is_testing(allowed = False) and not pkg.is_testing(allowed=True):
+ self.testingCheck.set_label("<i>(Testing)</i>")
+ self.testingCheck.get_child().set_use_markup(True)
+ else:
+ self.testingCheck.set_label("Testing")
+ self.testingCheck.set_active(pkg.is_testing(allowed = False))
+
+ if self.doEmerge:
+ # set emerge-button-label
+ if not self.actual_package().is_installed():
+ self.emergeBtn.set_label("_Emerge")
+ self.unmergeBtn.set_sensitive(False)
+ else:
+ self.emergeBtn.set_label("R_emerge")
+ self.unmergeBtn.set_sensitive(True)
+
+ self.table.show_all()
+
+ return True
+
+ def cb_button_pressed (self, b, event):
+ """Callback for pressed checkboxes. Just quits the event-loop - no redrawing."""
+ if not isinstance(b, gtk.CellRendererToggle):
+ b.emit_stop_by_name("button-press-event")
+ return True
+
+ def cb_package_revert_clicked (self, button):
+ """Callback for pressed cancel-button. Closes the window."""
+ self.actual_package().remove_new_use_flags()
+ self.actual_package().remove_new_masked()
+ self.actual_package().remove_new_testing()
+ self.cb_combo_changed(self.vCombo)
+ if self.instantChange:
+ self._update_keywords(True, update = True)
+ return True
+
+ def cb_package_emerge_clicked (self, button):
+ """Callback for pressed emerge-button. Adds the package to the EmergeQueue."""
+ if not am_i_root():
+ not_root_dialog()
+ else:
+ self._update_keywords(True)
+ self.main.notebook.set_current_page(self.main.QUEUE_PAGE)
+ return True
+
+ def cb_package_unmerge_clicked (self, button):
+ """Callback for pressed unmerge-button clicked. Adds the package to the UnmergeQueue."""
+ if not am_i_root():
+ not_root_dialog()
+ else:
+ self._update_keywords(False)
+ self.main.notebook.set_current_page(self.main.QUEUE_PAGE)
+ return True
+
+ def cb_testing_toggled (self, button):
+ """Callback for toggled testing-checkbox."""
+ status = button.get_active()
+
+ if self.actual_package().is_testing(allowed = False) == status:
+ return False
+
+ if not self.actual_package().is_testing(allowed = True):
+ self.actual_package().set_testing(False)
+ button.set_label("Testing")
+ button.set_active(True)
+ else:
+ self.actual_package().set_testing(True)
+ if self.actual_package().is_testing(allowed=False):
+ button.set_label("<i>(Testing)</i>")
+ button.get_child().set_use_markup(True)
+ button.set_active(True)
+
+ if self.instantChange:
+ self._update_keywords(True, update = True)
+
+ return True
+
+ def cb_masked_toggled (self, button):
+ """Callback for toggled masking-checkbox."""
+ status = button.get_active()
+ self.actual_package().set_masked(status)
+
+ if self.instantChange:
+ self._update_keywords(True, update = True)
+
+ return True
+
+ def cb_use_flag_toggled (self, cell, path, store):
+ """Callback for a toggled use-flag button."""
+ store[path][0] = not store[path][0]
+ prefix = ""
+ if not store[path][0]:
+ prefix = "-"
+ self.actual_package().set_use_flag(prefix+store[path][1])
+
+ if self.instantChange:
+ self._update_keywords(True, update = True)
+
+ return True
+
+class MainWindow (Window):
+ """Application main window."""
+
+ # NOTEBOOK PAGE CONSTANTS
+ PKG_PAGE = 0
+ QUEUE_PAGE = 1
+ CONSOLE_PAGE = 2
+
+ def __init__ (self):
+ """Build up window"""
+
+ # main window stuff
+ Window.__init__(self)
+ self.window.set_title(("Portato (%s)" % VERSION))
+ mHeight = 800
+ if gtk.gdk.screen_height() <= 800: mHeight = 600
+ self.window.set_geometry_hints (self.window, min_width = 600, min_height = mHeight, max_height = gtk.gdk.screen_height(), max_width = gtk.gdk.screen_width())
+
+ # booleans
+ self.doUpdate = False
+ self.packageInit = True
+
+ # package db
+ self.db = Database()
+ self.db.populate()
+
+ # config
+ try:
+ self.cfg = Config(CONFIG_LOCATION)
+ except IOError, e:
+ io_ex_dialog(e)
+ raise e
+
+ self.cfg.modify_external_configs()
+
+ # set vpaned position
+ vpaned = self.tree.get_widget("vpaned")
+ vpaned.set_position(mHeight/2)
+
+ # cat and pkg list
+ self.catList = self.tree.get_widget("catList")
+ self.pkgList = self.tree.get_widget("pkgList")
+ self.build_cat_list()
+ self.build_pkg_list()
+
+ # queue list
+ self.queueList = self.tree.get_widget("queueList")
+ self.build_queue_list()
+
+ # the terminal
+ term = vte.Terminal()
+ term.set_scrollback_lines(1024)
+ term.set_scroll_on_output(True)
+ term.set_font_from_string("Monospace 11")
+ # XXX why is this not working with the colors
+ term.set_color_background(gtk.gdk.color_parse("white"))
+ term.set_color_foreground(gtk.gdk.color_parse("black"))
+ termHB = self.tree.get_widget("termHB")
+ termScroll = gtk.VScrollbar(term.get_adjustment())
+ termHB.pack_start(term, True, True)
+ termHB.pack_start(termScroll, False)
+
+ # notebook
+ self.notebook = self.tree.get_widget("notebook")
+ self.window.show_all()
+
+ # table
+ self.packageTable = PackageTable(self)
+ self.packageTable.table.hide_all()
+
+ # popup
+ popupTree = gtk.glade.XML(DATA_DIR+"portato.glade", root = "queuePopup")
+ popupTree.signal_autoconnect(self)
+ self.queuePopup = popupTree.get_widget("queuePopup")
+
+ # set emerge queue
+ self.queueTree = GtkTree(self.queueList.get_model())
+ self.queue = EmergeQueue(console = GtkConsole(term), tree = self.queueTree, db = self.db)
+
+ def show_package (self, *args, **kwargs):
+ self.packageTable.update(*args, **kwargs)
+ self.notebook.set_current_page(self.PKG_PAGE)
+
+ def build_queue_list (self):
+ """Builds the queue list."""
+
+ store = gtk.TreeStore(str,str)
+
+ self.queueList.set_model(store)
+
+ cell = gtk.CellRendererText()
+ col = gtk.TreeViewColumn("Queue", cell, text = 0)
+ self.queueList.append_column(col)
+
+ col = gtk.TreeViewColumn("Options", cell, markup = 1)
+ self.queueList.append_column(col)
+
+ def build_cat_list (self):
+ """Builds the category list."""
+
+ store = gtk.ListStore(str)
+
+ # build categories
+ for p in backend.list_categories():
+ store.append([p])
+ # sort them alphabetically
+ store.set_sort_column_id(0, gtk.SORT_ASCENDING)
+
+ self.catList.set_model(store)
+ cell = gtk.CellRendererText()
+ col = gtk.TreeViewColumn("Categories", cell, text = 0)
+ self.catList.append_column(col)
+
+ def build_pkg_list (self, name = None):
+ """Builds the package list.
+
+ @param name: name of the selected catetegory
+ @type name: string"""
+
+ store = gtk.ListStore(str)
+ self.fill_pkg_store(store,name)
+
+ # build view
+ self.pkgList.set_model(store)
+ cell = gtk.CellRendererText()
+ col = gtk.TreeViewColumn("Packages", cell, text = 0)
+ self.pkgList.append_column(col)
+
+ def fill_pkg_store (self, store, name = None):
+ """Fills a given ListStore with the packages in a category.
+
+ @param store: the store to fill
+ @type store: gtk.ListStore
+ @param name: the name of the category
+ @type name: string
+ @returns: the filled store
+ @rtype: gtk.ListStore"""
+
+ if name:
+ for p in self.db.get_cat(name):
+ store.append([p])
+ return store
+
+ def jump_to (self, cp):
+ """Is called when we want to jump to a specific package."""
+ self.show_package(cp, self.queue)
+
+ def cb_cat_list_selection (self, view):
+ """Callback for a category-list selection. Updates the package list with the packages in the category."""
+ # get the selected category
+ sel = view.get_selection()
+ store, it = sel.get_selected()
+ if it:
+ self.selCatName = store.get_value(it, 0)
+ self.pkgList.get_model().clear()
+ self.fill_pkg_store(self.pkgList.get_model(), self.selCatName)
+ return True
+
+ def cb_pkg_list_selection (self, view):
+ """Callback for a package-list selection. Updates the package info."""
+ sel = view.get_selection()
+ store, it = sel.get_selected()
+ if it:
+ package = store.get_value(it, 0)
+ if package[-1] == '*': package = package[:-1]
+ self.show_package(self.selCatName+"/"+package, self.queue)
+ return True
+
+ def cb_row_activated (self, view, path, *args):
+ """Callback for an activated row in the emergeQueue. Opens a package window."""
+ store = self.queueTree
+ if len(path) > 1:
+ iterator = store.get_original().get_iter(path)
+ if store.is_in_emerge(iterator):
+ package = store.get_value(iterator, 0)
+ cat, name, vers, rev = backend.split_package_name(package)
+ if rev != "r0": vers = vers+"-"+rev
+ self.show_package(cat+"/"+name, queue = self.queue, version = vers, instantChange = True, doEmerge = False)
+ return True
+
+ def cb_emerge_clicked (self, action):
+ """Do emerge."""
+
+ self.notebook.set_current_page(self.CONSOLE_PAGE)
+
+ if len(flags.newUseFlags) > 0:
+ changed_flags_dialog("use flags")
+ flags.write_use_flags()
+
+ if len(flags.new_masked)>0 or len(flags.new_unmasked)>0 or len(flags.newTesting)>0:
+ debug("new masked:",flags.new_masked)
+ debug("new unmasked:", flags.new_unmasked)
+ debug("new testing:", flags.newTesting)
+ changed_flags_dialog("masking keywords")
+ flags.write_masked()
+ flags.write_testing()
+ backend.reload_settings()
+
+ if not self.doUpdate:
+ self.queue.emerge(force=True)
+ else:
+ self.queue.update_world(force=True, newuse = self.cfg.get_boolean("newuse_opt"), deep = self.cfg.get_boolean("deep_opt"))
+ self.doUpdate = False
+
+ def cb_unmerge_clicked (self, button):
+ """Do unmerge."""
+
+ self.notebook.set_current_page(self.CONSOLE_PAGE)
+ self.queue.unmerge(force=True)
+ return True
+
+ @Window.watch_cursor
+ def cb_update_clicked (self, action):
+ if not backend.am_i_root():
+ not_root_dialog()
+
+ else:
+ updating = backend.update_world(newuse = self.cfg.get_boolean("newuse_opt"), deep = self.cfg.get_boolean("deep_opt"))
+
+ debug("updating list:", [(x.get_cpv(), y.get_cpv()) for x,y in updating])
+ try:
+ for pkg, old_pkg in updating:
+ self.queue.append(pkg.get_cpv())
+ except BlockedException, e:
+ blocked_dialog(e[0], e[1])
+ if len(updating): self.doUpdate = True
+ return True
+
+ def cb_remove_clicked (self, button):
+ """Removes a selected item in the (un)emerge-queue if possible."""
+ selected = self.queueList.get_selection()
+
+ if selected:
+ model, iter = selected.get_selected()
+
+ if iter == None: return False
+
+ if not model.iter_parent(iter): # top-level
+ if model.iter_n_children(iter) > 0: # and has children which can be removed :)
+ if remove_queue_dialog() == gtk.RESPONSE_YES :
+ self.queue.remove_children(iter)
+ self.doUpdate = False
+
+ elif model.iter_parent(model.iter_parent(iter)): # this is in the 3rd level => dependency
+ remove_deps_dialog()
+ else:
+ self.queue.remove_children(iter) # remove children first
+ self.queue.remove(iter)
+ self.doUpdate = False
+
+ return True
+
+ def cb_sync_clicked (self, action):
+ if not backend.am_i_root():
+ not_root_dialog()
+ else:
+ self.notebook.set_current_page(self.CONSOLE_PAGE)
+ cmd = self.cfg.get("syncCmd_opt")
+
+ if cmd != "emerge --sync":
+ cmd = cmd.split()
+ self.queue.sync(cmd)
+ else:
+ self.queue.sync()
+
+ def cb_save_flags_clicked (self, action):
+ if not backend.am_i_root():
+ not_root_dialog()
+ else:
+ flags.write_use_flags()
+ flags.write_testing()
+ flags.write_masked()
+
+ @Window.watch_cursor
+ def cb_reload_clicked (self, action):
+ """Reloads the portage settings and the database."""
+ backend.reload_settings()
+ del self.db
+ self.db = Database()
+ self.db.populate()
+
+ @Window.watch_cursor
+ def cb_search_clicked (self, entry):
+ """Do a search."""
+ if entry.get_text() != "":
+ packages = backend.find_all_packages(entry.get_text(), withVersion = False)
+
+ if packages == []:
+ nothing_found_dialog()
+ else:
+ if len(packages) == 1:
+ self.jump_to(packages[0])
+ else:
+ SearchWindow(self.window, packages, self.jump_to)
+
+ def cb_preferences_clicked (self, button):
+ PreferenceWindow(self.window, self.cfg)
+ return True
+
+ def cb_about_clicked (self, button):
+ AboutWindow(self.window)
+ return True
+
+ def cb_queue_right_click (self, queue, event):
+ if event.button == 3:
+ x = int(event.x)
+ y = int(event.y)
+ time = event.time
+ pthinfo = queue.get_path_at_pos(x, y)
+ if pthinfo is not None:
+ path, col, cellx, celly = pthinfo
+ if self.queueTree.is_in_emerge(self.queueTree.get_original().get_iter(path)):
+ queue.grab_focus()
+ queue.set_cursor(path, col, 0)
+ self.queuePopup.popup(None, None, None, event.button, time)
+ return True
+ else:
+ return False
+
+ def cb_oneshot_clicked (self, action):
+ sel = self.queueList.get_selection()
+ store, it = sel.get_selected()
+ if it:
+ package = store.get_value(it, 0)
+ if not self.cfg.get_local(package, "oneshot_opt"):
+ set = True
+ else:
+ set = False
+
+ self.cfg.set_local(package, "oneshot_opt", set)
+ self.queue.append(package, update = True, oneshot = set, forceUpdate = True)
+
+ def cb_destroy (self, widget):
+ """Calls main_quit()."""
+ gtk.main_quit()
+
+ def main (self):
+ """Main."""
+ gobject.threads_init()
+ # now subthreads can run normally, but are not allowed to touch the GUI. If threads should change sth there - use gobject.idle_add().
+ # for more informations on threading and gtk: http://www.async.com.br/faq/pygtk/index.py?req=show&file=faq20.006.htp
+ gtk.main()
diff --git a/portato/gui/gtk/wrapper.py b/portato/gui/gtk/wrapper.py
new file mode 100644
index 0000000..7066acb
--- /dev/null
+++ b/portato/gui/gtk/wrapper.py
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+#
+# File: portato/gui/gtk/wrapper.py
+# This file is part of the Portato-Project, a graphical portage-frontend.
+#
+# Copyright (C) 2006 René 'Necoro' Neumann
+# This is free software. You may redistribute copies of it under the terms of
+# the GNU General Public License version 2.
+# There is NO WARRANTY, to the extent permitted by law.
+#
+# Written by René 'Necoro' Neumann <necoro@necoro.net>
+
+from portato.gui.wrapper import Tree, Console
+
+class GtkTree (Tree):
+ """The implementation of the abstract tree."""
+
+ def __init__ (self, tree, col = 0):
+ """Constructor.
+
+ @param tree: original tree
+ @type tree: gtk.TreeStore
+ @param col: the column where the cpv is stored
+ @type col: int"""
+
+ self.tree = tree
+ self.cpv_col = col
+ self.emergeIt = self.append(None, ["Emerge", ""])
+ self.unmergeIt = self.append(None, ["Unmerge", ""])
+
+ def build_append_value (self, cpv, oneshot = False, update = False, version = None):
+ string = ""
+
+ if oneshot:
+ string += "<i>oneshot</i>"
+ if update: string += "; "
+
+ if update:
+ string += "<i>updating</i>"
+ if version != None:
+ string += "<i> from version %s</i>" % version
+
+ return [cpv, string]
+
+ def get_emerge_it (self):
+ return self.emergeIt
+
+ def get_unmerge_it (self):
+ return self.unmergeIt
+
+ def is_in_emerge (self, it):
+ return self.get_path_from_iter(it).split(":")[0] == self.get_path_from_iter(self.emergeIt)
+
+ def is_in_unmerge (self, it):
+ return self.get_path_from_iter(it).split(":")[0] == self.get_path_from_iter(self.unmergeIt)
+
+ def iter_has_parent (self, it):
+ return (self.tree.iter_parent(it) != None)
+
+ def parent_iter (self, it):
+ return self.tree.iter_parent(it)
+
+ def first_child_iter (self, it):
+ return self.tree.iter_children(it)
+
+ def iter_has_children (self, it):
+ return self.tree.iter_has_child(it)
+
+ def next_iter (self, it):
+ return self.tree.iter_next(it)
+
+ def get_value (self, it, column):
+ return self.tree.get_value(it, column)
+
+ def get_path_from_iter (self, it):
+ return self.tree.get_string_from_iter(it)
+
+ def append (self, parent = None, values = None):
+ return self.tree.append(parent, values)
+
+ def remove (self, it):
+ return self.tree.remove(it)
+
+ def get_original (self):
+ return self.tree
+
+ def get_cpv_column (self):
+ return self.cpv_col
+
+class GtkConsole (Console):
+ """The implementation of the abstract Console for GTK."""
+
+ def __init__ (self, console):
+ """Constructor.
+
+ @param console: the original console
+ @type console: vte.Terminal"""
+
+ self.console = console
+
+ def set_pty (self, pty):
+ self.console.set_pty(pty)
+
+ def get_original (self):
+ return self.console