|
|
|
|
#!/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 tdeui import *
|
|
|
|
|
from tdecore 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()
|