diff options
Diffstat (limited to 'geneticone/gui/gtk')
-rw-r--r-- | geneticone/gui/gtk/glade/geneticone.glade | 940 | ||||
-rw-r--r-- | geneticone/gui/gtk/windows.py | 983 |
2 files changed, 1314 insertions, 609 deletions
diff --git a/geneticone/gui/gtk/glade/geneticone.glade b/geneticone/gui/gtk/glade/geneticone.glade new file mode 100644 index 0000000..63f54e8 --- /dev/null +++ b/geneticone/gui/gtk/glade/geneticone.glade @@ -0,0 +1,940 @@ +<?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_ALWAYS</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> + </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> + </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="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="y_padding">5</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> + </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">GTK_EXPAND</property> + <property name="y_padding">10</property> + </packing> + </child> + <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> + </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="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="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> + <property name="x_padding">5</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"><span foreground='red'><b>MISSING KEYWORD</b></span></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="notInSysLabel"> + <property name="visible">True</property> + <property name="no_show_all">True</property> + <property name="label" translatable="yes"><b>Installed, but not in portage anymore</b></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="GtkHButtonBox" id="buttonBB"> + <property name="visible">True</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> + </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> + </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="GtkStatusbar" id="statusbar"> + <property name="visible">True</property> + </widget> + <packing> + <property name="expand">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"><b>General Options</b></property> + <property name="use_markup">True</property> + </widget> + <packing> + <property name="type">label_item</property> + </packing> + </child> + </widget> + </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"><b>Update World Options</b></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="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> + <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"><u><i>Masking Keywords</i></u></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> + <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"><u><i>Testing Keywords</i></u></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="useLabel"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">5</property> + <property name="label" translatable="yes"><u><i>Use-Flags</i></u></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> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </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.029999999329447746</property> + <property name="label" translatable="yes"><u>You may use the following placeholders:</u> + +<i>$(cat)</i>: category +<i>$(pkg)</i>: package name +<i>$(cat-1)/$(cat-2)</i>: 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="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="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="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="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="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="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="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="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="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> + </widget> + </child> + </widget> + </child> + <child> + <widget class="GtkLabel" id="label5"> + <property name="visible">True</property> + <property name="label" translatable="yes"><b>Use Flag and Keyword Options</b></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="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">3</property> + </packing> + </child> + </widget> + </child> + </widget> +</glade-interface> diff --git a/geneticone/gui/gtk/windows.py b/geneticone/gui/gtk/windows.py index 0f36a67..3ce01f9 100644 --- a/geneticone/gui/gtk/windows.py +++ b/geneticone/gui/gtk/windows.py @@ -10,17 +10,16 @@ # # Written by René 'Necoro' Neumann <necoro@necoro.net> -VERSION = "0.4.6-svn" -CONFIG_LOCATION = "/etc/geneticone/geneticone.cfg" - # gtk stuff import pygtk pygtk.require("2.0") import gtk +import gtk.glade import gobject #our backend stuff from geneticone.helper import * +from geneticone.constants import CONFIG_LOCATION, VERSION, DATA_DIR from geneticone import backend from geneticone.backend import flags from geneticone.backend.exceptions import * @@ -36,34 +35,45 @@ import vte # other from portage_util import unique_array -class AbstractDialog: +class Window: + def __init__ (self): + self.tree = gtk.glade.XML(DATA_DIR+"geneticone.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, title): + def __init__ (self, parent): """Constructor. @param parent: the parent window - @type parent: gtk.Window - @param title: the title of the window - @type title: string""" - - # create new - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) - - # set title - self.window.set_title(title) + @type parent: gtk.Window""" - # set modal and transient for the parent --> you have to close this one to get back to the parent - self.window.set_modal(True) - self.window.set_transient_for(parent) - self.window.set_destroy_with_parent(True) + Window.__init__(self) - # not resizable - self.window.set_resizable(False) + # set parent + self.window.set_transient_for(parent) - # default size = (1,1) ==> as small as possible - self.window.set_default_size(1,1) - # catch the ESC-key self.window.connect("key-press-event", self.cb_key_pressed) @@ -71,11 +81,14 @@ class AbstractDialog: """Closes the window if ESC is pressed.""" keyname = gtk.gdk.keyval_name(event.keyval) if keyname == "Escape": - self.window.destroy() + self.close() return True else: return False + def close (self, *args): + self.window.destroy() + class AboutWindow (AbstractDialog): """A window showing the "about"-informations.""" @@ -84,15 +97,10 @@ class AboutWindow (AbstractDialog): @param parent: the parent window @type parent: gtk.Window""" - - AbstractDialog.__init__(self, parent, "About Genetic/One") - box = gtk.VBox(False) - self.window.add(box) - - # about label - label = gtk.Label() - label.set_justify(gtk.JUSTIFY_CENTER) + AbstractDialog.__init__(self, parent) + + label = self.tree.get_widget("aboutLabel") label.set_markup(""" <big><b>Genetic/One v.%s</b></big> A Portage-GUI @@ -102,14 +110,7 @@ Copyright (C) 2006 René 'Necoro' Neumann <necoro@necoro.net> <small>Thanks to Fred for support and ideas :P</small> """ % VERSION) - box.pack_start(label) - # button - okBtn = gtk.Button("OK") - okBtn.connect("clicked", lambda x: self.window.destroy()) - box.pack_start(okBtn) - - # finished -> show self.window.show_all() class SearchWindow (AbstractDialog): @@ -125,49 +126,54 @@ class SearchWindow (AbstractDialog): @param jump_to: function to call if "OK"-Button is hit @type jump_to: function(string)""" - AbstractDialog.__init__(self, parent, "Search results") + AbstractDialog.__init__(self, parent) self.list = list # list to show self.jump_to = jump_to # function to call for jumping - - box = gtk.HBox(False) - self.window.add(box) - + # 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) - - box.pack_start(self.combo) - - # ok-button - okBtn = gtk.Button("OK") - okBtn.connect("clicked", self.cb_ok_btn_clicked) - box.pack_start(okBtn) + + self.window.add(self.combo) # finished --> show self.window.show_all() - def cb_ok_btn_clicked (self, button): - """Called if the OK-Button is clicked. - Calls self.jump_to(selected_entry) and closes the window.""" - self.window.destroy() - self.jump_to(self.list[self.combo.get_active()]) - return True - 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.cb_ok_btn_clicked(widget) + 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" + } def __init__ (self, parent, cfg): """Constructor. @@ -176,239 +182,139 @@ class PreferenceWindow (AbstractDialog): @type parent: gtk.Window @param cfg: configuration object @type cfg: gui_helper.Config""" - - AbstractDialog.__init__(self, parent, "Preferences") - self.window.set_resizable(True) # override the default of the AbstractDialog + AbstractDialog.__init__(self, parent) + # our config self.cfg = cfg - box = gtk.VBox() - box.set_spacing(5) + # set the bg-color of the hint + hintEB = self.tree.get_widget("hintEB") + hintEB.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse("#f3f785")) - self.window.add(box) - # En-/Disable Debugging - self.debugCb = self.draw_cb(box, "Debugging modus", "debug_opt") + for box in self.checkboxes: + self.tree.get_widget(box).\ + set_active(self.cfg.get_boolean(\ + self.cfg.const[self.checkboxes[box]])) - # --deep - self.deepCb = self.draw_cb(box, "--deep", "deep_opt") + for edit in self.edits: + self.tree.get_widget(edit).\ + set_text(self.cfg.get(\ + self.cfg.const[self.edits[edit]])) - # --newuse - self.newuseCb = self.draw_cb(box, "--newuse", "newuse_opt") - - pHolderLabel = gtk.Label("""<u>For the following options, you might use these placeholders:</u> -<b>$(cat)</b> = category -<b>$(pkg)</b> = package-name -<b>$(cat-1)</b>/<b>$(cat-2)</b> = first/second part of the category""") - pHolderLabel.set_use_markup(True) - pHolderLabel.set_alignment(0,0) - box.pack_start(pHolderLabel) - - # The use/mask/keywording checkboxes and edits - self.usePerVersionCb, self.useFileEdit = self.draw_cb_and_edit(box, "package.use", "usePerVersion_opt", "useFile_opt") - self.maskPerVersionCb, self.maskFileEdit = self.draw_cb_and_edit(box, "package.mask/package.unmask", "maskPerVersion_opt", "maskFile_opt") - self.testPerVersionCb, self.testFileEdit = self.draw_cb_and_edit(box, "package.keywords", "testingPerVersion_opt", "testingFile_opt") - # buttons - buttonHB = gtk.HButtonBox() - buttonHB.set_layout(gtk.BUTTONBOX_SPREAD) - - okBtn = gtk.Button("_OK") - cancelBtn = gtk.Button("_Cancel") - okBtn.connect("clicked", self.cb_ok_clicked) - cancelBtn.connect("clicked", lambda x: self.window.destroy()) - buttonHB.pack_start(okBtn) - buttonHB.pack_start(cancelBtn) - - box.pack_start(buttonHB, True, True, 5) - - # finished --> show all self.window.show_all() - def draw_cb_and_edit (self, box, string, cb_opt, edit_opt): - """Draws a checkbox and an edit-field. - - @param box: box to place the both things into - @type box: gtk.Box - @param string: string to show - @type string: string - @param cb_opt: the option string for the Config.const-dict - @type cb_opt: string - @param edit_opt: the option string for the Config.const-dic - @type edit_opt: string - - @return: the checkbox and the edit-field - @rtype: (gtk.CheckButton, gtk.Edit)""" - - # check-button - cb = self.draw_cb(box, label=("Add to %s on a per-version-base" % string), opt = cb_opt) - - # edit with label - hBox = gtk.HBox() - label = gtk.Label("File name to use if %s is a directory:" % string) - edit = gtk.Entry() - edit.set_text(self.cfg.get(self.cfg.const[edit_opt])) - hBox.pack_start(label, False) - hBox.pack_start(edit, True, True, 5) - box.pack_start(hBox, True, True) - - return (cb, edit) - - def draw_cb (self, box, label, opt): - """Draws a checkbox. - - @param box: box to place the cb into - @type box: gtk.Box - @param label: Label to show - @type label: string - @param opt: the option string for the Config.const-dict - @type opt: string - @returns: the checkbox - @rtype: gtk.CheckButton""" - - cb = gtk.CheckButton(label=label) - cb.set_active(self.cfg.get_boolean(self.cfg.const[opt])) - box.pack_start(cb, True, True) - - return cb - def _save(self): """Sets all options in the Config-instance.""" - self.cfg.set(self.cfg.const["usePerVersion_opt"], str(self.usePerVersionCb.get_active())) - self.cfg.set(self.cfg.const["useFile_opt"], self.useFileEdit.get_text()) - self.cfg.set(self.cfg.const["maskPerVersion_opt"], str(self.maskPerVersionCb.get_active())) - self.cfg.set(self.cfg.const["maskFile_opt"], self.maskFileEdit.get_text()) - self.cfg.set(self.cfg.const["testingPerVersion_opt"], str(self.testPerVersionCb.get_active())) - self.cfg.set(self.cfg.const["testingFile_opt"], self.testFileEdit.get_text()) - self.cfg.set(self.cfg.const["debug_opt"], str(self.debugCb.get_active())) - self.cfg.set(self.cfg.const["deep_opt"], str(self.deepCb.get_active())) - self.cfg.set(self.cfg.const["newuse_opt"], str(self.newuseCb.get_active())) + + for box in self.checkboxes: + self.cfg.set(\ + self.cfg.const[self.checkboxes[box]],\ + str(self.tree.get_widget(box).get_active())) + for edit in self.edits: + self.cfg.set(\ + self.cfg.const[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() self.cfg.write() self.window.destroy() -class PackageWindow (AbstractDialog): + 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, parent, cp, queue = None, version = None, delOnClose = True, doEmerge = True): + def __init__ (self, main): """Build up window contents. - @param parent: the parent window - @type parent: gtk.Window + @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 delOnClose: if True (default) changed flags are changed on closing - @type delOnClose: boolean @param doEmerge: if False, the emerge buttons are disabled - @type doEmerge: False""" - - AbstractDialog.__init__(self, parent, cp) - + @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.delOnClose = delOnClose self.doEmerge = doEmerge - self.flagChanged = False + 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)) - # main structure - the table - self.table = gtk.Table(rows=4,columns=2) - self.window.add(self.table) - # version-combo-box self.vCombo = self.build_vers_combo() - self.table.attach(self.vCombo, 0, 1, 1, 2, yoptions = gtk.FILL) 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") + desc = self.actual_package().get_env_var("DESCRIPTION").replace("&","&") if not desc: desc = "<no description>" use_markup = False else: desc = "<b>"+desc+"</b>" use_markup = True - self.descLabel = gtk.Label(desc) - self.descLabel.set_line_wrap(True) - self.descLabel.set_justify(gtk.JUSTIFY_CENTER) + self.descLabel = self.tree.get_widget("descLabel") self.descLabel.set_use_markup(use_markup) - self.table.attach(self.descLabel, 0, 2, 0, 1, xoptions = gtk.FILL, ypadding = 10) - - # the check boxes - checkHB = gtk.HBox (True, 1) - self.table.attach(checkHB, 1, 2, 1, 2, yoptions = gtk.FILL) - - self.installedCheck = gtk.CheckButton() - self.installedCheck.connect("button-press-event", self.cb_button_pressed) - self.installedCheck.set_label("Installed") - self.installedCheck.set_no_show_all(True) - checkHB.pack_start(self.installedCheck, True, False) - - self.maskedCheck = gtk.CheckButton() - self.maskedCheck.connect("toggled", self.cb_masked_toggled) - self.maskedCheck.set_label("Masked") - self.maskedCheck.set_no_show_all(True) - checkHB.pack_start(self.maskedCheck, True, False) - - self.testingCheck = gtk.CheckButton() - self.testingCheck.connect("toggled", self.cb_testing_toggled) - self.testingCheck.set_label("Testing") - self.testingCheck.set_no_show_all(True) - checkHB.pack_start(self.testingCheck, True, False) - - self.missing_label = gtk.Label("<span foreground='red'><b>MISSING KEYWORD</b></span>") - self.missing_label.set_use_markup(True) - self.missing_label.set_no_show_all(True) - self.table.attach(self.missing_label, 1, 2, 1, 2, yoptions = gtk.FILL) - - self.not_in_sys_label = gtk.Label("<b>Installed, but not in portage anymore</b>") - self.not_in_sys_label.set_use_markup(True) - self.not_in_sys_label.set_no_show_all(True) - self.table.attach(self.not_in_sys_label, 1, 2, 1, 2, yoptions = gtk.FILL) - - # use list - self.useList = self.build_use_list() - self.useListScroll = gtk.ScrolledWindow() - self.useListScroll.add(self.useList) - self.useListScroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER) # XXX: make this work correctly - self.table.attach(self.useListScroll, 0, 2, 2, 3, ypadding = 10) + self.descLabel.set_label(desc) - # buttons - buttonHB = gtk.HButtonBox() - buttonHB.set_layout(gtk.BUTTONBOX_SPREAD) - self.table.attach(buttonHB, 0, 2, 3, 4) - - self.emergeBtn = gtk.Button("_Emerge") - self.unmergeBtn = gtk.Button("_Unmerge") if not self.queue or not self.doEmerge: self.emergeBtn.set_sensitive(False) self.unmergeBtn.set_sensitive(False) - self.cancelBtn = gtk.Button("_Cancel") - if not self.delOnClose: - self.cancelBtn.set_label("_Close") - self.cancelBtn.connect("clicked", self.cb_cancel_clicked) - self.emergeBtn.connect("clicked", self.cb_emerge_clicked) - self.unmergeBtn.connect("clicked", self.cb_unmerge_clicked) - buttonHB.pack_start(self.emergeBtn) - buttonHB.pack_start(self.unmergeBtn) - buttonHB.pack_start(self.cancelBtn) - + # current status self.cb_combo_changed(self.vCombo) - - # show - self.window.show_all() + self.table.show_all() def fill_use_list(self, store): """Fills a given ListStore with the use-flag data. @@ -488,12 +394,30 @@ class PackageWindow (AbstractDialog): 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 - self.useListScroll.remove(self.useList) + w = self.useListScroll.get_child() + if w: + self.useListScroll.remove(w) # build new self.useList = self.build_use_list() @@ -505,19 +429,19 @@ class PackageWindow (AbstractDialog): # if (not pkg.is_in_system()) or pkg.is_missing_keyword(): if not pkg.is_in_system(): - self.missing_label.hide() - self.not_in_sys_label.show() + self.missingLabel.hide() + self.notInSysLabel.show() else: # missing keyword - self.missing_label.show() - self.not_in_sys_label.hide() + self.missingLabel.show() + self.notInSysLabel.hide() self.installedCheck.hide() self.maskedCheck.hide() self.testingCheck.hide() self.emergeBtn.set_sensitive(False) else: - self.missing_label.hide() - self.not_in_sys_label.hide() + self.missingLabel.hide() + self.notInSysLabel.hide() self.installedCheck.show() self.maskedCheck.show() self.testingCheck.show() @@ -541,9 +465,8 @@ class PackageWindow (AbstractDialog): self.emergeBtn.set_label("R_emerge") self.unmergeBtn.set_sensitive(True) - # refresh - make window as small as possible self.table.show_all() - self.window.resize(1,1) + return True def cb_button_pressed (self, b, event): @@ -552,54 +475,29 @@ class PackageWindow (AbstractDialog): b.emit_stop_by_name("button-press-event") return True - def cb_cancel_clicked (self, button, data = None): + def cb_package_revert_clicked (self, button): """Callback for pressed cancel-button. Closes the window.""" - if self.delOnClose: - self.actual_package().remove_new_use_flags() - self.actual_package().remove_new_masked() - self.actual_package().remove_new_testing() - elif self.flagChanged: - if self.queue: - try: - try: - self.queue.append(self.actual_package().get_cpv(), update = True) - except backend.PackageNotFoundException, e: - if unmask_dialog(e[0]) == gtk.RESPONSE_YES: - self.queue.append(self.actual_package().get_cpv(), update = True, unmask = True) - except backend.BlockedException, e: - blocked_dialog(e[0], e[1]) - - self.window.destroy() + 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) return True - def cb_emerge_clicked (self, button, data = None): + 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: - try: - try: - self.queue.append(self.actual_package().get_cpv(), unmerge = False) - self.window.destroy() - except backend.PackageNotFoundException, e: - if unmask_dialog(e[0]) == gtk.RESPONSE_YES: - self.queue.append(self.actual_package().get_cpv(), unmerge = False, unmask = True) - self.window.destroy() - except BlockedException, e: - blocked_dialog(e[0], e[1]) + self._update_keywords(True) + self.main.notebook.set_current_page(self.main.QUEUE_PAGE) return True - def cb_unmerge_clicked (self, button, data = None): + 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: - try: - self.queue.append(self.actual_package().get_cpv(), unmerge = True) - except backend.PackageNotFoundException, e: - masked_dialog(e[0]) - - self.window.destroy() + self._update_keywords(False) return True def cb_testing_toggled (self, button): @@ -619,14 +517,20 @@ class PackageWindow (AbstractDialog): button.set_label("<i>(Testing)</i>") button.get_child().set_use_markup(True) button.set_active(True) - self.flagChanged = 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) - self.flagChanged = True + + if self.instantChange: + self._update_keywords(True, update = True) + return True def cb_use_flag_toggled (self, cell, path, store): @@ -636,27 +540,33 @@ class PackageWindow (AbstractDialog): if not store[path][0]: prefix = "-" self.actual_package().set_use_flag(prefix+store[path][1]) - self.flagChanged = True + + if self.instantChange: + self._update_keywords(True, update = True) + return True -class MainWindow: +class MainWindow (Window): """Application main window.""" + + # NOTEBOOK PAGE CONSTANTS + PKG_PAGE = 0 + QUEUE_PAGE = 1 + CONSOLE_PAGE = 2 - def __init__ (self): + def __init__ (self): """Build up window""" - # window - self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) + + # main window stuff + Window.__init__(self) self.window.set_title(("Genetic/One (%s)" % VERSION)) - self.window.connect("destroy", self.cb_destroy) - self.window.set_border_width(2) - self.window.set_resizable(True) - 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() @@ -666,101 +576,20 @@ class MainWindow: self.cfg = Config(CONFIG_LOCATION) self.cfg.modify_external_configs() - # actions needed - self.emergeAction = gtk.Action("Emerge", "_Emerge", None, None) - self.emergeAction.connect("activate", self.cb_emerge_clicked) - self.unmergeAction = gtk.Action("Unmerge", "_Unmerge", None, None) - self.unmergeAction.connect("activate", self.cb_emerge_clicked) - self.updateAction = gtk.Action("UpdateWorld", "Update _World", None, None) - self.updateAction.connect("activate", self.cb_update_clicked) - - # main vb - vb = gtk.VBox(False, 1) - self.window.add(vb) - - # menus - self.uimanager = self.create_uimanager() - self.queuePopup = self.uimanager.get_widget("/popupQueue") - menubar = self.uimanager.get_widget("/bar") - vb.pack_start(menubar, False) - - # search - self.searchEntry = gtk.Entry() - self.searchBtn = gtk.Button("_Search") - self.searchBtn.connect("clicked", self.cb_search_clicked) - self.searchEntry.connect("activate", self.cb_search_clicked) - hbSearch = gtk.HBox(False, 5) - hbSearch.pack_start(self.searchEntry, True, True) - hbSearch.pack_start(self.searchBtn, False, False) - vb.pack_start(hbSearch, False, False, 5) - - # VPaned holding the lists and the Terminal - vpaned = gtk.VPaned() + # set vpaned position + vpaned = self.tree.get_widget("vpaned") vpaned.set_position(mHeight/2) - vb.pack_start(vpaned, True, True) - - # a HB holding the lists - hb = gtk.HBox(True, 5) - hbFrame = gtk.Frame() - hbFrame.add(hb) - hbFrame.set_shadow_type(gtk.SHADOW_IN) - vpaned.pack1(hbFrame, shrink = True, resize = True) - - self.scroll_1 = gtk.ScrolledWindow() - self.scroll_2 = gtk.ScrolledWindow() - self.scroll_1.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) - self.scroll_2.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) - hb.pack_start(self.scroll_1, True, True) - hb.pack_start(self.scroll_2, True, True) - - # create cat List - self.catList = self.create_cat_list() - self.scroll_1.add(self.catList) - - # create pkg list - self.pkgList = self.create_pkg_list() - self.scroll_2.add(self.pkgList) - + + # 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 - queueHB = gtk.HBox(False, 0) - - queueScroll = gtk.ScrolledWindow() - queueScroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - emergeStore = gtk.TreeStore(str,str) - self.emergeView = gtk.TreeView(emergeStore) - cell = gtk.CellRendererText() - col = gtk.TreeViewColumn("Queue", cell, text = 0) - self.emergeView.append_column(col) - col = gtk.TreeViewColumn("Options", cell, markup = 1) - self.emergeView.append_column(col) - self.emergeView.connect("row-activated", self.cb_row_activated, emergeStore) - self.emergeView.connect("button-press-event", self.cb_queue_right_click) - self.emergeView.set_headers_visible(False) - queueScroll.add(self.emergeView) - queueHB.pack_start(queueScroll, True, True) - - # buttons right to the queue list - buttonBox = gtk.VButtonBox() - buttonBox.set_layout(gtk.BUTTONBOX_SPREAD) - queueHB.pack_start(buttonBox, False) - - emergeBtn = gtk.Button() - self.emergeAction.connect_proxy(emergeBtn) - - updateBtn = gtk.Button() - self.updateAction.connect_proxy(updateBtn) + self.queueList = self.tree.get_widget("queueList") + self.build_queue_list() - unmergeBtn = gtk.Button() - self.unmergeAction.connect_proxy(unmergeBtn) - - removeBtn = gtk.Button("_Remove") - removeBtn.connect("clicked", self.cb_remove_clicked) - - buttonBox.pack_start(emergeBtn) - buttonBox.pack_start(unmergeBtn) - buttonBox.pack_start(updateBtn) - buttonBox.pack_start(removeBtn) - # the terminal term = vte.Terminal() term.set_scrollback_lines(1024) @@ -769,129 +598,42 @@ class MainWindow: # 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")) - termBox = gtk.HBox(False, 0) + termHB = self.tree.get_widget("termHB") termScroll = gtk.VScrollbar(term.get_adjustment()) - termBox.pack_start(term, True, True) - termBox.pack_start(termScroll, False) + termHB.pack_start(term, True, True) + termHB.pack_start(termScroll, False) # notebook - self.notebook = gtk.Notebook() - self.notebook.append_page(queueHB, gtk.Label("Queue")) - self.notebook.append_page(termBox, gtk.Label("Console")) - - vpaned.pack2(self.notebook, shrink = True, resize = True) - - # the status line - self.statusLabel = gtk.Label("Genetic/One - A Portage GUI") - self.statusLabel.set_alignment(0.0,0.7) - self.statusLabel.set_single_line_mode(True) - vb.pack_start(self.statusLabel, False, False) - - # show + self.notebook = self.tree.get_widget("notebook") self.window.show_all() + + # table + self.packageTable = PackageTable(self) + self.packageTable.table.hide_all() # set emerge queue - self.queue = EmergeQueue(console = GtkConsole(term), tree = GtkTree(emergeStore), db = self.db) - - def create_uimanager(self): - """Creates a UIManager holding the menubar and the popups. - @returns: created UIManager - @rtype: gtk.UIManager""" - - ui =""" - <ui> - <menubar name="bar"> - <menu action="File"> - <menuitem action="Prefs" /> - <menuitem action="Reload" /> - <separator /> - <menuitem action="Close" /> - </menu> - <menu action="EmergeMenu"> - <menuitem action="Emerge" /> - <menuitem action="Unmerge" /> - <menuitem action="UpdateWorld" /> - <menuitem action="Sync" /> - </menu> - <menu action="Help"> - <menuitem action="About" /> - </menu> - </menubar> - <popup name="popupQueue"> - <menuitem action="Oneshot" /> - </popup> - </ui>""" - - um = gtk.UIManager() - - # menubar - group = gtk.ActionGroup("MenuActions") - group.add_actions([ - ("File", None, "_File"), - ("EmergeMenu", None, "_Emerge"), - ("Help", None, "_?"), - ("Sync", None, "_Sync", None, None, self.cb_sync_clicked), - ("Prefs", None, "_Preferences", None, None, lambda x: PreferenceWindow(self.window, self.cfg)), - ("Reload", None, "_Reload Portage", None, None, self.cb_reload_clicked), - ("Close", None, "_Close", None, None, self.cb_destroy), - ("About", None, "_About", None, None, lambda x: AboutWindow(self.window))]) - # the following actions are defined in __init__, because they are used for buttons too - group.add_action(self.emergeAction) - group.add_action(self.unmergeAction) - group.add_action(self.updateAction) - - um.insert_action_group(group,0) - - # popup - group = gtk.ActionGroup("PopupActions") - group.add_actions([ - ("Oneshot", None, "Oneshot", None, None, self.cb_oneshot_clicked)]) - - um.insert_action_group(group, 1) - - um.add_ui_from_string(ui) - return um + self.queue = EmergeQueue(console = GtkConsole(term), tree = GtkTree(self.queueList.get_model()), db = self.db) - 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""" + def show_package (self, *args, **kwargs): + self.packageTable.update(*args, **kwargs) + self.notebook.set_current_page(self.PKG_PAGE) - if name: - for p in self.db.get_cat(name): - store.append([p]) - return store - - def create_pkg_list (self, name = None): - """Creates the package list. - - @param name: name of the selected catetegory - @type name: string - @returns: the filled package list - @rtype: gtk.TreeView""" + def build_queue_list (self): + """Builds the queue list.""" + + store = gtk.TreeStore(str,str) - store = gtk.ListStore(str) - self.fill_pkg_store(store,name) + self.queueList.set_model(store) - # build view - pkgList = gtk.TreeView(store) cell = gtk.CellRendererText() - col = gtk.TreeViewColumn("Packages", cell, text = 0) - pkgList.append_column(col) - pkgList.connect("row-activated", self.cb_row_activated, store) - - return pkgList - - def create_cat_list (self): - """Creates the category list. + col = gtk.TreeViewColumn("Queue", cell, text = 0) + self.queueList.append_column(col) - @returns: created view - @rtype: gtk.TreeView""" + 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) @@ -901,23 +643,44 @@ class MainWindow: # sort them alphabetically store.set_sort_column_id(0, gtk.SORT_ASCENDING) - view = gtk.TreeView(store) + self.catList.set_model(store) cell = gtk.CellRendererText() col = gtk.TreeViewColumn("Categories", cell, text = 0) - view.append_column(col) - view.connect("cursor-changed", self.cb_cat_list_selection) - view.connect("row-activated", lambda v,p,c : self.cb_cat_list_selection(v)) - view.set_search_column(0) + self.catList.append_column(col) - return view + 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.""" - PackageWindow(self.window, cp, self.queue) - - def cb_destroy (self, widget, data = None): - """Calls main_quit().""" - gtk.main_quit() + 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.""" @@ -930,90 +693,55 @@ class MainWindow: self.fill_pkg_store(self.pkgList.get_model(), self.selCatName) return True - def cb_row_activated (self, view, path, col, store = None): - """Callback for an activated row in the pkgList or in the emergeQueue. Opens a package window.""" - if view == self.pkgList: - package = store.get_value(store.get_iter(path), 0) + 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] - PackageWindow(self.window, self.selCatName+"/"+package, self.queue) - elif view == self.emergeView: - if len(path) > 1: - package = store.get_value(store.get_iter(path), 0) - cat, name, vers, rev = backend.split_package_name(package) - if rev != "r0": vers = vers+"-"+rev - PackageWindow(self.window, cat+"/"+name, queue = self.queue, version = vers, delOnClose = False, doEmerge = False) + self.show_package(self.selCatName+"/"+package, self.queue) return True - def cb_remove_clicked (self, button): - """Removes a selected item in the (un)emerge-queue if possible.""" - selected = self.emergeView.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 - + def cb_row_activated (self, view, path, *args): + """Callback for an activated row in the emergeQueue. Opens a package window.""" + store = view.get_model() + if len(path) > 1: + package = store.get_value(store.get_iter(path), 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 or unemerge.""" + """Do emerge.""" - self.notebook.set_current_page(1) + self.notebook.set_current_page(self.CONSOLE_PAGE) - if action == self.emergeAction: - 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: - 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(self.cfg.const["newuse_opt"]), deep = self.cfg.get_boolean(self.cfg.const["deep_opt"])) - self.doUpdate = False + 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: + changed_flags_dialog("masking keywords") + flags.write_masked() + flags.write_testing() + backend.reload_settings() - elif action == self.unmergeAction: - self.queue.unmerge(force=True) + if not self.doUpdate: + self.queue.emerge(force=True) + else: + self.queue.update_world(force=True, newuse = self.cfg.get_boolean(self.cfg.const["newuse_opt"]), deep = self.cfg.get_boolean(self.cfg.const["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 - 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 - - @watch_cursor + @Window.watch_cursor def cb_update_clicked (self, action): if not backend.am_i_root(): not_root_dialog() @@ -1030,23 +758,47 @@ class MainWindow: 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): - self.notebook.set_current_page(1) + self.notebook.set_current_page(self.CONSOLE_PAGE) self.queue.sync() - @watch_cursor + @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() - - @watch_cursor - def cb_search_clicked (self, button, data = None): + + @Window.watch_cursor + def cb_search_clicked (self, entry): """Do a search.""" - if self.searchEntry.get_text() != "": - packages = backend.find_all_packages(self.searchEntry.get_text(), withVersion = False) + if entry.get_text() != "": + packages = backend.find_all_packages(entry.get_text(), withVersion = False) if packages == []: nothing_found_dialog() @@ -1056,35 +808,48 @@ class MainWindow: 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 - queue.grab_focus() - queue.set_cursor(path, col, 0) - self.queuePopup.popup(None, None, None, event.button, time) - return True - else: - return False + pass + # 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 + # 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.emergeView.get_selection() - store, it = sel.get_selected() - if it: - package = store.get_value(it, 0) - if not self.cfg.get_local(package, self.cfg.const["oneshot_opt"]): - set = True - else: - set = False - - self.cfg.set_local(package, self.cfg.const["oneshot_opt"], set) - self.queue.append(package, update = True, oneshot = set, forceUpdate = True) - - + pass + # 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, self.cfg.const["oneshot_opt"]): + # set = True + # else: + # set = False + # + # self.cfg.set_local(package, self.cfg.const["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() |