summaryrefslogtreecommitdiffstats
path: root/wineconfig
diff options
context:
space:
mode:
Diffstat (limited to 'wineconfig')
-rw-r--r--wineconfig/drivedetect.py122
-rwxr-xr-xwineconfig/firstrunwizard.py326
-rw-r--r--wineconfig/kcm_wineconfig.cpp156
-rw-r--r--wineconfig/wineconfig.desktop57
-rwxr-xr-xwineconfig/wineconfig.py3552
-rw-r--r--wineconfig/wineread.py543
-rw-r--r--wineconfig/winewrite.py489
7 files changed, 5245 insertions, 0 deletions
diff --git a/wineconfig/drivedetect.py b/wineconfig/drivedetect.py
new file mode 100644
index 0000000..5916b18
--- /dev/null
+++ b/wineconfig/drivedetect.py
@@ -0,0 +1,122 @@
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+###########################################################################
+# wineread.py - description #
+# ------------------------------ #
+# begin : Fri Mar 26 2004 #
+# copyright : (C) 2006 by Yuriy Kozlov #
+# email : yuriy.kozlov@gmail.com #
+# #
+###########################################################################
+# #
+# 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. #
+# #
+###########################################################################
+
+import os
+import wineread
+
+""" Reads a default set of drives from /etc/fstab """
+
+fstabpath = "/etc/fstab"
+
+# Listed in winecfg
+ignored_fs_types = set(["devpts",
+ "tmpfs",
+ "proc",
+ "sysfs",
+ "swap",
+ "usbdevfs",
+ "rpc_pipefs",
+ "binfmt_misc"])
+
+# Listed in winecfg
+ignored_mnt_pts = set(["/boot"])
+
+cd_fs_types = set(["cdfs","udf","iso9660"])
+
+# An incomplete listing, I don't know how winecfg does this.
+# RAMFS is included here because I don't know what the correct type for it is in wine.
+hd_fs_types = set(["ext4","ext3","ext2","ext","fat","fat32","fat16","ntfs","reiserfs","reiser4",
+ "jfs","xfs","ramfs","vfat","ufs","hfs","hfsplus"])
+
+# Listed in winecfg
+net_fs_types = set(["nfs","nfs4","smbfs","cifs","coda"])
+
+def autodetect(drives=None):
+ """ Returns a set of drives found by scanning /etc/fstab, and an error code """
+ if not drives:
+ drives = wineread.GetEmptyDrives()
+ mappings = set()
+ if not drives[2][2]:
+ drives[2][2] = "../drive_c"
+ drives[2][3] = "hd"
+
+ for drive in drives:
+ mapping = drive[2]
+ if mapping:
+ mappings.add(mapping)
+
+ driveid = 3
+ fstab=open(fstabpath,'r')
+
+ for driveline in fstab:
+ if driveline[0] == '#' or len(driveline.strip()) == 0: # Comment or empty line
+ continue
+ else:
+ driveprops = driveline.split()
+ fs = driveprops[0]
+ mnt = driveprops[1]
+ fstypes = set(driveprops[2].split(','))
+
+ ignore = False
+ for fstype in fstypes:
+ if fstype in ignored_fs_types:
+ ignore = True
+ break
+
+ if mnt in ignored_mnt_pts or mnt in mappings:
+ ignore = True
+
+ if not ignore:
+ while drives[driveid][2]: # Drive is in use, don't overwrite.
+ driveid += 1
+ if driveid > 25:
+ return (1,drives)
+ drives[driveid][2] = mnt
+ if "/dev/fd" in fs or "floppy" in mnt:
+ drives[driveid][3] = "floppy"
+ elif fstype in cd_fs_types or "/dev/cdrom" in fs or "cdrom" in mnt:
+ drives[driveid][3] = "cdrom"
+ elif fstype in hd_fs_types:
+ drives[driveid][3] = "hd"
+ elif fstype in net_fs_types:
+ drives[driveid][3] = "network"
+ else:
+ drives[driveid][3] = "auto"
+ driveid += 1
+
+ fstab.close()
+ return (0,drives)
+
+def autodetectshelllinks(shelllinks = None):
+ """ Returns a default set of windows shell folder mappings """
+ if not shelllinks:
+ shelllinks = wineread.GetEmptyShellLinks()
+
+ for link in shelllinks:
+ if link[2]:
+ continue
+ else:
+ link[3] = "shellfolder"
+ #link[4] = wineread.winepath + "/dosdevices/c:/windows/profiles/" + os.environ['USER'] + "/" + link[1]
+ link[4] = wineread.defaultwinfolderspath + "\\" + link[1]
+ link[5] = wineread.defaultwinfolderspath + "\\" + link[1]
+ link[2] = os.environ['HOME']
+ if link[1] == "Desktop":
+ link[2] = os.environ['HOME'] + "/Desktop"
+
+ return shelllinks
diff --git a/wineconfig/firstrunwizard.py b/wineconfig/firstrunwizard.py
new file mode 100755
index 0000000..c6d3d67
--- /dev/null
+++ b/wineconfig/firstrunwizard.py
@@ -0,0 +1,326 @@
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+###########################################################################
+# wineconfig.py - description #
+# ------------------------------ #
+# begin : Fri Mar 26 2004 #
+# copyright : (C) 2006 by Yuriy Kozlov #
+# email : yuriy.kozlov@gmail.com #
+# #
+###########################################################################
+# #
+# 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 kdecore import *
+from kdeui import *
+from kfile import *
+from kio import *
+import os
+import sys
+import signal
+import wineread
+import winewrite
+import drivedetect
+
+class FirstRunWizard(KWizard):
+ default_winepath = os.environ['HOME'] + "/.wine"
+
+ def __init__(self, parent = None, name=None, modal=0, fl=0):
+ KWizard.__init__(self,parent,name,modal,fl)
+
+ if not name:
+ self.setName("firstrunwizard")
+
+ self.imagedir = unicode(KGlobal.dirs().findDirs("data","guidance/pics")[0])
+
+ self.setupPage1()
+ self.setupPageVersion()
+ self.setupPageExistingWine()
+ self.setupPageCreateWine()
+ self.slotCreateExistingToggled(0)
+ #self.connect(self,SIGNAL("selected(const QString &)"),self.slotPageChanged)
+
+ #self.resize(QSize(600,480).expandedTo(self.minimumSizeHint()))
+ self.clearWState(Qt.WState_Polished)
+
+ def setupPage1(self):
+ page1 = QHBox(self,"page1")
+
+ self.kdewinepicture = QLabel(page1,"kdewinepicture")
+ self.kdewinepicture.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.kdewinepicture.sizePolicy().hasHeightForWidth()))
+ self.kdewinepicture.setMinimumSize(QSize(140,320))
+ self.kdewinepicture.setPixmap(QPixmap(self.imagedir+"kdewinewizard.png"))
+ #self.kdewinepicture.setScaledContents(1)
+
+ spacer = QWidget(page1)
+ spacer.setMinimumSize(QSize(6,300))
+
+ pagebody = QVBox(page1,"pagebody")
+ page1.setStretchFactor(pagebody,1)
+
+ introtext = QLabel(pagebody,"introtext")
+ introtext.setText(i18n("It appears that you do not yet have a Windows drive set up.\n" +\
+ "This wizard will help set it up so that you can run windows applications.\n"))
+
+ spacer = QWidget(pagebody)
+ spacer.setMinimumSize(QSize(6,20))
+
+ self.createinstall = True
+
+ createwinepathchoice = QRadioButton(i18n("Set up the fake windows installation " +\
+ "in the following directory:"),pagebody)
+
+ self.winepath = self.default_winepath
+ hbox = QHBox(pagebody)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.winefolderedit = KLineEdit(self.winepath,hbox)
+ self.urlcompletion = KURLCompletion(KURLCompletion.DirCompletion)
+ self.winefolderedit.setCompletionObject(self.urlcompletion)
+ self.winefolderedit.setCompletionMode(KGlobalSettings.CompletionPopup)
+ self.connect(self.winefolderedit,SIGNAL("textChanged(const QString &)"),self.slotWineFolderEdited)
+
+ self.browsecreatebutton = KPushButton(i18n("Browse"),hbox)
+ self.connect(self.browsecreatebutton,SIGNAL("clicked()"),self.slotBrowseClicked)
+
+ spacer = QWidget(pagebody)
+ spacer.setMinimumSize(QSize(6,10))
+
+ existingwinepathchoice = QRadioButton(i18n("There is already a fake windows installation " +\
+ "in the following directory:"),pagebody)
+
+ hbox = QHBox(pagebody)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.existingwinefolderedit = KLineEdit("",hbox)
+ self.urlcompletion = KURLCompletion(KURLCompletion.DirCompletion)
+ self.existingwinefolderedit.setCompletionObject(self.urlcompletion)
+ self.existingwinefolderedit.setCompletionMode(KGlobalSettings.CompletionPopup)
+ self.connect(self.existingwinefolderedit,SIGNAL("textChanged(const QString &)"),self.slotWineFolderEdited)
+
+ self.browseexistingbutton = KPushButton(i18n("Browse"),hbox)
+ self.connect(self.browseexistingbutton,SIGNAL("clicked()"),self.slotBrowseClicked)
+
+ self.createexistingchoicesgroup = QButtonGroup(pagebody,"createexistingchoicesgroup")
+ self.createexistingchoicesgroup.insert(createwinepathchoice,0)
+ self.createexistingchoicesgroup.insert(existingwinepathchoice,1)
+ self.createexistingchoicesgroup.setExclusive(True)
+ self.createexistingchoicesgroup.hide()
+ self.createexistingchoicesgroup.setButton(0)
+ self.connect(self.createexistingchoicesgroup,SIGNAL("clicked(int)"),self.slotCreateExistingToggled)
+
+ bottomspacer = QWidget(pagebody)
+ pagebody.setStretchFactor(bottomspacer,1)
+
+ self.addPage( page1, i18n("Setting up your windows drive") )
+
+ self.setBackEnabled( page1, False )
+ self.setNextEnabled( page1, True )
+ self.setHelpEnabled( page1, False )
+ self.setFinishEnabled( page1, False )
+
+ def setupPageExistingWine(self):
+ self.pageexisting = QHBox(self,"pageexisting")
+
+ self.kdewinepicture = QLabel(self.pageexisting,"kdewinepicture")
+ self.kdewinepicture.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.kdewinepicture.sizePolicy().hasHeightForWidth()))
+ self.kdewinepicture.setMinimumSize(QSize(140,320))
+ self.kdewinepicture.setPixmap(QPixmap(self.imagedir+"kdewinewizard.png"))
+ #self.kdewinepicture.setScaledContents(1)
+
+ spacer = QWidget(self.pageexisting)
+ spacer.setMinimumSize(QSize(6,300))
+
+ valid = wineread.VerifyWineDrive(self.winepath)
+
+ pagebody = QVBox(self.pageexisting,"pagebody")
+ self.pageexisting.setStretchFactor(pagebody,1)
+
+ existstext = QLabel(pagebody,"existstext")
+ if valid:
+ existstext.setText(i18n("A fake windows installation was found."))
+ else:
+ existstext.setText(i18n("No fake windows installation was found in\n" +\
+ self.winepath + "\nPlease go back and create one."))
+
+ bottomspacer = QWidget(pagebody)
+ pagebody.setStretchFactor(bottomspacer,1)
+
+ self.addPage( self.pageexisting, i18n("Setting up your windows drive") )
+
+ self.setBackEnabled( self.pageexisting, True )
+ self.setNextEnabled( self.pageexisting, True )
+ self.setHelpEnabled( self.pageexisting, False )
+ self.setFinishEnabled( self.pageexisting, True )
+
+ def setupPageCreateWine(self):
+ self.pagecreate = QHBox(self,"pagecreate")
+
+ self.kdewinepicture = QLabel(self.pagecreate,"kdewinepicture")
+ self.kdewinepicture.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.kdewinepicture.sizePolicy().hasHeightForWidth()))
+ self.kdewinepicture.setMinimumSize(QSize(140,320))
+ self.kdewinepicture.setPixmap(QPixmap(self.imagedir+"kdewinewizard.png"))
+ #self.kdewinepicture.setScaledContents(1)
+
+ spacer = QWidget(self.pagecreate)
+ spacer.setMinimumSize(QSize(6,300))
+
+ pagebody = QVBox(self.pagecreate,"pagebody")
+ self.pagecreate.setStretchFactor(pagebody,1)
+
+ self.createdtext = QLabel(pagebody,"existstext")
+ self.createdtext.setText(i18n("A fake windows installation was created for you in\n" +\
+ self.winepath))
+
+ bottomspacer = QWidget(pagebody)
+ pagebody.setStretchFactor(bottomspacer,1)
+
+ self.addPage( self.pagecreate, i18n("Setting up your windows drive") )
+
+ self.setBackEnabled( self.pagecreate, False )
+ self.setNextEnabled( self.pagecreate, True )
+ self.setHelpEnabled( self.pagecreate, False )
+ self.setFinishEnabled( self.pagecreate, True )
+
+ def setupPageVersion(self):
+ self.pageversion = QHBox(self,"pageversion")
+
+ self.kdewinepicture = QLabel(self.pageversion,"kdewinepicture")
+ self.kdewinepicture.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.kdewinepicture.sizePolicy().hasHeightForWidth()))
+ self.kdewinepicture.setMinimumSize(QSize(140,320))
+ self.kdewinepicture.setPixmap(QPixmap(self.imagedir+"kdewinewizard.png"))
+ #self.kdewinepicture.setScaledContents(1)
+
+ spacer = QWidget(self.pageversion)
+ spacer.setMinimumSize(QSize(6,300))
+
+ pagebody = QVBox(self.pageversion,"pagebody")
+ self.pageversion.setStretchFactor(pagebody,1)
+
+ versiontext = QLabel(pagebody,"versiontext")
+ versiontext.setText(i18n("What windows version would you like to emulate?\n"))
+
+ self.winversions = wineread.winversions
+
+ self.verid=1
+ self.versioncombo = KComboBox(0,pagebody,"versioncombo")
+ self.fillVersionCombo(self.versioncombo)
+ self.connect(self.versioncombo,SIGNAL("activated(int)"),self.slotVersionActivated)
+ self.__selectWinVer(self.verid)
+
+ bottomspacer = QWidget(pagebody)
+ pagebody.setStretchFactor(bottomspacer,1)
+
+ self.addPage( self.pageversion, i18n("Setting up your windows drive") )
+
+ self.setBackEnabled( self.pageversion, True )
+ self.setNextEnabled( self.pageversion, True )
+ self.setHelpEnabled( self.pageversion, False )
+ self.setFinishEnabled( self.pageversion, False )
+
+ def fillVersionCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for version in self.winversions:
+ combo.insertItem(version[1])
+
+ def __selectWinVer(self,verid):
+ """
+ Sets the current windows version and selects it in the combo box
+ """
+ self.versioncombo.setCurrentItem(verid)
+
+ def slotVersionActivated(self,verid):
+ self.verid = verid
+
+ def slotFolderChanged(self,folder):
+ """ Change the directory when a new one is entered in the URL box """
+ self.winepath = str(folder)
+
+ def slotWineFolderEdited(self,folder):
+ """ Change the directory when a new one is entered manually in the URL box """
+ self.urlcompletion.makeCompletion("") # Doesn't seem like this should be required.
+ self.slotFolderChanged(folder)
+
+ def slotBrowseClicked(self):
+ """ Bring up a browse window to choose a directory """
+ path = KFileDialog.getExistingDirectory(wineread.winepath,self,i18n("Windows Directory"))
+ if path:
+ self.winepath = str(path)
+
+ #def slotPageChanged(self,pagename):
+ # if pagename == "pagecreate":
+ # self.CreateWindowsInstall()
+
+ def slotCreateExistingToggled(self, buttonid):
+ """ Called when the choice to create a new windows drive or use an existing one is changed """
+ if buttonid == 0:
+ self.createinstall = True
+ self.winefolderedit.setEnabled(True)
+ self.browsecreatebutton.setEnabled(True)
+ self.existingwinefolderedit.setEnabled(False)
+ self.browseexistingbutton.setEnabled(False)
+ self.setAppropriate(self.pageversion,True)
+ self.setAppropriate(self.pageexisting,False)
+ self.setAppropriate(self.pagecreate,True)
+ elif buttonid == 1:
+ self.createinstall = False
+ self.winefolderedit.setEnabled(False)
+ self.browsecreatebutton.setEnabled(False)
+ self.existingwinefolderedit.setEnabled(True)
+ self.browseexistingbutton.setEnabled(True)
+ self.setAppropriate(self.pageversion,False)
+ self.setAppropriate(self.pageexisting,True)
+ self.setAppropriate(self.pagecreate,False)
+
+ def showPage(self,page):
+ if page == self.pagecreate:
+ self.CreateWindowsInstall()
+
+ KWizard.showPage(self,page)
+
+ def CreateWindowsInstall(self):
+ winewrite.CreateWineDrive(self.winepath)
+ wineread.SetWinePath(self.winepath)
+
+ autodrives = drivedetect.autodetect()
+ autoshelllinks = drivedetect.autodetectshelllinks()
+
+ if autodrives[0] == 1:
+ KMessageBox.sorry(self, \
+ i18n("There were not enough letters to add all the autodetected drives."))
+ drives = autodrives[1]
+ drives[26:] = autoshelllinks
+
+ winewrite.SetDriveMappings(drives)
+
+ winewrite.SetAudioDriver('alsa')
+
+ dsoundsettings = {"HardwareAcceleration":"Full",
+ "DefaultSampleRate":"44100",
+ "DefaultBitsPerSample":"8",
+ "EmulDriver":"N"}
+
+ winewrite.SetDSoundSettings(dsoundsettings)
+
+ windowsettings = {"DXGrab":"N",
+ "DesktopDoubleBuffered":"Y",
+ "Managed":"Y",
+ "Desktop":""}
+
+ winewrite.SetWindowSettings(windowsettings)
+
+ d3dsettings = {"VertexShaderMode":"hardware",
+ "PixelShaderMode":"Y"}
+
+ winewrite.SetD3DSettings(d3dsettings)
+
+ winewrite.SetWinVersion(self.winversions[self.verid])
+
+ self.createdtext.setText(i18n("A fake windows installation was created for you in\n" +\
+ self.winepath)) \ No newline at end of file
diff --git a/wineconfig/kcm_wineconfig.cpp b/wineconfig/kcm_wineconfig.cpp
new file mode 100644
index 0000000..bfd9217
--- /dev/null
+++ b/wineconfig/kcm_wineconfig.cpp
@@ -0,0 +1,156 @@
+
+/*
+ * pykcm_launcher.cpp
+ *
+ * Launch Control Centre modules written in Python using an embedded Python
+ * interpreter.
+ * Based on David Boddie's PyKDE-components.
+ */
+
+// pythonize.h must be included first.
+#include <pythonize.h>
+#include <kcmodule.h>
+#include <kglobal.h>
+#include <klocale.h>
+#include <klibloader.h>
+#include <kstandarddirs.h>
+#include <ksimpleconfig.h>
+#include <qstring.h>
+#include <sip.h>
+
+#define MODULE_DIR "/opt/kde3/share/apps/guidance"
+#define EXTRA_MODULE_DIR "/opt/kde3/share/python-support/kde-guidance-kde3"
+#define EXTRA_MODULE_DIR_TWO "/opt/kde3/share/python-support/guidance-backends-kde3"
+#define EXTRA_MODULE_DIR_THREE "/opt/kde3/share/python-support/kde-guidance-powermanager-kde3"
+#define MODULE_NAME "wineconfig"
+#define FACTORY "create_wineconfig"
+#define CPP_FACTORY create_wineconfig
+#define LIB_PYTHON "libpython2.5.so"
+#define debug 1
+
+static KCModule *report_error(char *msg) {
+ if (debug) printf ("error: %s\n", msg);
+ return NULL;
+}
+
+static KCModule* return_instance( QWidget *parent, const char *name ) {
+ KCModule* kcmodule;
+ PyObject *pyKCModuleTuple;
+ PyObject *pyKCModule;
+ Pythonize *pyize; // Pythonize object to manage the Python interpreter.
+ int isErr;
+
+ // Try to determine what py script we're loading. Note that "name"
+ // typically appears to be NULL.
+ QString script(MODULE_NAME);
+
+ // Reload libpython, but this time tell the runtime linker to make the
+ // symbols global and available for later loaded libraries/module.
+ KLibLoader::self()->globalLibrary(LIB_PYTHON);
+
+ // Start the interpreter.
+ pyize = initialize();
+ if (!pyize) {
+ return report_error ("***Failed to start interpreter\n");
+ }
+
+ // Add the path to the python script to the interpreter search path.
+ QString path = QString(MODULE_DIR);
+ if(path == QString::null) {
+ return report_error ("***Failed to locate script path");
+ }
+ if(!pyize->appendToSysPath (path.latin1 ())) {
+ return report_error ("***Failed to set sys.path\n");
+ }
+ QString extrapath = QString(EXTRA_MODULE_DIR);
+ if(!pyize->appendToSysPath (extrapath.latin1 ())) {
+ return report_error ("***Failed to set extra sys.path\n");
+ }
+ QString extrapath_two = QString(EXTRA_MODULE_DIR_TWO);
+ if(!pyize->appendToSysPath (extrapath_two.latin1 ())) {
+ return report_error ("***Failed to set extra 2 sys.path\n");
+ }
+ QString extrapath_three = QString(EXTRA_MODULE_DIR_THREE);
+ if(!pyize->appendToSysPath (extrapath_three.latin1 ())) {
+ return report_error ("***Failed to set extra 3 sys.path\n");
+ }
+
+ // Load the Python script.
+ PyObject *pyModule = pyize->importModule ((char *)script.latin1 ());
+ if(!pyModule) {
+ PyErr_Print();
+ return report_error ("***failed to import module\n");
+ }
+
+ // Inject a helper function
+ QString bridge = QString("import sip\n"
+ "import qt\n"
+ "def kcontrol_bridge_" FACTORY "(parent,name):\n"
+ " if parent!=0:\n"
+#if SIP_VERSION >= 0x040200
+ " wparent = sip.wrapinstance(parent,qt.QWidget)\n"
+#else
+ " wparent = sip.wrapinstance(parent,'QWidget')\n"
+#endif
+ " else:\n"
+ " wparent = None\n"
+ " inst = " FACTORY "(wparent, name)\n"
+ " return (inst,sip.unwrapinstance(inst))\n");
+ PyRun_String(bridge.latin1(),Py_file_input,PyModule_GetDict(pyModule),PyModule_GetDict(pyModule));
+
+ // Get the Python module's factory function.
+ PyObject *kcmFactory = pyize->getNewObjectRef(pyModule, "kcontrol_bridge_" FACTORY);
+ if(!kcmFactory) {
+ return report_error ("***failed to find module factory\n");
+ }
+
+ // Call the factory function. Set up the args.
+ PyObject *pyParent = PyLong_FromVoidPtr(parent);
+ PyObject *pyName = PyString_FromString(MODULE_NAME);
+ // Using NN here is effect gives our references to the arguement away.
+ PyObject *args = Py_BuildValue ("NN", pyParent, pyName);
+ if(pyName && pyParent && args) {
+ // run the factory function
+ pyKCModuleTuple = pyize->runFunction(kcmFactory, args);
+ if(!pyKCModuleTuple) {
+ PyErr_Print();
+ return report_error ("*** runFunction failure\n;");
+ }
+ } else {
+ return report_error ("***failed to create args\n");
+ }
+ // cleanup a bit
+ pyize->decref(args);
+ pyize->decref(kcmFactory);
+
+ // Stop this from getting garbage collected.
+ Py_INCREF(PyTuple_GET_ITEM(pyKCModuleTuple,0));
+
+ // convert the KCModule PyObject to a real C++ KCModule *.
+ isErr = 0;
+ pyKCModule = PyTuple_GET_ITEM(pyKCModuleTuple,1);
+ kcmodule = (KCModule *)PyLong_AsVoidPtr(pyKCModule);
+ if(!kcmodule) {
+ return report_error ("***failed sip conversion to C++ pointer\n");
+ }
+ pyize->decref(pyKCModuleTuple);
+
+ // PyKDE can't run the module without this - Pythonize
+ // grabs the lock at initialization and we have to give
+ // it back before exiting. At this point, we no longer need
+ // it.
+ //pyize->releaseLock ();
+
+ // take care of any translation info
+ KGlobal::locale()->insertCatalogue(script);
+
+ // Return the pointer to our new KCModule
+ return kcmodule;
+}
+
+extern "C" {
+ // Factory function that kcontrol will call.
+ KCModule* CPP_FACTORY(QWidget *parent, const char *name) {
+ return return_instance(parent, name);
+ }
+}
diff --git a/wineconfig/wineconfig.desktop b/wineconfig/wineconfig.desktop
new file mode 100644
index 0000000..c485e65
--- /dev/null
+++ b/wineconfig/wineconfig.desktop
@@ -0,0 +1,57 @@
+[Desktop Entry]
+Categories=Qt;KDE;X-KDE-settings-system;X-KDE-systemsettings-advancedadministration;
+Comment=Wine Configuration
+Comment[el]=Ρυθμίσεις του Wine
+Comment[es]=Configuración de wine
+Comment[et]=Wine seadistamine
+Comment[it]=Configurazione di Wine
+Comment[ja]=Wine の設定
+Comment[nl]=Wine instellen
+Comment[pt]=Configuração do Wine
+Comment[pt_BR]=Configuração do Wine
+Comment[sr]=Wine подешавања
+Comment[sr@Latn]=Wine podešavanja
+Comment[sv]=Inställning av Wine
+Comment[xx]=xxWine Configurationxx
+Encoding=UTF-8
+Exec=kcmshell System/wineconfig
+GenericName=Wine Configuration Editor
+GenericName[el]=Επεξεργαστής ρυθμίσεων του Wine
+GenericName[es]=Editor de la configuración de wine
+GenericName[et]=Wine seadistuste redaktor
+GenericName[it]=Editor della configurazione di Wine
+GenericName[ja]=Wine 設定エディタ
+GenericName[nl]=Wine-configuratiemodule
+GenericName[pt]=Editor de Configuração do Wine
+GenericName[pt_BR]=Editor de Configurações do Wine
+GenericName[sr]=Уређивач Wine подешавања
+GenericName[sr@Latn]=Uređivač Wine podešavanja
+GenericName[sv]=Editor för inställning av Wine
+GenericName[xx]=xxWine Configuration Editorxx
+Icon=wineconfig
+MimeType=
+Name=Windows Applications
+Name[el]=Εφαρμογές Windows
+Name[es]=Aplicaciones de Windows
+Name[et]=Windowsi rakendused
+Name[it]=Applicazioni Windows
+Name[ja]=Windows アプリケーション
+Name[nl]=Windows-programma's
+Name[pt]=Aplicações do Windows
+Name[pt_BR]=Aplicativos Windows
+Name[sr]=Windows програми
+Name[sr@Latn]=Windows programi
+Name[sv]=Windows-program
+Name[xx]=xxWindows Applicationsxx
+Path=
+StartupNotify=true
+Terminal=false
+TerminalOptions=
+Type=Application
+X-DCOP-ServiceType=
+X-KDE-FactoryName=wineconfig
+X-KDE-Library=wineconfig
+X-KDE-ModuleType=Library
+X-KDE-RootOnly=false
+X-KDE-SubstituteUID=false
+X-KDE-Username=
diff --git a/wineconfig/wineconfig.py b/wineconfig/wineconfig.py
new file mode 100755
index 0000000..d4c39ac
--- /dev/null
+++ b/wineconfig/wineconfig.py
@@ -0,0 +1,3552 @@
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+###########################################################################
+# wineconfig.py - description #
+# ------------------------------ #
+# begin : Fri Mar 26 2004 #
+# copyright : (C) 2006 by Yuriy Kozlov #
+# email : yuriy.kozlov@gmail.com #
+# #
+###########################################################################
+# #
+# 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 kdecore import *
+from kdeui import *
+from kfile import *
+from kio import *
+#import string
+#import math
+import os
+import shutil
+#import select
+import sys
+#import struct
+#import csv
+#import time
+import signal
+#import shutil
+import wineread
+import winewrite
+import drivedetect
+import wineconfig
+
+programname = "Wine Configuration"
+version = "0.7.1"
+
+default_winepath = os.environ['HOME'] + "/.wine"
+
+# Are we running as a separate standalone application or in KControl?
+standalone = __name__=='__main__'
+
+# Editing application specific settings? For which application?
+application = None
+
+# Running as the root user or not? Doesn't matter for wine
+isroot = os.getuid()==0
+
+############################################################################
+if standalone:
+ programbase = KDialogBase
+else:
+ programbase = KCModule
+
+############################################################################
+class WineConfigApp(programbase):
+ ########################################################################
+ def __init__(self,parent=None,name=None):
+ global standalone,kapp,default_winepath,application
+ KGlobal.locale().insertCatalogue("guidance")
+
+ if standalone:
+ KDialogBase.__init__(self,KJanusWidget.Tabbed,"Wine Configuration",\
+ KDialogBase.Apply|KDialogBase.User1|KDialogBase.User2|KDialogBase.Close, KDialogBase.Close)
+ self.setButtonText(KDialogBase.User1,i18n("Reset"))
+ self.setButtonText(KDialogBase.User2,i18n("About"))
+ args = KCmdLineArgs.parsedArgs()
+ if args.count() > 0:
+ application = args.arg(0)
+ else:
+ KCModule.__init__(self,parent,name)
+ self.setButtons(KCModule.Apply|KCModule.Reset)
+ self.aboutdata = MakeAboutData()
+
+ # Create a configuration object.
+ self.config = KConfig("wineconfigrc")
+
+ # Compact mode means that we have to make the GUI
+ # much smaller to fit on low resolution screens.
+ self.compact_mode = kapp.desktop().height()<=600
+
+ KGlobal.iconLoader().addAppDir("guidance")
+
+ self.wineconfigchanged = False
+
+ self.updatingGUI = True
+
+ if not wineread.GetWineBuildPath():
+ install = KMessageBox.questionYesNo(self, \
+ i18n("It appears that you do not have Wine installed. Wine " + \
+ "can be used to run some programs designed for Windows. " + \
+ "Would you " + \
+ "like to install it?\n" + \
+ "You will need administrative privileges, and the " + \
+ "community-maintained (universe) repository will be enabled."), \
+ i18n("Windows Applications"))
+ if install == KMessageBox.Yes:
+ self.InstallWine()
+
+ wineread.SetWineBuildPath(wineread.GetWineBuildPath())
+
+ if wineread.GetWineBuildPath():
+ # wine doesn't set the WINEPREFIX globally, but just in case...
+ wineprefix = os.environ.get('WINEPREFIX',default_winepath)
+ newrc = not self.config.hasKey("ColorScheme")
+ firstrun = not wineread.VerifyWineDrive(wineprefix)
+ if firstrun:
+ KMessageBox.information(self, \
+ i18n("It appears that you do not yet have a Windows drive set up. " + \
+ "A fake Windows installation will be created for you in " + \
+ wineprefix + "\nThis may take up to a minute."), \
+ i18n("Setting up your Windows drive"))
+ self.CreateWindowsInstall()
+
+ self._buildGUI()
+
+ if firstrun and newrc:
+ self.appearancepage.slotColorSchemeActivated(1)
+ else:
+ self._buildGUI_noWine()
+
+ self.aboutus = KAboutApplication(self)
+
+ if standalone:
+ self.enableButton(KDialogBase.User1,False) # Reset button
+ self.enableButtonApply(False) # Apply button
+
+ self.updatingGUI = False
+
+
+ def _buildGUI(self):
+ global standalone,application
+ if not standalone:
+ toplayout = QVBoxLayout( self, 0, KDialog.spacingHint() )
+ tabcontrol = QTabWidget(self)
+ toplayout.addWidget(tabcontrol)
+ toplayout.setStretchFactor(tabcontrol,1)
+
+ #--- General tab ---
+ tabname = i18n("General")
+ if standalone:
+ general1page = self.addGridPage(1,QGrid.Horizontal,tabname)
+ general1page.setSpacing(0)
+ self.generalpage = GeneralPage(general1page,self.compact_mode)
+ else:
+ self.generalpage = GeneralPage(tabcontrol,self.compact_mode)
+ self.generalpage.setMargin(KDialog.marginHint())
+
+ # Connect all PYSIGNALs from GeneralPage Widget to appropriate actions.
+ self.connect(self.generalpage,PYSIGNAL("changedSignal()"),self._sendChangedSignal)
+
+ if not standalone:
+ tabcontrol.addTab(self.generalpage,tabname)
+
+ #--- Drives tab ---
+ if not application:
+ tabname = i18n("Drives && Directories")
+ if standalone:
+ drives1page = self.addGridPage(1,QGrid.Horizontal,tabname)
+ drives1page.setSpacing(0)
+ self.drivespage = DrivesPage(drives1page,self.compact_mode)
+ else:
+ self.drivespage = DrivesPage(tabcontrol,self.compact_mode)
+ self.drivespage.setMargin(KDialog.marginHint())
+
+ # Connect all PYSIGNALs from DrivesPage Widget to appropriate actions.
+ self.connect(self.drivespage,PYSIGNAL("changedSignal()"),self._sendChangedSignal)
+
+ if not standalone:
+ tabcontrol.addTab(self.drivespage,tabname)
+
+ #--- Audio tab ---
+ tabname = i18n("Audio")
+ if standalone:
+ audio1page = self.addGridPage(1,QGrid.Horizontal,tabname)
+ self.audiopage = AudioPage(audio1page)
+ else:
+ self.audiopage = AudioPage(tabcontrol)
+ self.audiopage.setMargin(KDialog.marginHint())
+
+ # Connect all PYSIGNALs from AudioPage Widget to appropriate actions.
+ self.connect(self.audiopage,PYSIGNAL("changedSignal()"),self._sendChangedSignal)
+
+ if not standalone:
+ tabcontrol.addTab(self.audiopage,tabname)
+
+ #--- Graphics tab ---
+ tabname = i18n("Graphics")
+ if standalone:
+ graphics1page = self.addGridPage(1,QGrid.Horizontal,tabname)
+ self.graphicspage = GraphicsPage(graphics1page)
+ else:
+ self.graphicspage = GraphicsPage(tabcontrol)
+ self.graphicspage.setMargin(KDialog.marginHint())
+
+
+ # Connect all PYSIGNALs from GraphicsPage Widget to appropriate actions.
+ self.connect(self.graphicspage,PYSIGNAL("changedSignal()"),self._sendChangedSignal)
+
+ if not standalone:
+ tabcontrol.addTab(self.graphicspage,tabname)
+
+ #--- Appearance tab ---
+ if not application:
+ tabname = i18n("Appearance")
+ if standalone:
+ appearance1page = self.addGridPage(1,QGrid.Horizontal,tabname)
+ self.appearancepage = AppearancePage(appearance1page)
+ else:
+ self.appearancepage = AppearancePage(tabcontrol)
+ self.appearancepage.setMargin(KDialog.marginHint())
+
+ # Connect all PYSIGNALs from DesktopPage Widget to appropriate actions.
+ self.connect(self.appearancepage,PYSIGNAL("changedSignal()"),self._sendChangedSignal)
+ self.graphicspage.connect(self.graphicspage.allowwmcheckbox,
+ SIGNAL("toggled(bool)"),
+ self.appearancepage.slotFillItemCombo)
+ self.connect(self.graphicspage.emudesktopcheckbox,
+ SIGNAL("toggled(bool)"),
+ self.appearancepage.slotFillItemComboDesktop)
+
+ self.appearancepage.slotFillItemComboDesktop(\
+ self.graphicspage.currentemudesktop)
+
+ if not standalone:
+ tabcontrol.addTab(self.appearancepage,tabname)
+
+ #--- Applications tab ---
+ if not application:
+ tabname = i18n("Applications")
+ if standalone:
+ apps1page = self.addGridPage(1,QGrid.Horizontal,tabname)
+ self.appspage = ApplicationsPage(apps1page)
+ else:
+ self.appspage = ApplicationsPage(tabcontrol)
+ self.appspage.setMargin(KDialog.marginHint())
+
+ # Connect all PYSIGNALs from ApplicationsPage Widget to appropriate actions.
+ self.connect(self.appspage,PYSIGNAL("changedSignal()"),self._sendChangedSignal)
+
+ if not standalone:
+ tabcontrol.addTab(self.appspage,tabname)
+
+ #--- Libraries tab ---
+ tabname = i18n("Libraries")
+ if standalone:
+ libs1page = self.addGridPage(1,QGrid.Horizontal,tabname)
+ self.libspage = LibrariesPage(libs1page)
+ else:
+ self.libspage = LibrariesPage(tabcontrol)
+ self.libspage.setMargin(KDialog.marginHint())
+
+ # Connect all PYSIGNALs from LibrariesPage Widget to appropriate actions.
+ self.connect(self.libspage,PYSIGNAL("changedSignal()"),self._sendChangedSignal)
+
+ if not standalone:
+ tabcontrol.addTab(self.libspage,tabname)
+
+
+ def _buildGUI_noWine(self):
+ """ Displays an error that wine is not installed """
+ global standalone
+ if not standalone:
+ toplayout = QVBoxLayout( self, 0, KDialog.spacingHint() )
+
+ if not standalone:
+ nowinewarning = QLabel(self,"nowinewarning")
+ toplayout.addWidget(nowinewarning)
+ else:
+ vbox = self.addVBoxPage ("Wine Not Installed")
+ nowinewarning = QLabel(vbox,"nowinewarning")
+ nowinewarning.setText(i18n("It appears that you do not have wine " +\
+ "installed.\nwine " + \
+ "can be used to run some programs designed for " + \
+ "Windows.\nPlease " +\
+ "install the wine package to get this functionality."))
+ nowinewarning.setFrameStyle( QFrame.Box | QFrame.Raised )
+
+ def InstallWine(self):
+ """ Allows the user to enable the proper repositories and
+ install wine.
+ Currently Kubuntu specific, requires kdesudo, adept_batch
+ and software-properties-kde """
+ if not isroot:
+ if os.system("kdesudo \"software-properties-kde --enable-component universe\""):
+ KMessageBox.error(self, i18n("There was a problem running " + \
+ "software-properties-kde. Make sure " + \
+ "software-properties-kde is installed."))
+ elif os.system("kdesudo \"adept_batch install wine\""):
+ KMessageBox.error(self, i18n("There was a problem running " + \
+ "adept_batch. Make sure " + \
+ "Adept is installed."))
+ else:
+ if os.system("software-properties-kde --enable-component=universe" + \
+ " && adept_batch install wine"):
+ KMessageBox.error(self, i18n("There was a problem running " + \
+ "software-properties-kde and adept_batch. Make sure " + \
+ "Adept and software-properties-kde are installed."))
+
+ def CreateWindowsInstall(self,winepath = None):
+ if not winepath:
+ winepath = default_winepath
+ winewrite.CreateWineDrive(winepath)
+ wineread.SetWinePath(winepath)
+
+ drives = wineread.LoadDrives()
+ autodrives = drivedetect.autodetect(drives)
+ autoshelllinks = drivedetect.autodetectshelllinks()
+
+ if autodrives[0] == 1:
+ KMessageBox.sorry(self, \
+ i18n("There were not enough letters to add all the autodetected drives."))
+ drives = autodrives[1]
+ drives[26:] = autoshelllinks
+
+ winewrite.SetDriveMappings(drives)
+
+ winewrite.SetAudioDriver('alsa')
+
+ dsoundsettings = {"HardwareAcceleration":"Full",
+ "DefaultSampleRate":"44100",
+ "DefaultBitsPerSample":"8",
+ "EmulDriver":"N"}
+
+ winewrite.SetDSoundSettings(dsoundsettings)
+
+ windowsettings = {"DXGrab":"N",
+ "DesktopDoubleBuffered":"Y",
+ "Managed":"Y",
+ "Desktop":""}
+
+ winewrite.SetWindowSettings(windowsettings)
+
+ d3dsettings = {"VertexShaderMode":"hardware",
+ "PixelShaderMode":"Y",
+ "UseGLSL":"enabled"}
+
+ winewrite.SetD3DSettings(d3dsettings)
+
+ winewrite.SetWinVersion(wineread.winversions[1])
+
+ # Removed pending a patch to winebrowser
+ #winewrite.SetFirstBrowser("kfmclient exec")
+ #winewrite.SetFirstMailer("kfmclient exec")
+
+ def exec_loop(self,appname):
+ global application, programbase
+ if appname:
+ application = appname
+ KDialogBase.exec_loop(self)
+ else:
+ programbase.exec_loop(self)
+
+ def save(self): # KCModule
+ # Find out what's changed
+ generalchanged = self.generalpage.isChanged()
+ driveschanged = not application and self.drivespage.isChanged()
+ audiochanged = self.audiopage.isChanged()
+ graphicschanged = self.graphicspage.isChanged()
+ appearancechanged = not application and self.appearancepage.isChanged()
+ applicationschanged = not application and self.appspage.isChanged()
+ libschanged = self.libspage.isChanged()
+
+ # Apply changes for each tab
+ if generalchanged:
+ self.generalpage.applyChanges()
+ if driveschanged:
+ self.drivespage.applyChanges()
+ if audiochanged:
+ self.audiopage.applyChanges()
+ if graphicschanged:
+ self.graphicspage.applyChanges()
+ if appearancechanged:
+ self.appearancepage.applyChanges()
+ if applicationschanged:
+ self.appspage.applyChanges()
+ if libschanged:
+ self.libspage.applyChanges()
+
+ self._sendChangedSignal()
+
+ def slotApply(self): # KDialogBase
+ self.save()
+
+ def slotClose(self): # KDialogBase
+ KDialogBase.slotClose(self)
+
+ def load(self): # KCModule
+ self.__reset()
+ self._sendChangedSignal()
+
+ def slotUser1(self): # Reset button, KDialogBase
+ self.load()
+
+ def slotUser2(self): # About button, KDialogBase
+ self.aboutus.show()
+
+ def __reset(self):
+ # Reset each configuration page
+ if not application:
+ self.drivespage.reset()
+ self.audiopage.reset()
+ self.graphicspage.reset()
+ self.appearancepage.reset()
+ if not application:
+ self.appspage.reset()
+ self.libspage.reset()
+
+ # Kcontrol expects updates about whether the contents have changed.
+ # Also we fake the Apply and Reset buttons here when running outside kcontrol.
+ def _sendChangedSignal(self):
+ global standalone
+
+ changed = False
+ changed = changed or (not application and self.drivespage.isChanged()) or \
+ self.audiopage.isChanged() \
+ or self.generalpage.isChanged() or \
+ (not application and self.appspage.isChanged()) or \
+ self.libspage.isChanged() or \
+ (not application and self.appearancepage.isChanged())
+ graphicschanged = self.graphicspage.isChanged()
+ changed = changed or graphicschanged
+
+ if standalone:
+ self.enableButton(KDialogBase.User1,changed) # Reset button
+ self.enableButtonApply(changed) # Apply button
+ else:
+ self.emit(SIGNAL("changed(bool)"), (changed,) )
+
+############################################################################
+''' Not used.
+class ErrorPage(QWidget):
+ """
+ Displayed when there is no fake Windows drive
+ """
+
+ def __init__(self,parent = None, name = None, parentapp = None, modal = 0,fl=0):
+ QWidget.__init__(self,parent)
+
+ if not name:
+ self.setName("ErrorPage")
+
+ self.parent = parentapp
+
+ self.top_layout = QVBoxLayout(self,0,0,"ErrorPageLayout")
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ self.top_layout.addWidget(vbox)
+
+ errortext = QLabel(vbox,"errortext")
+ errortext.setText(i18n("You need to set up a " +\
+ "fake Windows drive\n before you can edit settings or run " +\
+ "Windows applications."))
+
+ self.createbutton = KPushButton(i18n("Create Fake Windows Drive"),vbox)
+ self.connect(self.createbutton,SIGNAL("clicked()"),self.slotCreateClicked)
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ self.top_layout.addItem(bottomspacer)
+
+ self.clearWState(Qt.WState_Polished)
+
+ def slotCreateClicked(self):
+ self.parent.CreateWindowsInstall()
+ self.parent._buildGUI()
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+'''
+
+##############################################################################
+
+class DrivesPage(QWidget):
+ """
+ A TabPage with configuration for drive mappings
+ """
+
+ types = (
+ (0,i18n("Autodetect"),"auto"),
+ (1,i18n("Local Hard Disk"),"hd"),
+ (2,i18n("Network Share"),"network"),
+ (3,i18n("Floppy Disk"),"floppy"),
+ (4,i18n("CD-ROM"),"cdrom"))
+
+ typesdic = {
+ 'auto':0,
+ 'hd':1,
+ 'network':2,
+ 'floppy':3,
+ 'cdrom':4}
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ QWidget.__init__(self,parent)
+
+ self.updatingGUI = True
+
+ self.selecteddriveid = None
+
+ if not name:
+ self.setName("DrivesTab")
+
+ self.drives = wineread.LoadDrives()
+ self.drives[26:] = wineread.GetShellLinks()
+
+ drives_tab_layout = QVBoxLayout(self,0,0,"DrivesTabLayout")
+ self.top_layout = drives_tab_layout
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ drives_tab_layout.addWidget(vbox)
+
+ # -- Drive mappings group
+ self.mappings_group_box = QHGroupBox(vbox)
+ self.mappings_group_box.setTitle(i18n("Drive and Directory Mappings"))
+ self.mappings_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.mappings_group_box.setInsideMargin(KDialog.marginHint())
+
+ vbox2 = QVBox(self.mappings_group_box)
+ vbox2.setSpacing(KDialog.spacingHint())
+
+ spacer = QWidget(vbox2)
+ vbox2.setStretchFactor(spacer,1)
+
+ self.driveslist = KListView(vbox2)
+ self.driveslist.addColumn(i18n("Directory"))
+ self.driveslist.addColumn(i18n("Links to"))
+ self.driveslist.setAllColumnsShowFocus(True)
+ self.driveslist.setSelectionMode(QListView.Single)
+ self.driveslist.setSorting(-1,True)
+
+ self.connect(self.driveslist, SIGNAL("selectionChanged(QListViewItem *)"), self.slotListClicked)
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.addbutton = KPushButton(i18n("Add Drive..."),hbox)
+ self.connect(self.addbutton,SIGNAL("clicked()"),self.slotAddClicked)
+
+ self.removebutton = KPushButton(i18n("Remove Drive"),hbox)
+ self.connect(self.removebutton,SIGNAL("clicked()"),self.slotRemoveClicked)
+
+ spacer = QWidget(hbox)
+ hbox.setStretchFactor(spacer,1)
+
+ self.autobutton = KPushButton(i18n("Autodetect"),hbox)
+ self.connect(self.autobutton,SIGNAL("clicked()"),self.slotAutoClicked)
+
+ hbox2 = QHBox(vbox2)
+ hbox2.setSpacing(KDialog.spacingHint())
+
+ pathtext = QLabel(hbox2,"pathtext")
+ pathtext.setText(i18n("Path:"))
+
+ self.fsfolderedit = KLineEdit("/",hbox2)
+ self.urlcompletion = KURLCompletion(KURLCompletion.DirCompletion)
+ self.fsfolderedit.setCompletionObject(self.urlcompletion)
+ self.fsfolderedit.setCompletionMode(KGlobalSettings.CompletionPopup)
+ self.connect(self.fsfolderedit,SIGNAL("textChanged(const QString &)"),self.slotFolderEdited)
+
+ self.browsebutton = KPushButton(i18n("Browse"),hbox2)
+ self.connect(self.browsebutton,SIGNAL("clicked()"),self.slotBrowseClicked)
+
+ hbox2 = QHBox(vbox2)
+ hbox2.setSpacing(KDialog.spacingHint())
+
+ self.typetext = QLabel(hbox2,"typetext")
+ self.typetext.setText(i18n("Type:"))
+
+ self.typecombo = KComboBox(0,hbox2,"typecombo")
+ self.fillTypeCombo(self.typecombo)
+ self.connect(self.typecombo,SIGNAL("activated(int)"),self.slotTypeActivated)
+
+ spacer = QWidget(hbox2)
+ hbox2.setStretchFactor(spacer,1)
+
+ hbox2 = QHBox(vbox2)
+ hbox2.setSpacing(KDialog.spacingHint())
+
+ self.infotext1 = QLabel(hbox2,"infotext1")
+
+ hbox2 = QHBox(vbox2)
+ hbox2.setSpacing(KDialog.spacingHint())
+
+ self.infotext2 = QLabel(hbox2,"infotext2")
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ drives_tab_layout.addItem(bottomspacer)
+
+ self.changed = False
+
+ self.clearWState(Qt.WState_Polished)
+
+ self.updatingGUI=False
+
+ self.updateDrivesList()
+
+ def reset(self):
+ self.drives = wineread.LoadDrives()
+ self.drives[26:] = wineread.GetShellLinks()
+ self.updatingGUI=True
+ self.updateDrivesList()
+ self.updatingGUI=False
+ self.changed = False
+
+ def isChanged(self):
+ """ Check if something has changed since startup or last apply(). """
+ return self.changed
+
+ def applyChanges(self):
+ """ Apply the changes """
+ winewrite.SetDriveMappings(self.drives)
+ self.reset()
+
+ def updateChanges(self):
+ """ Update the GUI and send the signal that changes were made """
+ self.updatingGUI=True
+ self.updateDrivesList()
+ self.updatingGUI=False
+ self.changed = True
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotListClicked(self,item):
+ """ Show the drive information and settings for the newly selected drive """
+ if self.updatingGUI==False:
+ for driveid in self.drivesToListItems:
+ if self.drivesToListItems[driveid]==item:
+ self.updatingGUI = True
+ self.__selectDrive(driveid)
+ self.updatingGUI = False
+ return
+
+ def slotFolderChanged(self,folder):
+ """ Change the directory mapping when a new one is entered in the URL box """
+ self.drives[self.selecteddriveid][2] = unicode(folder)
+ self.updateChanges()
+
+ def slotFolderEdited(self,folder):
+ """ Change the directory mapping when a new one is entered manually in the URL box """
+ if not self.updatingGUI:
+ self.urlcompletion.makeCompletion("") # Doesn't seem like this should be required.
+ self.slotFolderChanged(folder)
+
+ def slotBrowseClicked(self):
+ """ Bring up a browse window to choose a ndew mapping directory """
+ mapping = KFileDialog.getExistingDirectory(wineread.winepath,self,i18n("Drive Mapping"))
+ if mapping:
+ mapping = unicode(mapping)
+ self.drives[self.selecteddriveid][2] = mapping
+ self.updateChanges()
+
+ def slotAddClicked(self):
+ """
+ Let the user choose a directory to map a new drive to.
+ Uses the next available drive letter. """
+ # TODO: Maybe the user should choose the drive letter?
+ for drive in self.drives[2:26]:
+ if drive[2]:
+ continue
+ else:
+ mapping = KFileDialog.getExistingDirectory(wineread.winepath,self,i18n("Drive Mapping"))
+ if mapping:
+ mapping = unicode(mapping)
+ drive[2] = mapping
+ else:
+ return
+ self.selecteddriveid = drive[0]
+ break
+ else:
+ KMessageBox.sorry(self, \
+ i18n("Can't add another drive. There can only be 26, for letters A-Z"))
+ return
+
+ self.updateChanges()
+
+ def slotRemoveClicked(self):
+ """ Removes the currently selected drive """
+ if self.selecteddriveid == 2: # Drive C:
+ if KMessageBox.warningContinueCancel(self, \
+ i18n("Are you sure you want to delete drive C:?\n\n"\
+ "Most Windows applications expect drive C: to exist, "\
+ "and will die messily if it doesn't. If you proceed "\
+ "remember to recreate it!"),\
+ i18n("Warning")) != KMessageBox.Continue:
+ return
+ self.drives[self.selecteddriveid][2:4] = ("","")
+ self.selecteddriveid -= 1 # Not quite correct, should select previous drive.
+ self.updateChanges()
+
+ def slotAutoClicked(self):
+ """
+ Autodetects a default set of drives from /etc/fstab
+ Allows the user to start with a fresh list of drives or append to the current one
+ """
+ automethod = KMessageBox.questionYesNoCancel(self, \
+ i18n("Would you like to remove the current set of drives?"),\
+ i18n("Drive Autodetection"))
+ if automethod == KMessageBox.Yes:
+ autodrives = drivedetect.autodetect()
+ autoshelllinks = drivedetect.autodetectshelllinks()
+ elif automethod == KMessageBox.No:
+ autodrives = drivedetect.autodetect(self.drives[:26])
+ autoshelllinks = drivedetect.autodetectshelllinks(self.drives[26:])
+ else:
+ return
+
+ if autodrives[0] == 1:
+ KMessageBox.sorry(self, \
+ i18n("There were not enough letters to add all the autodetected drives."))
+ self.drives[0:26] = autodrives[1]
+ self.drives[26:] = autoshelllinks
+
+ self.updateChanges()
+
+ def slotTypeActivated(self,index):
+ self.__selectType(self.types[index][2])
+ self.updateChanges()
+
+ def fillTypeCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for drivetype in self.types:
+ combo.insertItem(drivetype[1])
+
+ def __selectType(self,typename):
+ if typename:
+ typeid = self.typesdic[typename]
+ else:
+ typeid = self.typesdic['auto']
+ self.drives[self.selecteddriveid][3] = typename
+ self.typecombo.setCurrentItem(typeid)
+
+ def updateDrivesList(self):
+ """ Updates the displayed list of drives """
+ self.driveslist.clear()
+ self.drivesToListItems = {}
+ firstselecteddriveid = None
+ lastdriveid = None
+
+ for driveid, driveletter, mapping, drivetype, drivelabel, serial in reversed(self.drives):
+ if mapping or drivelabel:
+ lvi = QListViewItem(self.driveslist,driveletter,mapping)
+ self.drivesToListItems[driveid] = lvi
+ if self.selecteddriveid==driveid:
+ firstselecteddriveid = driveid
+ lastdriveid = driveid
+ else:
+ continue
+
+ if firstselecteddriveid==None:
+ firstselecteddriveid = lastdriveid
+
+ self.selecteddriveid = firstselecteddriveid
+ self.__selectDrive(self.selecteddriveid)
+ self.driveslist.ensureItemVisible(self.driveslist.currentItem())
+
+ def __selectDrive(self,driveid):
+ """ Updates the GUI for a newly selected drive """
+ self.selecteddriveid = driveid
+ lvi = self.drivesToListItems[driveid]
+ self.driveslist.setSelected(lvi,True)
+ self.driveslist.setCurrentItem(lvi)
+
+ self.fsfolderedit.setText(self.drives[driveid][2])
+ if self.drives[driveid][3] == 'shellfolder':
+ self.typecombo.insertItem(i18n("Shell Folder"))
+ self.typecombo.setCurrentItem(5)
+ self.typecombo.setEnabled(False)
+
+ self.removebutton.setEnabled(False)
+
+ self.infotext1.setText(unicode(i18n("Windows path: ")) + self.drives[driveid][4])
+
+ # It seems some old versions of wine didn't store the shell folders in the same place
+ if self.drives[driveid][5] != self.drives[driveid][4]:
+ changeregistryshell = KMessageBox.warningYesNo(self, \
+ i18n("The " + self.drives[driveid][1] + " folder is currently located in\n" + \
+ self.drives[driveid][5] + "\nIt is recommended that it is put in the default " + \
+ "location in\n" + wineread.defaultwinfolderspath + "\nWould you like to move it there?"),\
+ i18n("Shell Folder Mapping"))
+ changeregistryshell = changeregistryshell == KMessageBox.Yes
+
+ if changeregistryshell:
+ self.drives[driveid][5] = self.drives[driveid][4]
+ self.changed = True
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ if self.drives[driveid][2] == wineread.profilesdirectory + self.drives[driveid][1]:
+ realfolderwarning = KMessageBox.information(self, \
+ i18n(self.drives[driveid][1] + " is an actual folder and is not linked elsewhere." + \
+ " Remapping it will create a backup of the directory in " + \
+ wineread.profilesdirectory),\
+ i18n("Shell Folder Mapping"))
+ else:
+ if self.typecombo.count() > 5:
+ self.typecombo.removeItem(5)
+ self.typecombo.setEnabled(True)
+ self.__selectType(self.drives[driveid][3])
+
+ self.removebutton.setEnabled(True)
+
+ if self.drives[driveid][4]:
+ self.infotext1.setText(unicode(i18n("Label: ")) + self.drives[driveid][4])
+ else:
+ self.infotext1.setText("")
+ if self.drives[driveid][5]:
+ self.infotext2.setText(unicode(i18n("Serial: ")) + self.drives[driveid][5])
+ else:
+ self.infotext2.setText("")
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+############################################################################
+class AudioPage(QWidget):
+ driversdic = {
+ "":i18n("None - Disable Sound"),
+ "alsa":"ALSA",
+ "arts":"aRts",
+ "esd":"EsounD",
+ "oss":"OSS",
+ "jack":"JACK",
+ "nas":"NAS",
+ "coreaudio":"CoreAudio"}
+
+ drivers = ("","alsa","arts","esd","oss","jack","nas","coreaudio")
+
+ accel = (
+ (0,i18n("Full")),
+ (1,i18n("Standard")),
+ (2,i18n("Basic")),
+ (3,i18n("Emulation")))
+
+ samplerates = (
+ (0,"48000",48000),
+ (1,"44100",44100),
+ (2,"22050",22050),
+ (3,"16000",16000),
+ (4,"11025",11025),
+ (5,"8000",8000))
+
+ bitspersample = (
+ (0,"8",8),
+ (1,"16",16))
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ global application
+ QWidget.__init__(self,parent)
+
+ if not name:
+ self.setName("AudioTab")
+
+ audio_tab_layout = QVBoxLayout(self,0,0,"AudioTabLayout")
+ self.top_layout = audio_tab_layout
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ audio_tab_layout.addWidget(vbox)
+
+ if application:
+ appwarning = QLabel(vbox,"appwarning")
+ appwarning.setText(i18n("Application specific settings for <b>" +\
+ application + "</b><p>Changing a setting here will permanently " +\
+ "make that setting independent of settings for all other " +\
+ "applications.</p>"))
+ appwarning.setFrameStyle( QFrame.Box | QFrame.Raised )
+
+ # -- Drivers group
+ self.driver_group_box = QHGroupBox(vbox)
+ self.driver_group_box.setTitle(i18n("Driver Selection"))
+ self.driver_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.driver_group_box.setInsideMargin(KDialog.marginHint())
+
+ vbox2 = QVBox(self.driver_group_box)
+ vbox2.setSpacing(KDialog.spacingHint())
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ drivertext = QLabel(hbox,"drivertext")
+ drivertext.setText(i18n("Audio Driver:"))
+
+ self.drivercombo = KComboBox(0,hbox,"drivercombo")
+ self.fillDriverCombo(self.drivercombo)
+ self.connect(self.drivercombo,SIGNAL("activated(int)"),self.slotDriverActivated)
+
+ QToolTip.add(hbox, i18n("Choose an audio driver. Not all audio " +\
+ "drivers are available."))
+ spacer = QWidget(hbox)
+ hbox.setStretchFactor(spacer,1)
+
+ if application:
+ self.driver_group_box.hide()
+
+ # -- DirectSound Settings group
+ self.dsound_group_box = QHGroupBox(vbox)
+ self.dsound_group_box.setTitle(i18n("DirectSound"))
+ self.dsound_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.dsound_group_box.setInsideMargin(KDialog.marginHint())
+
+ vbox2 = QVBox(self.dsound_group_box)
+ vbox2.setSpacing(KDialog.spacingHint())
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ acceltext = QLabel(hbox,"acceltext")
+ acceltext.setText(i18n("Hardware Acceleration:"))
+
+ self.accelcombo = KComboBox(0,hbox,"accelcombo")
+ self.fillAccelCombo(self.accelcombo)
+ self.connect(self.accelcombo,SIGNAL("activated(int)"),self.slotAccelActivated)
+
+ spacer = QWidget(hbox)
+ hbox.setStretchFactor(spacer,1)
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.overridecheckbox = QCheckBox(i18n("Override KDE Sample Rate"),hbox)
+ hbox.setStretchFactor(self.overridecheckbox,0)
+ self.connect(self.overridecheckbox,SIGNAL("toggled(bool)"),self.slotOverrideKDESoundToggled)
+ self.overridecheckbox.hide()
+
+ self.sampleratehbox = QHBox(vbox2)
+ self.sampleratehbox.setSpacing(KDialog.spacingHint())
+
+ sampletext = QLabel(self.sampleratehbox,"sampletext")
+ sampletext.setText(i18n("Default Sample Rate:"))
+
+ self.samplecombo = KComboBox(0,self.sampleratehbox,"samplecombo")
+ self.fillSampleCombo(self.samplecombo)
+ self.connect(self.samplecombo,SIGNAL("activated(int)"),self.slotSampleActivated)
+
+ bitstext = QLabel(self.sampleratehbox,"bitstext")
+ bitstext.setText(i18n("Default Bits Per Sample:"))
+
+ self.bitscombo = KComboBox(0,self.sampleratehbox,"bitscombo")
+ self.fillBitsCombo(self.bitscombo)
+ self.connect(self.bitscombo,SIGNAL("activated(int)"),self.slotBitsActivated)
+
+ spacer = QWidget(self.sampleratehbox)
+ self.sampleratehbox.setStretchFactor(spacer,1)
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.drvemucheckbox = QCheckBox(i18n("Driver Emulation"),hbox)
+ hbox.setStretchFactor(self.drvemucheckbox,0)
+ self.connect(self.drvemucheckbox,SIGNAL("toggled(bool)"), self.slotDriverEmulToggled)
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ audio_tab_layout.addItem(bottomspacer)
+
+ self.reset()
+
+ self.clearWState(Qt.WState_Polished)
+
+ def fillDriverCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for driver in self.drivers:
+ combo.insertItem(self.driversdic[driver])
+
+ def fillAccelCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for accel in self.accel:
+ combo.insertItem(accel[1])
+
+ def fillSampleCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for rate in self.samplerates:
+ combo.insertItem(rate[1])
+
+ def fillBitsCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for bits in self.bitspersample:
+ combo.insertItem(bits[1])
+
+ def isChanged(self):
+ changed = False
+ changed = changed or (not application and self.currentdriver != self.originaldriver)
+ changed = changed or self.currentaccel != self.originalaccel
+ changed = changed or self.currentsamplerate != self.originalsamplerate
+ changed = changed or self.currentbitspersample != self.originalbitspersample
+ changed = changed or self.currentemuldriver != self.originalemuldriver
+ return changed
+
+ def reset(self):
+ if not application:
+ self.currentdriver = wineread.GetAudioDriver()
+ self.originaldriver = self.currentdriver
+ self.__selectDriver(self.currentdriver)
+
+ dsoundsettings = wineread.GetDSoundSettings(application)
+ globaldsoundsettings = wineread.GetDSoundSettings()
+
+ self.currentaccel = dsoundsettings.get("HardwareAcceleration",\
+ globaldsoundsettings.get("HardwareAcceleration", "Full"))
+ self.originalaccel = self.currentaccel
+ self.__selectAccel(self.currentaccel)
+
+ self.currentsamplerate = dsoundsettings.get("DefaultSampleRate",\
+ globaldsoundsettings.get("DefaultSampleRate", "44100"))
+ self.originalsamplerate = self.currentsamplerate
+ self.__selectSampleRate(self.currentsamplerate)
+
+ self.currentbitspersample = dsoundsettings.get("DefaultBitsPerSample",\
+ globaldsoundsettings.get("DefaultBitsPerSample","16"))
+ self.originalbitspersample = self.currentbitspersample
+ self.__selectBitsPerSample(self.currentbitspersample)
+
+ self.currentemuldriver = dsoundsettings.get("EmulDriver",\
+ globaldsoundsettings.get("EmulDriver", "N"))
+ self.originalemuldriver = self.currentemuldriver
+ self.__setDriverEmul(self.currentemuldriver)
+
+ self.currentkdeoverride = True
+ self.originalkdeoverride = self.currentkdeoverride
+ self.__setOverrideKDESound(self.currentkdeoverride)
+
+ def applyChanges(self):
+ if not application:
+ winewrite.SetAudioDriver(self.currentdriver)
+
+ dsoundsettings = {"HardwareAcceleration":self.currentaccel,
+ "DefaultSampleRate":self.currentsamplerate,
+ "DefaultBitsPerSample":self.currentbitspersample,
+ "EmulDriver":self.currentemuldriver}
+
+ winewrite.SetDSoundSettings(dsoundsettings, application)
+
+ self.reset()
+
+ def slotDriverActivated(self,driverid):
+ self.currentdriver = self.drivers[driverid]
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotAccelActivated(self,accelid):
+ self.currentaccel = self.accel[accelid][1]
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotSampleActivated(self,sampleid):
+ self.currentsamplerate = self.samplerates[sampleid][1]
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotBitsActivated(self,bitsid):
+ self.currentbitspersample = self.bitspersample[bitsid][1]
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotDriverEmulToggled(self,driveremul):
+ if driveremul:
+ self.currentemuldriver = 'Y'
+ else:
+ self.currentemuldriver = 'N'
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotOverrideKDESoundToggled(self,override):
+ self.__setOverrideKDESound(override)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def __selectDriver(self,drivername):
+ """
+ Sets the current driver and selects it in the combo box
+ Assumes drivername is a valid driver
+ """
+ driverid = 0
+ for driver in self.drivers:
+ if driver == drivername:
+ break
+ else:
+ driverid += 1
+
+ self.currentdriver = drivername
+ self.drivercombo.setCurrentItem(driverid)
+
+ def __selectAccel(self,accelmode):
+ """
+ Sets the current acceleration mode and selects it in the combo box
+ Assumes accelmode i sa valid acceleration mode
+ """
+ accelid = 0
+ for accelmode1 in self.accel:
+ if accelmode1[1] == accelmode:
+ break
+ else:
+ accelid += 1
+
+ self.currentaccel = accelmode
+ self.accelcombo.setCurrentItem(accelid)
+
+ def __selectSampleRate(self,samplerate):
+ """
+ Sets the current acceleration mode and selects it in the combo box
+ Assumes samplerate is a valid sample rate
+ """
+ sampleid = 0
+ for samplerate1 in self.samplerates:
+ if samplerate1[1] == samplerate:
+ break
+ else:
+ sampleid += 1
+
+ self.currentsamplerate = samplerate
+ self.samplecombo.setCurrentItem(sampleid)
+
+ def __selectBitsPerSample(self,bits):
+ """
+ Sets the current acceleration mode and selects it in the combo box
+ Assumes bits is a valid value for bits per sample
+ """
+ bitsid = 0
+ for bits1 in self.bitspersample:
+ if bits1[1] == bits:
+ break
+ else:
+ bitsid += 1
+
+ self.currentbitspersample = bits
+ self.bitscombo.setCurrentItem(bitsid)
+
+ def __setDriverEmul(self,driveremul):
+ """ Enables/disables the driver emulation mode """
+ self.currentdriveremul = driveremul
+ driveremul = driveremul != 'N'
+ self.drvemucheckbox.setChecked(driveremul)
+
+ def __setOverrideKDESound(self,override):
+ """ Enables/disables use of KDE's (aRts) sample rate settings """
+ self.currentkdeoverride = override
+ self.sampleratehbox.setEnabled(override)
+ self.overridecheckbox.setChecked(override)
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+
+############################################################################
+class GraphicsPage(QWidget):
+
+ # Mapping values in seconds to human-readable labels.
+ vertexshadersupport = (
+ (0,i18n("Hardware")),
+ (1,i18n("None")),
+ (2,i18n("Emulation")))
+
+ vertexshadersupportdic = {
+ "hardware":0,
+ "none":1,
+ "emulation":2}
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ global currentallowwm
+ QWidget.__init__(self,parent)
+
+ if not name:
+ self.setName("GraphicsTab")
+
+ graphics_tab_layout = QVBoxLayout(self,0,0,"GraphicsTabLayout")
+ self.top_layout = graphics_tab_layout
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ graphics_tab_layout.addWidget(vbox)
+
+ if application:
+ appwarning = QLabel(vbox,"appwarning")
+ appwarning.setText(i18n("Application specific settings for <b>" +\
+ application + "</b><p>Changing a setting here will permanently " +\
+ "make that setting independent of settings for all other " +\
+ "applications.</p>"))
+ appwarning.setFrameStyle( QFrame.Box | QFrame.Raised )
+
+ # -- Window settings group
+ self.windows_group_box = QHGroupBox(vbox)
+ self.windows_group_box.setTitle(i18n("Window Settings"))
+ self.windows_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.windows_group_box.setInsideMargin(KDialog.marginHint())
+
+ vbox2 = QVBox(self.windows_group_box)
+ vbox2.setSpacing(KDialog.spacingHint())
+
+ self.allowcursorcheckbox = QCheckBox(i18n("Allow DirectX applications to stop the mouse leaving their window"),vbox2)
+ self.connect(self.allowcursorcheckbox,SIGNAL("toggled(bool)"), self.slotAllowCursorToggled)
+
+ self.dubbuffercheckbox = QCheckBox(i18n("Enable desktop double buffering"),vbox2)
+ self.connect(self.dubbuffercheckbox,SIGNAL("toggled(bool)"), self.slotDubBufferToggled)
+
+ self.allowwmcheckbox = QCheckBox(i18n("Allow the window manager to control the windows"),vbox2)
+ self.connect(self.allowwmcheckbox,SIGNAL("toggled(bool)"), self.slotAllowWMToggled)
+
+ QToolTip.add(self.allowwmcheckbox, \
+ i18n("<p>If windows are managed by your window manager, then they" +\
+ " will have the standard borders, they will respect your virtual" +\
+ " desktop and appear in your window list.\n</p><p>" +\
+ "If the windows are unmanaged, they will be disconnected from your" +\
+ " window manager. This will mean the windows do not integrate as" +\
+ " closely with your desktop, but the emulation will be more" +\
+ " accurate so it can help some programs work better.</p>"))
+
+ self.showdragcheckbox = QCheckBox(i18n("Display window contents while dragging"),vbox2)
+ self.connect(self.showdragcheckbox,SIGNAL("toggled(bool)"), self.slotShowDragToggled)
+
+ self.emudesktopcheckbox = QCheckBox(i18n("Emulate a virtual desktop"),vbox2)
+ self.connect(self.emudesktopcheckbox,SIGNAL("toggled(bool)"), self.slotEmuDesktopToggled)
+
+ self.desksizehbox = QHBox(vbox2)
+ self.desksizehbox.setSpacing(KDialog.spacingHint())
+
+ desksizetext = QLabel(self.desksizehbox,"desksizetext")
+ desksizetext.setText(i18n("Desktop size:"))
+
+ self.xsizeedit = KLineEdit("640",self.desksizehbox)
+ self.xsizeedit.setValidator(QIntValidator(self.xsizeedit))
+ self.connect(self.xsizeedit,SIGNAL("textChanged(const QString &)"),self.slotDesktopSizeChanged)
+ bytext = QLabel(self.desksizehbox,"bytext")
+ bytext.setText(i18n("x"))
+ self.ysizeedit = KLineEdit("480",self.desksizehbox)
+ self.ysizeedit.setValidator(QIntValidator(self.ysizeedit))
+ self.connect(self.ysizeedit,SIGNAL("textChanged(const QString &)"),self.slotDesktopSizeChanged)
+
+ spacer = QWidget(self.desksizehbox)
+ self.desksizehbox.setStretchFactor(spacer,1)
+
+ QToolTip.add(self.emudesktopcheckbox,
+ i18n("<p>You can choose to emulate a Windows desktop, where all" +\
+ " the windows are confined to one 'virtual screen', or you" +\
+ " can have the windows placed on your standard desktop.</p>"))
+ QToolTip.add(self.desksizehbox, QToolTip.textFor(self.emudesktopcheckbox))
+
+ if application:
+ self.emudesktopcheckbox.hide()
+ self.desksizehbox.hide()
+ self.showdragcheckbox.hide()
+
+ # -- Direct3D settings group
+ self.d3d_group_box = QHGroupBox(vbox)
+ self.d3d_group_box.setTitle(i18n("Direct3D"))
+ self.d3d_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.d3d_group_box.setInsideMargin(KDialog.marginHint())
+
+ vbox2 = QVBox(self.d3d_group_box)
+ vbox2.setSpacing(KDialog.spacingHint())
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ vertexshadertext = QLabel(hbox,"vertexshadertext")
+ vertexshadertext.setText(i18n("Vertex Shader Support:"))
+
+ self.accelcombo = KComboBox(0,hbox,"accelcombo")
+ self.fillCombo(self.accelcombo)
+ self.connect(self.accelcombo,SIGNAL("activated(int)"),self.slotVertexShaderModeActivated)
+
+ spacer = QWidget(hbox)
+ hbox.setStretchFactor(spacer,1)
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.pixelshadercheckbox = QCheckBox(i18n("Allow Pixel Shader (if supported by hardware)"),hbox)
+ self.connect(self.pixelshadercheckbox,SIGNAL("toggled(bool)"), self.slotPixelShaderModeToggled)
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.glslcheckbox = QCheckBox(i18n("Use GL Shader Language"),hbox)
+ self.connect(self.glslcheckbox,SIGNAL("toggled(bool)"), self.slotGLSLToggled)
+
+ QToolTip.add(hbox,
+ i18n("<p>This enables the use of GL Shading Language for vertex" +\
+ " and pixel shaders, as long as the hardware supports it." +\
+ " This is experimental.</p>"))
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ graphics_tab_layout.addItem(bottomspacer)
+
+ self.reset()
+
+ self.clearWState(Qt.WState_Polished)
+
+ def fillCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for accel in self.vertexshadersupport:
+ combo.insertItem(accel[1])
+
+ def isChanged(self):
+ changed = False
+ changed = changed or self.originalallowcursor != self.currentallowcursor
+ changed = changed or self.originaldubbuffer != self.currentdubbuffer
+ changed = changed or self.originalallowwm != currentallowwm
+ changed = changed or (not application and \
+ self.originalemudesktop != self.currentemudesktop)
+ changed = changed or self.originalvertexshadermode != self.currentvertexshadermode
+ changed = changed or self.originalpixelshadermode != self.currentpixelshadermode
+ changed = changed or self.originalglsl != self.currentglsl
+ changed = changed or (not application and \
+ self.originalshowdrag != self.currentshowdrag)
+ return changed
+
+ def reset(self):
+ """ Resets the settings to ones read from the registry """
+ global currentallowwm
+ settings = wineread.GetWindowSettings(application)
+ globalsettings = wineread.GetWindowSettings()
+
+ self.currentallowcursor = settings.get("DXGrab",\
+ globalsettings.get("DXGrab",'N'))
+ self.originalallowcursor = self.currentallowcursor
+ self.__setAllowCursor(self.currentallowcursor)
+
+ self.currentdubbuffer = settings.get("DesktopDoubleBuffered",\
+ globalsettings.get("DesktopDoubleBuffered",'Y'))
+ self.originaldubbuffer = self.currentdubbuffer
+ self.__setDubBuffer(self.currentdubbuffer)
+
+ currentallowwm = settings.get("Managed",\
+ globalsettings.get("Managed",'Y'))
+ self.originalallowwm = currentallowwm
+
+ if not application:
+ self.currentemudesktop = settings.get("Desktop","")
+ self.originalemudesktop = self.currentemudesktop
+ self.__setEmuDesktop(self.currentemudesktop)
+ self.__setAllowWM(currentallowwm)
+
+ d3dsettings = wineread.GetD3DSettings(application)
+ globald3dsettings = wineread.GetD3DSettings()
+
+ self.currentvertexshadermode = d3dsettings.get("VertexShaderMode",\
+ globald3dsettings.get("VertexShaderMode","hardware"))
+ self.originalvertexshadermode = self.currentvertexshadermode
+ self.__selectVertexShaderMode(self.currentvertexshadermode)
+
+ self.currentpixelshadermode = d3dsettings.get("PixelShaderMode",\
+ globald3dsettings.get("PixelShaderMode","enabled"))
+ self.originalpixelshadermode = self.currentpixelshadermode
+ self.__setPixelShaderMode(self.currentpixelshadermode)
+
+ self.currentglsl = d3dsettings.get("UseGLSL",\
+ globald3dsettings.get("UseGLSL","disabled"))
+ self.originalglsl = self.currentglsl
+ self.__setGLSL(self.currentglsl)
+
+ if not application:
+ cpdesktopsettings = wineread.GetDesktopSettings()
+
+ self.currentshowdrag = cpdesktopsettings.get("DragFullWindows","0")
+ self.originalshowdrag = self.currentshowdrag
+ self.__setShowDrag(self.currentshowdrag)
+
+ def applyChanges(self):
+ """ Applies the changes to wine's configuration """
+ settings = {"DXGrab":self.currentallowcursor,
+ "DesktopDoubleBuffered":self.currentdubbuffer,
+ "Managed":currentallowwm}
+
+ if not application:
+ settings["Desktop"] = self.currentemudesktop
+
+ winewrite.SetWindowSettings(settings, application)
+
+ d3dsettings = {"VertexShaderMode":self.currentvertexshadermode,
+ "PixelShaderMode":self.currentpixelshadermode,
+ "UseGLSL":self.currentglsl}
+
+ winewrite.SetD3DSettings(d3dsettings, application)
+
+ if not application:
+ cpdesktopsettings = {"DragFullWindows":self.currentshowdrag}
+
+ winewrite.SetDesktopSettings(cpdesktopsettings)
+
+ self.reset()
+
+ def slotAllowCursorToggled(self,allow):
+ if allow:
+ self.currentallowcursor = 'Y'
+ else:
+ self.currentallowcursor = 'N'
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotDubBufferToggled(self,dub):
+ if dub:
+ self.currentdubbuffer = 'Y'
+ else:
+ self.currentdubbuffer = 'N'
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotAllowWMToggled(self,allow):
+ global currentallowwm
+ if allow:
+ currentallowwm = 'Y'
+ else:
+ currentallowwm = 'N'
+ if not application:
+ if allow and self.currentemudesktop == "":
+ self.showdragcheckbox.setEnabled(False)
+ else:
+ self.showdragcheckbox.setEnabled(True)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotShowDragToggled(self,show):
+ if show:
+ self.currentshowdrag = '2'
+ else:
+ self.currentshowdrag = '0'
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotEmuDesktopToggled(self,emudesktop):
+ if emudesktop:
+ self.currentemudesktop = unicode(self.xsizeedit.text()) + 'x' + str(self.ysizeedit.text())
+ else:
+ self.currentemudesktop = ""
+ self.__setEmuDesktop(self.currentemudesktop)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotDesktopSizeChanged(self,size):
+ self.slotEmuDesktopToggled(True)
+
+ def slotVertexShaderModeActivated(self,modeid):
+ mode = self.vertexshadersupport[modeid][1][0].lower() + self.vertexshadersupport[modeid][1][1:]
+ self.currentvertexshadermode = mode
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotPixelShaderModeToggled(self,mode):
+ if mode:
+ self.currentpixelshadermode = 'enabled'
+ else:
+ self.currentpixelshadermode = 'disabled'
+
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotGLSLToggled(self,mode):
+ if mode:
+ self.currentglsl = 'enabled'
+ else:
+ self.currentglsl = 'disabled'
+
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def __setAllowCursor(self, allow):
+ self.currentallowcursor = allow
+ allow = allow != 'N'
+ self.allowcursorcheckbox.setChecked(allow)
+
+ def __setDubBuffer(self, dub):
+ self.currentdubbuffer = dub
+ dub = dub != 'N'
+ self.dubbuffercheckbox.setChecked(dub)
+
+ def __setAllowWM(self, allow):
+ global currentallowwm
+ currentallowwm = allow
+ allow = allow != 'N'
+ self.allowwmcheckbox.setChecked(allow)
+ if not application:
+ if allow and self.currentemudesktop == "":
+ self.showdragcheckbox.setEnabled(False)
+ else:
+ self.showdragcheckbox.setEnabled(True)
+
+ def __setEmuDesktop(self, emudesktop):
+ self.currentemudesktop = emudesktop
+ emudesktopbool = emudesktop != ""
+ self.emudesktopcheckbox.setChecked(emudesktopbool)
+ self.desksizehbox.setEnabled(emudesktopbool)
+ if emudesktopbool:
+ desktopsize = emudesktop.split('x')
+ self.xsizeedit.setText(desktopsize[0])
+ self.ysizeedit.setText(desktopsize[1])
+ self.showdragcheckbox.setEnabled(True)
+ elif currentallowwm:
+ self.showdragcheckbox.setEnabled(False)
+
+ def __selectVertexShaderMode(self,mode):
+ self.currentvertexshadermode = mode
+ self.accelcombo.setCurrentItem(self.vertexshadersupportdic[mode])
+
+ def __setPixelShaderMode(self,mode):
+ self.currentpixelshadermode = mode
+ mode = mode == 'enabled'
+ self.pixelshadercheckbox.setChecked(mode)
+
+ def __setGLSL(self,mode):
+ self.currentglsl = mode
+ mode = mode == 'enabled'
+ self.glslcheckbox.setChecked(mode)
+
+ def __setShowDrag(self,show):
+ self.currentshowdrag = show
+ show = show != '0'
+ self.showdragcheckbox.setChecked(show)
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+
+############################################################################
+class AppearancePage(QWidget):
+
+ themes = [unicode(i18n("No Theme"))]
+ colorschemes = [unicode(i18n("Custom"))]
+ sizes = [("NormalSize",unicode(i18n("Normal"))),
+ ("LargeSize",unicode(i18n("Large Fonts"))),
+ ("ExtraLargeSize",unicode(i18n("Extra Large Fonts")))]
+
+ # Items for the combo box reference a tuple of dictionaries for color
+ # and size values and translations for that item
+ # For example, the value of BorderWidth is
+ # customizableitems[str(i18n("Window Border"))][1]["BorderWidth"][1]
+ customizableitems = {"Window Border":
+ ({"ActiveBorder":[unicode(i18n("Active Color:")),QColor()],
+ "InactiveBorder":[unicode(i18n("Inactive Color:")),QColor()]},
+ {"BorderWidth":[unicode(i18n("Width:")),1]}), #ActiveBorder, InactiveBorder, metrics: BorderWidth
+ "Title Bar":
+ ({"ActiveTitle":[unicode(i18n("Active Color:")),QColor()],
+ "GradientActiveTitle":[unicode(i18n("Gradient:")),QColor()],
+ "InactiveTitle":[unicode(i18n("Inactive Color:")),QColor()],
+ "GradientInactiveTitle":[unicode(i18n("Gradient:")),QColor()],
+ "TitleText":[unicode(i18n("Active Text:")),QColor()],
+ "InactiveTitleText":[unicode(i18n("Inactive Text:")),QColor()]},
+ {}), #ActiveTitle, GradientActiveTitle, InactiveTitle, GradientInactiveTitle, TitleText, InactiveTitleText
+ "Application Workspace":
+ ({"AppWorkSpace":[unicode(i18n("Background Color:")),QColor()]},
+ {}), #AppWorkSpace "Background"
+ "Buttons":
+ ({"ButtonFace":[unicode(i18n("Face:")),QColor()],
+ "ButtonHilight":[unicode(i18n("Hilight:")),QColor()],
+ "ButtonLight":[unicode(i18n("Light:")),QColor()],
+ "ButtonShadow":[unicode(i18n("Shadow:")),QColor()],
+ "ButtonText":[unicode(i18n("Text Color:")),QColor()],
+ "ButtonAlternateFace":[unicode(i18n("Alternate Face:")),QColor()],
+ "ButtonDkShadow":[unicode(i18n("Dark Shadow:")),QColor()],
+ "WindowFrame":[unicode(i18n("Frame:")),QColor()]},
+ {}), #ButtonFace, ButtonHilight, ButtonLight, ButtonShadow, ButtonText, ButtonAlternateFace, ButtonDkShadow, WindowFrame
+ "Caption Buttons":
+ ({},
+ {"CaptionHeight":[unicode(i18n("Height:")),1],
+ "CaptionWidth":[unicode(i18n("Width:")),1]}), #Metrics: CaptionHeight, CaptionWidth
+ "Desktop":
+ ({"Background":[unicode(i18n("Background:")),QColor()]},
+ {}), #Background
+ "Menu":
+ ({"Menu":[unicode(i18n("Menu Background:")),QColor()],
+ "MenuBar":[unicode(i18n("Menu Bar Color:")),QColor()],
+ "MenuHilight":[unicode(i18n("Menu Hilight:")),QColor()],
+ "MenuText":[unicode(i18n("Text Color:")),QColor()]},
+ {"MenuHeight":[unicode(i18n("Menu Bar Height:")),1]}), #Menu (Background), MenuBar, MenuHilight, MenuText, metrics: MenuHeight, MenuWidth (does nothing)
+ "Scrollbar":
+ ({"Scrollbar":[unicode(i18n("Color:")),QColor()]},
+ {"ScrollWidth":[unicode(i18n("Width:")),1]}), #Scrollbar, metrics: ScrollHeight (does nothing), ScrollWidth
+ "Window":
+ ({"Window":[unicode(i18n("Background:")),QColor()],
+ "WindowText":[unicode(i18n("Text Color:")),QColor()]},
+ {}), #Window "Background", WindowText
+ "Selected Items":
+ ({"Hilight":[unicode(i18n("Hilight Color:")),QColor()],
+ "HilightText":[unicode(i18n("Text Color:")),QColor()]},
+ {})} #Hilight, HilightText
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ global imagedir
+ QWidget.__init__(self,parent)
+
+ if not name:
+ self.setName("AppearanceTab")
+
+ appearance_tab_layout = QVBoxLayout(self,0,0,"AppearanceTabLayout")
+ self.top_layout = appearance_tab_layout
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ appearance_tab_layout.addWidget(vbox)
+
+ # -- Appearance group
+ self.appearance_group_box = QVGroupBox(vbox)
+ self.appearance_group_box.setTitle(i18n("Style and Colors"))
+ self.appearance_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.appearance_group_box.setInsideMargin(KDialog.marginHint())
+
+ themebox = QWidget(self.appearance_group_box)
+
+ theme_layout = QGridLayout(themebox,3,3)
+ theme_layout.setSpacing(KDialog.spacingHint())
+ theme_layout.setColStretch(1,1)
+
+ styletext = QLabel(themebox,"styletext")
+ styletext.setText(i18n("Widget Style:"))
+ theme_layout.addWidget(styletext,0,0)
+
+ self.themes = self.themes + wineread.GetThemesList()
+ self.themecombo = KComboBox(0,themebox,"themecombo")
+ self.fillThemeCombo(self.themecombo)
+ self.connect(self.themecombo,SIGNAL("activated(int)"),self.slotThemeActivated)
+ theme_layout.addWidget(self.themecombo,0,1)
+
+ self.installbutton = KPushButton(i18n("Install style..."),themebox)
+ self.connect(self.installbutton,SIGNAL("clicked()"),self.slotInstallThemeClicked)
+ theme_layout.addWidget(self.installbutton,0,2)
+
+ fontsizetext = QLabel(themebox,"fontsizetext")
+ fontsizetext.setText(i18n("Font Size:"))
+ theme_layout.addWidget(fontsizetext,1,0)
+
+ self.fontsizecombo = KComboBox(0,themebox,"fontsizecombo")
+ self.fillFontSizeCombo(self.fontsizecombo)
+ self.connect(self.fontsizecombo,SIGNAL("activated(int)"),self.slotFontSizeActivated)
+ theme_layout.addWidget(self.fontsizecombo,1,1)
+
+ colorschemetext = QLabel(themebox,"colorschemetext")
+ colorschemetext.setText(i18n("Color Scheme:"))
+ theme_layout.addWidget(colorschemetext,2,0)
+
+ self.colorschemecombo = KComboBox(0,themebox,"colorschemecombo")
+ self.fillColorSchemeCombo(self.colorschemecombo)
+ self.connect(self.colorschemecombo,SIGNAL("activated(int)"),self.slotColorSchemeActivated)
+ theme_layout.addWidget(self.colorschemecombo,2,1)
+
+ self.saveschemebutton = KPushButton(i18n("Save..."),themebox)
+ self.connect(self.saveschemebutton,SIGNAL("clicked()"),self.slotSaveSchemeClicked)
+ theme_layout.addWidget(self.saveschemebutton,2,2)
+
+ # --- Custom Colors ---
+ hbox = QHBox(self.appearance_group_box)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.sizehbox = hbox
+ self.leftspacer = QWidget(hbox)
+
+ self.customcolorsvbox = QVBox(hbox)
+ self.customcolorsvbox.setSpacing(KDialog.spacingHint())
+
+ hbox = QHBox(self.customcolorsvbox)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ itemtext = QLabel(hbox,"itemtext")
+ itemtext.setText(i18n("Item:"))
+
+ self.itemcombo = KComboBox(0,hbox,"itemcombo")
+ self.fillItemCombo(self.itemcombo)
+ self.connect(self.itemcombo,SIGNAL("activated(int)"),self.slotItemActivated)
+ hbox.setStretchFactor(self.itemcombo,1)
+
+ self.customcolorsgrid = QWidget(self.customcolorsvbox)
+ self.customcolorsgrid_layout = QGridLayout(self.customcolorsgrid,4,2)
+ self.customcolorsgrid_layout.setSpacing(KDialog.spacingHint())
+
+ # Box 1 of 8
+ self.colorsizehbox1 = QWidget(self.customcolorsgrid,"colorsizehbox1")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox1,0,0)
+ self.colorsizehbox1_layout = QGridLayout(self.colorsizehbox1,1,2)
+ self.colorsizehbox1_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext1 = QLabel(self.colorsizehbox1,"colorsizetext1")
+ self.colorsizetext1.setText(i18n(":"))
+ self.colorsizehbox1_layout.addWidget(self.colorsizetext1,0,0,Qt.AlignRight)
+
+ self.sizespinbox1 = QSpinBox(self.colorsizehbox1,"sizespinbox1")
+ self.sizespinbox1.setMinValue(0)
+ self.connect(self.sizespinbox1,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo1 = KColorCombo(self.colorsizehbox1,"colorcombo1")
+ self.connect(self.colorcombo1,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ # Box 2 of 8
+ self.colorsizehbox2 = QWidget(self.customcolorsgrid,"colorsizehbox2")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox2,0,1)
+ self.colorsizehbox2_layout = QGridLayout(self.colorsizehbox2,1,2)
+ self.colorsizehbox2_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext2 = QLabel(self.colorsizehbox2,"colorsizetext2")
+ self.colorsizetext2.setText(i18n(":"))
+ self.colorsizehbox2_layout.addWidget(self.colorsizetext2,0,0,Qt.AlignRight)
+
+ self.sizespinbox2 = QSpinBox(self.colorsizehbox2,"sizespinbox2")
+ self.sizespinbox2.setMinValue(0)
+ self.connect(self.sizespinbox2,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo2 = KColorCombo(self.colorsizehbox2,"colorcombo2")
+ self.connect(self.colorcombo2,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ # Box 3 of 8
+ self.colorsizehbox3 = QWidget(self.customcolorsgrid,"colorsizehbox3")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox3,1,0)
+ self.colorsizehbox3_layout = QGridLayout(self.colorsizehbox3,1,2)
+ self.colorsizehbox3_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext3 = QLabel(self.colorsizehbox3,"colorsizetext3")
+ self.colorsizetext3.setText(i18n(":"))
+ self.colorsizehbox3_layout.addWidget(self.colorsizetext3,0,0,Qt.AlignRight)
+
+ self.sizespinbox3 = QSpinBox(self.colorsizehbox3,"sizespinbox3")
+ self.sizespinbox3.setMinValue(0)
+ self.connect(self.sizespinbox3,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo3 = KColorCombo(self.colorsizehbox3,"colorcombo3")
+ self.connect(self.colorcombo3,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ # Box 4 of 8
+ self.colorsizehbox4 = QWidget(self.customcolorsgrid,"colorsizehbox4")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox4,1,1)
+ self.colorsizehbox4_layout = QGridLayout(self.colorsizehbox4,1,2)
+ self.colorsizehbox4_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext4 = QLabel(self.colorsizehbox4,"colorsizetext4")
+ self.colorsizetext4.setText(i18n(":"))
+ self.colorsizehbox4_layout.addWidget(self.colorsizetext4,0,0,Qt.AlignRight)
+
+ self.sizespinbox4 = QSpinBox(self.colorsizehbox4,"sizespinbox4")
+ self.sizespinbox4.setMinValue(0)
+ self.connect(self.sizespinbox4,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo4 = KColorCombo(self.colorsizehbox4,"colorcombo4")
+ self.connect(self.colorcombo4,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ # Box 5 of 8
+ self.colorsizehbox5 = QWidget(self.customcolorsgrid,"colorsizehbox5")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox5,2,0)
+ self.colorsizehbox5_layout = QGridLayout(self.colorsizehbox5,1,2)
+ self.colorsizehbox5_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext5 = QLabel(self.colorsizehbox5,"colorsizetext5")
+ self.colorsizetext5.setText(i18n(":"))
+ self.colorsizehbox5_layout.addWidget(self.colorsizetext5,0,0,Qt.AlignRight)
+
+ self.sizespinbox5 = QSpinBox(self.colorsizehbox5,"sizespinbox5")
+ self.sizespinbox5.setMinValue(0)
+ self.connect(self.sizespinbox5,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo5 = KColorCombo(self.colorsizehbox5,"colorcombo5")
+ self.connect(self.colorcombo5,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ # Box 6 of 8
+ self.colorsizehbox6 = QWidget(self.customcolorsgrid,"colorsizehbox6")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox6,2,1)
+ self.colorsizehbox6_layout = QGridLayout(self.colorsizehbox6,1,2)
+ self.colorsizehbox6_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext6 = QLabel(self.colorsizehbox6,"colorsizetext6")
+ self.colorsizetext6.setText(i18n(":"))
+ self.colorsizehbox6_layout.addWidget(self.colorsizetext6,0,0,Qt.AlignRight)
+
+ self.sizespinbox6 = QSpinBox(self.colorsizehbox6,"sizespinbox6")
+ self.sizespinbox6.setMinValue(0)
+ self.connect(self.sizespinbox6,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo6 = KColorCombo(self.colorsizehbox6,"colorcombo6")
+ self.connect(self.colorcombo6,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ # Box 7 of 8
+ self.colorsizehbox7 = QWidget(self.customcolorsgrid,"colorsizehbox7")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox7,3,0)
+ self.colorsizehbox7_layout = QGridLayout(self.colorsizehbox7,1,2)
+ self.colorsizehbox7_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext7 = QLabel(self.colorsizehbox7,"colorsizetext7")
+ self.colorsizetext7.setText(i18n(":"))
+ self.colorsizehbox7_layout.addWidget(self.colorsizetext7,0,0,Qt.AlignRight)
+
+ self.sizespinbox7 = QSpinBox(self.colorsizehbox7,"sizespinbox7")
+ self.sizespinbox7.setMinValue(0)
+ self.connect(self.sizespinbox7,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo7 = KColorCombo(self.colorsizehbox7,"colorcombo7")
+ self.connect(self.colorcombo7,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ # Box 8 of 8
+ self.colorsizehbox8 = QWidget(self.customcolorsgrid,"colorsizehbox8")
+ self.customcolorsgrid_layout.addWidget(self.colorsizehbox8,3,1)
+ self.colorsizehbox8_layout = QGridLayout(self.colorsizehbox8,1,2)
+ self.colorsizehbox8_layout.setSpacing(KDialog.spacingHint())
+
+ self.colorsizetext8 = QLabel(self.colorsizehbox8,"colorsizetext8")
+ self.colorsizetext8.setText(i18n(":"))
+ self.colorsizehbox8_layout.addWidget(self.colorsizetext8,0,0,Qt.AlignRight)
+
+ self.sizespinbox8 = QSpinBox(self.colorsizehbox8,"sizespinbox8")
+ self.sizespinbox8.setMinValue(0)
+ self.connect(self.sizespinbox8,SIGNAL("valueChanged(int)"),self.slotSizeActivated)
+
+ self.colorcombo8 = KColorCombo(self.colorsizehbox8,"colorcombo8")
+ self.connect(self.colorcombo8,SIGNAL("activated(const QColor &)"),self.slotColorActivated)
+
+ spacer = QWidget(self.customcolorsvbox)
+ self.customcolorsvbox.setStretchFactor(spacer,1)
+ self.customcolorsvbox.setMinimumHeight(itemtext.height()*4.5)
+ #self.customcolorsvbox.setStretchFactor(self.customcolorsgrid,1)
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ appearance_tab_layout.addItem(bottomspacer)
+
+ self.selecteditem = None
+ self.config = KConfig("wineconfigrc",False,False)
+ self.reset()
+
+ self.clearWState(Qt.WState_Polished)
+
+ def isChanged(self):
+ changed = False
+ changed = changed or self.currenttheme != self.originaltheme\
+ or self.currentthemecolorscheme != self.originalthemecolorscheme\
+ or self.currentfontsize != self.originalfontsize\
+ or self.customizableItemsChanged()
+ return changed
+
+ def customizableItemsChanged(self):
+ """ Returns true if any custom setting was changed """
+ colors = wineread.GetColorSettings()
+ metrics = wineread.GetWindowMetrics()
+
+ changed = False
+ custom = False # For a little efficiency
+ for item in self.customizableitems.keys():
+ for key in self.customizableitems[item][0].keys():
+ color = colors.get(key,"0 0 0")
+ color = color.split()
+ color = QColor(int(color[0]),int(color[1]),int(color[2]))
+ if not custom and self.customizableitems[item][0][key][1] !=\
+ self.config.readColorEntry(key,QColor(0,0,0)):
+ self.__selectColorScheme(0)
+ custom = True
+ if self.customizableitems[item][0][key][1] != color:
+ if custom:
+ return True
+ else:
+ changed = True
+ for key in self.customizableitems[item][1].keys():
+ size = int(metrics.get(key,1))
+ if not custom and self.customizableitems[item][1][key][1] !=\
+ self.config.readNumEntry(key,1):
+ self.__selectColorScheme(0)
+ custom = True
+ if self.customizableitems[item][1][key][1] != size:
+ if custom:
+ return True
+ else:
+ changed = True
+ return changed
+
+ def reset(self):
+ self.fillItemCombo(self.itemcombo)
+ self.config.setGroup("")
+ self.currentcustomcolorscheme = unicode(self.config.readEntry("ColorScheme",i18n("Custom")))
+ self.originalcustomcolorscheme = self.currentcustomcolorscheme
+ schemeslist = self.config.readListEntry("ColorSchemes")
+ self.colorschemes = [unicode(i18n("Custom")),
+ unicode(i18n("Get KDE Colors"))] + list(schemeslist)
+ self.config.setGroup(self.currentcustomcolorscheme)
+
+ for preset in self.presets:
+ if preset[0] not in schemeslist:
+ self.saveColorScheme(preset[0],preset[1])
+ self.colorschemes.append(preset[0])
+
+ self.fillColorSchemeCombo(self.colorschemecombo)
+
+ theme = wineread.GetCurrentTheme()
+ if not theme:
+ self.currenttheme = self.themes[0]
+ self.originaltheme = self.currenttheme
+ self.__selectTheme(0)
+
+ self.currentthemecolorscheme = "NormalColor"
+ self.originalthemecolorscheme = self.currentthemecolorscheme
+
+ self.currentfontsize = self.sizes[0][0]
+ self.originalfontsize = self.currentfontsize
+ for i,sizename in enumerate(self.sizes):
+ if sizename[0] == self.currentfontsize:
+ self.__selectFontSize(i)
+ break
+ else:
+ self.currenttheme = theme[0]
+ self.originaltheme = self.currenttheme
+ for i,themename in enumerate(self.themes):
+ if themename == self.currenttheme:
+ self.__selectTheme(i)
+ break
+ self.currentthemecolorscheme = theme[1]
+ self.originalthemecolorscheme = self.currentthemecolorscheme
+
+ self.currentfontsize = theme[2]
+ self.originalfontsize = self.currentfontsize
+ for i,sizename in enumerate(self.sizes):
+ if sizename[0] == self.currentfontsize:
+ self.__selectFontSize(i)
+ break
+
+ colors = wineread.GetColorSettings()
+ metrics = wineread.GetWindowMetrics()
+
+ for item in self.customizableitems.keys():
+ for key in self.customizableitems[item][0].keys():
+ color = colors.get(key,"0 0 0")
+ color = color.split()
+ color = QColor(int(color[0]),int(color[1]),int(color[2]))
+ if color != self.config.readColorEntry(key,QColor(0,0,0)):
+ self.currentcustomcolorscheme = self.colorschemes[0]
+ self.customizableitems[item][0][key][1] = color
+ for key in self.customizableitems[item][1].keys():
+ size = int(metrics.get(key,1))
+ if size != self.config.readNumEntry(key,1):
+ self.currentcustomcolorscheme = self.colorschemes[0]
+ self.customizableitems[item][1][key][1] = size
+
+ for i,colorname in enumerate(self.colorschemes):
+ if colorname == self.currentcustomcolorscheme:
+ self.__selectColorScheme(i)
+ break
+
+ self.desktopsettings = wineread.GetDesktopSettings()
+
+ def applyChanges(self):
+ """ Applies the changes to wine's configuration """
+ if self.currenttheme == self.themes[0]:
+ winewrite.SetCurrentTheme(None)
+ else:
+ winewrite.SetCurrentTheme((self.currenttheme,
+ self.currentthemecolorscheme,
+ self.currentfontsize))
+
+ colorsettings = {}
+ metricssettings = {}
+ for item in self.customizableitems.keys():
+ for key in self.customizableitems[item][0].keys():
+ color = self.customizableitems[item][0][key][1]
+ color = str(color.red()) + " " + str(color.green()) +\
+ " " + str(color.blue())
+ colorsettings[key] = color
+ for key in self.customizableitems[item][1].keys():
+ size = self.customizableitems[item][1][key][1]
+
+ metricssettings[key] = str(size)
+
+ winewrite.SetColorSettings(colorsettings)
+ winewrite.SetWindowMetrics(metricssettings)
+
+ self.config.setGroup("")
+ if self.currentcustomcolorscheme == self.colorschemes[1]:
+ self.currentcustomcolorscheme = self.colorschemes[0]
+ self.config.writeEntry("ColorScheme",self.currentcustomcolorscheme)
+ self.config.sync()
+
+ if self.customizableitems["Title Bar"][0]["ActiveTitle"][1]\
+ !=\
+ self.customizableitems["Title Bar"][0]["GradientActiveTitle"][1]\
+ or\
+ self.customizableitems["Title Bar"][0]["InactiveTitle"][1]\
+ !=\
+ self.customizableitems["Title Bar"][0]["GradientInactiveTitle"][1]:
+ prefmask = self.desktopsettings["UserPreferencemask"]
+ prefmask = prefmask[:4] + "1" + prefmask[5:]
+ self.desktopsettings["UserPreferencemask"] = prefmask
+ else:
+ prefmask = self.desktopsettings["UserPreferencemask"]
+ prefmask = prefmask[:4] + "0" + prefmask[5:]
+ self.desktopsettings["UserPreferencemask"] = prefmask
+
+ winewrite.SetDesktopSettings(self.desktopsettings)
+
+ self.reset()
+
+ def fillThemeCombo(self,combo):
+ """ Fill the combo box with the list of themes """
+ for theme in self.themes:
+ combo.insertItem(theme)
+
+ def fillColorSchemeCombo(self,combo):
+ """ Fill the combo box with the list of color schemes """
+ combo.clear()
+ for color in self.colorschemes:
+ combo.insertItem(color)
+
+ def fillFontSizeCombo(self,combo):
+ """ Fill the combo box with the list of font sizes """
+ for size in self.sizes:
+ combo.insertItem(size[1])
+
+ def slotFillItemCombo(self,allowwm):
+ """
+ Fill the combo box with the list of customizable items
+ Called when window managing is changed
+ """
+ combo = self.itemcombo
+ combo.clear()
+ items = self.customizableitems.keys()
+ items.sort()
+ for item in items:
+ if not (allowwm and (item == "Window Border" \
+ or item == "Title Bar" or \
+ item == "Caption Buttons")):
+ combo.insertItem(unicode(i18n(item)))
+
+ def slotFillItemComboDesktop(self,desktop):
+ """
+ Fill the combo box with the list of customizable items
+ Called when virtual desktop is changed
+ """
+ self.slotFillItemCombo(not desktop)
+
+ def fillItemCombo(self,combo = None):
+ """ Fill the combo box with the list of customizable items """
+ if not combo:
+ combo = self.itemcombo
+ combo.clear()
+ items = self.customizableitems.keys()
+ items.sort()
+ self.currentitems = []
+ for item in items:
+ if not (currentallowwm == 'Y' and (item == "Window Border" \
+ or item == "Title Bar" or \
+ item == "Caption Buttons")):
+ combo.insertItem(unicode(i18n(item)))
+ self.currentitems.append(item)
+
+ def slotThemeActivated(self,themeid):
+ """ Picks an already installed theme """
+ self.__selectTheme(themeid)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotInstallThemeClicked(self):
+ """ Opens up a dialog to install a new theme """
+ themepath = unicode(KFileDialog.getOpenFileName(os.environ['HOME'],\
+ "*.msstyles|" + str(i18n("Windows Styles (*.msstyles)")),self,i18n("Install Style")))
+ if themepath:
+ themename = themepath.split('/')
+ themename = themename[-1]
+ themename = themename.split('.')
+ themename = themename[0]
+ themedir = wineread.winepath +\
+ "/dosdevices/c:/windows/Resources/Themes/" +\
+ themename
+ if not os.path.exists(themedir):
+ os.mkdir(themedir)
+ shutil.copy(themepath, themedir)
+ self.themes.append(str(i18n(themename)))
+ self.themecombo.insertItem(self.themes[-1])
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotSaveSchemeClicked(self):
+ """ Lets the user save the current color scheme """
+ schemename = KInputDialog.getText(i18n("Save Color Scheme"),\
+ i18n("Name: "),\
+ i18n("CustomScheme"),\
+ self,"schemenameinput")
+
+ while schemename[1] and schemename[0] == "" or \
+ schemename[0] == self.colorschemes[0] or \
+ schemename[0] == self.colorschemes[1]:
+ KMessageBox.information(self, \
+ i18n("Please enter a unique name for the color scheme."), \
+ i18n("Save Color Scheme"))
+ schemename = KInputDialog.getText(i18n("Save Color Scheme"),\
+ i18n("Name: "),\
+ i18n("CustomScheme"),\
+ self,"schemenameinput")
+
+ if schemename[1]:
+ schemename = str(schemename[0])
+ self.saveColorScheme(schemename)
+ if schemename not in self.colorschemes:
+ self.colorschemes.append(schemename)
+ self.colorschemecombo.insertItem(schemename)
+ for i,colorname in enumerate(self.colorschemes):
+ if colorname == schemename:
+ self.__selectColorScheme(i)
+ break
+
+ def saveColorScheme(self,name,schemesettings = None):
+ """ Saves the colorscheme """
+ if not schemesettings:
+ schemesettings = self.customizableitems
+ self.config.setGroup("")
+ if name != self.colorschemes[1]:
+ self.config.writeEntry("ColorScheme",name)
+ schemeslist = self.config.readListEntry("ColorSchemes")
+ if name not in schemeslist and name != self.colorschemes[0] and \
+ name != self.colorschemes[1]:
+ schemeslist.append(name)
+ self.config.writeEntry("ColorSchemes",schemeslist)
+ self.config.setGroup(name)
+ for item in self.customizableitems.keys():
+ for key in schemesettings[item][0].keys():
+ self.config.writeEntry(key,schemesettings[item][0][key][1])
+ for key in schemesettings[item][1].keys():
+ self.config.writeEntry(key,schemesettings[item][1][key][1])
+ self.config.sync()
+
+ def GetKdeColorScheme(self):
+ """ Sets the current color scheme settings to those currently set in KDE """
+ # Create a configuration object.
+ config = KConfig("kdesktoprc")
+
+ config.setGroup("General")
+ self.customizableitems["Application Workspace"][0]["AppWorkSpace"][1] =\
+ config.readColorEntry("background",QColor(100,100,100))
+ self.customizableitems["Buttons"][0]["ButtonFace"][1] =\
+ config.readColorEntry("background",QColor(230,230,230))
+ self.customizableitems["Buttons"][0]["ButtonHilight"][1] =\
+ config.readColorEntry("windowBackground",QColor(240,240,240))
+ self.customizableitems["Buttons"][0]["ButtonLight"][1] =\
+ config.readColorEntry("selectBackground",QColor(200,200,200)).light(135)
+ self.customizableitems["Buttons"][0]["ButtonShadow"][1] =\
+ config.readColorEntry("background",QColor(100,100,100)).dark(180)
+ self.customizableitems["Buttons"][0]["ButtonText"][1] =\
+ config.readColorEntry("buttonForeground",QColor(0,0,0))
+ self.customizableitems["Buttons"][0]["ButtonAlternateFace"][1] =\
+ config.readColorEntry("background",QColor(230,230,230))
+ self.customizableitems["Buttons"][0]["ButtonDkShadow"][1] =\
+ config.readColorEntry("selectBackground",QColor(0,0,0)).dark(146)
+ self.customizableitems["Buttons"][0]["WindowFrame"][1] =\
+ config.readColorEntry("selectBackground",QColor(0,0,0))
+ self.customizableitems["Menu"][0]["Menu"][1] =\
+ config.readColorEntry("background",QColor(230,230,230)).light(105)
+ self.customizableitems["Menu"][0]["MenuBar"][1] =\
+ config.readColorEntry("background",QColor(230,230,230))
+ self.customizableitems["Menu"][0]["MenuHilight"][1] =\
+ config.readColorEntry("selectBackground",QColor(0,0,0))
+ self.customizableitems["Menu"][0]["MenuText"][1] =\
+ config.readColorEntry("foreground",QColor(0,0,0))
+ self.customizableitems["Scrollbar"][0]["Scrollbar"][1] =\
+ config.readColorEntry("background",QColor(230,230,230))
+ self.customizableitems["Window"][0]["Window"][1] =\
+ config.readColorEntry("windowBackground",QColor(255,255,255))
+ self.customizableitems["Window"][0]["WindowText"][1] =\
+ config.readColorEntry("foreground",QColor(0,0,0))
+ self.customizableitems["Selected Items"][0]["Hilight"][1] =\
+ config.readColorEntry("selectBackground",QColor(0,0,0))
+ self.customizableitems["Selected Items"][0]["HilightText"][1] =\
+ config.readColorEntry("selectForeground",QColor(255,255,255))
+
+ config.setGroup("WM")
+ self.customizableitems["Title Bar"][0]["ActiveTitle"][1] =\
+ config.readColorEntry("activeBackground",QColor(10,10,100))
+ self.customizableitems["Title Bar"][0]["GradientActiveTitle"][1] =\
+ config.readColorEntry("activeBlend",QColor(10,10,200)).light(110)
+ self.customizableitems["Title Bar"][0]["InactiveTitle"][1] =\
+ config.readColorEntry("inactiveBackground",QColor(100,100,100))
+ self.customizableitems["Title Bar"][0]["GradientInactiveTitle"][1] =\
+ config.readColorEntry("inactiveBlend",QColor(100,100,200))
+ self.customizableitems["Title Bar"][0]["TitleText"][1] =\
+ config.readColorEntry("activeForeground",QColor(255,255,255))
+ self.customizableitems["Title Bar"][0]["InactiveTitleText"][1] =\
+ config.readColorEntry("inactiveForeground",QColor(250,250,250))
+ self.customizableitems["Window Border"][0]["ActiveBorder"][1] =\
+ config.readColorEntry("frame",QColor(10,10,100))
+ self.customizableitems["Window Border"][0]["InactiveBorder"][1] =\
+ config.readColorEntry("frame",QColor(100,100,200))
+
+ config.setGroup("Desktop0")
+ self.customizableitems["Desktop"][0]["Background"][1] =\
+ config.readColorEntry("Color1",QColor(50,150,85))
+
+ self.saveColorScheme(self.colorschemes[1])
+
+ def slotColorSchemeActivated(self,colorid):
+ """ Picks a color scheme """
+ self.__selectColorScheme(colorid)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotFontSizeActivated(self,fontid):
+ """ Picks a font size """
+ self.__selectFontSize(fontid)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotItemActivated(self,itemid):
+ """ Picks an item to customize """
+ items = self.customizableitems.keys()
+ items.sort()
+ for i,item in enumerate(self.currentitems):
+ if i == itemid:
+ if item != self.selecteditem:
+ self.__selectItem(item)
+
+ def slotColorActivated(self,color):
+ """ Picks a color for the currently selected item """
+ key = self.sender().name()
+ self.customizableitems[self.selecteditem][0][key][1] = color
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotSizeActivated(self,sizevalue):
+ """ Sets the size value from the spin box """
+ key = self.sender().name()
+ self.customizableitems[self.selecteditem][1][key][1] = sizevalue
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def __selectTheme(self,themeid):
+ """ Selects the browser in the combobox """
+ self.currenttheme = self.themes[themeid]
+
+ self.themecombo.setCurrentItem(themeid)
+
+ #if themeid == 0:
+ # self.colorfontbox.setEnabled(False)
+ #else:
+ # self.colorfontbox.setEnabled(True)
+
+ def __selectColorScheme(self,colorid):
+ """ Selects a color scheme in the combo box """
+ self.currentcustomcolorscheme = self.colorschemes[colorid]
+
+ self.colorschemecombo.setCurrentItem(colorid)
+
+ if colorid > 1:
+ self.config.setGroup("")
+ self.config.writeEntry("ColorScheme",self.colorschemes[colorid])
+ self.config.setGroup(self.colorschemes[colorid])
+ for item in self.customizableitems.keys():
+ for key in self.customizableitems[item][0].keys():
+ color = self.config.readColorEntry(key,QColor(0,0,0))
+ self.customizableitems[item][0][key][1] = color
+ for key in self.customizableitems[item][1].keys():
+ size = self.config.readNumEntry(key,1)
+ self.customizableitems[item][1][key][1] = size
+ elif colorid == 1:
+ self.GetKdeColorScheme()
+
+ if not self.selecteditem:
+ self.__selectItem("Desktop")
+ else:
+ self.__selectItem(self.selecteditem)
+
+ def __selectColorSchemeByName(self,name):
+ """ Finds the index of name in colorschemes and calls the above function """
+ for i,colorname in enumerate(self.colorschemes):
+ if colorname == name:
+ self.__selectColorScheme(i)
+ break
+
+ def __selectFontSize(self,sizeid):
+ """ Selects a font size in the combo box """
+ self.currentfontsize = self.sizes[sizeid][0]
+
+ self.fontsizecombo.setCurrentItem(sizeid)
+
+ def __selectItem(self,item):
+ """ Sets the color and size settings boxes to those for item """
+ self.selecteditem = item
+
+ for i,item1 in enumerate(self.currentitems):
+ if item1 == item:
+ self.itemcombo.setCurrentItem(i)
+
+ if item == "Application Workspace":
+ key = "AppWorkSpace"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ self.colorsizehbox2.hide()
+ self.colorsizehbox3.hide()
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Buttons":
+ key = "ButtonFace"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ key = "WindowFrame"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox2.hide()
+ self.colorsizehbox2_layout.remove(self.sizespinbox2)
+ self.colorsizehbox2_layout.addWidget(self.colorcombo2,0,1)
+ self.colorcombo2.show()
+ self.colorcombo2.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo2.setName(key)
+
+ key = "ButtonShadow"
+ self.colorsizehbox3.show()
+ self.colorsizetext3.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox3.hide()
+ self.colorsizehbox3_layout.remove(self.sizespinbox3)
+ self.colorsizehbox3_layout.addWidget(self.colorcombo3,0,1)
+ self.colorcombo3.show()
+ self.colorcombo3.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo3.setName(key)
+
+ key = "ButtonDkShadow"
+ self.colorsizehbox4.show()
+ self.colorsizetext4.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox4.hide()
+ self.colorsizehbox4_layout.remove(self.sizespinbox4)
+ self.colorsizehbox4_layout.addWidget(self.colorcombo4,0,1)
+ self.colorcombo4.show()
+ self.colorcombo4.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo4.setName(key)
+
+ key = "ButtonLight"
+ self.colorsizehbox5.show()
+ self.colorsizetext5.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox5.hide()
+ self.colorsizehbox5_layout.remove(self.sizespinbox5)
+ self.colorsizehbox5_layout.addWidget(self.colorcombo5,0,1)
+ self.colorcombo5.show()
+ self.colorcombo5.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo5.setName(key)
+
+ key = "ButtonHilight"
+ self.colorsizehbox6.show()
+ self.colorsizetext6.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox6.hide()
+ self.colorsizehbox6_layout.remove(self.sizespinbox6)
+ self.colorsizehbox6_layout.addWidget(self.colorcombo6,0,1)
+ self.colorcombo6.show()
+ self.colorcombo6.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo6.setName(key)
+
+ key = "ButtonAlternateFace"
+ self.colorsizehbox7.show()
+ self.colorsizetext7.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox7.hide()
+ self.colorsizehbox7_layout.remove(self.sizespinbox7)
+ self.colorsizehbox7_layout.addWidget(self.colorcombo7,0,1)
+ self.colorcombo7.show()
+ self.colorcombo7.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo7.setName(key)
+
+ key = "ButtonText"
+ self.colorsizehbox8.show()
+ self.colorsizetext8.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox8.hide()
+ self.colorsizehbox8_layout.remove(self.sizespinbox8)
+ self.colorsizehbox8_layout.addWidget(self.colorcombo8,0,1)
+ self.colorcombo8.show()
+ self.colorcombo8.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo8.setName(key)
+ elif item == "Caption Buttons":
+ key = "CaptionHeight"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][1][key][0])
+ self.colorcombo1.hide()
+ self.colorsizehbox1_layout.remove(self.colorcombo1)
+ self.colorsizehbox1_layout.addWidget(self.sizespinbox1,0,1)
+ self.sizespinbox1.show()
+ self.sizespinbox1.setName(key)
+ self.sizespinbox1.setValue(\
+ self.customizableitems[item][1][key][1])
+ self.sizespinbox1.setMinValue(8)
+ self.sizespinbox1.setMaxValue(100)
+
+ key = "CaptionWidth"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][1][key][0])
+ self.colorcombo2.hide()
+ self.colorsizehbox2_layout.remove(self.colorcombo2)
+ self.colorsizehbox2_layout.addWidget(self.sizespinbox2,0,1)
+ self.sizespinbox2.show()
+ self.sizespinbox2.setName(key)
+ self.sizespinbox2.setValue(\
+ self.customizableitems[item][1][key][1])
+ self.sizespinbox2.setMinValue(8)
+ self.sizespinbox2.setMaxValue(100)
+
+ self.colorsizehbox3.hide()
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Desktop":
+ key = "Background"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ self.colorsizehbox2.hide()
+ self.colorsizehbox3.hide()
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Menu":
+ key = "Menu"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ key = "MenuBar"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox2.hide()
+ self.colorsizehbox2_layout.remove(self.sizespinbox2)
+ self.colorsizehbox2_layout.addWidget(self.colorcombo2,0,1)
+ self.colorcombo2.show()
+ self.colorcombo2.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo2.setName(key)
+
+ key = "MenuHilight"
+ self.colorsizehbox3.show()
+ self.colorsizetext3.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox3.hide()
+ self.colorsizehbox3_layout.remove(self.sizespinbox3)
+ self.colorsizehbox3_layout.addWidget(self.colorcombo3,0,1)
+ self.colorcombo3.show()
+ self.colorcombo3.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo3.setName(key)
+
+ key = "MenuText"
+ self.colorsizehbox4.show()
+ self.colorsizetext4.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox4.hide()
+ self.colorsizehbox4_layout.remove(self.sizespinbox4)
+ self.colorsizehbox4_layout.addWidget(self.colorcombo4,0,1)
+ self.colorcombo4.show()
+ self.colorcombo4.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo4.setName(key)
+
+ key = "MenuHeight"
+ self.colorsizehbox5.show()
+ self.colorsizetext5.setText(\
+ self.customizableitems[item][1][key][0])
+ self.colorcombo5.hide()
+ self.colorsizehbox5_layout.remove(self.colorcombo5)
+ self.colorsizehbox5_layout.addWidget(self.sizespinbox5,0,1)
+ self.sizespinbox5.show()
+ self.sizespinbox5.setName(key)
+ self.sizespinbox5.setValue(\
+ self.customizableitems[item][1][key][1])
+ self.sizespinbox5.setMinValue(15)
+ self.sizespinbox5.setMaxValue(100)
+
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Scrollbar":
+ key = "Scrollbar"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ key = "ScrollWidth"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][1][key][0])
+ self.colorcombo2.hide()
+ self.colorsizehbox2_layout.remove(self.colorcombo2)
+ self.colorsizehbox2_layout.addWidget(self.sizespinbox2,0,1)
+ self.sizespinbox2.show()
+ self.sizespinbox2.setName(key)
+ self.sizespinbox2.setValue(\
+ self.customizableitems[item][1][key][1])
+ self.sizespinbox2.setMinValue(8)
+ self.sizespinbox2.setMaxValue(100)
+
+ self.colorsizehbox3.hide()
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Selected Items":
+ key = "Hilight"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ key = "HilightText"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox2.hide()
+ self.colorsizehbox2_layout.remove(self.sizespinbox2)
+ self.colorsizehbox2_layout.addWidget(self.colorcombo2,0,1)
+ self.colorcombo2.show()
+ self.colorcombo2.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo2.setName(key)
+
+ self.colorsizehbox3.hide()
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Title Bar":
+ key = "ActiveTitle"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ key = "GradientActiveTitle"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox2.hide()
+ self.colorsizehbox2_layout.remove(self.sizespinbox2)
+ self.colorsizehbox2_layout.addWidget(self.colorcombo2,0,1)
+ self.colorcombo2.show()
+ self.colorcombo2.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo2.setName(key)
+
+ key = "InactiveTitle"
+ self.colorsizehbox3.show()
+ self.colorsizetext3.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox3.hide()
+ self.colorsizehbox3_layout.remove(self.sizespinbox3)
+ self.colorsizehbox3_layout.addWidget(self.colorcombo3,0,1)
+ self.colorcombo3.show()
+ self.colorcombo3.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo3.setName(key)
+
+ key = "GradientInactiveTitle"
+ self.colorsizehbox4.show()
+ self.colorsizetext4.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox4.hide()
+ self.colorsizehbox4_layout.remove(self.sizespinbox4)
+ self.colorsizehbox4_layout.addWidget(self.colorcombo4,0,1)
+ self.colorcombo4.show()
+ self.colorcombo4.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo4.setName(key)
+
+ key = "TitleText"
+ self.colorsizehbox5.show()
+ self.colorsizetext5.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox5.hide()
+ self.colorsizehbox5_layout.remove(self.sizespinbox5)
+ self.colorsizehbox5_layout.addWidget(self.colorcombo5,0,1)
+ self.colorcombo5.show()
+ self.colorcombo5.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo5.setName(key)
+
+ key = "InactiveTitleText"
+ self.colorsizehbox6.show()
+ self.colorsizetext6.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox6.hide()
+ self.colorsizehbox6_layout.remove(self.sizespinbox6)
+ self.colorsizehbox6_layout.addWidget(self.colorcombo6,0,1)
+ self.colorcombo6.show()
+ self.colorcombo6.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo6.setName(key)
+
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Window":
+ key = "Window"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ key = "WindowText"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox2.hide()
+ self.colorsizehbox2_layout.remove(self.sizespinbox2)
+ self.colorsizehbox2_layout.addWidget(self.colorcombo2,0,1)
+ self.colorcombo2.show()
+ self.colorcombo2.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo2.setName(key)
+
+ self.colorsizehbox3.hide()
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ elif item == "Window Border":
+ key = "ActiveBorder"
+ self.colorsizehbox1.show()
+ self.colorsizetext1.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox1.hide()
+ self.colorsizehbox1_layout.remove(self.sizespinbox1)
+ self.colorsizehbox1_layout.addWidget(self.colorcombo1,0,1)
+ self.colorcombo1.show()
+ self.colorcombo1.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo1.setName(key)
+
+ key = "InactiveBorder"
+ self.colorsizehbox2.show()
+ self.colorsizetext2.setText(\
+ self.customizableitems[item][0][key][0])
+ self.sizespinbox2.hide()
+ self.colorsizehbox2_layout.remove(self.sizespinbox2)
+ self.colorsizehbox2_layout.addWidget(self.colorcombo2,0,1)
+ self.colorcombo2.show()
+ self.colorcombo2.setColor(\
+ self.customizableitems[item][0][key][1])
+ self.colorcombo2.setName(key)
+
+ key = "BorderWidth"
+ self.colorsizehbox3.show()
+ self.colorsizetext3.setText(\
+ self.customizableitems[item][1][key][0])
+ self.colorcombo3.hide()
+ self.colorsizehbox3_layout.remove(self.colorcombo3)
+ self.colorsizehbox3_layout.addWidget(self.sizespinbox3,0,1)
+ self.sizespinbox3.show()
+ self.sizespinbox3.setName(key)
+ self.sizespinbox3.setValue(\
+ self.customizableitems[item][1][key][1])
+ self.sizespinbox3.setMinValue(1)
+ self.sizespinbox3.setMaxValue(50)
+
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+ else:
+ # Shouldn't happen.
+ self.colorsizehbox1.hide()
+ self.colorsizehbox2.hide()
+ self.colorsizehbox3.hide()
+ self.colorsizehbox4.hide()
+ self.colorsizehbox5.hide()
+ self.colorsizehbox6.hide()
+ self.colorsizehbox7.hide()
+ self.colorsizehbox8.hide()
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+ # --- Some default color schemes, with names ---
+ preset1 = (unicode(i18n("Purple")),
+ {"Window Border":
+ ({"ActiveBorder":[unicode(i18n("Active Color:")),QColor(239,239,239)],
+ "InactiveBorder":[unicode(i18n("Inactive Color:")),QColor(239,239,239)]},
+ {"BorderWidth":[unicode(i18n("Width:")),1]}), #ActiveBorder, InactiveBorder, metrics: BorderWidth
+ "Title Bar":
+ ({"ActiveTitle":[unicode(i18n("Active Color:")),QColor(91,86,168)],
+ "GradientActiveTitle":[unicode(i18n("Gradient:")),QColor(136,118,202)],
+ "InactiveTitle":[unicode(i18n("Inactive Color:")),QColor(223,225,230)],
+ "GradientInactiveTitle":[unicode(i18n("Gradient:")),QColor(157,170,186)],
+ "TitleText":[unicode(i18n("Active Text:")),QColor(255,255,255)],
+ "InactiveTitleText":[unicode(i18n("Inactive Text:")),QColor(168,168,168)]},
+ {}), #ActiveTitle, GradientActiveTitle, InactiveTitle, GradientInactiveTitle, TitleText, InactiveTitleText
+ "Application Workspace":
+ ({"AppWorkSpace":[unicode(i18n("Background Color:")),QColor(90,90,90)]},
+ {}), #AppWorkSpace "Background"
+ "Buttons":
+ ({"ButtonFace":[unicode(i18n("Face:")),QColor(238,239,242)],
+ "ButtonHilight":[unicode(i18n("Hilight:")),QColor(255,255,255)],
+ "ButtonLight":[unicode(i18n("Light:")),QColor(201,199,255)],
+ "ButtonShadow":[unicode(i18n("Shadow:")),QColor(132,132,134)],
+ "ButtonText":[unicode(i18n("Text Color:")),QColor(0,0,0)],
+ "ButtonAlternateFace":[unicode(i18n("Alternate Face:")),QColor(238,239,242)],
+ "ButtonDkShadow":[unicode(i18n("Dark Shadow:")),QColor(98,96,143)],
+ "WindowFrame":[unicode(i18n("Frame:")),QColor(144,140,209)]},
+ {}), #ButtonFace, ButtonHilight, ButtonLight, ButtonShadow, ButtonText, ButtonAlternateFace, ButtonDkShadow, WindowFrame
+ "Caption Buttons":
+ ({},
+ {"CaptionHeight":[unicode(i18n("Height:")),22],
+ "CaptionWidth":[unicode(i18n("Width:")),22]}), #Metrics: CaptionHeight, CaptionWidth
+ "Desktop":
+ ({"Background":[unicode(i18n("Background:")),QColor(146,127,188)]},
+ {}), #Background
+ "Menu":
+ ({"Menu":[unicode(i18n("Menu Background:")),QColor(250,251,254)],
+ "MenuBar":[unicode(i18n("Menu Bar Color:")),QColor(238,239,242)],
+ "MenuHilight":[unicode(i18n("Menu Hilight:")),QColor(144,140,209)],
+ "MenuText":[unicode(i18n("Text Color:")),QColor(0,0,0)]},
+ {"MenuHeight":[unicode(i18n("Menu Bar Height:")),22]}), #Menu (Background), MenuBar, MenuHilight, MenuText, metrics: MenuHeight, MenuWidth (does nothing)
+ "Scrollbar":
+ ({"Scrollbar":[unicode(i18n("Color:")),QColor(238,239,242)]},
+ {"ScrollWidth":[unicode(i18n("Width:")),16]}), #Scrollbar, metrics: ScrollHeight (does nothing), ScrollWidth
+ "Window":
+ ({"Window":[unicode(i18n("Background:")),QColor(255,255,255)],
+ "WindowText":[unicode(i18n("Text Color:")),QColor(0,0,0)]},
+ {}), #Window "Background", WindowText
+ "Selected Items":
+ ({"Hilight":[unicode(i18n("Hilight Color:")),QColor(144,140,209)],
+ "HilightText":[unicode(i18n("Text Color:")),QColor(255,255,255)]},
+ {})}) #Hilight, HilightText
+
+ preset2 = (unicode(i18n("Blue")),
+ {"Window Border":
+ ({"ActiveBorder":[unicode(i18n("Active Color:")),QColor(239,239,239)],
+ "InactiveBorder":[unicode(i18n("Inactive Color:")),QColor(239,239,239)]},
+ {"BorderWidth":[unicode(i18n("Width:")),1]}), #ActiveBorder, InactiveBorder, metrics: BorderWidth
+ "Title Bar":
+ ({"ActiveTitle":[unicode(i18n("Active Color:")),QColor(0,113,201)],
+ "GradientActiveTitle":[unicode(i18n("Gradient:")),QColor(87,161,219)],
+ "InactiveTitle":[unicode(i18n("Inactive Color:")),QColor(191,191,191)],
+ "GradientInactiveTitle":[unicode(i18n("Gradient:")),QColor(171,171,171)],
+ "TitleText":[unicode(i18n("Active Text:")),QColor(255,255,255)],
+ "InactiveTitleText":[unicode(i18n("Inactive Text:")),QColor(95,95,95)]},
+ {}), #ActiveTitle, GradientActiveTitle, InactiveTitle, GradientInactiveTitle, TitleText, InactiveTitleText
+ "Application Workspace":
+ ({"AppWorkSpace":[unicode(i18n("Background Color:")),QColor(90,90,90)]},
+ {}), #AppWorkSpace "Background"
+ "Buttons":
+ ({"ButtonFace":[unicode(i18n("Face:")),QColor(239,239,239)],
+ "ButtonHilight":[unicode(i18n("Hilight:")),QColor(246,246,246)],
+ "ButtonLight":[unicode(i18n("Light:")),QColor(191,207,251)],
+ "ButtonShadow":[unicode(i18n("Shadow:")),QColor(148,148,153)],
+ "ButtonText":[unicode(i18n("Text Color:")),QColor(0,0,0)],
+ "ButtonAlternateFace":[unicode(i18n("Alternate Face:")),QColor(238,239,242)],
+ "ButtonDkShadow":[unicode(i18n("Dark Shadow:")),QColor(50,101,146)],
+ "WindowFrame":[unicode(i18n("Frame:")),QColor(74,149,214)]},
+ {}), #ButtonFace, ButtonHilight, ButtonLight, ButtonShadow, ButtonText, ButtonAlternateFace, ButtonDkShadow, WindowFrame
+ "Caption Buttons":
+ ({},
+ {"CaptionHeight":[unicode(i18n("Height:")),22],
+ "CaptionWidth":[unicode(i18n("Width:")),22]}), #Metrics: CaptionHeight, CaptionWidth
+ "Desktop":
+ ({"Background":[unicode(i18n("Background:")),QColor(44,109,189)]},
+ {}), #Background
+ "Menu":
+ ({"Menu":[unicode(i18n("Menu Background:")),QColor(249,249,249)],
+ "MenuBar":[unicode(i18n("Menu Bar Color:")),QColor(239,239,239)],
+ "MenuHilight":[unicode(i18n("Menu Hilight:")),QColor(74,149,214)],
+ "MenuText":[unicode(i18n("Text Color:")),QColor(0,0,0)]},
+ {"MenuHeight":[unicode(i18n("Menu Bar Height:")),22]}), #Menu (Background), MenuBar, MenuHilight, MenuText, metrics: MenuHeight, MenuWidth (does nothing)
+ "Scrollbar":
+ ({"Scrollbar":[unicode(i18n("Color:")),QColor(230,230,230)]},
+ {"ScrollWidth":[unicode(i18n("Width:")),16]}), #Scrollbar, metrics: ScrollHeight (does nothing), ScrollWidth
+ "Window":
+ ({"Window":[unicode(i18n("Background:")),QColor(255,255,255)],
+ "WindowText":[unicode(i18n("Text Color:")),QColor(0,0,0)]},
+ {}), #Window "Background", WindowText
+ "Selected Items":
+ ({"Hilight":[unicode(i18n("Hilight Color:")),QColor(74,149,214)],
+ "HilightText":[unicode(i18n("Text Color:")),QColor(255,255,255)]},
+ {})}) #Hilight, HilightText
+ presets = [preset1,preset2]
+
+############################################################################
+class GeneralPage(QWidget):
+
+ winversions = wineread.winversions
+
+ verdic = {
+ "win2003":0,
+ "winxp":1,
+ "win2k":2,
+ "winme":3,
+ "win98":4,
+ "win95":5,
+ "nt40":6,
+ "nt351":7,
+ "win31":8,
+ "win30":9,
+ "win20":10}
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ global application
+ QWidget.__init__(self,parent)
+
+ if not name:
+ self.setName("GeneralTab")
+
+ general_tab_layout = QVBoxLayout(self,0,0,"GeneralTabLayout")
+ self.top_layout = general_tab_layout
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ general_tab_layout.addWidget(vbox)
+
+ if application:
+ appwarning = QLabel(vbox,"appwarning")
+ appwarning.setText(i18n("Application specific settings for <b>" +\
+ application + "</b><p>Changing a setting here will permanently " +\
+ "make that setting independent of settings for all other " +\
+ "applications.</p>"))
+ appwarning.setFrameStyle( QFrame.Box | QFrame.Raised )
+ self.winversions = self.winversions + (( "global",\
+ unicode(i18n("Use Global Setting")), 0, 0, 0, "", "", 0, 0, ""),)
+ self.verdic["global"]=11
+
+ hbox = QHBox(vbox)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ versiontext = QLabel(hbox,"versiontext")
+ versiontext.setText(i18n("Windows version:"))
+
+ self.versioncombo = KComboBox(0,hbox,"versioncombo")
+ self.fillVersionCombo(self.versioncombo)
+ self.connect(self.versioncombo,SIGNAL("activated(int)"),self.slotVersionActivated)
+
+ spacer = QWidget(hbox)
+ hbox.setStretchFactor(spacer,1)
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ general_tab_layout.addItem(bottomspacer)
+
+ self.reset()
+
+ self.clearWState(Qt.WState_Polished)
+
+ def isChanged(self):
+ changed = False
+ changed = changed or self.currentwinverid != self.originalwinverid
+ return changed
+
+ def reset(self):
+ settings = wineread.GetGeneralWineSettings(application)
+
+ if application:
+ self.currentwinverid = self.verdic[settings.get("Version","global")]
+ else:
+ self.currentwinverid = self.verdic[settings.get("Version","winxp")]
+ self.originalwinverid = self.currentwinverid
+ self.__selectWinVer(self.currentwinverid)
+
+ def applyChanges(self):
+ """ Applies the changes to wine's configuration """
+ winewrite.SetWinVersion(self.winversions[self.currentwinverid], application)
+
+ self.reset()
+
+ def fillVersionCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for version in self.winversions:
+ combo.insertItem(version[1])
+
+ def slotVersionActivated(self,verid):
+ self.currentwinverid = verid
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def __selectWinVer(self,verid):
+ """
+ Sets the current Windows version and selects it in the combo box
+ """
+ self.versioncombo.setCurrentItem(verid)
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+
+############################################################################
+class ApplicationsPage(QWidget):
+
+ applications = []
+
+ browsers = []
+ mailers = []
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ QWidget.__init__(self,parent)
+
+ if not name:
+ self.setName("ApplicationsTab")
+
+ applications_tab_layout = QVBoxLayout(self,0,0,"ApplicationsTabLayout")
+ self.top_layout = applications_tab_layout
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ applications_tab_layout.addWidget(vbox)
+
+ # -- Application Specific Settings group --
+ self.perapp_group_box = QHGroupBox(vbox)
+ self.perapp_group_box.setTitle(i18n("Application specific settings"))
+ self.perapp_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.perapp_group_box.setInsideMargin(KDialog.marginHint())
+
+ vbox2 = QVBox(self.perapp_group_box)
+ vbox2.setSpacing(KDialog.spacingHint())
+
+ applicationstext = QLabel(vbox2,"applicationstext")
+ applicationstext.setText(i18n("Change application specific settings for:"))
+
+ self.appslist = KListBox(vbox2)
+ self.connect(self.appslist, SIGNAL("selectionChanged(QListBoxItem *)"), self.slotListClicked)
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.addbutton = KPushButton(i18n("Add Application..."),hbox)
+ self.connect(self.addbutton,SIGNAL("clicked()"),self.slotAddClicked)
+
+ self.removebutton = KPushButton(i18n("Remove..."),hbox)
+ self.connect(self.removebutton,SIGNAL("clicked()"),self.slotRemoveClicked)
+
+ spacer = QWidget(hbox)
+ hbox.setStretchFactor(spacer,1)
+
+ self.settingsbutton = KPushButton(i18n("Settings"),hbox)
+ self.connect(self.settingsbutton,SIGNAL("clicked()"),self.slotSettingsClicked)
+
+ # -- Native Applications Settings group --
+ # Removed pending a patch to winebrowser
+ #self.nativeapp_group_box = QVGroupBox(vbox)
+ #self.nativeapp_group_box.setTitle(i18n("Native applications"))
+ #self.nativeapp_group_box.setInsideSpacing(KDialog.spacingHint())
+ #self.nativeapp_group_box.setInsideMargin(KDialog.marginHint())
+
+ #vbox3 = QWidget(self.nativeapp_group_box)
+
+ #native_apps_layout = QGridLayout(vbox3,2,3)
+ #native_apps_layout.setSpacing(KDialog.spacingHint())
+
+ #browsertext = QLabel(vbox3,"browsertext")
+ #browsertext.setText(i18n("Web Browser:"))
+ #native_apps_layout.addWidget(browsertext,0,0)
+
+ #self.browsercombo = KComboBox(0,vbox3,"browsercombo")
+ #self.browsercombo.setEditable(False)
+ #self.connect(self.browsercombo,SIGNAL("activated(int)"),self.slotBrowserActivated)
+ #native_apps_layout.addWidget(self.browsercombo,0,1)
+ #native_apps_layout.setColStretch(1,1)
+
+ #QToolTip.add(self.browsercombo,
+ #i18n("<p>Select the browser to be launched when clicking on a link" +\
+ #" in a Windows application.</p>"))
+
+ #self.browserbutton = KPushButton(i18n("..."),vbox3)
+ #self.connect(self.browserbutton,SIGNAL("clicked()"),self.slotBrowserClicked)
+ #native_apps_layout.addWidget(self.browserbutton,0,2)
+
+ #mailertext = QLabel(vbox3,"mailertext")
+ #mailertext.setText(i18n("Mail Client:"))
+ #native_apps_layout.addWidget(mailertext,1,0)
+
+ #self.mailercombo = KComboBox(0,vbox3,"mailercombo")
+ #self.connect(self.mailercombo,SIGNAL("activated(int)"),self.slotMailerActivated)
+ #native_apps_layout.addWidget(self.mailercombo,1,1)
+
+ #QToolTip.add(self.mailercombo,
+ #i18n("<p>Select the mail client to be launched when clicking on" +\
+ #" a mailto link in a Windows application.</p>"))
+
+ #self.mailerbutton = KPushButton(i18n("..."),vbox3)
+ #self.connect(self.mailerbutton,SIGNAL("clicked()"),self.slotMailerClicked)
+ #native_apps_layout.addWidget(self.mailerbutton,1,2)
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ applications_tab_layout.addItem(bottomspacer)
+
+ self.changed = False
+
+ # Removed pending a patch to winebrowser
+ #browsers = wineread.GetNativeBrowserList()
+ #if "kfmclient exec" not in browsers:
+ #browsers.append("kfmclient exec")
+ #self.currentbrowser = wineread.GetBrowser()
+ #self.browsers = self.createBrowserList(browsers,[self.currentbrowser])
+ #self.fillCombo(self.browsercombo,self.browsers)
+
+ #mailers = wineread.GetNativeMailerList()
+ #if "kfmclient exec" not in mailers:
+ #mailers.append("kfmclient exec")
+ #self.currentmailer = wineread.GetMailer()
+ #self.mailers = self.createMailerList(mailers,[self.currentmailer])
+ #self.fillCombo(self.mailercombo,self.mailers)
+
+ self.reset()
+
+ self.clearWState(Qt.WState_Polished)
+
+ def isChanged(self):
+ changed = False
+ changed = changed or self.applications != self.originalapplications
+ #changed = changed or self.currentbrowser != self.originalbrowser
+ #changed = changed or self.currentmailer != self.originalmailer
+ return changed
+
+ def reset(self):
+ self.applications = wineread.GetApps()
+ self.originalapplications = self.applications[:]
+ self.updateAppsList()
+
+ # Removed pending a patch to winebrowser
+ #self.currentbrowser = wineread.GetBrowser()
+ #self.__selectBrowser(self.currentbrowser)
+ #self.originalbrowser = self.currentbrowser
+
+ #self.currentmailer = wineread.GetMailer()
+ #self.__selectMailer(self.currentmailer)
+ #self.originalmailer = self.currentmailer
+
+ def applyChanges(self):
+ """ Applies the changes to wine's configuration """
+ if self.applications != self.originalapplications:
+ winewrite.SetApps(self.applications)
+ # Removed pending a patch to winebrowser
+ #if self.currentbrowser != self.originalbrowser:
+ #winewrite.SetDefaultBrowser(self.currentbrowser)
+ #if self.currentmailer != self.originalmailer:
+ #winewrite.SetDefaultMailer(self.currentmailer)
+ self.reset()
+
+ def createBrowserList(self,native,wine):
+ """
+ Takes a list of native browsers and a list wine browsers
+ and creates a list of the commands with descriptions
+ """
+
+ browsers = []
+
+ for browser in native:
+ browserwords = browser.split()
+ if browserwords and browserwords[0] == "kfmclient":
+ browserkfmcmd = browser.split(' ')
+ if len(browserkfmcmd) > 2 and \
+ browserkfmcmd[1] == 'openProfile':
+ browsertr = "Konqueror " + browserkfmcmd[2] +\
+ str(i18n(" profile (Native)"))
+ elif len(browserkfmcmd) > 1 and \
+ browserkfmcmd[1] == 'exec':
+ browsertr = str(i18n("Use KDE Default"))
+ else:
+ browsertr = str(i18n("Konqueror (Native)"))
+ else:
+ browsertr = browser.capitalize() + str(i18n(" (Native)"))
+ browsers.append((browser,browsertr))
+ for browser in wine:
+ if browser and browser[1] == ':':
+ browser = browser.lower()
+ browsertr = browser[browser.rfind('\\\\')+2:browser.rfind('.exe')]
+ browsertr = browsertr.capitalize() + str(i18n(" (Windows, set by application)"))
+ else: # winebrowser
+ continue
+ browsers.append((browser,browsertr))
+
+ return browsers
+
+ def createMailerList(self,native,wine):
+ """
+ Takes a list of native mailers and a list wine mailers
+ and creates a list of the commands with descriptions
+ """
+
+ mailers = []
+
+ for mailer in native:
+ mailerwords = mailer.split()
+ if mailerwords and mailerwords[0] == "kfmclient":
+ mailerkfmcmd = mailer.split(' ')
+ if len(mailerkfmcmd) > 1 and \
+ mailerkfmcmd[1] == 'exec':
+ mailertr = str(i18n("Use KDE Default"))
+ else:
+ mailertr = str(i18n("KDE (Native)"))
+ else:
+ mailertr = mailer.capitalize() + unicode(i18n(" (Native)"))
+ mailers.append((mailer,mailertr))
+ for mailer in wine:
+ if mailer and mailer[1] == ':':
+ mailer = mailer.lower()
+ mailertr = mailer[mailer.rfind('\\\\')+2:mailer.rfind('.exe')]
+ mailertr = mailertr.capitalize() + unicode(i18n(" (Windows, set by application)"))
+ else: # winebrowser
+ continue
+ mailers.append((mailer,mailertr))
+
+ return mailers
+
+ def slotListClicked(self,item):
+ """ Called when an application in the list is clicked """
+ for appid,appname in enumerate(self.applications):
+ if appname==item.text():
+ self.__selectApp(appid)
+ return
+
+ def slotAddClicked(self):
+ """
+ Let the user choose a new application to change settings for
+ """
+ app = KFileDialog.getOpenFileName(wineread.winepath + \
+ "/dosdevices/c:",\
+ "*.exe|" + unicode(i18n("Windows Executables (*.exe)")),self,i18n("Application"))
+ if app:
+ app = str(app).split('/')
+ app = app[-1]
+ self.applications.append(app)
+ self.updateAppsList()
+ for appid,appname in enumerate(self.applications):
+ if appname==app:
+ self.__selectApp(appid)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotRemoveClicked(self):
+ """ Removes settings for selected application """
+ if KMessageBox.warningContinueCancel(self, \
+ i18n("This will remove all application specific settings for \n" +\
+ self.applications[self.selectedappid] +"\n" +\
+ "Do you want to proceed?"),\
+ i18n("Warning")) == KMessageBox.Continue:
+ del self.applications[self.selectedappid]
+ self.updateAppsList()
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotSettingsClicked(self):
+ """
+ Launches a new wineconfig window for the selected application
+ """
+ os.system("wineconfig " + self.applications[self.selectedappid])
+
+ def slotBrowserEdited(self,browser):
+ """ Sets the first browser to use to the one selected in the combo box """
+ self.currentbrowser = str(browser).strip()
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotBrowserActivated(self,browserid):
+ """ Sets the first browser to use to the one selected in the combo box """
+ self.currentbrowser = self.browsers[browserid][0]
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotBrowserClicked(self):
+ """ Sets the first browser to use to the one selected in the combo box """
+ browserdlg = KOpenWithDlg(self)
+ browserdlg.hideNoCloseOnExit()
+ browserdlg.hideRunInTerminal()
+ if browserdlg.exec_loop():#i18n("Choose a Web Browser"),self.currentbrowser)
+ self.__selectBrowser(str(browserdlg.text()))
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotMailerEdited(self,mailer):
+ """ Sets the first mailer to use to the one selected in the combo box """
+ self.currentmailer = str(mailer).strip()
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotMailerActivated(self,mailerid):
+ """ Sets the first browser to use to the one selected in the combo box """
+ self.currentmailer = self.mailers[mailerid][0]
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotMailerClicked(self):
+ """ Sets the first mailer to use to the one selected in the combo box """
+ mailerdlg = KOpenWithDlg(self)
+ mailerdlg.hideNoCloseOnExit()
+ mailerdlg.hideRunInTerminal()
+ if mailerdlg.exec_loop():#i18n("Choose a Web Browser"),self.currentbrowser)
+ self.__selectMailer(str(mailerdlg.text()))
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def fillCombo(self,combo,_list):
+ """ Fill the combobox with the values from our list
+ Uses the second value from each tuple """
+ for item in _list:
+ combo.insertItem(item[1])
+
+ def updateAppsList(self):
+ """ Updates the displayed list of applications """
+ self.appslist.clear()
+
+ self.applications.sort()
+
+ self.appslist.insertStringList(QStringList.fromStrList(self.applications))
+
+ self.__selectApp(None)
+
+ def __selectBrowser(self,browsercommand):
+ """ Selects the browser in the combobox """
+ self.currentbrowser = browsercommand
+
+ for i,browser in enumerate(self.browsers):
+ if browser[0].lower() == browsercommand.lower():
+ self.browsercombo.setCurrentItem(i)
+ break
+ else:
+ browserwords = browsercommand.split()
+ #if len(browserwords) > 1 and browserwords[0] != "kfmclient":
+ # browsercommand = browserwords[0]
+ self.browsers = self.browsers +\
+ self.createBrowserList([browsercommand],[])
+ self.browsercombo.insertItem(self.browsers[-1][1])
+ self.__selectBrowser(browsercommand)
+
+ def __selectMailer(self,mailercommand):
+ """ Selects the mailer in the combobox """
+ self.currentmailer = mailercommand
+
+ for i,mailer in enumerate(self.mailers):
+ if mailer[0] == mailercommand:
+ self.mailercombo.setCurrentItem(i)
+ break
+ else:
+ mailerwords = mailercommand.split()
+ #if len(mailerwords) > 1 and mailerwords[0] != "kfmclient":
+ # mailercommand = mailerwords[0]
+ self.mailers = self.mailers +\
+ self.createBrowserList([mailercommand],[])
+ self.mailercombo.insertItem(self.mailers[-1][1])
+ self.__selectMailer(mailercommand)
+
+ def __selectApp(self,appid):
+ """ Selects the application """
+ if appid or appid == 0:
+ self.selectedappid = appid
+ self.appslist.setCurrentItem(appid)
+ self.removebutton.setEnabled(True)
+ self.settingsbutton.setEnabled(True)
+ else:
+ self.selectedappid = None
+ self.removebutton.setEnabled(False)
+ self.settingsbutton.setEnabled(False)
+
+ def GetKdeDefaultBrowser(self):
+ """ Returns the default browser set in KDE """
+ # Create a configuration object.
+ config = KConfig("wineconfigrc")
+ return str(config.lookupData(KEntryKey("General","BrowserApplication")).mValue).strip('!')
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+
+############################################################################
+class LibrariesPage(QWidget):
+
+ dlls = [""]
+ overriddendlls = {}
+
+ orderoptions = ("builtin","native","builtin,native","native,builtin","")
+ orderoptionstr = [
+ unicode(i18n("Built-in (Wine)")),
+ unicode(i18n("Native (Windows)")),
+ unicode(i18n("Built-in then Native")),
+ unicode(i18n("Native then Built-in")),
+ unicode(i18n("Disable"))]
+
+ def __init__(self,parent = None,name = None,modal = 0,fl = 0):
+ QWidget.__init__(self,parent)
+
+ if not name:
+ self.setName("LibrariesTab")
+
+ libraries_tab_layout = QVBoxLayout(self,0,0,"LibrariesTabLayout")
+ self.top_layout = libraries_tab_layout
+
+ vbox = QVBox(self)
+ vbox.setSpacing(KDialog.spacingHint())
+
+ libraries_tab_layout.addWidget(vbox)
+
+ # -- DLL overrides group
+ self.overrides_group_box = QHGroupBox(vbox)
+ self.overrides_group_box.setTitle(i18n("DLL Overrides"))
+ self.overrides_group_box.setInsideSpacing(KDialog.spacingHint())
+ self.overrides_group_box.setInsideMargin(KDialog.marginHint())
+
+ vbox2 = QVBox(self.overrides_group_box)
+ vbox2.setSpacing(KDialog.spacingHint())
+
+ spacer = QWidget(vbox2)
+ vbox2.setStretchFactor(spacer,1)
+
+ newtext = QLabel(vbox2,"newtext")
+ newtext.setText(i18n("New override for library:"))
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.dllcombo = KComboBox(0,hbox,"dllcombo")
+ self.dllcombo.setEditable(True)
+ hbox.setStretchFactor(self.dllcombo,3)
+ self.connect(self.dllcombo,SIGNAL("activated(int)"),self.slotDllComboActivated)
+
+ QToolTip.add(self.dllcombo,
+ i18n("<p>Dynamic Link Libraries can be specified individually to" +\
+ " be either builtin (provided by Wine) or native (taken from" +\
+ " Windows or provided by the application).</p>"))
+ self.addbutton = KPushButton(i18n("Add"),hbox)
+ hbox.setStretchFactor(self.addbutton,1)
+ self.connect(self.addbutton,SIGNAL("clicked()"),self.slotAddClicked)
+
+ existingtext = QLabel(vbox2,"existingtext")
+ existingtext.setText(i18n("Existing overrides:"))
+
+ hbox = QHBox(vbox2)
+ hbox.setSpacing(KDialog.spacingHint())
+
+ self.dllslist = KListView(hbox)
+ self.dllslist.addColumn(i18n("Library"))
+ self.dllslist.addColumn(i18n("Load Order"))
+ self.dllslist.setAllColumnsShowFocus(True)
+ self.dllslist.setSelectionMode(QListView.Single)
+ self.dllslist.setSorting(-1,True)
+ hbox.setStretchFactor(self.dllslist,3)
+
+ self.connect(self.dllslist, SIGNAL("selectionChanged(QListViewItem *)"), self.slotListClicked)
+
+ vbox3 = QVBox(hbox)
+ vbox3.setSpacing(KDialog.spacingHint())
+ hbox.setStretchFactor(vbox3,1)
+
+ self.editbutton = KPushButton(i18n("Edit"),vbox3)
+ self.connect(self.editbutton,SIGNAL("clicked()"),self.slotEditClicked)
+ self.editbutton.setEnabled(False)
+
+ self.removebutton = KPushButton(i18n("Remove"),vbox3)
+ self.connect(self.removebutton,SIGNAL("clicked()"),self.slotRemoveClicked)
+ self.removebutton.setEnabled(False)
+
+ spacer = QWidget(vbox3)
+ vbox3.setStretchFactor(spacer,1)
+
+ bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding)
+ libraries_tab_layout.addItem(bottomspacer)
+
+ self.changed = False
+
+ self.reset()
+
+ self.clearWState(Qt.WState_Polished)
+
+ def isChanged(self):
+ changed = False
+ changed = changed or self.overriddendlls != self.originaloverriddendlls
+ return changed
+
+ def reset(self):
+ self.dlls = wineread.GetDllsList()
+ self.fillCombo(self.dllcombo)
+
+ self.overriddendlls = wineread.GetDllOverrides(application)
+ self.originaloverriddendlls = self.overriddendlls.copy()
+ self.selecteddll = None
+ self.updateDllOverridesList()
+
+ def applyChanges(self):
+ """ Applies the changes to wine's configuration """
+ winewrite.SetDllOverrides(self.overriddendlls,application)
+ self.reset()
+
+ def slotListClicked(self,item):
+ """ Called when an application in the list is clicked """
+ self.__selectOverriddenDll(item.text(0))
+
+ def slotAddClicked(self):
+ """
+ Adds the selected library to the overrides list
+ """
+ dll = self.dllcombo.currentText()
+ if dll:
+ self.overriddendlls[str(dll)]="native,builtin"
+ self.updateDllOverridesList()
+ self.__selectOverriddenDll(dll)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotRemoveClicked(self):
+ """ Removes override for selected library """
+ del self.overriddendlls[str(self.selecteddll)]
+ self.updateDllOverridesList()
+ self.__selectOverriddenDll(None)
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotEditClicked(self):
+ """
+ Gives a choice for the load order for the library
+ """
+ if self.selecteddll:
+ order = KInputDialog.getItem(i18n("Edit Library Override"),\
+ unicode(i18n("Load order for %s:")) % (unicode(self.selecteddll),),
+ QStringList.fromStrList(self.orderoptionstr),\
+ False,0,self,"editdll")
+
+ if order[1]:
+ self.overriddendlls[str(self.selecteddll)] = \
+ self.orderoptions[self.orderoptionstr.index(str(order[0]))]
+ self.updateDllOverridesList()
+ self.emit(PYSIGNAL("changedSignal()"), ())
+
+ def slotDllComboActivated(self,dllid):
+ return
+
+ def fillCombo(self,combo):
+ """ Fill the combobox with the values from our list """
+ for dll in self.dlls:
+ combo.insertItem(dll)
+
+ def updateDllOverridesList(self):
+ """ Updates the displayed list of drives """
+ self.dllslist.clear()
+ self.dllsToListItems = {}
+ firstselecteddll = None
+ lastdll = None
+
+ for dll,order in self.overriddendlls.iteritems():
+ lvi = QListViewItem(self.dllslist,dll,order)
+ self.dllsToListItems[dll] = lvi
+ if self.selecteddll and self.selecteddll==dll:
+ firstselecteddll = dll
+ lastdll = dll
+
+ self.dllslist.setSortColumn(0)
+ self.selecteddll = firstselecteddll
+ self.__selectOverriddenDll(self.selecteddll)
+ self.dllslist.ensureItemVisible(self.dllslist.currentItem())
+
+ def __selectOverriddenDll(self,dll):
+ """ Select a dll from the overridden list """
+ self.selecteddll = dll
+ if dll:
+ self.dllslist.setSelected(self.dllsToListItems[str(dll)],True)
+ self.editbutton.setEnabled(True)
+ self.removebutton.setEnabled(True)
+ else:
+ self.editbutton.setEnabled(False)
+ self.removebutton.setEnabled(False)
+
+ def setMargin(self,margin):
+ self.top_layout.setMargin(margin)
+
+ def setSpacing(self,spacing):
+ self.top_layout.setSpacing(spacing)
+
+
+############################################################################
+def create_wineconfig(parent,name):
+ """ Factory function for KControl """
+ global kapp
+ kapp = KApplication.kApplication()
+ return WineConfigApp(parent, name)
+
+############################################################################
+def MakeAboutData():
+ aboutdata = KAboutData("guidance",programname,version, \
+ "Wine Configuration Tool", KAboutData.License_GPL, \
+ "Copyright (C) 2006-2007 Yuriy Kozlov", \
+ "Thanks go to Simon Edwards, Sebastian Kügler")
+ aboutdata.addAuthor("Yuriy Kozlov","Developer","yuriy.kozlov@gmail.com", \
+ "http://www.yktech.us/")
+ 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)
+
+ # Can't do i18n?
+ options = [("+[appname]", str(i18n("Application to change settings for")))]
+ KCmdLineArgs.addCmdLineOptions( options )
+
+ kapp = KApplication()
+
+ wineconfigapp = WineConfigApp()
+ wineconfigapp.exec_loop(None)
diff --git a/wineconfig/wineread.py b/wineconfig/wineread.py
new file mode 100644
index 0000000..c1fa3c5
--- /dev/null
+++ b/wineconfig/wineread.py
@@ -0,0 +1,543 @@
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+###########################################################################
+# wineread.py - description #
+# ------------------------------ #
+# begin : Fri Mar 26 2004 #
+# copyright : (C) 2006 by Yuriy Kozlov #
+# email : yuriy.kozlov@gmail.com #
+# #
+###########################################################################
+# #
+# 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. #
+# #
+###########################################################################
+
+import os
+
+""" Provides a set of functions for accessing wine's settings """
+
+# Assumes the fake windows is installed in ~/.wine
+default_winepath = os.environ['HOME'] + "/.wine"
+winepath = default_winepath
+defaultwinfolderspath = "c:\\windows\\profiles\\" + os.environ['USER']
+
+# Where the dll's are
+default_winebuildpath = "/usr/lib/wine"
+default_winebuildpath2 = "/usr/lib32/wine"
+default_winebuildpath3 = "/usr/local/lib/wine"
+
+winebuildpath = None
+
+def GetWineBuildPath():
+ """ Returns the wine build path, None if not present """
+ path = None
+ if winebuildpath:
+ path = winebuildpath
+ elif os.path.exists(default_winebuildpath):
+ path = default_winebuildpath
+ elif os.path.exists(default_winebuildpath2):
+ path = default_winebuildpath2
+ elif os.path.exists(default_winebuildpath3):
+ path = default_winebuildpath3
+
+ return path
+
+def SetWineBuildPath(path):
+ """ Sets the winebuildpath to path """
+ global winebuildpath
+ winebuildpath = path
+
+# drive = [index, letter, unixpath/mapping, type, label, serial]
+empty_drives = (
+ [0,"A:","","","",""],
+ [1,"B:","","","",""],
+ [2,"C:","","","",""],
+ [3,"D:","","","",""],
+ [4,"E:","","","",""],
+ [5,"F:","","","",""],
+ [6,"G:","","","",""],
+ [7,"H:","","","",""],
+ [8,"I:","","","",""],
+ [9,"J:","","","",""],
+ [10,"K:","","","",""],
+ [11,"L:","","","",""],
+ [12,"M:","","","",""],
+ [13,"N:","","","",""],
+ [14,"O:","","","",""],
+ [15,"P:","","","",""],
+ [16,"Q:","","","",""],
+ [17,"R:","","","",""],
+ [18,"S:","","","",""],
+ [19,"T:","","","",""],
+ [20,"U:","","","",""],
+ [21,"V:","","","",""],
+ [22,"W:","","","",""],
+ [23,"X:","","","",""],
+ [24,"Y:","","","",""],
+ [25,"Z:","","","",""])
+
+def GetEmptyDrives():
+ """ Returns a list of 26 empty drives """
+ drives = []
+ for drive in empty_drives:
+ drives.append(drive[:])
+ return drives
+
+def LoadDrives():
+ drives = GetEmptyDrives()
+
+ driveletters = os.listdir(winepath + "/dosdevices")
+ for folder in driveletters:
+ if len(folder) > 2 or folder[1] != ':':
+ del folder
+ set(driveletters)
+
+ drivetypes = GetDriveTypes()
+
+ for drive in drives:
+ letter = drive[1].lower()
+ if letter in driveletters:
+ drive[2] = os.readlink(winepath + "/dosdevices/" + letter)
+ if drivetypes.has_key(drive[1]):
+ drive[3] = drivetypes[drive[1]]
+ return drives
+
+empty_shelllinks = ([26,"Desktop","","","",""],
+ [27,"My Documents","","","",""],
+ [28,"My Pictures","","","",""],
+ [29,"My Music","","","",""],
+ [30,"My Video","","","",""])
+
+folder_nonexistent = "This folder does not exist, please map it."
+profilesdirectory = winepath + "/dosdevices/c:/windows/profiles/" + os.environ['USER']
+
+def GetEmptyShellLinks():
+ """ Returns a list of important windows folders """
+ shelllinks = []
+ for link in empty_shelllinks:
+ shelllinks.append(link[:])
+ return shelllinks
+
+def GetShellLinks():
+ shelllinks = GetEmptyShellLinks()
+
+ existingshelllinks = os.listdir(profilesdirectory)
+ set(existingshelllinks)
+ shellregistry = GetShellRegistry()
+ usershellregistry = GetUserShellRegistry()
+
+ for link in shelllinks:
+ if link[1] in existingshelllinks:
+ linkpath = profilesdirectory + "/" + link[1]
+ if os.path.islink(linkpath):
+ link[2] = os.readlink(linkpath)
+ else:
+ link[2] = linkpath
+ link[3] = "shellfolder"
+ winpath = defaultwinfolderspath + "\\" + link[1]
+ link[4] = winpath
+ link[5] = shellregistry.get(link[1], defaultwinfolderspath + "\\" + link[1])
+ link[5] = link[5].replace("\\\\","\\")
+ else:
+ link[3] = "shellfolder"
+ link[4] = folder_nonexistent
+ link[5] = shellregistry.get(link[1], folder_nonexistent)
+ link[5] = link[5].replace("\\\\","\\")
+
+ return shelllinks
+
+def GetValue(key, value):
+ """ Returns a specific value, returns a blank string if the value is not there. """
+ # Need 4 \'s to generate one because both python and the shell use it as an escape character
+ key = key.replace("\\","\\\\")
+ key = key.replace(" ","\\ ")
+ error = os.system("wine regedit /E .registryvalue.reg " + key)
+ if error != 0:
+ return ""
+
+ file=open('.registryvalue.reg')
+
+ for line in file:
+ if line and line[0] == '"' or line[0] == '@':
+ line = line.strip('\r\n')
+ line = line.split('=')
+ line = (line[0].strip('"'),line[1].strip('"@'))
+ if line[0] == value:
+ file.close()
+ os.remove(".registryvalue.reg")
+ return line[1]
+ else:
+ file.close()
+ os.remove(".registryvalue.reg")
+ return ""
+
+def GetKeyValues(key):
+ """ Returns a dictionary of all the values in the key
+ Returns an empty dictionary if the key does not exist
+ Does not read subkeys within the key """
+ # Need 4 \'s to generate one because both python and the shell use it as an escape character
+ key = key.replace("\\","\\\\")
+ key = key.replace(" ","\\ ")
+ error = os.system("wine regedit /E .registrykey.reg " + key)
+ if error != 0:
+ return {}
+
+ settings = {}
+
+ file=open('.registrykey.reg')
+
+ keycount = 0
+ for line in file:
+ if keycount > 1:
+ break
+ elif line and line[0] == '[':
+ keycount += 1
+ elif line and line[0] == '"':
+ line = line.split('=')
+ settings[line[0].strip('"')] = line[1].strip('"\r\n@')
+
+ file.close()
+ os.remove(".registrykey.reg")
+
+ return settings
+
+def GetUserShellRegistry():
+ error = os.system("wine regedit /E .registryshelluser.reg HKEY_USERS\\\\.Default\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\User\\ Shell\\ Folders")
+ if error != 0:
+ return {}
+
+ usershellfile=open('.registryshelluser.reg')
+ usershellfilelines = usershellfile.readlines()
+ usershellfile.close()
+ os.remove(".registryshelluser.reg")
+
+ settings = {}
+
+ del(usershellfilelines[:3])
+
+ for usershellline in usershellfilelines:
+ usershellline = usershellline.split('=')
+ settings[usershellline[0].strip('"')] = usershellline[1].strip('"\r\n')
+
+ return settings
+
+def GetShellRegistry():
+ error = os.system("wine regedit /E .registryshell.reg HKEY_USERS\\\\.Default\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Explorer\\\\Shell\\ Folders")
+ if error != 0:
+ return {}
+
+ shellfile=open('.registryshell.reg')
+ shellfilelines = shellfile.readlines()
+ shellfile.close()
+ os.remove(".registryshell.reg")
+
+ settings = {}
+
+ del(shellfilelines[:3])
+
+ for shellline in shellfilelines:
+ shellline = shellline.split('=')
+ settings[shellline[0].strip('"')] = shellline[1].strip('"\r\n')
+
+ return settings
+
+def GetDriveTypes():
+ """ Returns a dictionary of the drive types """
+ # Drive C: doesn't get stored in the registry
+ defaulttypes = {"C:":"hd"}
+
+ types = GetKeyValues("HKEY_LOCAL_MACHINE\\Software\\Wine\\Drives")
+ types.update(defaulttypes)
+
+ return types
+
+def GetAudioDriver():
+ """ Returns the audio driver currently set in the registry """
+ return GetValue("HKEY_CURRENT_USER\\Software\\Wine\\Drivers","Audio")
+
+def GetDSoundSettings(app = None):
+ """ Returns a dictionary of the settings for the DirectSound section """
+ if not app:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\DirectSound")
+ else:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\DirectSound")
+
+def GetWindowSettings(app = None):
+ """ Returns a dictionary of the Window Settings """
+ if not app:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver")
+ else:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\X11 Driver")
+
+def GetD3DSettings(app = None):
+ """ Returns a dictionary of the Direct3D Settings """
+ if not app:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\Direct3D")
+ else:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\Direct3D")
+
+# Copied from winecfg
+winversions = (
+ ( "win2003", "Windows 2003", 5, 2, 0xECE, "VER_PLATFORM_WIN32_NT", "Service Pack 1", 1, 0, "ServerNT"),
+ ( "winxp", "Windows XP", 5, 1, 0xA28, "VER_PLATFORM_WIN32_NT", "Service Pack 2", 2, 0, "WinNT"),
+ ( "win2k", "Windows 2000", 5, 0, 0x893, "VER_PLATFORM_WIN32_NT", "Service Pack 4", 4, 0, "WinNT"),
+ ( "winme", "Windows ME", 4, 90, 0xBB8, "VER_PLATFORM_WIN32_WINDOWS", " ", 0, 0, ""),
+ ( "win98", "Windows 98", 4, 10, 0x8AE, "VER_PLATFORM_WIN32_WINDOWS", " A ", 0, 0, ""),
+ ( "win95", "Windows 95", 4, 0, 0x3B6, "VER_PLATFORM_WIN32_WINDOWS", "", 0, 0, ""),
+ ( "nt40", "Windows NT 4.0", 4, 0, 0x565, "VER_PLATFORM_WIN32_NT", "Service Pack 6a", 6, 0, "WinNT"),
+ ( "nt351", "Windows NT 3.5", 3, 51, 0x421, "VER_PLATFORM_WIN32_NT", "Service Pack 2", 0, 0, "WinNT"),
+ ( "win31", "Windows 3.1", 2, 10, 0, "VER_PLATFORM_WIN32s", "Win32s 1.3", 0, 0, ""),
+ ( "win30", "Windows 3.0", 3, 0, 0, "VER_PLATFORM_WIN32s", "Win32s 1.3", 0, 0, ""),
+ ( "win20", "Windows 2.0", 2, 0, 0, "VER_PLATFORM_WIN32s", "Win32s 1.3", 0, 0, ""))
+
+def GetGeneralWineSettings(app = None):
+ """ Returns a dictionary of the general wine Settings, including the windows version """
+ if not app:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine")
+ else:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app)
+
+def GetApps():
+ """
+ Returns a list of the applications which have keys for application
+ specific settings.
+ """
+ error = os.system("wine regedit /E .registryapps.reg HKEY_CURRENT_USER\\\\Software\\\\Wine\\\\AppDefaults")
+ if error != 0:
+ return []
+
+ settingsfile=open('.registryapps.reg')
+ settingsfilelines = settingsfile.readlines()
+ settingsfile.close()
+ os.remove('.registryapps.reg')
+
+ apps = set([])
+
+ del(settingsfilelines[:3])
+
+ for line in settingsfilelines:
+ if line[0] == '[':
+ line = line.split('\\')
+ line[4] = line[4].strip(']\r\n')
+ apps.add(line[4])
+
+ apps = list(apps)
+ apps.sort()
+
+ return apps
+
+builtin_only = set(("advapi32",
+ "capi2032",
+ "dbghelp",
+ "ddraw",
+ "gdi32",
+ "glu32",
+ "icmp",
+ "iphlpapi",
+ "joystick.drv",
+ "kernel32",
+ "mswsock",
+ "ntdll",
+ "opengl32",
+ "stdole2.tlb",
+ "stdole32.tlb",
+ "twain_32",
+ "unicows",
+ "user32",
+ "vdmdbg",
+ "w32skrnl",
+ "winealsa.drv",
+ "winearts.drv",
+ "wineaudioio.drv",
+ "wined3d",
+ "winedos",
+ "wineesd.drv",
+ "winejack.drv",
+ "winemp3.acm",
+ "winenas.drv",
+ "wineoss.drv",
+ "wineps",
+ "wineps.drv",
+ "winex11.drv",
+ "winmm",
+ "wintab32",
+ "wnaspi32",
+ "wow32",
+ "ws2_32",
+ "wsock32"))
+
+def GetDllsList():
+ """ Returns a list of dlls that can be overridden """
+ origdlls = os.listdir(GetWineBuildPath())
+ dlls = [""]
+
+ for dll in origdlls:
+ dll = dll.rstrip('.so')
+ dots = dll.count('.')
+ if dots != 1:
+ continue
+ dll, extension = dll.split('.')
+ if not (extension != "dll" or dll in builtin_only):
+ dlls.append(dll)
+
+ dlls.sort()
+ return dlls
+
+def GetDllOverrides(app = None):
+ """ Returns a dictionary of overridden dlls """
+ if not app:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides")
+ else:
+ return GetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\DllOverrides")
+
+
+# --- Getting and Setting the Default browser ---
+
+# WineBrowser>Browsers
+# List of browsers that Wine will attempt to launch when running winebrowser
+# command or clicking on a link in a windows application. Default value is
+default_browserlist = ["firefox","konqueror","mozilla","netscape","galeon","opera","dillo"]
+
+# WineBrowser>Mailers
+# List of mail clients that Wine will attempt to launch when running winebrowser
+# Default value is
+default_mailerlist = ["mozilla-thunderbird","thunderbird","evolution","kmail"]
+
+#with firefox installed
+browser_formats = ["CHROME","FirefoxHTML","HTML","htmlfile","FTP","GOPHER","http","https"]
+
+default_browser_formats = ["htmlfile","http","https"] # just "winebrowser"
+
+default_mailer_formats = ["mailto"] # "winebrowser %1"
+
+def GetBrowser():
+ """ Returns the default browser """
+ browser = GetValue("HKEY_LOCAL_MACHINE\\Software\\Classes\\http\\shell\\open\\command",'@')
+
+ if browser == "winebrowser":
+ return GetWineBrowser()
+ else:
+ return browser
+
+def GetWineBrowser():
+ """ Returns the first browser tried by winebrowser """
+ browserlist = GetValue("HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser","Browsers")
+ if browserlist:
+ browser = browserlist.split(',')[0].strip()
+ return browser
+ else:
+ return default_browserlist[0]
+
+#def GetWinBrowserList():
+
+def GetNativeBrowserList():
+ """ Returns the list of browsers tried by winebrowser """
+ browserlist = GetValue("HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser","Browsers")
+ if browserlist:
+ browserlist = list(set(browserlist.split(',')))
+ for i,item in enumerate(browserlist):
+ browserlist[i] = item.strip()
+ return browserlist
+ else:
+ return default_browserlist
+
+def GetMailer():
+ """ Returns the default mail client """
+ mailer = GetValue("HKEY_LOCAL_MACHINE\\Software\\Classes\\mailto\\shell\\open\\command",'@')
+
+ if mailer == "winebrowser" or mailer == "winebrowser %1":
+ return GetWineMailer()
+ else:
+ return mailer
+
+def GetWineMailer():
+ """ Returns the first mail client tried by winebrowser """
+ mailerlist = GetValue("HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser","Mailers")
+ if mailerlist:
+ mailer = mailerlist.split(',')[0].strip()
+ return mailer
+ else:
+ # Default first mailer to try in wine is mozilla-thunderbird
+ return default_mailerlist[0]
+
+def GetNativeMailerList():
+ """ Returns the list of mail clients tried by winebrowser """
+ mailerlist = GetValue("HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser","Mailers")
+ if mailerlist:
+ mailerlist = list(set(mailerlist.split(',')))
+ for i,item in enumerate(mailerlist):
+ mailerlist[i] = item.strip()
+ return mailerlist
+ else:
+ return default_mailerlist
+
+
+# ----- Theming -----
+
+def GetThemesList():
+ """ Returns a list of installed thiemes """
+ if not os.path.exists(winepath + "/dosdevices/c:/windows/Resources/Themes"):
+ return []
+ origthemes = os.listdir(winepath + "/dosdevices/c:/windows/Resources/Themes")
+ themes = []
+
+ for i,theme in enumerate(origthemes):
+ if os.path.exists(winepath +\
+ "/dosdevices/c:/windows/Resources/Themes/" + theme +\
+ "/" + theme + ".msstyles"):
+ themes.append(theme)
+
+ themes.sort()
+ return themes
+
+def GetCurrentTheme():
+ """ Returns the current (theme,color,size), None if none is set """
+ themeinfo = GetKeyValues("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager")
+
+ if not themeinfo or themeinfo["ThemeActive"] == "0":
+ return None
+ else:
+ # themename from themename.msstyles
+ themename = themeinfo["DllName"].split('\\\\')[-1].split('.')[0]
+ theme = (themename, themeinfo["ColorName"], themeinfo["SizeName"])
+ return theme
+
+def GetColorSettings():
+ """ Returns a dictionary of the set colors """
+ return GetKeyValues("HKEY_CURRENT_USER\\Control Panel\\Colors")
+
+def GetWindowMetrics():
+ """ Returns a dictionary of the WindowMetrics settings """
+ return GetKeyValues("HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics")
+
+def GetDesktopSettings():
+ """ Returns a dictionary of the control panel \ Desktop settings """
+ return GetKeyValues("HKEY_CURRENT_USER\\Control Panel\\Desktop")
+
+def SetWinePath(path):
+ """ Sets the winepath to path """
+ global winepath
+ winepath = path
+
+def GetWinePath():
+ return winepath
+
+def VerifyWineDrive(path = None):
+ """ Does a very basic check of if the given path is a valid fake windows installation
+ Returns False if there is no C: drive """
+ if not path:
+ path = self.default_winepath
+
+ return os.path.exists(path + "/dosdevices/c:/windows/profiles/" + os.environ['USER']) and \
+ os.path.exists(path + "/dosdevices/c:/windows/system32") and \
+ os.path.exists(path + "/system.reg") and os.path.exists(path + "/userdef.reg") and \
+ os.path.exists(path + "/user.reg")
diff --git a/wineconfig/winewrite.py b/wineconfig/winewrite.py
new file mode 100644
index 0000000..0d0d365
--- /dev/null
+++ b/wineconfig/winewrite.py
@@ -0,0 +1,489 @@
+#!/usr/bin/python
+# -*- coding: UTF-8 -*-
+###########################################################################
+# winewrite.py - description #
+# ------------------------------ #
+# begin : Fri Mar 26 2004 #
+# copyright : (C) 2006 by Yuriy Kozlov #
+# email : yuriy.kozlov@gmail.com #
+# #
+###########################################################################
+# #
+# 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. #
+# #
+###########################################################################
+
+import os
+import wineread
+import random
+
+""" Provides functions for changings settings in wine """
+
+def SetDriveMappings(drives):
+ """ Sets wine's drive settings """
+ driveletters = os.listdir(wineread.winepath + "/dosdevices")
+ set(driveletters)
+
+ for drive in drives[:26]:
+ letter = drive[1].lower()
+ defineDrive = False
+ if letter in driveletters: # The drive exists
+ if drive[2]: # The drive is in use
+ # Compare for changes
+ changed = False
+ # Check if the mapping changed
+ if drive[2] != os.readlink(wineread.winepath + "/dosdevices/" + letter):
+ changed = True
+
+ # If it's changed, it will be recreated
+ if changed:
+ os.unlink(wineread.winepath + "/dosdevices/" + letter)
+ defineDrive = True
+ else:
+ # Remove the drive
+ os.unlink(wineread.winepath + "/dosdevices/" + letter)
+ else: # The drive doesn't exist
+ if drive[2]: # The drive is in use
+ # Create it
+ defineDrive = True
+ else:
+ # Do nothing
+ continue
+
+ if defineDrive:
+ os.symlink(drive[2], wineread.winepath + "/dosdevices/" + letter)
+
+ SetDriveTypes(drives[:26])
+ SetShellLinks(drives[26:])
+
+def SetShellLinks(shelllinks):
+ existingshelllinks = os.listdir(wineread.winepath + "/dosdevices/c:/windows/profiles/" + os.environ['USER'])
+ set(existingshelllinks)
+ shellregistry = wineread.GetShellRegistry()
+
+ for link in shelllinks:
+ createLink = False
+ if link[1] in existingshelllinks: # The link exists
+ linkpath = wineread.winepath + "/dosdevices/c:/windows/profiles/" + os.environ['USER'] + "/" + link[1]
+ if link[2]: # The folder is mapped
+ # Compare for changes
+ changed = False
+ # Check if the mapping changed
+ if os.path.islink(linkpath) and link[2] != os.readlink(linkpath):
+ changed = True
+ elif not os.path.islink(linkpath) and link[2] != linkpath:
+ changed = True
+ elif link[5] != shellregistry.get(link[1], wineread.defaultwinfolderspath + "\\" + link[1]):
+ changed = True
+
+ # If it's changed, it will be recreated
+ if changed:
+ if os.path.islink(linkpath):
+ os.unlink(linkpath)
+ else:
+ os.rename(linkpath,linkpath + "-backup" + str(random.randint(1,1000000)))
+ createLink = True
+ else:
+ # Remove the link
+ os.unlink(linkpath)
+ else: # The link doesn't exist
+ if link[2]: # The folder is mapped
+ # Create it
+ createLink = True
+ else:
+ # Do nothing
+ continue
+
+ if createLink:
+ os.symlink(link[2], wineread.winepath + "/dosdevices/c:/windows/profiles/" + os.environ['USER'] + "/" + link[1])
+ if shellregistry.has_key(link[1]):
+ SetShellRegistry(link)
+
+
+def SetShellRegistry(link):
+ shellfile=open('.registryshellw.reg','w')
+ shellfile.write("REGEDIT4\n\n[HKEY_USERS\\.Default\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders]\n")
+
+ link[5] = link[5].replace("\\","\\\\")
+ shellfile.write('"' + link[1] + '"="' + link[5] + '"\n')
+
+ shellfile.write("\n[HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders]\n")
+
+ link[5] = link[5].replace("\\","\\\\")
+ shellfile.write('"' + link[1] + '"="' + link[5] + '"\n')
+
+ shellfile.write("\n[HKEY_USERS\\.Default\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders]\n")
+
+ shellfile.write('"' + link[1] + '"="' + "%USERPROFILE%\\\\" + link[1] + '"')
+
+ shellfile.write("\n[HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders]\n")
+
+ shellfile.write('"' + link[1] + '"="' + "%USERPROFILE%\\\\" + link[1] + '"')
+ shellfile.close()
+
+ os.system("wine regedit .registryshellw.reg")
+ os.remove(".registryshellw.reg")
+
+def SetKeyValues(key,settings):
+ """ Sets all the values in key to those from the dictionary settings """
+ file=open('.registrykey.reg','w')
+ file.write("REGEDIT4\n\n[" + key + "]\n")
+
+ for setting in settings:
+ # Casting to a python string is necessary for older versions of pyQT
+ if str(settings[setting])[:4] == 'hex:':
+ file.write('"'+str(setting)+'"='+str(settings[setting])+'\n')
+ else:
+ file.write('"'+str(setting)+'"="'+str(settings[setting])+'"\n')
+
+ file.close()
+ os.system("wine regedit .registrykey.reg")
+ os.remove(".registrykey.reg")
+
+def SetValue(key,value,data):
+ """ Sets the value in key to data """
+ file=open('.registryvalue.reg','w')
+ file.write("REGEDIT4\n\n[" + key + "]\n")
+ file.write('"' + value + '"="' + data + '"')
+ file.close()
+
+ os.system("wine regedit .registryvalue.reg")
+ os.remove(".registryvalue.reg")
+
+def SetDriveTypes(drives):
+ """ Sets the type for the drives in the registry """
+ drivesfile=open('.registrydrives.reg','w')
+ drivesfile.write("REGEDIT4\n\n[HKEY_LOCAL_MACHINE\\Software\\Wine\\Drives]\n")
+
+ for drive in drives:
+ mapping = drive[2]
+ if mapping:
+ drivesfile.write('"' + drive[1] + '"="' + drive[3] + '"\n')
+
+ drivesfile.close()
+
+ os.system("wine regedit .registrydrives.reg")
+ os.remove(".registrydrives.reg")
+
+def SetAudioDriver(driver):
+ """ Sets the audio driver in the registry """
+ SetValue("HKEY_CURRENT_USER\\Software\\Wine\\Drivers","Audio",driver)
+
+def SetDSoundSettings(settings, app = None):
+ """ Sets the settings for Direct Sound in the registry """
+ if not app:
+ SetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\DirectSound", settings)
+ else:
+ SetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\DirectSound", settings)
+
+def SetWindowSettings(settings, app = None):
+ """ Sets the window settings in the registry """
+ windowsfile=open('.registrywindows.reg','w')
+ if not app:
+ windowsfile.write("REGEDIT4\n\n[HKEY_CURRENT_USER\\Software\\Wine\\X11 Driver]\n")
+ else:
+ windowsfile.write("REGEDIT4\n\n[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\X11 Driver]\n")
+
+ # There is a bug in wine that doesn't allow removing of registry entries from
+ # a reg file, so unchecking emulate desktop can't be implemented this way yet.
+
+ for setting in settings:
+ if settings[setting]:
+ windowsfile.write('"'+str(setting)+'"="'+str(settings[setting])+'"\n')
+ else:
+ # winecfg removes the value when the emulate desktop checkbox is unchecked
+ windowsfile.write('"'+str(setting)+'"=-\n')
+
+ windowsfile.close()
+ os.system("wine regedit .registrywindows.reg")
+ os.remove(".registrywindows.reg")
+
+def SetD3DSettings(settings, app = None):
+ """ Sets the settings for Direct3D in the registry """
+ if not app:
+ SetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\Direct3D", settings)
+ else:
+ SetKeyValues("HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\Direct3D", settings)
+
+def SetDesktopSettings(settings):
+ """ Sets the control panel \ Desktop settings in the registry """
+ SetKeyValues("HKEY_CURRENT_USER\\Control Panel\\Desktop", settings)
+
+def SetWinVersion(version, app = None):
+ """
+ Sets the windows version in the registry
+ Sample format for version:
+ ( "winxp", "Windows XP", 5, 1, 0xA28, "VER_PLATFORM_WIN32_NT", "Service Pack 2", 2, 0, "WinNT")
+ """
+ winverfile=open('.registrywinver.reg','w')
+ if not app:
+ winverfile.write("REGEDIT4\n\n[HKEY_CURRENT_USER\\Software\\Wine]\n")
+ winverfile.write('"Version"="' + version[0] + '"\n')
+
+ Key9x = "\n[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows\\CurrentVersion]\n"
+ KeyNT = "\n[HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion]\n"
+ KeyProdNT = "\n[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\ProductOptions]\n"
+ KeyWindNT = "\n[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Windows\n"
+ KeyEnvNT = "\n[HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\Environment]\n"
+
+ versionnumber9x = str(version[2]) + '.' + str(version[3]) + '.' + str(version[4])
+ versionnumberNT = str(version[2]) + '.' + str(version[3])
+
+ if version[5] == "VER_PLATFORM_WIN32_WINDOWS":
+ winverfile.write(Key9x + '"VersionNumber"="' + versionnumber9x + '"\n')
+ winverfile.write(Key9x + '"SubVersionNumber"="' + str(version[6]) + '"\n')
+
+ winverfile.write(KeyNT + '"CSDVersion"=-\n')
+ winverfile.write(KeyNT + '"CurrentVersion"=-\n')
+ winverfile.write(KeyNT + '"CurrentBuildNumber"=-\n')
+ winverfile.write(KeyProdNT + '"ProductType"=-\n')
+ winverfile.write(KeyWindNT + '"CSDVersion"=-\n')
+ winverfile.write(KeyEnvNT + '"OS"=-\n')
+ elif version[5] == "VER_PLATFORM_WIN32_NT":
+ winverfile.write(KeyNT + '"CurrentVersion"="' + versionnumberNT + '"\n')
+ winverfile.write(KeyNT + '"CSDVersion"="' + str(version[6]) + '"\n')
+ winverfile.write(KeyNT + '"CurrentBuildNumber"="' + str(version[4]) + '"\n')
+ winverfile.write(KeyProdNT + '"ProductType"="' + str(version[9]) + '"\n')
+ winverfile.write(KeyWindNT + '"CSDVersion"=dword:00000' + str(version[7]) + '00\n')
+ winverfile.write(KeyEnvNT + '"OS"="Windows_NT"\n')
+
+ winverfile.write(Key9x + '"VersionNumber"=-\n')
+ winverfile.write(Key9x + '"SubVersionNumber"=-\n')
+ elif version[5] == "VER_PLATFORM_WIN32s":
+ winverfile.write(Key9x + '"VersionNumber"=-\n')
+ winverfile.write(Key9x + '"SubVersionNumber"=-\n')
+ winverfile.write(KeyNT + '"CSDVersion"=-\n')
+ winverfile.write(KeyNT + '"CurrentVersion"=-\n')
+ winverfile.write(KeyNT + '"CurrentBuildNumber"=-\n')
+ winverfile.write(KeyProdNT + '"ProductType"=-\n')
+ winverfile.write(KeyWindNT + '"CSDVersion"=-\n')
+ winverfile.write(KeyEnvNT + '"OS"=-\n')
+ else:
+ winverfile.write("REGEDIT4\n\n[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "]\n")
+ if version[0] == "global":
+ winverfile.write('"Version"=-\n')
+ else:
+ winverfile.write('"Version"="' + version[0] + '"\n')
+
+ winverfile.close()
+
+ os.system("wine regedit .registrywinver.reg")
+ os.remove(".registrywinver.reg")
+
+def SetApps(apps):
+ """ Adds and removes keys for app specific settings for apps """
+ oldapps = wineread.GetApps()
+ newapps = []
+
+ # Add new app keys
+ for app in apps:
+ if app not in oldapps:
+ newapps.append(app)
+ AddApps(newapps)
+
+ # Remove removed app keys
+ for app in oldapps:
+ if app not in apps:
+ RemoveApp(app)
+
+def RemoveApp(app):
+ """ Removes the key for settings for app """
+ os.system("wine regedit /D HKEY_USERS\\\\S-1-5-4\\\\Software\\\\Wine\\\\AppDefaults\\\\" +\
+ app)
+
+def AddApps(apps):
+ """ Adds a key for app """
+ appsfile=open('.registryapps.reg','w')
+ appsfile.write("REGEDIT4\n\n")
+
+ for app in apps:
+ appsfile.write('[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\' +\
+ app + ']\n')
+
+ appsfile.close()
+ os.system("wine regedit .registryapps.reg")
+ os.remove(".registryapps.reg")
+
+def SetDllOverrides(overrides, app = None):
+ """ Sets the dll override settings in the registry """
+ dllfile=open('.registrydll.reg','w')
+ if not app:
+ dllfile.write("REGEDIT4\n\n[HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides]\n")
+ else:
+ dllfile.write("REGEDIT4\n\n[HKEY_CURRENT_USER\\Software\\Wine\\AppDefaults\\" +\
+ app + "\\DllOverrides]\n")
+
+ origoverrides = wineread.GetDllOverrides(app)
+
+ for dll in overrides.keys():
+ dllfile.write('"'+str(dll)+'"="'+str(overrides[dll])+'"\n')
+
+ for dll in origoverrides.keys():
+ if dll not in overrides:
+ dllfile.write('"'+str(dll)+'"=-\n')
+
+ dllfile.close()
+ os.system("wine regedit .registrydll.reg")
+ os.remove(".registrydll.reg")
+
+def SetDefaultBrowser(browser):
+ """
+ Sets the default browser to browser
+ Doesn't set windows browsers, leaves it for the program to do.
+ """
+ file=open('.registrybrowser.reg','w')
+ file.write("REGEDIT4\n")
+
+ if browser[1] == ':':
+ for format in wineread.default_browser_formats:
+ file.write("\n[HKEY_LOCAL_MACHINE\\Software\\Classes\\" +\
+ format + "\\shell\\open\\command]\n")
+ file.write('@="' + browser + '"\n')
+ file.close()
+
+ os.system("wine regedit .registrybrowser.reg")
+ os.remove(".registrybrowser.reg")
+ else: # winebrowser
+ for format in wineread.default_browser_formats:
+ file.write("\n[HKEY_LOCAL_MACHINE\\Software\\Classes\\" +\
+ format + "\\shell\\open\\command]\n")
+ file.write('@="winebrowser"\n')
+ file.close()
+
+ os.system("wine regedit .registrybrowser.reg")
+ os.remove(".registrybrowser.reg")
+
+ SetFirstBrowser(browser)
+
+def SetDefaultMailer(mailer):
+ """
+ Sets the default mailer to mailer
+ Doesn't set windows mailers, leaves it for the program to do.
+ """
+ file=open('.registrymailer.reg','w')
+ file.write("REGEDIT4\n")
+
+ if mailer[1] == ':':
+ for format in wineread.default_mailer_formats:
+ file.write("\n[HKEY_LOCAL_MACHINE\\Software\\Classes\\" +\
+ format + "\\shell\\open\\command]\n")
+ file.write('@="' + mailer + '"\n')
+ file.close()
+
+ os.system("wine regedit .registrymailer.reg")
+ os.remove(".registrymailer.reg")
+ else: # winebrowser
+ for format in wineread.default_mailer_formats:
+ file.write("\n[HKEY_LOCAL_MACHINE\\Software\\Classes\\" +\
+ format + "\\shell\\open\\command]\n")
+ file.write('@="winebrowser %1"\n')
+ file.close()
+
+ os.system("wine regedit .registrymailer.reg")
+ os.remove(".registrymailer.reg")
+
+ SetFirstMailer(mailer)
+
+def SetFirstBrowser(browser):
+ """ Sets the first in the list of browsers for winebrowser to use to browser """
+ originalbrowserlist = wineread.GetNativeBrowserList()
+
+ if browser in originalbrowserlist:
+ originalbrowserlist.remove(browser)
+ browserlist = [browser] + originalbrowserlist
+
+ browserlist = str(browserlist).strip('[]')
+ browserlist = browserlist.replace("'","")
+ browserlist = browserlist.replace(", ",",")
+
+ SetValue("HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser","Browsers",browserlist)
+
+def SetFirstMailer(mailer):
+ """ Sets the first in the list of mailers for winebrowser to use to mailer """
+ originalmailerlist = wineread.GetNativeMailerList()
+
+ if mailer in originalmailerlist:
+ originalmailerlist.remove(mailer)
+ mailerlist = [mailer] + originalmailerlist
+
+ mailerlist = str(mailerlist).strip('[]')
+ mailerlist = mailerlist.replace("'","")
+ mailerlist = mailerlist.replace(", ",",")
+
+ SetValue("HKEY_CURRENT_USER\\Software\\Wine\\WineBrowser","Mailers",mailerlist)
+
+def CreateWineDrive(path = None):
+ """
+ Creates a fake windows installation in path
+ """
+ if not path:
+ path = wineread.default_winepath
+
+ os.system("WINEPREFIX=" + path + " wineprefixcreate --wait")
+
+# ----- Theming -----
+
+def SetCurrentTheme(theme):
+ """
+ Sets the current theme
+ theme = (theme,color,size), None if none is set
+ """
+ if not theme:
+ theme = ("", "", "")
+
+ themesettings = {"ColorName":theme[1],
+ "SizeName":theme[2],
+ "ThemeActive":"1"}
+
+ if not theme[0]:
+ themesettings["DllName"] = ""
+ themesettings["ThemeActive"] = "0"
+ else:
+ themesettings["DllName"] = "C:\\\\windows\\\\Resources\\\\Themes\\\\" +\
+ theme[0] + "\\\\" + theme[0] +".msstyles"
+
+ themefile=open('.registrytheme.reg','w')
+ themefile.write("REGEDIT4\n\n[HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager]\n")
+ for setting in themesettings:
+ if themesettings[setting]:
+ themefile.write('"'+str(setting)+'"="'+str(themesettings[setting])+'"\n')
+ else:
+ themefile.write('"'+str(setting)+'"=-\n')
+
+ themefile.close()
+ os.system("wine regedit .registrytheme.reg")
+ os.remove(".registrytheme.reg")
+
+def SetColorSettings(colors):
+ """ Takes a dictionary of color settings and sets them in the registry """
+ SetKeyValues("HKEY_CURRENT_USER\\Control Panel\\Colors",colors)
+ SetKeyValues("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager\\Control Panel\\Colors",colors)
+
+def SetWindowMetrics(metrics):
+ """
+ Takes a dictionary of WindowMetrics settings and sets them in the registry
+ """
+ SetKeyValues("HKEY_CURRENT_USER\\Control Panel\\Desktop\\WindowMetrics",metrics)
+
+ports_translation = {"lp":"lpt","ttyS":"com"}
+
+def CreatePorts(ports = None):
+ """
+ Creates links to ports in dosdevices
+ """
+ if not ports:
+ # Find ports in /dev
+ ports = ["lp0"]
+
+ for port in ports:
+ winport = ports_translation[port.rstrip("012345678")] +\
+ str(int(port.lstrip("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")) + 1)
+ os.symlink("/dev/" + port, wineread.winepath + "/dosdevices/" + winport)
+ \ No newline at end of file