From ccbe93f0108547d033b67869ed3bf0a749b28fb8 Mon Sep 17 00:00:00 2001 From: necoro <> Date: Wed, 20 Sep 2006 17:40:33 +0000 Subject: Completly implemented use-flags in the GUI. --- geneticone/flags.py | 146 +++++++++++++++++++++++++++++-------------------- geneticone/gui/main.py | 36 +++++++++--- geneticone/package.py | 2 +- 3 files changed, 116 insertions(+), 68 deletions(-) diff --git a/geneticone/flags.py b/geneticone/flags.py index 01292cf..a523d0c 100644 --- a/geneticone/flags.py +++ b/geneticone/flags.py @@ -53,18 +53,18 @@ def get_data(pkg): USE_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.use") USE_PATH_IS_DIR = os.path.isdir(USE_PATH) useFlags = {} # useFlags in the file -newUseFlags = [] # useFlags as we want them to be: format: (cpv, file, line, useflag, (true if removed from list / false if added)) +newUseFlags = {} # useFlags as we want them to be: format: cpv -> [(file, line, useflag, (true if removed from list / false if added))] + +def invert_flag (_flag): + if _flag[0] == "-": + return _flag[1:] + else: + return "-"+_flag def set_use_flag (pkg, flag): """Sets the useflag for a given package.""" global useFlags, newUseFlags - def invert_flag (_flag): - if _flag[0] == "-": - return _flag[1:] - else: - return "-"+_flag - if not isinstance(pkg, Package): pkg = Package(pkg) # assume cpv or gentoolkit.Package @@ -79,23 +79,25 @@ def set_use_flag (pkg, flag): else: data = useFlags[cpv] + if not cpv in newUseFlags: + newUseFlags[cpv] = [] + print "data: "+str(data) # add a useflag / delete one added = False for file, line, crit, flags in data: if pkg.matches(crit): - # we have the inverted flag in the uselist/newuselist --> delete it - if invFlag in flags or (cpv, file, line, invFlag, False) in newUseFlags or (cpv, file, line, flag, True) in newUseFlags: + if invFlag in flags or (file, line, invFlag, False) in newUseFlags[cpv] or (file, line, flag, True) in newUseFlags[cpv]: if added: del newUseFlags[-1] # we currently added it as an extra option - delete it added = True jumpOut = False - for t in [(cpv, file, line, invFlag, False),(cpv, file, line, flag, True)]: - if t in newUseFlags: - newUseFlags.remove(t) + for t in [(file, line, invFlag, False),(file, line, flag, True)]: + if t in newUseFlags[cpv]: + newUseFlags[cpv].remove(t) jumpOut = True break - if not jumpOut: newUseFlags.append((cpv, file, line, invFlag, True)) + if not jumpOut: newUseFlags[cpv].append((file, line, invFlag, True)) break # we want to duplicate the flag --> ignore @@ -105,7 +107,7 @@ def set_use_flag (pkg, flag): # add as an extra flag else: - if not added: newUseFlags.append((cpv, file, line, flag, False)) + if not added: newUseFlags[cpv].append((file, line, flag, False)) added = True # create a new line @@ -115,13 +117,38 @@ def set_use_flag (pkg, flag): path = os.path.join(USE_PATH,"geneticone") try: - newUseFlags.remove((cpv, path, -1, invFlag, False)) + newUseFlags[cpv].remove((path, -1, invFlag, False)) except ValueError: # not in UseFlags - newUseFlags.append((cpv, path, -1, flag, False)) + newUseFlags[cpv].append((path, -1, flag, False)) - newUseFlags = unique_array(newUseFlags) + newUseFlags[cpv] = unique_array(newUseFlags[cpv]) print "newUseFlags: "+str(newUseFlags) +def remove_new_flags (cpv): + if isinstance(cpv, Package): + cpv = cpv.get_cpv() + + try: + del newUseFlags[cpv] + except KeyError: + pass + +def get_new_flags (cpv): + if isinstance(cpv, Package): + cpv = cpv.get_cpv() + + list2return = [] + try: + for file, line, flag, remove in newUseFlags[cpv]: + if remove: + list2return.append(invert_flag(flag)) + else: + list2return.append(flag) + except KeyError: + pass + + return list2return + def write_use_flags (): """This writes our changed useflags into the file.""" global newUseFlags, useFlags @@ -144,48 +171,49 @@ def write_use_flags (): insert("#removed by geneticone#",list) file_cache = {} # cache for having to read the file only once: name->[lines] - for cpv, file, line, flag, delete in newUseFlags: - line = int(line) # it is saved as a string so far! - - # add new line - if line == -1: - msg = "\n#geneticone update#\n=%s %s" % (cpv, flag) - if not file in file_cache: - f = open(file, "a") - f.write(msg) - f.close() - else: - file_cache[file].append(msg) - # change a line - else: - if not file in file_cache: - # read file - f = open(file, "r") - lines = [] - i = 1 - while i < line: # stop at the given line - lines.append(f.readline()) - i = i+1 - l = f.readline().split(" ") - # delete or insert - if delete: - remove(flag,l) - else: - insert(flag,l) - lines.append(" ".join(l)) - - # read the rest - lines.extend(f.readlines()) - - file_cache[file] = lines - f.close() - else: # in cache - l = file_cache[file][line-1].split(" ") - if delete: - remove(flag,l) + for cpv in newUseFlags: + for file, line, flag, delete in newUseFlags[cpv]: + line = int(line) # it is saved as a string so far! + + # add new line + if line == -1: + msg = "\n#geneticone update#\n=%s %s\n" % (cpv, flag) + if not file in file_cache: + f = open(file, "a") + f.write(msg) + f.close() else: - insert(flag,l) - file_cache[file][line-1] = " ".join(l) + file_cache[file].append(msg) + # change a line + else: + if not file in file_cache: + # read file + f = open(file, "r") + lines = [] + i = 1 + while i < line: # stop at the given line + lines.append(f.readline()) + i = i+1 + l = f.readline().split(" ") + # delete or insert + if delete: + remove(flag,l) + else: + insert(flag,l) + lines.append(" ".join(l)) + + # read the rest + lines.extend(f.readlines()) + + file_cache[file] = lines + f.close() + else: # in cache + l = file_cache[file][line-1].split(" ") + if delete: + remove(flag,l) + else: + insert(flag,l) + file_cache[file][line-1] = " ".join(l) # write to disk for file in file_cache.keys(): @@ -194,4 +222,4 @@ def write_use_flags (): f.close() # reset useFlags = {} - newUseFlags = [] + newUseFlags = {} diff --git a/geneticone/gui/main.py b/geneticone/gui/main.py index 8ecd184..a3d3ae6 100644 --- a/geneticone/gui/main.py +++ b/geneticone/gui/main.py @@ -129,22 +129,25 @@ class EmergeQueue: def remove (self, it): """Removes a specific item in the tree.""" 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): - del self.mergequeue[self.tree.get_value(it,0)] + del self.mergequeue[cpv] + flags.remove_new_flags(cpv) else: - self.unmergequeue.remove(self.tree.get_value(it,0)) + self.unmergequeue.remove(cpv) self.tree.remove(it) class PackageWindow: """A window with data about a specfic package.""" - def __init__ (self, parent, cp, queue = None, version = None): + def __init__ (self, parent, cp, queue = None, version = None, delOnClose = 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 # window self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) @@ -220,7 +223,9 @@ class PackageWindow: self.emergeBtn.set_sensitive(False) self.unmergeBtn.set_sensitive(False) self.cancelBtn = gtk.Button("_Cancel") - self.cancelBtn.connect("clicked", lambda x: self.window.destroy()) + 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) @@ -297,6 +302,11 @@ class PackageWindow: print "hallo" return True + def cb_cancel_clicked (self, button, data = None): + if self.delOnClose: flags.remove_new_flags(self.actual_package()) + 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(): @@ -338,10 +348,13 @@ class PackageWindow: store = gtk.ListStore(bool, str, str) pkg = self.actual_package() + newUses = flags.get_new_flags(pkg) for use in pkg.get_all_useflags(): - if pkg.is_installed() and use in pkg.get_set_useflags(): # flags set during install + if pkg.is_installed() and use in pkg.get_set_useflags() and not flags.invert_flag(use) in newUses: # flags set during install + enabled = True + elif (not pkg.is_installed()) and use in pkg.get_settings("USE").split() and not flags.invert_flag(use) in newUses: # flags that would be set enabled = True - elif (not pkg.is_installed()) and use in pkg.get_settings("USE").split(): # flags that would be set + elif use in newUses: enabled = True else: enabled = False @@ -499,7 +512,7 @@ class MainWindow: vpaned.pack2(termFrame, shrink = True, resize = True) # the status line - self.statusLabel = gtk.Label("Genetic/One") + self.statusLabel = gtk.Label("Genetic/One - ") self.statusLabel.set_alignment(0.0,0.7) self.statusLabel.set_single_line_mode(True) vb.pack_start(self.statusLabel, False, False) @@ -560,7 +573,8 @@ class MainWindow: if len(path) > 1: package = store.get_value(store.get_iter(path), 0) cat, name, vers, rev = geneticone.split_package_name(package) - PackageWindow(self.window, cat+"/"+name, queue = None, version = vers+"-"+rev) + if rev != "r0": vers = vers+"-"+rev + PackageWindow(self.window, cat+"/"+name, queue = None, version = vers, delOnClose=False) return True def create_cat_list (self): @@ -638,6 +652,12 @@ class MainWindow: def cb_emerge_clicked (self, button, data = None): """Do emerge or unemerge.""" if button == self.emergeBtn: + 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: self.queue.unmerge(force=True) diff --git a/geneticone/package.py b/geneticone/package.py index 4e18392..6916f49 100644 --- a/geneticone/package.py +++ b/geneticone/package.py @@ -50,7 +50,7 @@ class Package (gentoolkit.Package): def get_all_useflags (self): """Returns a list of _all_ useflags for this package.""" - return self.get_env_var("IUSE").split() + return unique_array(self.get_env_var("IUSE").split()) def get_all_deps (self): """Returns a linearised list of all first-level dependencies for this package, on -- cgit v1.2.3-54-g00ecf