#!/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 tdecore import *
from tdeui import *
from tdefile 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 = TDECModule

############################################################################
class WineConfigApp(programbase):
    ########################################################################
    def __init__(self,parent=None,name=None):
        global standalone,kapp,default_winepath,application
        TDEGlobal.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 = TDECmdLineArgs.parsedArgs()
            if args.count() > 0:
                application = args.arg(0)
        else:
            TDECModule.__init__(self,parent,name)
            self.setButtons(TDECModule.Apply|TDECModule.Reset)
            self.aboutdata = MakeAboutData()

        # Create a configuration object.
        self.config = TDEConfig("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

        TDEGlobal.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 tdesudo, adept_batch
        and software-properties-kde """
        if not isroot:
            if os.system("tdesudo \"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("tdesudo \"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): # TDECModule
        # 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): # TDECModule
        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(TDEGlobalSettings.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 = TDEConfig("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 = TDEConfig("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 = TDEConfig("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 = TDEApplication.kApplication()
    return WineConfigApp(parent, name)

############################################################################
def MakeAboutData():
    aboutdata = TDEAboutData("guidance",programname,version, \
        "Wine Configuration Tool", TDEAboutData.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()
    TDECmdLineArgs.init(sys.argv,aboutdata)

    # Can't do i18n?
    options = [("+[appname]", str(i18n("Application to change settings for")))]
    TDECmdLineArgs.addCmdLineOptions( options )

    kapp = TDEApplication()

    wineconfigapp = WineConfigApp()
    wineconfigapp.exec_loop(None)