summaryrefslogtreecommitdiff
path: root/geneticone
diff options
context:
space:
mode:
authornecoro <>2006-10-05 11:56:16 +0000
committernecoro <>2006-10-05 11:56:16 +0000
commitdfbeab611f68502631ed4c575f5809064c948d58 (patch)
tree626675b36f327588ce3ef9d70f28fd5547e94570 /geneticone
parent46c5530abed392a2d7d91da165cffca99938f906 (diff)
downloadportato-dfbeab611f68502631ed4c575f5809064c948d58.tar.gz
portato-dfbeab611f68502631ed4c575f5809064c948d58.tar.bz2
portato-dfbeab611f68502631ed4c575f5809064c948d58.zip
Added preference window
Diffstat (limited to 'geneticone')
-rw-r--r--geneticone/backend/flags.py44
-rw-r--r--geneticone/gui/gui_helper.py38
-rw-r--r--geneticone/gui/windows.py118
-rw-r--r--geneticone/helper.py4
4 files changed, 155 insertions, 49 deletions
diff --git a/geneticone/backend/flags.py b/geneticone/backend/flags.py
index 20b63ef..3065fbe 100644
--- a/geneticone/backend/flags.py
+++ b/geneticone/backend/flags.py
@@ -14,11 +14,17 @@ import os.path
from subprocess import Popen, PIPE # needed for grep
from geneticone.helper import *
+from portage_helper import split_package_name
import package
import portage
from portage_util import unique_array
+CONFIG = {
+ "usefile" : "geneticone",
+ "usePerVersion" : True
+ }
+
### GENERAL PART ###
def grep (pkg, path):
@@ -66,6 +72,19 @@ def get_data(pkg, path):
return flags
+def set_config (cfg):
+ """This function sets the CONFIG-variable for the whole module. Use this instead of modifying CONFIG directly.
+ @param cfg: a dictionary with at least all the keys of the CONFIG-var
+ @type cfg: dict
+ @raises KeyError: if a keyword is missing in the new cfg"""
+
+ for i in CONFIG.keys():
+ if not i in cfg:
+ raise KeyError, "Missing keyword in config: "+i
+
+ for i in CONFIG:
+ CONFIG[i] = cfg[i]
+
### USE FLAG PART ###
USE_PATH = os.path.join(portage.USER_CONFIG_PATH,"package.use")
USE_PATH_IS_DIR = os.path.isdir(USE_PATH)
@@ -149,7 +168,7 @@ def set_use_flag (pkg, flag):
if not added:
path = USE_PATH
if USE_PATH_IS_DIR:
- path = os.path.join(USE_PATH,"geneticone")
+ path = os.path.join(USE_PATH,CONFIG["usefile"])
try:
newUseFlags[cpv].remove((path, -1, invFlag, False))
@@ -216,18 +235,13 @@ def write_use_flags ():
file_cache = {} # cache for having to read the file only once: name->[lines]
for cpv in newUseFlags:
+ flagsToAdd = [] # this is used for collecting the flags to be inserted in a _new_ line
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:
- file_cache[file].append(msg)
+ flagsToAdd.append(flag)
# change a line
else:
if not file in file_cache:
@@ -258,6 +272,20 @@ def write_use_flags ():
else:
insert(flag,l)
file_cache[file][line-1] = " ".join(l)
+
+ # write new lines
+ msg = "\n#geneticone update#\n"
+ if CONFIG["usePerVersion"]:
+ msg += "=%s %s\n" % (cpv, ' '.join(flagsToAdd))
+ else:
+ list = split_package_name(cpv)
+ msg += "%s/%s %s\n" % (list[0], list[1], ' '.join(flagsToAdd))
+ if not file in file_cache:
+ f = open(file, "a")
+ f.write(msg)
+ f.close()
+ else:
+ file_cache[file].append(msg)
# write to disk
for file in file_cache.keys():
diff --git a/geneticone/gui/gui_helper.py b/geneticone/gui/gui_helper.py
index acbccd3..32dd56f 100644
--- a/geneticone/gui/gui_helper.py
+++ b/geneticone/gui/gui_helper.py
@@ -16,10 +16,48 @@ import windows
from subprocess import *
from threading import Thread
+from ConfigParser import SafeConfigParser
import pty
import vte
+class Config:
+ const = {
+ "main_sec" : "Main",
+ "usePerVersion_opt" : "usePerVersion",
+ "useFile_opt" : "usefile"
+ }
+
+ def __init__ (self, cfgFile):
+ self._cfg = SafeConfigParser()
+ if not isinstance(cfgFile, file):
+ self._file = open(cfgFile) # assume string
+ elif cfgFile.closed:
+ self._file = open(cfgFile.name)
+ else:
+ self._file = cfgFile
+
+ self._cfg.readfp(self._file)
+ self._file.close()
+
+ def get(self, name, section=const["main_sec"]):
+ return self._cfg.get(section, name)
+
+ def get_boolean(self, name, section=const["main_sec"]):
+ return self._cfg.getboolean(section, name)
+
+ def modify_flags_config (self):
+ flagCfg = {"usefile": self.get(self.const["useFile_opt"]), "usePerVersion" : self.get_boolean(self.const["usePerVersion_opt"])}
+ flags.set_config(flagCfg)
+
+ def set(self, name, val, section=const["main_sec"]):
+ self._cfg.set(section, name, val)
+
+ def write(self):
+ self._file = open(self._file.name,"w")
+ self._cfg.write(self._file)
+ self.modify_flags_config()
+
class Database:
"""An internal database which holds a simple dictionary cat -> [package_list]."""
diff --git a/geneticone/gui/windows.py b/geneticone/gui/windows.py
index 95703ce..1238a5e 100644
--- a/geneticone/gui/windows.py
+++ b/geneticone/gui/windows.py
@@ -12,6 +12,7 @@
# our backend stuff
VERSION = "0.3.4"
+CONFIG_LOCATION = "/etc/geneticone/geneticone.cfg"
MENU_EMERGE = 1
MENU_UNEMERGE = 2
@@ -33,19 +34,32 @@ import vte
# other
from portage_util import unique_array
-class AboutWindow:
- """A window showing the "about"-informations."""
+class AbstractDialog:
- def __init__ (self, parent):
- # window
+ def __init__ (self, parent, title):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
- self.window.set_title("About Genetic/One")
+ self.window.set_title(title)
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.window.connect("key-press-event", self.cb_key_pressed)
+
+ def cb_key_pressed (self, widget, event):
+ """Closes the window if esc is pressed."""
+ keyname = gtk.gdk.keyval_name(event.keyval)
+ if keyname == "Escape":
+ self.window.destroy()
+ return True
+ else:
+ return False
+
+class AboutWindow (AbstractDialog):
+ """A window showing the "about"-informations."""
+ def __init__ (self, parent):
+ AbstractDialog.__init__(self, parent, "About Genetic/One")
box = gtk.VBox(False)
self.window.add(box)
@@ -66,19 +80,12 @@ Copyright (C) 2006 Necoro d.M. &lt;necoro@necoro.net&gt;
self.window.show_all()
-class SearchWindow:
+class SearchWindow (AbstractDialog):
"""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.window.connect("key-press-event", self.cb_key_pressed)
+ AbstractDialog.__init__(self, parent, "Search results")
+
self.list = list
self.jump_to = jump_to
@@ -115,12 +122,59 @@ class SearchWindow:
else:
return False
-class PackageWindow:
+class PreferenceWindow (AbstractDialog):
+
+ def __init__ (self, parent, cfg):
+ AbstractDialog.__init__(self, parent, "Preferences")
+
+ self.cfg = cfg
+
+ box = gtk.VBox(True)
+ self.window.add(box)
+
+ self.perVersionCb = gtk.CheckButton(label="Add to package.use on a per-version-base")
+ self.perVersionCb.set_active(cfg.get_boolean(cfg.const["usePerVersion_opt"]))
+ box.pack_start(self.perVersionCb, True, True)
+
+ hBox = gtk.HBox()
+ label = gtk.Label("File name to use if package.use is a directory:")
+ self.editUsefile = gtk.Entry()
+ self.editUsefile.set_text(cfg.get(cfg.const["useFile_opt"]))
+ hBox.pack_start(label, False)
+ hBox.pack_start(self.editUsefile, True, True, 5)
+ box.pack_start(hBox, True, True)
+
+ # 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)
+
+ self.window.show_all()
+
+ def _save(self):
+ self.cfg.set(self.cfg.const["usePerVersion_opt"], str(self.perVersionCb.get_active()))
+ self.cfg.set(self.cfg.const["useFile_opt"], self.editUsefile.get_text())
+
+ def cb_ok_clicked(self, button):
+ self._save()
+ self.cfg.write()
+ self.window.destroy()
+
+class PackageWindow (AbstractDialog):
"""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
+ AbstractDialog.__init__(self, parent, cp)
+
self.cp = cp # category/package
self.version = version # version - if not None this is used
self.queue = queue
@@ -128,16 +182,6 @@ class PackageWindow:
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("key-press-event", self.cb_key_press_event)
-
# 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))
@@ -290,15 +334,6 @@ class PackageWindow:
"""Returns the actual package (a backend.Package-object)."""
return self.packages[self.vCombo.get_active()]
- def cb_key_press_event (self, widget, event):
- """Closes the window if esc is pressed."""
- keyname = gtk.gdk.keyval_name(event.keyval)
- if keyname == "Escape":
- self.window.destroy()
- return True
- else:
- return False
-
def cb_combo_changed (self, combo, data = None):
"""Callback for the changed ComboBox.
It then rebuilds the useList and the checkboxes."""
@@ -376,7 +411,6 @@ class MainWindow:
def __init__ (self):
"""Build up window"""
-
# window
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Genetic/One")
@@ -389,6 +423,10 @@ class MainWindow:
self.db = Database()
self.db.populate()
+ # config
+ self.cfg = Config(CONFIG_LOCATION)
+ self.cfg.modify_flags_config()
+
# main vb
vb = gtk.VBox(False, 1)
self.window.add(vb)
@@ -496,6 +534,8 @@ class MainWindow:
# the menu-list
mainMenuDesc = [
( "/_File", None, None, 0, "<Branch>"),
+ ( "/File/_Preferences", None, lambda x,y: PreferenceWindow(self.window, self.cfg), 0, ""),
+ ( "/File/", None, None, 0, "<Separator>"),
( "/File/_Close", None, self.cb_destroy, 0, ""),
( "/_Emerge", None, None, 0, "<Branch>"),
( "/Emerge/_Emerge", None, self.cb_emerge_clicked, MENU_EMERGE, ""),
@@ -515,7 +555,6 @@ class MainWindow:
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)
self.fill_pkg_store(store,name)
@@ -563,8 +602,9 @@ class MainWindow:
sel = view.get_selection()
store, it = sel.get_selected()
if it:
+ self.selCatName = store.get_value(it, 0)
self.pkgList.get_model().clear()
- self.fill_pkg_store(self.pkgList.get_model(), store.get_value(it, 0))
+ self.fill_pkg_store(self.pkgList.get_model(), self.selCatName)
return False
def cb_row_activated (self, view, path, col, store = None):
diff --git a/geneticone/helper.py b/geneticone/helper.py
index 7ceede8..4b2a207 100644
--- a/geneticone/helper.py
+++ b/geneticone/helper.py
@@ -30,9 +30,9 @@ def debug(*args, **kwargs):
out.append(str(obj))
text = ' '.join(out)
if "name" in kwargs:
- text = 'In %s (%s:%s) %s:' % (kwargs["name"], a, b, text)
+ text = 'In %s (%s:%s): %s' % (kwargs["name"], a, b, text)
else:
- text = 'In %s (%s:%s) %s:' % (c, a, b, text)
+ text = 'In %s (%s:%s): %s' % (c, a, b, text)
#if wrap:
# text = textwrap.fill(text)