summaryrefslogtreecommitdiff
path: root/geneticone/gui/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'geneticone/gui/main.py')
-rw-r--r--geneticone/gui/main.py853
1 files changed, 0 insertions, 853 deletions
diff --git a/geneticone/gui/main.py b/geneticone/gui/main.py
deleted file mode 100644
index 93decf2..0000000
--- a/geneticone/gui/main.py
+++ /dev/null
@@ -1,853 +0,0 @@
-#!/usr/bin/python
-
-#
-# File: geneticone/gui/main.py
-# This file is part of the Genetic/One-Project, a graphical portage-frontend.
-#
-# Copyright (C) 2006 Necoro d.M.
-# 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 Necoro d.M. <necoro@necoro.net>
-
-# our backend stuff
-
-VERSION = "0.3.1"
-MENU_EMERGE = 1
-MENU_UNEMERGE = 2
-
-import geneticone
-from geneticone import flags
-
-# gtk stuff
-import pygtk
-pygtk.require("2.0")
-import gtk
-import gobject
-
-# for doing emerge
-from subprocess import *
-
-# threading
-from threading import Thread
-
-# for the terminal
-import pty
-import vte
-
-# other
-from portage_util import unique_array
-
-class EmergeQueue:
- """This class manages the emerge queue."""
-
-
- def __init__ (self, tree = None, console = None, packages = None):
- """Constructor.
-
- @param tree: Tree to append all the items to. Default: None.
- @type tree: gtk.TreeStore
- @param console: Output is shown here. Default: None
- @type console: vte.Terminal
- @param packages: The list of packages sorted by categories. We will delete the appropriate category if we updated sth. Default: None
- @type packages: dictionary: {category: list_of_packages}."""
-
- self.mergequeue = []
- self.unmergequeue = []
- self.iters = {}
- self.deps = {}
- self.tree = tree
- self.console = console
- self.packages = packages
-
- if self.tree:
- self.emergeIt = self.tree.append(None, ["Emerge"])
- self.unmergeIt = self.tree.append(None, ["Unmerge"])
- else:
- self.emergeIt = self.unmergeIt = None
-
- def update_tree (self, it, cpv):
- """This updates the tree recursivly.
-
- @param it: iterator where to append
- @type it: gtk.TreeIter
- @param cpv: The package to append.
- @type cpv: string (cat/pkg-ver)
-
- @raise geneticone.BlockedException: When occured during dependency-calculation."""
-
- # get depencies
- if cpv in self.deps:
- return # in list already
- else:
- deps = geneticone.find_packages("="+cpv)[0].get_dep_packages()
- self.deps.update({cpv : deps})
-
- subIt = self.tree.append(it, [cpv])
-
- # recursive call
- for d in deps:
- try:
- self.update_tree(subIt, d)
- except geneticone.BlockedException, e:
- # remove the project
- while self.tree.iter_parent(subIt):
- subIt = self.tree.iter_parent(subIt)
- self.remove_children(subIt)
- raise e
-
- # add iter
- self.iters.update({cpv: subIt})
-
- def append (self, cpv, unmerge = False, update = False):
- """Appends a cpv either to the merge queue or to the unmerge-queue.
- Also updates the tree-view.
-
- @param cpv: Package to add
- @type cpv: string (cat/pkg-ver)
- @param unmerge: Set to True if you want to unmerge this package - else False. Default: False
- @type unmerge: boolean
- @param update: Set to True if a package is going to be updated (e.g. if the use-flags changed). Default: False
- @type update: boolean"""
-
- if not unmerge:
- try:
- # insert dependencies
- pkg = geneticone.find_packages("="+cpv)[0]
- deps = pkg.get_dep_packages()
-
- if update:
- if deps == self.deps[cpv]:
- return # nothing changed - return
- else:
- parentIt = self.tree.iter_parent(self.iters[cpv])
- self.remove_children(self.iters[cpv], False) # this is needed to def delete everything
- self.remove(self.iters[cpv], False)
- self.update_tree(parentIt, cpv)
- else: # not update
- self.mergequeue.append(cpv)
- if self.emergeIt: self.update_tree(self.emergeIt, cpv)
-
- except geneticone.BlockedException, e : # there is sth blocked --> call blocked_dialog
- blocks = e[0]
- blocked_dialog(cpv, blocks)
- return
- else: # unmerge
- self.unmergequeue.append(cpv)
- if self.unmergeIt: # update tree
- self.tree.append(self.unmergeIt, [cpv])
-
- def _update_packages(self, packages, process = None):
- """This updates the packages-list. It simply removes all affected categories so they have to be rebuilt.
-
- @param packages: The packages which we emerged.
- @type packages: list of cpvs
- @param process: The process we have to wait for before we can do our work. Default: None.
- @type process: subprocess.Popen"""
-
- if process: process.wait()
- for p in packages:
- try:
- cat = geneticone.split_package_name(p)[0] # get category
- while cat[0] in ["=",">","<","!"]:
- cat = cat[1:]
- print "Category: "+cat ,
- del self.packages[cat]
- print "marked for refreshing"
- except KeyError: # not in self.packages - ignore
- pass
-
- def _emerge (self, options, packages, it):
- """Calls emerge and updates the terminal.
-
- @param options: options to send to emerge
- @type options: list
- @param packages: packages to emerge
- @type packages: list
- @param it: Iterator which points to an entry whose children will be removed after completion.
- @type it: gtk.TreeIter"""
-
- # open tty
- (master, slave) = pty.openpty()
- self.console.set_pty(master)
-
- # start emerge
- process = Popen(["/usr/bin/python","/usr/bin/emerge"]+options+packages, stdout = slave, stderr = STDOUT, shell = False)
- Thread(target=self._update_packages, args=(packages, process)).start()
-
- # remove
- self.remove_children(it)
-
- def emerge (self, force = False):
- """Emerges everything in the merge-queue.
-
- @param force: If False, '-pv' is send to emerge. Default: False.
- @type force: boolean"""
-
- if len(self.mergequeue) == 0: return # nothing in queue
-
- # prepare package-list
- list = []
- for k in self.mergequeue:
- list += ["="+k]
-
- s = []
- if not force: s = ["-pv"]
-
- self._emerge(s, list, self.emergeIt)
-
- def unmerge (self, force = False):
- """Unmerges everything in the umerge-queue.
-
- @param force: If False, '-pv' is send to emerge. Default: False.
- @type force: boolean"""
-
- if len(self.unmergequeue) == 0: return # nothing in queue
-
- list = self.unmergequeue[:] # copy the unmerge-queue
-
- # set options
- s = ["-C"]
- if not force: s = ["-Cpv"]
-
- self._emerge(s,list, self.unmergeIt)
-
- def remove_children (self, parentIt, removeNewFlags = True):
- """Removes all children of a given parent TreeIter recursivly.
-
- @param parentIt: The iter from which to remove all children.
- @type parentIt: gtk.TreeIter
- @param removeNewFlags: True if new flags should be removed; False otherwise. Default: True.
- @type removeNewFlags: boolean"""
-
- childIt = self.tree.iter_children(parentIt)
-
- while childIt:
- if (self.tree.iter_has_child(childIt)): # recursive call
- self.remove_children(childIt, removeNewFlags)
- temp = childIt
- childIt = self.tree.iter_next(childIt)
- self.remove(temp, removeNewFlags)
-
- def remove (self, it, removeNewFlags = True):
- """Removes a specific item in the tree. This does not remove the top-entries.
-
- @param it: Iterator which points to the entry we are going to remove.
- @type it: gtk.TreeIter
- @param removeNewFlags: True if new flags should be removed; False otherwise. Default: True.
- @type removeNewFlags: boolean"""
-
- if self.tree.iter_parent(it): # NEVER remove our top stuff
- cpv = self.tree.get_value(it,0)
- if self.tree.get_string_from_iter(it).split(":")[0] == self.tree.get_string_from_iter(self.emergeIt): # in Emerge
- del self.iters[cpv]
- del self.deps[cpv]
- try:
- self.mergequeue.remove(cpv)
- except ValueError: # this is a dependency - ignore
- pass
- if removeNewFlags: flags.remove_new_use_flags(cpv)
-
- else: # in Unmerge
- self.unmergequeue.remove(cpv)
-
- self.tree.remove(it)
-
-class AboutWindow:
-
- def __init__ (self, parent):
- # window
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.set_title("About Genetic/One")
- self.window.set_modal(True)
- self.window.set_transient_for(parent)
- self.window.set_destroy_with_parent(True)
- self.window.set_resizable(False)
- self.window.set_default_size(1,1)
-
- box = gtk.VBox(False)
- self.window.add(box)
-
- label = gtk.Label()
- label.set_justify(gtk.JUSTIFY_CENTER)
- label.set_markup("""
-<big><b>Genetic/One v.%s</b></big>
-A Portage-GUI
-
-This software is licensed under the terms of the GPLv2.
-Copyright (C) 2006 Necoro d.M. &lt;necoro@necoro.net&gt;
-""" % VERSION)
- box.pack_start(label)
-
- okBtn = gtk.Button("OK")
- okBtn.connect("clicked", lambda x: self.window.destroy())
- box.pack_start(okBtn)
-
- self.window.show_all()
-
-class PackageWindow:
- """A window with data about a specfic package."""
-
- def __init__ (self, parent, cp, queue = None, version = None, delOnClose = True, doEmerge = True):
- """Build up window contents."""
- self.parent = parent # parent window
- 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
-
- # window
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.set_title(cp)
- self.window.set_modal(True)
- self.window.set_transient_for(parent)
- self.window.set_destroy_with_parent(True)
- self.window.set_resizable(False)
- self.window.set_default_size(1,1) # as small as possible
- self.window.connect("delete-event", lambda a,b: False)
- #self.window.connect("configure-event", self.cbSizeCheck)
-
- # packages and installed packages
- self.packages = geneticone.sort_package_list(geneticone.find_packages(cp, masked=True))
- self.instPackages = geneticone.sort_package_list(geneticone.find_installed_packages(cp, masked=True))
-
- # 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)
-
- # the label (must be here, because it depends on the combo box)
- desc = self.actual_package().get_env_var("DESCRIPTION")
- use_markup = True
- if not desc:
- desc = "<no description>"
- use_markup = False
- else:
- desc = "<b>"+desc+"</b>"
- self.descLabel = gtk.Label(desc)
- self.descLabel.set_line_wrap(True)
- self.descLabel.set_justify(gtk.JUSTIFY_CENTER)
- 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")
- checkHB.pack_start(self.installedCheck, True, False)
-
- self.maskedCheck = gtk.CheckButton()
- self.maskedCheck.connect("button-press-event", self.cb_button_pressed)
- self.maskedCheck.set_label("Masked")
- checkHB.pack_start(self.maskedCheck, True, False)
-
- self.testingCheck = gtk.CheckButton()
- self.testingCheck.connect("button-press-event", self.cb_button_pressed)
- self.testingCheck.set_label("Testing")
- checkHB.pack_start(self.testingCheck, True, False)
-
- # 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)
-
- # 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 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_changed(self.vCombo)
-
- # show
- self.window.show_all()
-
- def cb_changed (self, combo, data = None):
- """Callback for the changed ComboBox.
- It then rebuilds the useList and the checkboxes."""
- # remove old useList
- self.useListScroll.remove(self.useList)
-
- # build new
- self.useList = self.build_use_list()
- self.useListScroll.add(self.useList)
- self.update_checkboxes()
-
- self.useListScroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_NEVER)
-
- # 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)
-
- # refresh - make window as small as possible
- self.table.show_all()
- self.window.resize(1,1)
- return True
-
- 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 = geneticone.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
- combo.set_active(0)
-
- combo.connect("changed", self.cb_changed)
-
- return combo
-
- def actual_package (self):
- """Returns the actual package (a geneticone.Package-object)."""
- return self.packages[self.vCombo.get_active()]
-
- def cb_button_pressed (self, b, event, data = None):
- """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_cancel_clicked (self, button, data = None):
- if self.delOnClose: self.actual_package().remove_new_use_flags()
- if self.flagChanged:
- if self.queue:
- self.queue.append(self.actual_package().get_cpv(), update = True)
- self.window.destroy()
- return True
-
- def cb_emerge_clicked (self, button, data = None):
- """Adds the package to the EmergeQueue."""
- if not geneticone.am_i_root():
- errorMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "You cannot (un)merge without being root.")
- errorMB.run()
- errorMB.destroy()
- else:
- self.queue.append(self.actual_package().get_cpv(), False)
- self.window.destroy()
- return True
-
- def cb_unmerge_clicked (self, button, data = None):
- """Adds the package to the UnmergeQueue."""
- if not geneticone.am_i_root():
- errorMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, "You cannot (un)merge without being root.")
- errorMB.run()
- errorMB.destroy()
- else:
- self.queue.append(self.actual_package().get_cpv(), True)
- self.window.destroy()
- return True
-
- def cb_use_flag_toggled (self, cell, path, store, data = None):
- store[path][0] = not store[path][0]
- prefix = ""
- if not store[path][0]:
- prefix = "-"
- self.actual_package().set_use_flag(prefix+store[path][1])
- self.flagChanged = True
- return True
-
- def update_checkboxes (self):
- """Updates the checkboxes."""
- self.installedCheck.set_active(self.actual_package().is_installed())
- self.maskedCheck.set_active(self.actual_package().is_masked())
- self.testingCheck.set_active((self.actual_package().get_mask_status() % 3) == 1)
-
- def build_use_list (self):
- """Builds the useList."""
- store = gtk.ListStore(bool, str, str)
-
- pkg = self.actual_package()
- for use in pkg.get_all_use_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, geneticone.get_use_desc(use, self.cp)])
-
- # 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:
- view.set_child_visible(False)
- else:
- view.set_child_visible(True)
- return view
-
-class SearchWindow:
- """A window showing the results of a search process."""
-
- def __init__ (self, parent, list, jump_to):
- # window
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.set_title("Search results")
- self.window.set_modal(True)
- self.window.set_transient_for(parent)
- self.window.set_destroy_with_parent(True)
- self.window.set_resizable(False)
- self.window.set_default_size(1,1)
- self.list = list
- self.jump_to = jump_to
-
- box = gtk.HBox(False)
- self.window.add(box)
-
- self.combo = gtk.combo_box_new_text()
- for x in list:
- self.combo.append_text(x)
- self.combo.set_active(0)
-
- box.pack_start(self.combo)
-
- okBtn = gtk.Button("OK")
- okBtn.connect("clicked", self.cb_ok_btn_clicked)
- box.pack_start(okBtn)
-
- self.window.show_all()
-
- def cb_ok_btn_clicked (self, button, data = None):
- self.window.destroy()
- self.jump_to(self.list[self.combo.get_active()])
-
-class MainWindow:
- """Application main window."""
-
- def __init__ (self):
- """Build up window"""
-
- # window
- self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.set_title("Genetic/One")
- self.window.connect("delete_event", self.cb_delete)
- self.window.connect("destroy", self.cb_destroy)
- self.window.set_border_width(2)
- self.window.set_geometry_hints (self.window, min_width = 600, min_height = 800, max_height = gtk.gdk.screen_height(), max_width = gtk.gdk.screen_width())
- self.window.set_resizable(True)
-
- # main vb
- vb = gtk.VBox(False, 1)
- self.window.add(vb)
-
- # menubar
- menubar = self.create_main_menu()
- vb.pack_start(menubar, False)
-
- # search
- self.searchEntry = gtk.Entry()
- self.searchBtn = gtk.Button("_Search")
- self.searchBtn.connect("clicked", 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()
- vpaned.set_position(400)
- 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)
- # queue list
- queueVB = gtk.VBox(False, 0)
- hb.pack_start(queueVB, True, True)
-
- queueScroll = gtk.ScrolledWindow()
- queueScroll.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
- emergeStore = gtk.TreeStore(str)
- self.emergeView = gtk.TreeView(emergeStore)
- cell = gtk.CellRendererText()
- col = gtk.TreeViewColumn("Queue", cell, text = 0)
- self.emergeView.append_column(col)
- self.emergeView.connect("row-activated", self.cb_row_activated, emergeStore)
- queueScroll.add(self.emergeView)
- queueVB.pack_start(queueScroll, True, True)
-
- # buttons right unter the queue list
- buttonBox = gtk.HButtonBox()
- queueVB.pack_start(buttonBox, False)
- self.emergeBtn = gtk.Button("_Emerge")
- self.emergeBtn.connect("clicked", self.cb_emerge_clicked)
- self.unmergeBtn = gtk.Button("_Unmerge")
- self.unmergeBtn.connect("clicked", self.cb_emerge_clicked)
- self.removeBtn = gtk.Button("_Remove")
- self.removeBtn.connect("clicked", self.cb_remove_clicked)
- buttonBox.pack_start(self.emergeBtn)
- buttonBox.pack_start(self.removeBtn)
- buttonBox.pack_start(self.unmergeBtn)
-
- # the terminal
- term = vte.Terminal()
- term.set_scrollback_lines(1024)
- term.set_scroll_on_output(True)
- # 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)
- termScroll = gtk.VScrollbar(term.get_adjustment())
- termBox.pack_start(term, True, True)
- termBox.pack_start(termScroll, False)
-
- termFrame = gtk.Frame("Console")
- termFrame.set_shadow_type(gtk.SHADOW_IN)
- termFrame.add(termBox)
- vpaned.pack2(termFrame, shrink = True, resize = True)
-
- # the status line
- self.statusLabel = gtk.Label("Genetic/One - <Statusline>")
- self.statusLabel.set_alignment(0.0,0.7)
- self.statusLabel.set_single_line_mode(True)
- vb.pack_start(self.statusLabel, False, False)
-
- # show
- self.window.show_all()
-
- # set emerge queue
- self.queue = EmergeQueue(console=term, tree = emergeStore, packages = self.packages)
-
- def cb_delete (self, widget, data = None):
- """Returns false -> window is deleted."""
- return False
-
- def cb_destroy (self, widget, data = None):
- """Calls main_quit()."""
- gtk.main_quit()
-
- def create_main_menu (self):
- """Creates the main menu. XXX: Rebuild to use UIManager"""
- # the menu-list
- mainMenuDesc = [
- ( "/_File", None, None, 0, "<Branch>"),
- ( "/File/_Close", None, self.cb_destroy, 0, ""),
- ( "/_Emerge", None, None, 0, "<Branch>"),
- ( "/Emerge/_Emerge", None, self.cb_emerge_clicked, MENU_EMERGE, ""),
- ( "/Emerge/_Unmerge", None, self.cb_emerge_clicked, MENU_UNEMERGE, ""),
- ( "/_?", None, None, 0, "<Branch>"),
- ( "/?/_About", None, lambda x,y: AboutWindow(self.window), 0, "")
- ]
- self.itemFactory = gtk.ItemFactory(gtk.MenuBar, "<main>", None)
- self.itemFactory.create_items(mainMenuDesc)
- return self.itemFactory.get_widget("<main>")
-
- def cb_cat_list_selection (self, view, data = None, force = False):
- """Callback for a category-list selection. Updates the package list with these packages in the category."""
- if view == self.catList: # be sure it is the catList
- # get the selected category
- sel = view.get_selection()
- store, it = sel.get_selected()
-
- if it:
- # remove old one
- self.scroll_2.remove(self.pkgList)
- # create new package list
- self.pkgList = self.create_pkg_list(store.get_value(it,0), force)
- self.scroll_2.add(self.pkgList)
- self.scroll_2.show_all()
- return False
-
- def cb_row_activated (self, view, path, col, store = None):
- """Callback for an activated row in the pkgList. Opens a package window."""
- if view == self.pkgList:
- package = store.get_value(store.get_iter(path), 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 = geneticone.split_package_name(package)
- if rev != "r0": vers = vers+"-"+rev
- PackageWindow(self.window, cat+"/"+name, queue = self.queue, version = vers, delOnClose = False, doEmerge = False)
- return True
-
- def create_cat_list (self):
- """Creates the category list."""
- store = gtk.ListStore(str)
-
- # build categories
- for p in geneticone.list_categories():
- store.append([p])
- # sort them alphabetically
- store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-
- view = gtk.TreeView(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)
-
- return view
-
- packages = {} # directory category -> [packages]
- def create_pkg_list (self, name = None, force = False):
- """Creates the package list. Gets the name of the category."""
- self.selCatName = name # actual category
- store = gtk.ListStore(str)
-
- # calculate packages
- if name:
- if name not in self.packages and not force: # only calc packages if not already done
- self.packages[name] = []
- for p in unique_array([x.get_name() for x in geneticone.find_all_packages(name+"/")]):
- if geneticone.find_installed_packages(name+"/"+p, masked=True) != []:
- p += "*" # append a '*' if the package is installed
- self.packages[name].append(p)
-
- for p in self.packages[name]:
- store.append([p])
-
- # sort alphabetically
- store.set_sort_column_id(0, gtk.SORT_ASCENDING)
-
- # 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 cb_remove_clicked (self, button, data = None):
- """Removes a selected item in the (un)emerge-queue if possible."""
- selected = self.emergeView.get_selection()
-
- if selected:
- model, iter = selected.get_selected()
-
- if not model.iter_parent(iter): # top-level
- if model.iter_n_children(iter) > 0: # and has children which can be removed :)
- askMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, "Do you really want to clear the whole queue?")
- if askMB.run() == gtk.RESPONSE_YES :
- self.queue.remove_children(iter)
- askMB.destroy()
- elif model.iter_parent(model.iter_parent(iter)): # this is in the 3rd level => dependency
- infoMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "You cannot remove dependencies. :)")
- infoMB.run()
- infoMB.destroy()
- else:
- self.queue.remove(iter)
-
- return True
-
- def cb_emerge_clicked (self, button, data = None):
- """Do emerge or unemerge."""
- print button
- if button == self.emergeBtn or button == MENU_EMERGE:
- if len(flags.newUseFlags) > 0:
- hintMB = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
- "You have changed use flags. Genetic/One will write these changes into the appropriate files. Please backup them if you think it is necessairy.")
- hintMB.run()
- hintMB.destroy()
- flags.write_use_flags()
- self.queue.emerge(force=True)
- elif button == self.unmergeBtn or button == MENU_UNEMERGE:
- self.queue.unmerge(force=True)
-
- return True
-
- def cb_search_clicked (self, button, data = None):
- """Do a search."""
- if self.searchEntry.get_text() != "":
- packages = geneticone.find_all_packages(self.searchEntry.get_text())
-
- if packages == []:
- dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "Package not found!")
- dialog.run()
- dialog.destroy()
- else:
- packages = unique_array([p.get_cp() for p in packages])
-
- if len(packages) == 1:
- self.jump_to(packages[0])
- else:
- SearchWindow(self.window, packages, self.jump_to)
-
- def jump_to (self, cp):
- """Is called when we want to jump to a specific package."""
- PackageWindow(self.window, cp, self.queue)
-
- 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()
-
-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.")
- dialog.run()
- dialog.destroy()