summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--geneticone/flags.py146
-rw-r--r--geneticone/gui/main.py36
-rw-r--r--geneticone/package.py2
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 - <Statusline>")
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