diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-13 05:43:39 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-13 05:43:39 +0000 |
commit | 19ae07d0d443ff8b777f46bcbe97119483356bfd (patch) | |
tree | dae169167c23ba7c61814101995de21d6abac2e8 /grubconfig/grubconfig.py | |
download | tde-guidance-19ae07d0d443ff8b777f46bcbe97119483356bfd.tar.gz tde-guidance-19ae07d0d443ff8b777f46bcbe97119483356bfd.zip |
Added KDE3 version of KDE Guidance utilities
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kde-guidance@1102646 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'grubconfig/grubconfig.py')
-rw-r--r-- | grubconfig/grubconfig.py | 697 |
1 files changed, 697 insertions, 0 deletions
diff --git a/grubconfig/grubconfig.py b/grubconfig/grubconfig.py new file mode 100644 index 0000000..2445132 --- /dev/null +++ b/grubconfig/grubconfig.py @@ -0,0 +1,697 @@ +#!/usr/bin/python +# -*- coding: UTF-8 -*- +########################################################################### +# grubconfig.py - description # +# ------------------------------ # +# begin : Sun Dec 10 2006 # +# copyright : (C) 2006-2007 by Martin Böhm # +# email : martin.bohm@kubuntu.org # +# # +########################################################################### +# # +# This program is free software; you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation; either version 2 of the License, or # +# (at your option) any later version. # +# # +########################################################################### + + + +from qt import * +from kdeui import * +from kdecore import * +from kfile import * +import sys, os, string, re +import os.path +import shutil +import locale +import tempfile + +programname = "Boot Loader Configuration" +version = "0.0.2" + +standalone = __name__=='__main__' + + +if standalone: + programbase = KDialogBase +else: + programbase = KCModule + +parsable = ["default","menu","color","timeout","hiddenmenu","title","root","kernel","initrd"] +cat1 = ["default","menu","color","timeout","hiddenmenu","root","initrd"] +cat2 = ["savedefault","makeactive","chainloader"] +cat3 = ["kernel"] + + +class GreyListViewItem(KListViewItem): + def paintCell(self, p, cg, column, width, align ): + cgGrey = cg + cgGrey.setColor(QColorGroup.Text,QColor("grey")) + KListViewItem.paintCell(self, p, cgGrey, column, width, align) + cg.restore() + + +class BoldListViewItem(KListViewItem): + def paintCell(self, p, cg, column, width, align ): + p.save() + f = p.font() + f.setBold(True) + KListViewItem.paintCell(self, p, cg, column, width, align) + p.restore() + + +class GrubConfigAppClass(programbase): + def __init__(self,parent=None,name=None): + if standalone: + KDialogBase.__init__(self,KJanusWidget.Tabbed,i18n("Boot Loader Configuration"), + KDialogBase.Help|KDialogBase.Ok|KDialogBase.Close, KDialogBase.Close) + # no need to include About button yet + self.menulstlocation = "/boot/grub/menu.lst" + self.readfilename = self.menulstlocation + self.globalvars = {} + self.itemslist = [] + + #--- Load menu.lst using the load_menulst() method + self.load_menulst() + print self.globalvars + print self.itemslist + + # - GRUB Options Tab - + if standalone: + usershbox = self.addHBoxPage(i18n("Grub Options")) + vbox = QVBox(usershbox) + else: + vbox = QVBox(tabcontrol) + vbox.setMargin(KDialog.marginHint()) + + # -- Operating Systems List & MakeDefault Button -- + horizontalbox = QHBox(vbox) + self.itemslistview = KListView(horizontalbox) + self.itemslistview.addColumn("") + self.itemslistview.setSorting(-1) + self.itemslistview.header().hide() + self.itemslistviewitems = [] + arrowsbox = QVBox(horizontalbox) + self.upbutton = KPushButton(i18n("Move Up"),arrowsbox) + self.connect(self.upbutton,SIGNAL("clicked()"),self.slotUpButtonClicked) + + self.downbutton = KPushButton(i18n("Move Down"),arrowsbox) + self.connect(self.downbutton,SIGNAL("clicked()"),self.slotDownButtonClicked) + + self.defaultbutton = KPushButton(i18n("Make Default"),vbox) + self.connect(self.defaultbutton,SIGNAL("clicked()"),self.slotSetDefaultButtonClicked) + + + # -- Boot Options Group Box -- + bootoptionsbasebox = QVGroupBox(vbox,"Boot Options") + bootoptionsbasebox.setTitle(i18n("Boot Options")); + + bootoptionsbasevbox = QWidget(bootoptionsbasebox) + + infogrid = QGridLayout(bootoptionsbasevbox,3,2) + infogrid.setSpacing(KDialog.spacingHint()) + + # --- Timeout --- + label = QLabel(i18n("Timeout:"),bootoptionsbasevbox) + infogrid.addWidget(label,0,0) + + timeoutbox = QHBox(bootoptionsbasevbox) + timeoutbox.setSpacing(KDialog.spacingHint()) + + self.timeout = KIntSpinBox(timeoutbox,"Timeout") + if "timeout" in self.globalvars: + self.timeout.setValue(int(self.globalvars['timeout'][0])) + label = QLabel(i18n("seconds"),timeoutbox) + infogrid.addWidget(timeoutbox,0,1) + + + infogrid.addWidget(self.timeout,0,1) + + # --- Hide Menu on Boot --- + self.hidemenuonboot = QCheckBox(i18n("Hide Menu on Boot"),bootoptionsbasevbox) + if 'hiddenmenu' in self.globalvars: + self.hidemenuonboot.setChecked(int(self.globalvars['hiddenmenu'][0])) + infogrid.addWidget(self.hidemenuonboot,1,1) + + # --- Make Last OS Default --- + self.lastdefault = QCheckBox(i18n("Make Last Operating System Default"),bootoptionsbasevbox) + infogrid.addWidget(self.lastdefault,2,1) + + + # -- Security Group Box -- + securitybox = QVGroupBox(vbox,"Security") + securitybox.setTitle(i18n("Security")); + securityvbox = QWidget(securitybox) + + infogrid = QGridLayout(securityvbox,2,2) + infogrid.setSpacing(KDialog.spacingHint()) + + # --- Password --- + label = QLabel(i18n("Password:"),securityvbox) + infogrid.addWidget(label,0,0) + self.userpassword = KPasswordEdit(securityvbox) + infogrid.addWidget(self.userpassword,0,1) + + # --- Repeat Password --- + label = QLabel(i18n("Repeat Password:"),securityvbox) + infogrid.addWidget(label,1,0) + self.userrepeatpassword = KPasswordEdit(securityvbox) + infogrid.addWidget(self.userrepeatpassword,1,1) + + # -- Splash Screen Group Box -- + splashbox = QVGroupBox(vbox,"Splash screen") + splashbox.setTitle(i18n("Splash screen")); + + # --- Background Color --- + labelandeditbox = QHBox(splashbox) + label = QLabel(i18n("Background Color:"),labelandeditbox) + self.backgroundcolor = QComboBox(labelandeditbox) + + # --- Highlight Color --- + labelandeditbox = QHBox(splashbox) + label = QLabel(i18n("Highlight Color:"),labelandeditbox) + self.highlightcolor = QComboBox(labelandeditbox) + + # - Operating Systems Tab - + + if standalone: + groupsvbox = self.addVBoxPage(i18n("Operating Systems")) + vb = QVBox(groupsvbox) + else: + groupsvbox = QVBox(tabcontrol) + roupsvbox.setMargin(KDialog.marginHint()) + vb = QVBox(groupsvbox) + + # -- Operating Systems List -- + + horizontalbox = QHBox(vb) + self.oslistview = KListView(horizontalbox) + self.oslistview.addColumn("") + self.oslistview.addColumn("") + self.oslistview.setSorting(-1) + self.oslistview.header().hide() + self.oslistviewitems = [] + self.connect(self.oslistview,SIGNAL("selectionChanged()"),self.oslistviewitemSelected) + + # -- Operating Systems Details Box -- + osdetailsbox = QVGroupBox(vb,"Operating System Details") + # label = QLabel(i18n("Security"),securitybox) + detailsvbox = QWidget(osdetailsbox) + + infogrid = QGridLayout(detailsvbox,7,2) + infogrid.setSpacing(KDialog.spacingHint()) + + osdetailsbox.setTitle(i18n("Operating System Details")); + + # --- List in GRUB Menu --- + self.listingrub = QCheckBox(i18n("List in GRUB Menu"),detailsvbox) + infogrid.addWidget(self.listingrub,0,1) + + # --- Display Name --- + label = QLabel(i18n("Display Name:"),detailsvbox) + infogrid.addWidget(label,1,0) + self.displaynamelabel = QLineEdit("",detailsvbox) + infogrid.addWidget(self.displaynamelabel,1,1) + self.connect(self.displaynamelabel,SIGNAL("textChanged(const QString &)"),self.slotDisplayNameLabelChanged) + + # --- Operating System --- + label = QLabel(i18n("Operating System:"),detailsvbox) + infogrid.addWidget(label,2,0) + self.operatingsystem = QComboBox(detailsvbox) + infogrid.addWidget(self.operatingsystem,2,1) + + # --- Kernel --- + label = QLabel(i18n("Kernel:"),detailsvbox) + infogrid.addWidget(label,3,0) + self.kernel = KURLRequester(detailsvbox) + infogrid.addWidget(self.kernel,3,1) + + # --- Failsafe Kernel --- + # not sure if that is possible - requested by seele + label = QLabel(i18n("Failsafe Kernel:"),detailsvbox) + infogrid.addWidget(label,4,0) + self.failsafekernel = QComboBox(detailsvbox) + infogrid.addWidget(self.failsafekernel,4,1) + + # --- Initial RAM Disk --- + label = QLabel(i18n("Initial RAM Disk:"),detailsvbox) + infogrid.addWidget(label,5,0) + self.initrd = KURLRequester(detailsvbox) + infogrid.addWidget(self.initrd,5,1) + + # --- Root Filesystem --- + label = QLabel(i18n("Root Filesystem:"),detailsvbox) + infogrid.addWidget(label,6,0) + self.rootfilesystem = QComboBox(detailsvbox) + infogrid.addWidget(self.rootfilesystem,6,1) + + + # -- Boot Options Box -- + bootoptionsbox = QVGroupBox(vb,"Boot Options") + # label = QLabel(i18n("Security"),securitybox) + bootoptionsbox.setTitle(i18n("Boot Options")); + + + + self.acpibox = QCheckBox(i18n("Power Management (ACPI) "),bootoptionsbox) + self.debugbox = QCheckBox(i18n("Debugging Messages "),bootoptionsbox) + self.selinuxbox = QCheckBox(i18n("SELinux Support "),bootoptionsbox) + self.splashbox = QCheckBox(i18n("Splash Screen"),bootoptionsbox) + + labelandeditbox = QHBox(bootoptionsbox) + label = QLabel(i18n("Custom Options:"),labelandeditbox) + self.customoptions = KLineEdit("",labelandeditbox) + + # -- (static) UI finished -- + self.reloadListViews("oslist") + self.reloadListViews("itemslist") + try: + self.oslistview.setSelected(self.oslistviewitems[int(self.globalvars['default'][0])],True) + except ValueError: + self.oslistview.setSelected(self.oslistviewitems[0],True) + + ops_list = self.load_osprobe() + print ops_list # mhb debug + + ####################################################################### + # reload listviews, because they have changed + def reloadListViews(self,name): + print "reloaded" + # you should repaint the one that is not changed on screen + if name == "oslist": + self.oslistview.clear() + + for item in self.itemslist: + try: + if self.itemslist.index(item) == int(self.globalvars['default'][0]): + self.oslistviewitems.append(BoldListViewItem(self.oslistview,self.oslistview.lastItem(),item['title'][0])) + else: + self.oslistviewitems.append(KListViewItem(self.oslistview,self.oslistview.lastItem(),item['title'][0])) + except ValueError: + self.oslistviewitems.append(KListViewItem(self.oslistview,self.oslistview.lastItem(),item['title'][0])) + # if it has a root option (other than 1 which means only root by itself), it is an OS + else: + self.itemslistview.clear() + #repaint main list + for item in self.itemslist: + try: + if self.itemslist.index(item) == int(self.globalvars['default'][0]): + print "bam!" + self.itemslistviewitems.append(BoldListViewItem(self.itemslistview,self.itemslistview.lastItem(),item['title'][0])) + else: + self.itemslistviewitems.append(KListViewItem(self.itemslistview,self.itemslistview.lastItem(),item['title'][0])) + except ValueError: + self.itemslistviewitems.append(KListViewItem(self.itemslistview,self.itemslistview.lastItem(),item['title'][0])) + + ####################################################################### + def slotUser1(self): + self.aboutus.show() + + + ####################################################################### + # def slotClose(self): + # self.close() + + ####################################################################### + def slotOk(self): + self.save_menulst() + # mhb TODO: catching exceptions here would be useful + self.close() + + ####################################################################### + def slotCheckOsClicked(self): + self.OsProbedList = self.load_osprobe() + + ####################################################################### + def oslistviewitemSelected(self): + # save current item changes & select another one + i = self.oslistviewitems.index(self.oslistview.selectedItem()) + self.updatingGUI = True + self.displaynamelabel.setText(self.itemslist[i]["title"][0]) + # visible in GRUB reload + # kernel reload + try: + self.kernel.setURL(self.itemslist[i]["kernel"][0]) + except KeyError: + self.initrd.setURL("unavailable") # mhb debug + # initrd reload + try: + self.initrd.setURL(self.itemslist[i]["initrd"][0]) + except KeyError: + self.initrd.setURL("unavailable") # mhb debug + + # custom options reload + customoptions = "" + for word in self.itemslist[i]["kernel"][1:-1]: + customoptions += word + " " + self.customoptions.setText(customoptions[:-1]) + + self.updatingGUI = False + print "oslistview item selected" #mhb debug + pass + ####################################################################### + def slotDisplayNameLabelChanged(self, string): + if(self.updatingGUI == False): + print "display name changed" #mhb debug + i = self.oslistviewitems.index(self.oslistview.selectedItem()) + self.itemslist[i]["title"][0] = string + self.oslistview.selectedItem().setText(0,string) + self.reloadListViews("itemslist") + pass + ####################################################################### + def slotUpButtonClicked(self): + print "UpButton clicked" #mhb debug + i = self.itemslistviewitems.index(self.itemslistview.selectedItem()) + self.itemslistview.selectedItem().itemAbove().moveItem(self.itemslistview.selectedItem()) + # itemslist should have the same i for the same option + if(i != 0): + container = self.itemslist[i] + self.itemslist[i] = self.itemslist[i-1] + self.itemslist[i-1] = container + self.reloadListViews("oslist") + return "not working yet" + + ####################################################################### + def slotDownButtonClicked(self): + print "DownButton clicked" #mhb debug + i = self.itemslistviewitems.index(self.itemslistview.selectedItem()) + self.itemslistview.selectedItem().moveItem(self.itemslistview.selectedItem().itemBelow()) + if(i != len(self.itemslist)-1): + container = self.itemslist[i] + self.itemslist[i] = self.itemslist[i+1] + self.itemslist[i+1] = container + self.reloadListViews("oslist") + return "not working yet" + + ####################################################################### + def slotSetDefaultButtonClicked(self): + print "SetDefaultButton cliicked" #mhb debug + try: + defaultn = int(self.globalvars["default"][0]) + except ValueError: + pass + else: + container = self.itemslistviewitems[defaultn] + self.itemslistviewitems[defaultn] = KListViewItem(self.itemslistview,container,self.itemslist[defaultn]['title'][0]) + self.itemslistview.takeItem(container) + + + indexn = self.itemslistviewitems.index(self.itemslistview.selectedItem()) + self.globalvars["default"] = str(indexn) + self.itemslistviewitems[indexn] = BoldListViewItem(self.itemslistview,self.itemslistview.selectedItem(),self.itemslist[indexn]['title'][0]) + self.itemslistview.takeItem(self.itemslistview.selectedItem()) + + self.reloadListViews("oslist") + + return "not working yet" + + + + ####################################################################### + # loop + def exec_loop(self): + global programbase + # self.__loadOptions() + self.updatingGUI = True + #self.__updateUserList() + #self.__updateGroupList() + self.updatingGUI = False + programbase.exec_loop(self) + print "done" + + + ####################################################################### + # loads menu.lst + # NOT YET parsing: + # fallback + # currently parsing: (type of the location number) + # default <int> + # timeout <int> + # hiddenmenu <int> + # color <int> + # password (consider an md5 sum?) <int> + # AUTOMAGIC KERNELS LIST <interval - two ints> + # GRUBCONFIG DISABLED ITEMS <interval - two ints> + # IMPORTANT note: + # any value that is not parsed MUST not be ommited at the end! + # any value that is commented (parsed or not) MUST not be omitted at the end! + # not so important note: + # if a value we parse is not defined: + # apply defaults (how do find them out?) + # but specify it in the menu.lst when saving + # mhb TODO: somehow handle automagic kernel list (target: feisty) + # mhb TODO: adapt to more distributions, find menu.lst on different locations + def load_menulst(self): + self.modifiedlines = [] + menufd = open(self.menulstlocation,"r") + linenum = 0 + lock = 0 + itemlock = 0 + currentitem = 0 + for line in menufd: + # Checks if the first non-white char in a line is a # + if re.search(r'^(/s)*#',line) or re.search(r'^(/s)*$',line): + print "a commented line" # mhb debug + if itemlock == 1: + itemlock = 0 + currentitem += 1 + + # if it is a start of an area we parse, use a lock + if re.search(r'sumthin',line) and (lock == 0): + lock = 1 + elif re.search(r'sumthin_other',line) and (lock == 0): + lock = 2 + # else if it is an end of an area we parse, close the lock + elif re.search(r'sumthin_other_end',line) and (lock == 2): + lock = 0 + elif re.search(r'sumthin_end',line) and (lock == 1): + lock = 0 + + # errors + # mhb TODO: exception catching + elif re.search(r'sumthin',line) and (lock == 0): + raise IdentationError + elif re.search(r'sumthin_other',line) and (lock == 1): + raise EndOfNotOpenedError + + # if it is in the lock, do the mumbo-jumbo + # find out what kind of lock it is + # AUTOCONFIG + if lock == 1: + + + # automagic kernels list? + if re.search(r'sumthin',line): + pass + # or the other one (grubconfig disabled kernel's list )? + else: + self.modifiedlines.append(linenum) + # else save it as a commented line (does not save the locks) + # GRUBCONFiG commented item + elif lock == 2: + # remove leading spaces and one # + # the parse as a normal menu item + pass + # it's a commented, no need to do anything + else: + pass + # okay, it's not commented + else: + print "a not commented line" # mhb debug + self.modifiedlines.append(linenum) + # we presume the first character is already a name + var_name = line.split()[0] + #print "variable name is " + var_name # mhb debug + # var_value's last item is always the line that has to be changed + var_value = [] + if var_name in parsable: + # cat 0 - a title - triggers itemlock, has a name and a value, which should be stored as text + if var_name == "title": + print line.split(None,1) + var_value.append(line.split(None,1)[1][:-1]) + itemlock = 1 + self.itemslist.append({}) + # cat 1 - has a name and 1 value + elif var_name in cat1: + try: + var_value.append(line.split()[1]) + except IndexError: + var_value.append(1) + # cat 2 - has a name, but no value ( implicit 1 ) + elif var_name in cat2: + var_value.append(1) + # cat 3 - has a name, has multiple values, should be saved as list + elif var_name in cat3: + var_value = line.split()[1:] + # now, append the number + var_value.append(linenum) + + if itemlock == 1: + self.itemslist[currentitem][var_name] = var_value + else: + self.globalvars[var_name] = var_value + + + + + + #if var_name in parsable: + #print "variable name " + var_name + " is parsable " # mhb debug + #if var_name == "title": + #itemlock = 1 + #self.itemslist.append({}) + #if(len(line.split()) > 1): + #var_value = line.split()[1] + #if itemlock == 1: + + #else: + + #print "variable value is " + var_value # mhb debug + + #else: + #if itemlock == 1: + #self.itemslist[currentitem][var_name] = var_value + #else: + #self.globalvars[var_name] = 1 + #else: + #print "variable name " + var_name + " is currently not parsable" # mhb debug + + #print "it has no value" # mhb debug + # print "parsed another line" # mhb debug + linenum += 1; + print "load_menulst() called" # mhb debug + return "not working yet" + + ####################################################################### + # writes menu.lst + def save_menulst(self): + delimeter = " " + # phase 1: preparing the values + lines = [] + linecontent = [] + # this consists of: + # 1. concatenating the list of lines that were modified + # 2. writing the lines in another list (or something more efficient + output = {} + # the globals first + for unit, value in self.globalvars.items(): + lines.append(value[-1]) + temp_str="" + temp_str+=(str(unit)+" ") + for index in range(len(value)-1): + temp_str+=(str(value[index])+" ") + linecontent.append(temp_str) + + # itemslist next (abattoir) + for item in self.itemslist: + for unit, value in reversed(item.items()): + lines.append(value[-1]) + temp_str="" + temp_str+=(str(unit)+" ") + for index in range(len(value)-1): + temp_str+=(str(value[index])+" ") + linecontent.append(temp_str) + + # phase 2: writing the file + # by now we have a list of numbers (let's call it lines[]) + # and a list of mofified lines (let's call it linecontent[] ) + # lines[i] corresponds with linecontent[] + trfile = open(self.readfilename, "r" ) + twfilename = tempfile.mkstemp("menulst")[1] + twfile = open(twfilename,"w") + # the current solution is: + # read the menu.lst again (or rather its copy, to prevent the file being changed) + # line by line write it in the output file (to be exact, to a file in /tmp) + linenum = 0 + print linecontent + print lines + # foreach file as line: + for originalline in trfile: + # if its number isn't in the location list, simply write it + if linenum in lines: + twfile.writelines(linecontent[linenum]) + else: + twfile.writelines(originalline) + + linenum += 1; + + # if there are any more lines to be written (newly detected options) + # write them at the end (now) + + # when that process works out fine do a quick rewrite to /boot/grub/menu.lst + # mhb TODO: declare self.menulstlocation + twfile.close() + shutil.move(twfilename,self.menulstlocation) + # mhb TODO: Exception handling + os.remove(self.readfilename) + + print "save_menulst() called" # mhb debug + return "not working yet" + + + ####################################################################### + # loads output from os-probe + def load_osprobe(self): + detected = os.popen('os-prober').readlines() + ops_list = [] + for ops in detected: + ops = string.replace(ops,"\n","") + temp_list = ops.split(':') + partition = temp_list[0] + temp_list[0] = string.replace(temp_list[0],"/dev/","") + re_obj = re.search(r'([sh]d)([a-z])([0-9])*$',temp_list[0]) + disk = ord(re_obj.group(2))%97 + part = int(re_obj.group(3))-1 + if re_obj == None: + re_obj = re.search(r'(fd[0-9]*)$',temp_list[0]) + if re_obj: + disk = temp_list[0] + part = "" + else : re_obj = re.search(r'(part[0-9]*$', temp_list[0]) + if re_obj: + disk = '/disc' + part = temp_list[0] + temp_list[0] = '('+re_obj.group(1)+str(disk)+','+str(part)+')' + if temp_list[3].lower() == "linux": + mounted = os.popen('mount | grep '+partition).readlines() + if mounted: + linux_os = os.popen('linux-boot-prober --mounted '+partition).readlines() + else: + linux_os = os.popen('linux-boot-prober '+partition).readlines() + linux_list = [] + for lops in linux_os: + lops = string.replace(lops,"\n","") + temp_linux_list = lops.split(':') + linux_list.append(temp_linux_list) + temp_list.append(linux_list) + ops_list.append(temp_list) + temp_list = [] + return ops_list + + +############################################################################ +# Factory function for KControl +def create_grubconfig(parent,name): + return GrubConfigAppClass(parent, name) + + +########################################################################## +def MakeAboutData(): + aboutdata = KAboutData("guidance", programname, version, + unicode(i18n("Boot Loader Configuration Tool")).encode(locale.getpreferredencoding()), + KAboutData.License_GPL, "Copyright (C) 2006-2007 Martin Böhm") + aboutdata.addAuthor("Martin Böhm", "Developer", "martin.bohm@kubuntu.org", "http://mhb.ath.cx/") + aboutdata.addAuthor("Simon Edwards", "Developer", "simon@simonzone.com", "http://www.simonzone.com/software/") + aboutdata.addAuthor("Sebastian Kügler", "Developer", "sebas@kde.org", "http://vizZzion.org") + return aboutdata + +if standalone: + aboutdata = MakeAboutData() + + KCmdLineArgs.init(sys.argv,aboutdata) + + kapp = KApplication() + grubconfigapp = GrubConfigAppClass() + grubconfigapp.exec_loop() |