You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

651 lines
22 KiB

#!/usr/bin/env python
# Copyright (c) 2004 Michael Pyne <michael.pyne@kdemail.net>
# Distributed under the terms of the GNU GPL v2, or any later version.
# Script to auto-generate the configuration for kdesvn-build to use.
# See http://grammarian.homelinux.net/kdesvn-build/
from qt import *;
from re import split;
import re;
import sys;
import os;
defaultQtCopyOpts = "-system-zlib -qt-gif -system-libjpeg -system-libpng -plugin-imgfmt-mng -thread -no-exceptions -debug -fast -dlopen-opengl"
modules = {
'qt-copy': { 'order': 0, 'conf': { 'apply-qt-patches': 'true', 'use-qt-builddir-hack': 'true' } },
'arts': { 'order': 1, 'conf': { } },
'kdesupport': { 'order': 2, 'conf': { } },
'kdemultimedia': { 'order': 4, 'conf': { } },
'kdelibs': { 'order': 2, 'conf': { } },
'kdebase': { 'order': 3, 'conf': { } },
'kdepim': { 'order': 4, 'conf': { } },
'kdegraphics': { 'order': 4, 'conf': { } },
'kdeaddons': { 'order': 4, 'conf': { } },
'kdenetwork': { 'order': 4, 'conf': { } },
'kdegames': { 'order': 4, 'conf': { } },
'kdeadmin': { 'order': 4, 'conf': { } },
'kdeartwork': { 'order': 4, 'conf': { } },
'kdeutils': { 'order': 4, 'conf': { } },
'kdetoys': { 'order': 4, 'conf': { } },
'kdeedu': { 'order': 4, 'conf': { } },
'kdeaccessibility': { 'order': 4, 'conf': { } },
'valgrind': { 'order': 3, 'conf': { } },
'kdevelop': { 'order': 4, 'conf': { } },
'kde-common': { 'order': 2, 'conf': { } },
'kde-i18n': { 'order': 3, 'conf': { } },
'kdewebdev': { 'order': 4, 'conf': { } },
'koffice': { 'order': 4, 'conf': { } },
'kdebindings': { 'order': 4, 'conf': { } },
#'kdenonbeta': { 'order': 4, 'conf': { } },
'kdesdk': { 'order': 5, 'conf': { } },
}
globals = {
'binpath': {
'description': 'Binary path',
'whatsthis': """This is the path that you can find your development
toolchain in, including the <b>g++</b> and <b>make</b> programs. This
is specified by using colon (:) separated directories. Do not include
any KDE or Qt paths, as kdesvn-build will add those automatically as
appropriate.""",
'default': '/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin'
},
'source-dir': {
'description': 'Directory to hold KDE sources',
'whatsthis': """This is the directory to download the KDE sources into.
You may use the tilde (<b>~</b>) to stand for your home directory.""",
'default': '~/kdesvn'
},
'kdedir': {
'description': 'Directory to install KDE into',
'whatsthis': """This is the directory that KDE will be installed to.
You may use the tilde (<b>~</b>) to stand for your home directory. If
you choose to install into a system directory, then you will probably
need to adjust the <i>make-install-prefix</i> option using <b>sudo</b>.
""",
'default': '~/kde' # We probably don't want to default to KDEDIR
},
'qtdir': {
'description': 'Directory to Qt installation',
'whatsthis': """This is the directory of your Qt installation. If you
would like to use qt-copy from KDE Subversion, check the <b>Use KDE's
qt-copy instead of system Qt</b> checkbox.""",
'default': os.environ.get('QTDIR', '~/kdesvn/build/qt-copy')
},
'svn-server': {
'description': 'Subversion Server to use',
'whatsthis': "This is the server to download the KDE sources from",
'default': 'svn://svn.kde.org/home/kde'
},
'conf-flags': {
'description': 'Default configure flags',
'whatsthis': """This is what configure flags you would like to pass to
every Subversion module (except for qt-copy). Use this to specify
settings you want every module to have, such as --enable-debug""",
'default': '--enable-debug'
},
'cxxflags': {
'description': 'Your CXXFLAGS',
'whatsthis': """These flags control various <b>gcc</b> options, such as
the amount of optimization to perform. She the gcc manual for more
information. Whatever you do, don't put excessive CXXFLAGS here, as
higher levels of optimization tend to introduce errors sometimes.""",
'default': '-g -pipe -march=i686'
}
}
version = '0.93'
class BoldLabel(QLabel):
def __init__(self, label, parent):
QLabel.__init__(self, "<center><h3><b>" + label + "</b></h3></center>", parent)
class WizardPage(QVBox):
def __init__(self, wizard, title):
QVBox.__init__(self, wizard)
self.wizard = wizard
self.title = title
self.label = BoldLabel(title, self)
self.setSpacing(10)
wizard.addPage(self, title)
self.connect(wizard, SIGNAL("selected(const QString &)"), self.pageSelected)
def pageSelected(self, title):
if str(title) == self.title:
self.preparePage()
def preparePage(self):
pass
class IntroPage(WizardPage):
def __init__(self, wizard):
WizardPage.__init__(self, wizard, "Introduction to kdesvn-build-wizard")
self.body = QLabel("""<qt><center>This wizard will help you setup a
basic configuration file for kdesvn-build. To continue, please click the
Next button.</center></qt>""", self)
class DistributedPage(WizardPage):
def __init__(self, wizard):
WizardPage.__init__(self, wizard, "Distributed compilation options")
text = """<qt>On this page you can configure whether or not you want to
enable some options for distributed compilation. You would want this
if you have a SMP computer, or if you are using distributed build
tools such as <b>distcc</b>, <b>TeamBuilder</b>, or <b>icecream</b>.</qt>
"""
formBox = QVBox(self)
formBox.setSpacing(12)
self.explanation = QLabel(text, formBox)
self.usedcCheck = QCheckBox("Enable distributed compilation", formBox)
self.connect(self.usedcCheck, SIGNAL("toggled(bool)"),
self.setDCEnabled)
self.usedcCheck.setChecked(False)
self.setStretchFactor(self.explanation, 1)
self.optionsPage = DistributedOptionsPage(self.wizard)
self.wizard.setAppropriate(self.optionsPage, False)
def setDCEnabled(self, enable):
if enable:
self.wizard.setAppropriate(self.optionsPage, True)
else:
self.wizard.setAppropriate(self.optionsPage, False)
class DistributedOptionsPage(WizardPage):
def __init__(self, wizard):
WizardPage.__init__(self, wizard, "Distributed Compilation Options")
self.options = QGroupBox(2, Qt.Vertical, "Distributed compilation options", self)
box = QHBox(self.options)
label = QLabel("Number of simultaneous jobs", box)
edit = QSpinBox(1, 128, 1, box)
edit.setValue(4)
self.connect(edit, SIGNAL("valueChanged(int)"),
self.jobsChanged)
check = QCheckBox("Use unsermake instead of automake", self.options)
self.connect(check, SIGNAL("toggled(bool)"),
self.unsermakeChecked)
def preparePage(self):
if not globals.has_key('use-unsermake'):
globals['use-unsermake'] = { 'value': 'false' }
if not globals.has_key('make-options'):
globals['make-options'] = { 'value': '-j4' }
def jobsChanged(self, number):
globals['make-options']['value'] = '-j' + str(number)
def unsermakeChecked(self, enabled):
if enabled:
globals['use-unsermake']['value'] = 'true'
else:
globals['use-unsermake']['value'] = 'false'
# Reimplemented in order to shade the text background when an item is selected
class CheckItem(QCheckListItem):
def __init__(self, parent, text):
QCheckListItem.__init__(self, parent, text, QCheckListItem.CheckBox)
self.moduleName = text
self.listView().palette().setColor(QPalette.Disabled, QColorGroup.Text, Qt.darkGray)
def stateChange(self, status):
self.repaint()
modules[self.moduleName]['checked'] = self.state()
if not modules[self.moduleName].has_key('option-box'):
return
if self.state():
modules[self.moduleName]['option-box'].show()
else:
modules[self.moduleName]['option-box'].hide()
def paintCell(self, painter, cg, col, width, align):
newCg = QColorGroup(cg)
color = QColor(196, 223, 255)
if self.state() == QCheckListItem.On:
if self.listView().viewport().backgroundMode() != Qt.FixedColor:
newCg.setColor(QColorGroup.Base, color)
else:
newCg.setColor(QColorGroup.Background, color)
newCg.setColor(QColorGroup.Text, Qt.black)
QCheckListItem.paintCell(self, painter, newCg, col, width, align)
class GlobalSettingsPage(WizardPage):
class TextChangeProxy(QObject):
def __init__(self, parent, name):
QObject.__init__(self, parent)
self.name = name
def textChanged(self, value):
globals[self.name]['value'] = str(value)
def preparePage(self):
if modules['qt-copy']['checked'] == QCheckListItem.On:
self.toggleCheckBox.setChecked(True)
else:
self.toggleCheckBox.setChecked(False)
def qtCopyToggled(self, enable):
self.qtcopyLine.setEnabled(not enable)
modules['qt-copy']['checked'] = QCheckListItem.Off
if enable:
self.qtcopyLine.setText("~/kdesvn/build/qt-copy")
modules['qt-copy']['checked'] = QCheckListItem.On
def addGridLine(self, label):
templabel = QLabel(globals[label]['description'], self.layoutWidget)
editor = QLineEdit(globals[label]['default'], self.layoutWidget)
if label == 'qtdir':
self.qtcopyLine = editor
toggleQtCopy = QCheckBox("Use KDE's qt-copy instead of system Qt", self)
toggleQtCopy.setChecked(True)
self.qtCopyToggled(True)
self.connect(toggleQtCopy, SIGNAL("toggled(bool)"), self.qtCopyToggled)
self.toggleCheckBox = toggleQtCopy
QWhatsThis.add(toggleQtCopy, """<qt><p>Check this box if you'd like
to use the qt-copy module in KDE instead of the system
Qt.</p><p>qt-copy is the latest version of Qt, optionally with some
patches applied to fix bugs and improve performance.</p></qt>""")
globals[label]['value'] = globals[label]['default']
if globals[label].has_key('whatsthis'):
QWhatsThis.add(templabel, "<qt>" + globals[label]['whatsthis'] + "</qt>")
QWhatsThis.add(editor, "<qt>" + globals[label]['whatsthis'] + "</qt>")
proxy = self.TextChangeProxy(self, label)
proxy.connect(editor, SIGNAL("textChanged(const QString&)"),
proxy.textChanged)
return editor
def __init__(self, wizard):
WizardPage.__init__(self, wizard, "Global Settings")
self.layoutWidget = QGrid(2, self)
self.layoutWidget.setSpacing(4)
self.setStretchFactor(self.layoutWidget, 1)
for x in globals.keys():
temp = self.addGridLine(x)
# Abstract class, please subclass this
class ModulesPage(WizardPage):
def __init__(self, wizard, moduleDict, label, banner):
WizardPage.__init__(self, wizard, label)
defaultModules = [ 'arts', 'kdelibs', 'kdebase', 'kdesupport', 'kdepim',
'kdegraphics', 'kdeaddons', 'kdenetwork',
'kdegames', 'kdeartwork', 'kdeutils', 'qt-copy',
'kdemultimedia', 'kdetoys', 'kdeedu' ]
requiredModules = [ 'arts', 'kdelibs' ]
self.listview = QListView(self)
listview = self.listview
listview.setResizeMode(QListView.LastColumn)
for x in ['Module', 'Description']:
listview.addColumn(x)
self.moduleItems = { }
for x in moduleDict.keys():
self.moduleItems[x] = CheckItem(listview, x)
self.moduleItems[x].setText(1, moduleDict[x])
modules[x]['checked'] = QCheckListItem.Off
if x in defaultModules:
self.moduleItems[x].setState(QCheckListItem.On)
if x in requiredModules:
self.moduleItems[x].setEnabled(False)
listview.setColumnWidthMode(0, QListView.Manual)
def preparePage(self):
for x in self.moduleItems.keys():
self.moduleItems[x].setState(modules[x]['checked'])
def showEvent(self, event):
self.listview.adjustColumn(1)
self.listview.adjustColumn(0)
def resizeEvent(self, event):
self.listview.adjustColumn(0)
class BaseModulesPage(ModulesPage):
def __init__(self, wizard):
moduleDict = {
'arts': 'KDE Audio engine',
'qt-copy': 'Copy of the current Qt library, with bugfixes and optimizations',
'kdesupport': 'Support libraries for some KDE programs. Currently required for juk and amarok',
'kdemultimedia': 'KDE\'s multimedia software collection',
'kdelibs': 'Core KDE libraries, needed for all KDE apps',
'kdebase': 'Base KDE application distribution, includes konqueror',
'kdepim': 'Personal information management applications (e-mail, organizer)',
'kdegraphics': 'Programs to manage your images',
'kdeaddons': 'Useful addons to various KDE programs including kicker and konqueror',
'kdenetwork': 'Network utilities for KDE',
'kdegames': 'Simple games to make your KDE installation more fun!',
'kdeadmin': 'System administration tools for KDE',
'kdeartwork': 'More artwork and styles for KDE. Includes Plastik and dotNET',
'kdeutils': 'Useful utilities, including klipper and kgpg',
'kdetoys': 'Amusing doo-dads to ornament your desktop',
'kdeedu': 'Educational programs for KDE',
'kdeaccessibility': 'Accessibility-related programs for KDE'
}
ModulesPage.__init__(self, wizard, moduleDict, 'Base Modules', 'Base Module Selection')
class ExtraModulesPage(ModulesPage):
def __init__(self, wizard):
moduleDict = {
'valgrind': 'Excellent program optimization/memory-leak-checker',
'kdevelop': 'Powerful Integrated Development Environment for developers',
'kde-common': 'Code and data common to all of KDE',
'kde-i18n': 'Language translations for KDE. This module is VERY LARGE',
'kdewebdev': 'Applications useful for web site developers. Includes Quanta and Kommander',
'koffice': 'KDE Office Suite, includes word processor, spreadsheet, and more',
'kdebindings': 'Bindings to allow programming Qt and/or KDE in languages other than C++',
'kdesdk': 'Collection of applications to ease the job of KDE developers'
}
ModulesPage.__init__(self, wizard, moduleDict, 'Extra Modules', 'Extra Module Selection')
class ExtragearModulesPage(ModulesPage):
def __init__(self, wizard):
moduleDict = {
'addons': 'Addon programs not part of KDE',
'graphics': 'Graphics programs not part of KDE',
'libs': 'Libraries needed by other extragear modules',
'multimedia': 'Multimedia programs not part of KDE',
'network': 'Network/Internet programs not part of KDE',
'office': 'Office productivity applications not part of KDE',
'pim': 'Personal information management applications not part of KDE',
'security': 'Computer security applications not part of KDE',
'sysadmin': 'System administration tools not part of KDE',
'toys': 'Fun/silly programs not part of KDE',
'utils': 'Utility programs, or programs that don\'t fit a different category.'
}
dict = { }
for x in moduleDict.keys():
dict["extragear/%s" % x] = moduleDict[x]
ModulesPage.__init__(self, wizard, dict, 'Extragear Modules', 'Extragear Module Selection')
caption = '''
<qt>You can select some modules from the Extragear project here. Extragear is
a project that, although not part of KDE, contains a nice collection of KDE
programs, including favorites like <b>K3b</b> and <b>DigiKam</b>.</qt>'''
# Must be constructed after __init__() is called.
label = QLabel(caption, self)
class PlaygroundModulesPage(ModulesPage):
def __init__(self, wizard):
moduleDict = {
'artwork': 'Artwork/styles under development',
'base': 'General purpose programs under development',
'edu': 'Educational programs under development',
'games': 'Games under development',
'ioslaves': 'IOSlaves under development',
'multimedia': 'Multimedia programs under development',
'network': 'Network/Internet programs under development',
'pim': 'Personal Information Management programs under development',
'sysadmin': 'System administration tools under development',
'utils': 'Utility programs, or programs that don\'t fit a different category.'
}
dict = { }
for x in moduleDict.keys():
dict["playground/%s" % x] = moduleDict[x]
ModulesPage.__init__(self, wizard, dict, 'Playground Modules', 'Playground Module Selection')
caption = '''
<qt>You can select some modules from the KDE Playground here. The Playground
is a collection of modules holding programs that are currently in development.
Some are closer to release quality than others.</qt>'''
# Must be constructed after __init__() is called.
label = QLabel(caption, self)
class OptionsConfBox(QGroupBox):
class TextChangeProxy(QObject):
def __init__(self, parent, modName, key):
QObject.__init__(self, parent)
self.key = key
self.modName = modName
def textChanged(self, value):
modules[self.modName]['conf'][self.key] = str(value)
def __init__(self, title, parent):
QGroupBox.__init__(self, 2, Qt.Horizontal, title, parent)
self.moduleName = title
checkoutOnlyRe = re.compile("^(playground|extragear|kde-i18n)")
for x in ['conf-flags', 'checkout-only']:
if x == 'checkout-only' and not checkoutOnlyRe.match(title):
continue
label = QLabel(x, self)
edit = QLineEdit(self)
if title == 'qt-copy' and x == 'conf-flags':
edit.setText(defaultQtCopyOpts)
modules['qt-copy']['conf']['conf-flags'] = defaultQtCopyOpts
proxy = self.TextChangeProxy(self, title, x)
proxy.textChanged(edit.text())
self.connect (edit, SIGNAL("textChanged(const QString &)"),
proxy.textChanged)
class OptionsPage(QScrollView):
def __init__(self, wizard):
QScrollView.__init__(self, wizard)
self.setResizePolicy(self.AutoOneFit)
self.container = QVBox(self.viewport())
self.container.setSpacing(7)
self.addChild(self.container)
label = BoldLabel("Module Options", self.container)
self.wizard = wizard
self.name = "Module Options"
sortedModules = modules.keys()
sortedModules.sort(cmpModuleOrder)
for x in sortedModules:
box = OptionsConfBox(x, self.container)
if not modules.has_key(x):
continue
if not modules[x].has_key('checked'):
continue
if not modules[x]['checked']:
box.hide()
modules[x]['option-box'] = box
wizard.addPage(self, self.name)
def cmpModuleOrder(a,b):
aa = modules[a]['order']
bb = modules[b]['order']
if aa == bb:
return cmp(a, b)
return cmp(aa, bb)
class GeneratePage(WizardPage):
def __init__(self, wizard):
WizardPage.__init__(self, wizard, "Config file generation")
self.textEdit = QTextEdit(self)
self.textEdit.setFont(QFont('monospace'))
self.textEdit.setReadOnly(True)
self.textEdit.setWordWrap(QTextEdit.NoWrap)
box = QHBox(self)
box.setSpacing(6)
label = QLabel("&Filename", box)
self.browseLine = QLineEdit("~/.kdesvn-buildrc", box)
label.setBuddy(self.browseLine)
self.connect (self.browseLine, SIGNAL("textChanged(const QString &)"),
self.wizard.setFileName)
self.connect (self.browseLine, SIGNAL("returnPressed()"),
self.wizard.accept)
browseButton = QPushButton("&Save As...", box)
self.connect (browseButton, SIGNAL("clicked()"),
self.browseClicked)
def browseClicked(self):
fileName = re.sub('^~', os.environ['HOME'], str(self.browseLine.text()))
fileName = QFileDialog.getSaveFileName(fileName,
QString.null, self, "kdesvn-pywizard-filesave-dialog")
if not fileName.isNull():
print "Setting filename to " + str(fileName)
self.browseLine.setText(str(fileName))
self.wizard.setFileName(str(fileName))
def preparePage(self):
self.textEdit.clear()
te = self.textEdit.append
te("### Generated by kdecvs-pywizard, version %s" % version)
te("### Visit the homepage: http://grammarian.homelinux.net/kdesvn-build/")
te("global\n")
for x in globals.keys():
te("\t" + x + " " + globals[x]['value'] + "\n")
te("end global\n\n")
checkedFilter = lambda x: modules[x]['checked']
sortedCheckedModules = filter(checkedFilter, modules.keys())
sortedCheckedModules.sort(cmpModuleOrder)
last = sortedCheckedModules[-1]
for x in sortedCheckedModules:
te("module " + x + "\n")
mod = modules[x]['conf']
for y in mod.keys():
if mod[y] != "" and not (y == 'use-unsermake' and x == 'kdebindings'):
te("\t" + y + " " + mod[y] + "\n")
if x == 'kdebindings':
te("\t# kdebindings hurts badly with unsermake\n")
te("\tuse-unsermake false\n")
if x == 'qt-copy':
te("\t# unsermake makes no sense with qt-copy\n")
te("\tuse-unsermake false\n")
te("end module\n")
if x != last:
te("\n")
self.wizard.setFinishEnabled(self, True)
self.wizard.setFileName(self.browseLine.text())
self.wizard.setFileText(self.textEdit.text())
class ConfigWizard(QWizard):
def __init__(self, parent=None):
QWizard.__init__(self, parent)
def showPage(self, page):
QWizard.showPage(self, page)
self.setHelpEnabled(page, 0)
def setFileText(self, text):
self.text = str(text)
def setFileName(self, name):
self.filename = str(name)
def accept(self):
filename = self.filename
print "Saving " + filename
name = re.sub('^~', os.environ['HOME'], self.filename)
if os.access(name, os.F_OK):
caption = "Overwrite file?"
text = """
The file you have selected, %s, already exists.
Do you want to overwrite %s?""" % (filename, filename)
selection = QMessageBox.warning(self, caption, text,
QMessageBox.Yes, QMessageBox.No |
QMessageBox.Default | QMessageBox.Escape, 0)
if selection != QMessageBox.Yes:
return
try:
file = open(name, 'w')
except IOError:
QMessageBox.warning(self, "Unable to save", "Unable to save " + filename,
QMessageBox.Ok | QMessageBox.Default, 0, 0)
return
file.write(self.text)
file.close()
QWizard.accept(self)
def main(args):
print "kdesvn-pywizard version %s" % version
# extragear/ and playground have a shitload of modules, auto-generate some of
# their entries here.
playgroundMods = split('\s+', """artwork base edu games ioslaves multimedia
network pim sysadmin utils""")
extragearMods = split('\s+', """addons graphics libs multimedia network
office pim security sysadmin toys utils""")
for i in playgroundMods:
modulename = "playground/%s" % i
modules[modulename] = { 'order': 5, 'conf': { } }
for i in extragearMods:
modulename = "extragear/%s" % i
modules[modulename] = { 'order': 5, 'conf': { } }
a = QApplication(args)
wizard = ConfigWizard()
# I like bold fonts better
font = wizard.titleFont()
font.setBold(True)
wizard.setTitleFont(font)
# Add all of the pages to the wizard
page1 = IntroPage(wizard)
page2 = GlobalSettingsPage(wizard)
page3 = DistributedPage(wizard)
page4 = BaseModulesPage(wizard)
page5 = ExtraModulesPage(wizard)
page6 = ExtragearModulesPage(wizard)
page7 = PlaygroundModulesPage(wizard)
page8 = OptionsPage(wizard)
page9 = GeneratePage(wizard)
wizard.resize(QSize(640, 480))
# Start the show
wizard.exec_loop()
if __name__=="__main__":
main(sys.argv)
# vim: set noet sw=4 ts=4 tw=0: