diff options
Diffstat (limited to 'displayconfig/displayconfig.py')
-rwxr-xr-x | displayconfig/displayconfig.py | 1756 |
1 files changed, 0 insertions, 1756 deletions
diff --git a/displayconfig/displayconfig.py b/displayconfig/displayconfig.py deleted file mode 100755 index cc2ad79..0000000 --- a/displayconfig/displayconfig.py +++ /dev/null @@ -1,1756 +0,0 @@ -#!/usr/bin/python -# -*- coding: UTF-8 -*- -########################################################################### -# displayconfig.py - description # -# ------------------------------ # -# begin : Fri Mar 26 2004 # -# copyright : (C) 2004-2006 by Simon Edwards # -# email : simon@simonzone.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 * -import xorgconfig -import xf86misc -import string -import os -import select -import sys -import csv -import time -import signal -import shutil -from ktimerdialog import * -from displayconfigwidgets import * -from displayconfigabstraction import * -from execwithcapture import * - -programname = "Display and Graphics Configuration" -version = "0.8.0" -DUAL_PREVIEW_SIZE = 240 - -# Are we running as a separate standalone application or in KControl? -standalone = __name__=='__main__' - -# Running as the root user or not? -isroot = os.getuid()==0 - -############################################################################ -class GfxCardDialog(KDialogBase): - video_ram_list = [256,512,1024,2048,4096,8192,16384,32768,65536] - - def __init__(self,parent): - KDialogBase.__init__(self,parent,None,True,"Choose Graphics Card", - KDialogBase.Ok|KDialogBase.Cancel, KDialogBase.Cancel) - - self.gfxcarddb = None - self.updatingGUI = True - self.card2listitem = {} - - topbox = QVBox(self) - topbox.setSpacing(KDialog.spacingHint()) - self.setMainWidget(topbox) - label = QLabel(topbox) - label.setText(i18n("Select Graphics Card:")) - self.listview = TDEListView(topbox) - self.listview.addColumn("") - self.listview.header().hide() - self.listview.setRootIsDecorated(True) - self.connect(self.listview,SIGNAL("selectionChanged(QListViewItem *)"),self.slotListClicked) - topbox.setStretchFactor(self.listview,1) - - self.driver = TDEListViewItem(self.listview) - self.driver.setText(0,i18n("Drivers")) - self.driver.setSelectable(False) - - self.manufacturer = TDEListViewItem(self.listview) - self.manufacturer.setText(0,i18n("Manufacturers")) - self.manufacturer.setSelectable(False) - - hbox = QHBox(topbox) - topbox.setStretchFactor(hbox,0) - vbox = QVBox(hbox) - - self.detected_label = QLabel("",vbox) - - self.detected_button = KPushButton(vbox) - self.detected_button.setText(i18n("Select")) - self.connect(self.detected_button,SIGNAL("clicked()"),self.slotSelectDetectedClicked) - - spacer = QWidget(vbox) - vbox.setStretchFactor(self.detected_button,0) - vbox.setStretchFactor(spacer,1) - - hbox.setStretchFactor(vbox,0) - spacer = QWidget(hbox) - hbox.setStretchFactor(spacer,1) - - drivergrid = QGrid(2,hbox) - drivergrid.setSpacing(KDialog.spacingHint()) - QLabel(i18n("Driver:"),drivergrid) - self.standarddriverradio = QRadioButton(i18n("Standard"),drivergrid) - self.connect(self.standarddriverradio,SIGNAL("clicked()"),self.slotStandardDriverClicked) - QWidget(drivergrid) - self.proprietarydriverradio = QRadioButton(i18n("Proprietary"),drivergrid) - self.connect(self.proprietarydriverradio,SIGNAL("clicked()"),self.slotProprietaryDriverClicked) - - QLabel(i18n("Video RAM:"),drivergrid) - self.videoramcombo = QComboBox(drivergrid) - for s in [i18n("256 kB"), - i18n("512 kB"), - i18n("1 MB"), - i18n("2 MB"), - i18n("4 MB"), - i18n("8 MB"), - i18n("16 MB"), - i18n("32 MB"), - i18n("64 MB or more")]: - self.videoramcombo.insertItem(s) - - self.updatingGUI = False - self._setGfxCardDB(GetGfxCardModelDB()) - - def _setGfxCardDB(self,gfxcarddb): - self.updatingGUI = True - self.gfxcarddb = gfxcarddb - - # Add the GfxCards under the Manufacturer item. - keys = gfxcarddb.vendordb.keys() - keys.sort() - for key in keys: - cardkeys = self.gfxcarddb.vendordb[key].keys() - vendoritem = TDEListViewItem(self.manufacturer) - vendoritem.setText(0,key) - vendoritem.setSelectable(False) - for cardkey in cardkeys: - item = TDEListViewItem(vendoritem) - item.setText(0,cardkey) - self.card2listitem[self.gfxcarddb.vendordb[key][cardkey]] = item - - # Add the GfxCard _drivers_ under the Drivers item - drivers = gfxcarddb.driverdb.keys() - drivers.sort() - for driver in drivers: - driveritem = TDEListViewItem(self.driver) - driveritem.setText(0,driver) - self.card2listitem[gfxcarddb.driverdb[driver]] = driveritem - - self.updatingGUI = False - - def do(self,card,proprietarydriver,detected_card,video_ram): - self.updatingGUI = True - item = self.card2listitem[card] - self.listview.setSelected(item,True) - self.listview.ensureItemVisible(item) - - self.selected_video_ram = video_ram - - if detected_card is None: - self.detected_button.setEnabled(False) - self.detected_label.setText(i18n("Detected graphics card:\n(unknown)")) - else: - self.detected_button.setEnabled(True) - self.detected_label.setText(i18n("Detected graphics card:\n'%1'.").arg(detected_card.getName())) - - self.__syncDriver(card,proprietarydriver,video_ram) - - self.detected_card = detected_card - self.selected_card = card - self.updatingGUI = False - - if self.exec_loop()==QDialog.Accepted: - return (self.selected_card, - self.proprietarydriverradio.isChecked() and (self.selected_card is not None), - self.video_ram_list[self.videoramcombo.currentItem()]) - else: - return (card, proprietarydriver,video_ram) - - def __syncDriver(self,card,proprietarydriver,videoram): - if card.getProprietaryDriver() is None: - self.standarddriverradio.setChecked(True) - self.standarddriverradio.setEnabled(False) - self.proprietarydriverradio.setEnabled(False) - else: - self.standarddriverradio.setEnabled(True) - self.proprietarydriverradio.setEnabled(True) - self.standarddriverradio.setChecked(not proprietarydriver) - self.proprietarydriverradio.setChecked(proprietarydriver) - - self.videoramcombo.setEnabled(card.getNeedVideoRam()) - if card.getNeedVideoRam(): - self.videoramcombo.setCurrentItem(self.video_ram_list.index(videoram)) - - def slotSelectDetectedClicked(self): - self.updatingGUI = True - item = self.card2listitem[self.detected_card] - self.listview.setSelected(item,True) - self.listview.ensureItemVisible(item) - self.selected_card = self.detected_card - self.__syncDriver(self.selected_card, self.proprietarydriverradio.isChecked(), self.selected_video_ram) - self.updatingGUI = False - - def slotListClicked(self,item): - if self.updatingGUI: - return - - for key in self.card2listitem: - value = self.card2listitem[key] - if value is item: - self.selected_card = key - self.__syncDriver(self.selected_card, self.proprietarydriverradio.isChecked(), self.selected_video_ram) - - def slotStandardDriverClicked(self): - self.proprietarydriverradio.setChecked(False) - self.standarddriverradio.setChecked(True) - - def slotProprietaryDriverClicked(self): - self.standarddriverradio.setChecked(False) - self.proprietarydriverradio.setChecked(True) - -############################################################################ -class MonitorDialog(KDialogBase): - def __init__(self,parent): - KDialogBase.__init__(self,parent,None,True,"Choose Monitor", - KDialogBase.Ok|KDialogBase.Cancel, KDialogBase.Cancel) - - self.monitordb = None - self.selectedmonitor = None - self.aspect = ModeLine.ASPECT_4_3 - self.monitor2listitem = {} - self.updatingGUI = True - - topbox = QVBox(self) - topbox.setSpacing(KDialog.spacingHint()) - self.setMainWidget(topbox) - label = QLabel(topbox) - label.setText(i18n("Select Monitor:")) - self.listview = TDEListView(topbox) - self.listview.addColumn("") - self.listview.header().hide() - self.listview.setRootIsDecorated(True) - self.connect(self.listview,SIGNAL("selectionChanged(QListViewItem *)"),self.slotListClicked) - - self.generic = TDEListViewItem(self.listview) - self.generic.setText(0,i18n("Generic")) - self.generic.setSelectable(False) - - self.manufacturer = TDEListViewItem(self.listview) - self.manufacturer.setText(0,i18n("Manufacturers")) - self.manufacturer.setSelectable(False) - - grid = QGroupBox(4,QGroupBox.Horizontal,topbox) - grid.setTitle(i18n("Details")) - - label = QLabel(grid) - label.setText(i18n("Horizontal Range:")) - - self.horizrange = KLineEdit(grid) - self.horizrange.setReadOnly(True) - - label = QLabel(grid) - label.setText(i18n("Vertical Refresh:")) - - self.vertrange = KLineEdit(grid) - self.vertrange.setReadOnly(True) - - hbox = QHBox(topbox) - - self.detectbutton = KPushButton(hbox) - self.detectbutton.setText(i18n("Detect Monitor")) # FIXME better label/text? - self.connect(self.detectbutton,SIGNAL("clicked()"),self.slotDetectClicked) - - spacer = QWidget(hbox) - hbox.setStretchFactor(self.detectbutton,0) - hbox.setStretchFactor(spacer,1) - - label = QLabel(hbox) - label.setText(i18n("Image format:")) - hbox.setStretchFactor(label,0) - - self.aspectcombobox = KComboBox(hbox) - self.aspectcombobox.insertItem(i18n("Standard 4:3")) - self.aspectcombobox.insertItem(i18n("Widescreen 16:9")) - hbox.setStretchFactor(self.aspectcombobox,0) - - self.updatingGUI = False - - def setMonitorDB(self,monitordb): - self.monitordb = monitordb - - # Add the Monitors - vendors = monitordb.vendordb.keys() - vendors.sort() - for vendor in vendors: - monitorkeys = self.monitordb.vendordb[vendor].keys() - vendoritem = TDEListViewItem(self.manufacturer) - vendoritem.setText(0,vendor) - vendoritem.setSelectable(False) - for monitorkey in monitorkeys: - item = TDEListViewItem(vendoritem) - item.setText(0,monitorkey) - self.monitor2listitem[self.monitordb.vendordb[vendor][monitorkey]] = item - - generics = monitordb.genericdb.keys() - generics.sort() - for generic in generics: - genericitem = TDEListViewItem(self.generic) - genericitem.setText(0,generic) - self.monitor2listitem[monitordb.genericdb[generic]] = genericitem - - customs = monitordb.getCustomMonitors().keys() - customs.sort() - for custom in customs: - customitem = TDEListViewItem(self.listview) - customitem.setText(0,custom) - self.monitor2listitem[monitordb.getCustomMonitors()[custom]] = customitem - - def do(self,monitor,aspect,is_primary_monitor=True): - """Run the monitor selection dialog. - - Parameters: - - monitor - Currently selected 'Monitor' object. - - Returns the newly selected monitor object and aspect ratio as a tuple. - """ - if monitor is not None: - self.selectedmonitor = monitor - item = self.monitor2listitem[monitor] - - self.listview.setSelected(item,True) - self.listview.ensureItemVisible(item) - - else: - self.selectedmonitor = None - self.listview.clearSelection() - self.aspect = aspect - - # Only the first/primary monitor can be detected. :-/ - self.detectbutton.setEnabled(is_primary_monitor) - - self.updatingGUI = True - self._syncGUI() - self.updatingGUI = False - - if self.exec_loop()!=QDialog.Accepted: - # Dialog was cancelled. Return the original monitor. - self.selectedmonitor = monitor - else: - self.aspect = [ModeLine.ASPECT_4_3,ModeLine.ASPECT_16_9][self.aspectcombobox.currentItem()] - - return (self.selectedmonitor,self.aspect) - - def slotDetectClicked(self): - detectedmonitor = self.monitordb.detect() - if detectedmonitor is not None: - self.selectedmonitor = detectedmonitor - self._syncGUI() - else: - KMessageBox.error(self, i18n("Sorry, the model and capabilities of your\nmonitor couldn't be detected."), - i18n("Monitor detection failed")) - - def slotListClicked(self,item): - if self.updatingGUI: - return - self.updatingGUI = True - for key in self.monitor2listitem: - value = self.monitor2listitem[key] - if value is item: - self.selectedmonitor = key - break - self._syncGUI() - self.updatingGUI = False - - def _syncGUI(self): - if self.selectedmonitor is not None: - item = self.monitor2listitem[self.selectedmonitor] - self.listview.setSelected(item,True) - self.listview.ensureItemVisible(item) - self.vertrange.setText(self.selectedmonitor.getVerticalSync()) - self.horizrange.setText(self.selectedmonitor.getHorizontalSync()) - else: - self.vertrange.setText("-") - self.horizrange.setText("-") - - self.aspectcombobox.setCurrentItem({ModeLine.ASPECT_4_3:0,ModeLine.ASPECT_16_9:1}[self.aspect]) - -############################################################################ -if standalone: - programbase = KDialogBase -else: - programbase = TDECModule - -############################################################################ -class DisplayApp(programbase): - ######################################################################## - def __init__(self,parent=None,name=None): - global standalone,isroot,kapp - TDEGlobal.locale().insertCatalogue("guidance") - - if standalone: - KDialogBase.__init__(self,KJanusWidget.Tabbed,"Display Configuration",\ - KDialogBase.Apply|KDialogBase.User1|KDialogBase.User2|KDialogBase.Close, KDialogBase.Close) - self.setButtonText(KDialogBase.User1,i18n("Reset")) - self.setButtonText(KDialogBase.User2,i18n("About")) - else: - TDECModule.__init__(self,parent,name) - self.setButtons(TDECModule.Apply|TDECModule.Reset) - self.aboutdata = MakeAboutData() - - # This line has the effect of hiding the "Admin only" message and also forcing - # the Apply/Reset buttons to be shown. Yippie! Only had to read the source - # to work that out. - self.setUseRootOnlyMsg(False) - - # Create a configuration object. - self.config = TDEConfig("displayconfigrc") - - # 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") - - global imagedir - imagedir = unicode(TDEGlobal.dirs().findDirs("data","guidance/pics/displayconfig")[0]) - - self.imagedir = imagedir - - self.xconfigchanged = False - self.xconfigtested = True - - self.availabletargetgammas = [unicode(i18n('1.4')),unicode(i18n('1.6')),unicode(i18n('1.8')),unicode(i18n('2.0')),unicode(i18n('2.2')),unicode(i18n('2.4'))] - self.lightimages = [] - self.mediumimages = [] - self.darkimages = [] - - # X Server stuff - self.xf86server = xf86misc.XF86Server() - - self.xconfigpath = self._findXorgConfig() - SetDataFileDir(unicode(TDEGlobal.dirs().findResourceDir("data","guidance/pcitable")) + "guidance/") - self.xsetup = XSetup(self.xconfigpath) - - self.updatingGUI = True - self.gfxcarddb = GfxCardModelDB() - self.monitordb = GetMonitorModelDB() - self.monitormodedb = GetMonitorModeDB() - - self._buildGUI() - - # Work out if the currently running Gfxdriver is safe enough that we - # can test other drivers at the same time. - self.badfbrestore = self._badFbRestore() - self.testbutton.setEnabled(isroot and not self._badFbRestore()) - if isroot and not self._badFbRestore(): - self.testunavailablelabel.hide() - else: - self.testunavailablelabel.show() - - # Load up some of our databases, and initialise our state variables. - if len(self.xsetup.getUsedScreens()): - self.currentsizescreen = self.xsetup.getUsedScreens()[0] - self.currentgammascreen = self.xsetup.getUsedScreens()[0] - else: - # FIXME - print "Houston, we have a problem: No screens found in configuration file, exiting. :(" - sys.exit(1) - - self.monitordialog.setMonitorDB(self.monitordb) - - self.aboutus = TDEAboutApplication(self) - - # For centering the timed Apply dialog. - self.applytimerdialog = None - self.connect(kapp.desktop(), SIGNAL("resized(int)"), self.slotDesktopResized) - self.applydialogscreenindex = 0 - - self.__loadImages() - self._loadConfig() - self._syncGUI() - - if standalone: - self.enableButton(KDialogBase.User1,False) # Reset button - self.enableButtonApply(False) # Apply button - - self.updatingGUI = False - - def _findXorgConfig(self): - # Lookup location of X configfile - for line in ExecWithCapture("xset", ["xset","q"],True).split('\n'): - if line.strip().startswith("Config file"): - return line.split(":")[1].strip() - # Sometimes, xset doesn't know about the configfile location, hence ... - if os.path.isfile("/etc/X11/xorg.conf"): - return "/etc/X11/xorg.conf" - return None - - def _buildGUI(self): - global standalone - if not standalone: - toplayout = QVBoxLayout( self, 0, KDialog.spacingHint() ) - tabcontrol = QTabWidget(self) - toplayout.addWidget(tabcontrol) - toplayout.setStretchFactor(tabcontrol,1) - - #--- Size, Orientation and Positioning --- - tabname = i18n("Size, Orientation && Positioning") - if standalone: - sopage = self.addGridPage(1,QGrid.Horizontal,tabname) - sopage.setSpacing(0) - self.SizePage = SizeOrientationPage(sopage,self.xsetup,self.compact_mode) - else: - self.SizePage = SizeOrientationPage(tabcontrol,self.xsetup,self.compact_mode) - self.SizePage.setMargin(KDialog.marginHint()) - - # Connect all PYSIGNALs from SizeOrientationPage Widget to appropriate actions. - self.connect(self.SizePage,PYSIGNAL("changedSignal()"),self._sendChangedSignal) - self.connect(self.SizePage,PYSIGNAL("resolutionChange(int)"),self.slotResolutionChange) - - if not standalone: - tabcontrol.addTab(self.SizePage,tabname) - - #--- Color & Gamma tab --- - tabname = i18n("Color && Gamma") - if standalone: - gammapage = self.addVBoxPage(tabname) - vbox = QVBox(gammapage) - else: - vbox = QVBox(tabcontrol) - vbox.setMargin(KDialog.marginHint()) - vbox.setSpacing(KDialog.spacingHint()) - - hbox = QHBox(vbox) - hbox.setSpacing(KDialog.spacingHint()) - vbox.setStretchFactor(hbox,0) - label = QLabel(hbox,"textLabel1") - label.setText(i18n("Screen:")) - hbox.setStretchFactor(label,0) - self.gammadisplaycombobox = QComboBox(0,hbox,"comboBox11") - hbox.setStretchFactor(self.gammadisplaycombobox,0) - spacer = QWidget(hbox) - hbox.setStretchFactor(spacer,1) - self.connect(self.gammadisplaycombobox,SIGNAL("activated(int)"),self.slotGammaScreenCombobox) - - # fill the combobox. - for screen in self.xsetup.getUsedScreens(): - self.gammadisplaycombobox.insertItem(screen.getName()) - - if not self.compact_mode: - # Create the colour matching pics - label = QLabel(vbox) - label.setText(i18n("Color calibration image:")) - vbox.setStretchFactor(label,0) - - hbox = QWidget(vbox) - hboxlayout = QHBoxLayout(hbox) - hboxlayout.setSpacing(KDialog.spacingHint()) - self.mediumpic = QLabel(hbox) - self.mediumpic.setFixedSize(305,105) - hboxlayout.addWidget(self.mediumpic,0,Qt.AlignTop) - - label = QLabel(hbox) - label.setPixmap(SmallIcon('info')) - hboxlayout.addWidget(label,0,Qt.AlignTop) - - label = QLabel(i18n("<qt><p>Gamma controls how your monitor displays colors.</p><p>For accurate color reproduction, adjust the gamma correction sliders until the squares blend into the background as much as possible.</p></qt>"),hbox) - label.setTextFormat(Qt.RichText) - hboxlayout.addWidget(label,1,Qt.AlignTop) - - sliderspace = QWidget(vbox) - - grid = QGridLayout(sliderspace, 9, 4, 0, KDialog.spacingHint()) - grid.setSpacing(KDialog.spacingHint()) - grid.setColStretch(0,0) - grid.setColStretch(1,0) - grid.setColStretch(2,0) - grid.setColStretch(3,1) - - label = QLabel(i18n("Gamma correction:"),sliderspace) - grid.addWidget(label, 0, 0) - - self.gammaradiogroup = QButtonGroup() - self.gammaradiogroup.setRadioButtonExclusive(True) - self.connect(self.gammaradiogroup,SIGNAL("clicked(int)"),self.slotGammaRadioClicked) - - self.allradio = QRadioButton(sliderspace) - grid.addWidget(self.allradio, 0, 1, Qt.AlignTop) - - label = QLabel(i18n("All:"),sliderspace) - grid.addWidget(label, 0, 2) - - self.gammaslider = KDoubleNumInput(0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'gammaslider') - grid.addMultiCellWidget(self.gammaslider,0,1,3,3) - self.gammaslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.gammaslider, SIGNAL("valueChanged(double)"), self.slotGammaChanged) - - self.componentradio = QRadioButton(sliderspace) - grid.addWidget(self.componentradio, 2, 1, Qt.AlignTop) - - label = QLabel(i18n("Red:"),sliderspace) - grid.addWidget(label, 2, 2) - - self.redslider = KDoubleNumInput(self.gammaslider,0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'redslider') - grid.addMultiCellWidget(self.redslider,2,3,3,3) - self.redslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.redslider, SIGNAL("valueChanged(double)"), self.slotRedChanged) - - label = QLabel(i18n("Green:"),sliderspace) - grid.addWidget(label, 4, 2) - - self.greenslider = KDoubleNumInput(self.redslider,0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'greenslider') - grid.addMultiCellWidget(self.greenslider,4,5,3,3) - self.greenslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.greenslider, SIGNAL("valueChanged(double)"), self.slotGreenChanged) - - label = QLabel(i18n("Blue:"),sliderspace) - grid.addWidget(label, 6, 2) - - self.blueslider = KDoubleNumInput(self.greenslider,0.4, 3.5, 2.0, 0.05, 2, sliderspace, 'blueslider') - grid.addMultiCellWidget(self.blueslider,6,7,3,3) - self.blueslider.setRange(0.5, 2.5, 0.05, True) - self.connect(self.blueslider, SIGNAL("valueChanged(double)"), self.slotBlueChanged) - - self.gammaradiogroup.insert(self.allradio,0) - self.gammaradiogroup.insert(self.componentradio,1) - - if not self.compact_mode: - label = QLabel(i18n("Target gamma:"),sliderspace) - grid.addWidget(label, 8, 0) - - hbox = QHBox(sliderspace) - self.targetgammacombo = KComboBox(False,hbox) - self.targetgammacombo.insertItem(i18n('1.4')) - self.targetgammacombo.insertItem(i18n('1.6')) - self.targetgammacombo.insertItem(i18n('1.8 Apple Macintosh standard')) - self.targetgammacombo.insertItem(i18n('2.0 Recommend')) - self.targetgammacombo.insertItem(i18n('2.2 PC standard, sRGB')) - self.targetgammacombo.insertItem(i18n('2.4')) - hbox.setStretchFactor(self.targetgammacombo,0) - spacer = QWidget(hbox) - hbox.setStretchFactor(spacer,1) - grid.addMultiCellWidget(hbox, 8, 8, 1, 3) - - self.connect(self.targetgammacombo,SIGNAL("activated(int)"),self.slotTargetGammaChanged) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - if not standalone: - tabcontrol.addTab(vbox,tabname) - - #--- Hardware tab --- - if standalone: - hardwarepage = self.addVBoxPage(i18n("Hardware")) - vbox = QVBox(hardwarepage) - else: - vbox = QVBox(tabcontrol) - vbox.setMargin(KDialog.marginHint()) - self.gfxcarddialog = GfxCardDialog(None) - self.monitordialog = MonitorDialog(None) - - self.xscreenwidgets = [] - - for gfxcard in self.xsetup.getGfxCards(): - w = GfxCardWidget(vbox,self.xsetup, gfxcard, self.gfxcarddialog, self.monitordialog) - self.xscreenwidgets.append(w) - self.connect(w,PYSIGNAL("configChanged"),self.slotConfigChanged) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - if not self.xsetup.mayModifyXorgConfig(): - QLabel(i18n("Changes on this tab require 'root' access."),vbox) - if not standalone: - QLabel(i18n("Click the \"Administrator Mode\" button to allow modifications on this tab."),vbox) - - hbox = QHBox(vbox) - hbox.setSpacing(KDialog.spacingHint()) - self.testbutton = KPushButton(i18n("Test"),hbox) - self.connect(self.testbutton,SIGNAL("clicked()"),self.slotTestClicked) - hbox.setStretchFactor(self.testbutton,0) - - self.testunavailablelabel = QHBox(hbox) - self.testunavailablelabel.setSpacing(KDialog.spacingHint()) - tmplabel = QLabel(self.testunavailablelabel) - self.testunavailablelabel.setStretchFactor(tmplabel,0) - tmplabel.setPixmap(SmallIcon('info')) - label = QLabel(i18n("This configuration cannot be safely tested."),self.testunavailablelabel) - self.testunavailablelabel.setStretchFactor(label,1) - self.testunavailablelabel.hide() - - spacer = QWidget(hbox) - hbox.setStretchFactor(spacer,1) - vbox.setStretchFactor(hbox,0) - - if not standalone: - tabcontrol.addTab(vbox,i18n("Hardware")) - - #--- Display Power Saving --- - tabname = i18n("Power saving") - if standalone: - powerpage = self.addGridPage(1,QGrid.Horizontal,tabname) - self.dpmspage = DpmsPage(powerpage) - else: - self.dpmspage = DpmsPage(tabcontrol) - self.dpmspage.setMargin(KDialog.marginHint()) - - #self.SizePage.setScreens(self.xsetup.getScreens()) - - # Connect all PYSIGNALs from SizeOrientationPage Widget to appropriate actions. - #self.connect(self.SizePage,PYSIGNAL("dualheadEnabled(bool)"),self.slotDualheadEnabled) - self.connect(self.dpmspage,PYSIGNAL("changedSignal()"),self._sendChangedSignal) - - if not standalone: - tabcontrol.addTab(self.dpmspage,tabname) - - def save(self): # TDECModule - xorg_config_changed = self.xsetup.isXorgConfigChanged() - restart_recommended = self.xsetup.getRestartHint() - - # Check the Size & Orientation tab. - if self.applytimerdialog is None: - self.applytimerdialog = KTimerDialog(15000, KTimerDialog.CountDown, self, "mainKTimerDialog", - True, i18n("Confirm Display Setting Change"), KTimerDialog.Ok | KTimerDialog.Cancel, \ - KTimerDialog.Cancel) - self.applytimerdialog.setButtonOK(KGuiItem(i18n("&Keep"), "button_ok")) - self.applytimerdialog.setButtonCancel(KGuiItem(i18n("&Cancel"), "button_cancel")) - label = KActiveLabel(i18n("Trying new screen settings. Keep these new settings? (Automatically cancelling in 15 seconds.)"), - self.applytimerdialog, "userSpecifiedLabel") - self.applytimerdialog.setMainWidget(label) - - if self.xsetup.isLiveResolutionConfigChanged(): - if self.xsetup.applyLiveResolutionChanges(): - # running X server config has changed. Ask the user. - KDialog.centerOnScreen(self.applytimerdialog, 0) - if self.applytimerdialog.exec_loop(): - self.xsetup.acceptLiveResolutionChanges() - else: - try: - self.xsetup.rejectLiveResolutionChanges() - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - return - else: - # Nothing really changed, just accept the changes. - self.xsetup.acceptLiveResolutionChanges() - - - self.xsetup.acceptLiveGammaChanges() - self.dpmspage.apply() - - # Save the X server config. - if isroot and xorg_config_changed: - - if not self.xconfigtested: - if self.badfbrestore or self._badFbRestore(): - if KMessageBox.warningContinueCancel(self, \ - i18n("The selected driver and monitor configuration can not be safely tested on this computer.\nContinue with this configuration?"), - i18n("Configuration not tested"))!=KMessageBox.Continue: - return - else: - if KMessageBox.warningContinueCancel(self, - i18n("The selected driver and monitor configuration has not been successfully tested on this computer.\nContinue with this configuration?"), - i18n("Configuration not tested"))!=KMessageBox.Continue: - return - - try: - # Backup up the current config file. - i = 1 - while os.path.exists("%s.%i" % (self.xconfigpath,i)): - i += 1 - try: - shutil.copyfile(self.xconfigpath,"%s.%i" % (self.xconfigpath,i)) - except IOError, errmsg: - print "IOError", errmsg, " - while trying to save new xorg.conf - trying to fix" - self.xconfigpath = "/etc/X11/xorg.conf" - xorgfile = open(self.xconfigpath, 'a') - xorgfile.close() - shutil.copyfile(self.xconfigpath,"%s.%i" % (self.xconfigpath,i)) - - # Write out the new config - tmpfilename = self.xconfigpath + ".tmp" - self.xsetup.writeXorgConfig(tmpfilename) - - os.rename(tmpfilename,self.xconfigpath) - except (IOError,TypeError): - print "******* Bang" - raise - return - # FIXME error - - # FIXME the instructions in these messages are probably not quite right. - if restart_recommended==XSetup.RESTART_X: - KMessageBox.information(self, - i18n("Some changes require that the X server be restarted before they take effect. Log out and select \"Restart X server\" from the menu button."), - i18n("X Server restart recommend")) - - if restart_recommended==XSetup.RESTART_SYSTEM: - KMessageBox.information(self, - i18n("Some changes require that the entire system be restarted before they take effect. Log out and select \"Restart computer\" from the log in screen."), - i18n("System restart recommend")) - - self._saveConfig() - self._sendChangedSignal() - - # Called when the desktop is resized. Just center the confirm dialog. - def slotDesktopResized(self): - if self.applytimerdialog is not None: - KDialog.centerOnScreen(self.applytimerdialog, self.applydialogscreenindex) - - def slotApply(self): # KDialogBase - self.save() - - def slotClose(self): # KDialogBase - try: - self.xsetup.rejectLiveGammaChanges() - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - 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 slotResolutionChange(self,i): - self.currentsizescreen.setResolutionIndex(i) - self._sendChangedSignal() - - def slotTargetGammaChanged(self,i): - self.targetgamma = i - self._selectGamma(self.targetgamma) - self._sendChangedSignal() - - def slotGammaRadioClicked(self,i): - self.settingall = i==0 - self.gammaslider.setDisabled(not self.settingall) - self.redslider.setDisabled(self.settingall) - self.greenslider.setDisabled(self.settingall) - self.blueslider.setDisabled(self.settingall) - try: - if self.settingall: - self.currentgammascreen.setAllGamma(self.currentgammascreen.getAllGamma()) - else: - self.currentgammascreen.setRedGamma(self.currentgammascreen.getRedGamma()) - self.currentgammascreen.setGreenGamma(self.currentgammascreen.getGreenGamma()) - self.currentgammascreen.setBlueGamma(self.currentgammascreen.getBlueGamma()) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotGammaChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setAllGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotRedChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setRedGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotGreenChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setGreenGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotBlueChanged(self,value): - if self.updatingGUI: - return - try: - self.currentgammascreen.setBlueGamma(value) - except: - """Workaround! FIXME: Use isGammaLive function in displayconfigabstraction when this is implemented""" - print "Live gamma change not supported" - self._sendChangedSignal() - - def slotGammaScreenCombobox(self,i): - self.currentgammascreen = self.xsetup.getUsedScreens()[i] - self._syncGUI() - self._sendChangedSignal() - - def slotConfigChanged(self): - self.xconfigchanged = True - self.xconfigtested = False - - # Check if the current X config can be tested. - self.SizePage._syncGUI() - for widget in self.xscreenwidgets: - widget.syncConfig() - self._syncTestButton() - self._sendChangedSignal() - - def slotTestClicked(self): - self.xconfigtested = self.testX() - - def testX(self): - - self.xserverbin = "/usr/X11R6/bin/XFree86" - if not os.path.isfile(self.xserverbin): - self.xserverbin = "/usr/X11R6/bin/Xorg" - rc = False - - # Remove an stale X server lock - try: os.remove("/tmp/.X9-lock") - except OSError: pass - - # Try to find a safe tmp dir. - tmp_dir = None - if os.environ.get("TMPDIR") is not None: - tmp_dir = os.environ.get("TMPDIR") - if tmp_dir is None or not os.path.isdir(tmp_dir): - tmp_dir = os.path.join(os.environ.get("HOME"),"tmp") - if not os.path.isdir(tmp_dir): - tmp_dir = "/tmp" - working_tmp_dir = os.path.join(tmp_dir,"guidance."+str(os.getpid())) - error_filename = os.path.join(working_tmp_dir,"testserver.xoutput") - config_filename = os.path.join(working_tmp_dir,"testserver.config") - auth_filename = os.path.join(working_tmp_dir,"xauthority") - - # Start the Xserver up with the new config file. - try: - # Create our private dir. - os.mkdir(working_tmp_dir,0700) - - # Backup the XAUTHORITY environment variable. - old_xauthority = os.environ.get("XAUTHORITY",None) - - # Write out the new config file. - self.xsetup.writeXorgConfig(config_filename) - - os.system("xauth -f %s add :9 . `mcookie`" % (auth_filename,) ) - # FIXME:: -xf86config is nowhere in man X ?? - pid = os.spawnv(os.P_NOWAIT,"/bin/bash",\ - ["bash","-c","exec %s :9 -xf86config %s -auth %s &> %s" % \ - (self.xserverbin, config_filename, auth_filename, error_filename)]) - print "Got pid",pid - - # Wait for the server to show up. - print str(os.waitpid(pid,os.WNOHANG)) - - # Use our private xauthority file. - os.environ["XAUTHORITY"] = auth_filename - - time.sleep(1) # Wait a sec. - testserver = None - while True: - # Try connecting to the server. - try: - testserver = xf86misc.XF86Server(":9") - break - except xf86misc.XF86Error: - testserver = None - # Check if the server process is still alive. - if os.waitpid(pid,os.WNOHANG) != (0,0): - break - time.sleep(1) # Give the server some more time. - - print "checkpoint 1" - print str(testserver) - - if testserver is not None: - # Start the timed popup on the :9 display. - #servertestpy = str(TDEGlobal.dirs().findResource("data","guidance/servertestdialog.py")) - servertestpy = os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])),"servertestdialog.py") - pythonexe = unicode(TDEStandardDirs.findExe("python")) - - testrc = os.system(pythonexe + " " + servertestpy + " '" + auth_filename+"' ") - rc = (rc >> 8) == 0 # Test is good if the return code was 0. - testserver = None - os.kill(pid,signal.SIGINT) - else: - # Server failed, read the error info. - msg = "" - try: - fhandle = open(error_filename,'r') - for line in fhandle.readlines(): - if (line.startswith("(EE)") and ("Disabling" not in line)) or line.startswith("Fatal"): - msg += line - msg = unicode(i18n("Messages from the X server:\n")) + msg - except IOError: - msg += unicode(i18n("Sorry, unable to capture the error messages from the X server.")) - KMessageBox.detailedSorry(self,i18n("Sorry, this configuration video card driver\nand monitor doesn't appear to work."),msg) - - finally: - # Attempt some cleanup before we go. - try: os.remove(error_filename) - except OSError: pass - try: os.remove(config_filename) - except OSError: pass - try: os.remove(auth_filename) - except OSError: pass - try: os.rmdir(working_tmp_dir) - except OSError: pass - - if old_xauthority is None: - del os.environ["XAUTHORITY"] - else: - os.environ["XAUTHORITY"] = old_xauthority - - return rc - - def _syncGUI(self): - self.SizePage._syncGUI() - - for gfxcard_widget in self.xscreenwidgets: - gfxcard_widget.syncConfig() - - # Sync the gamma tab. - if not self.compact_mode: - self.targetgammacombo.setCurrentItem(self.targetgamma) - self._selectGamma(self.targetgamma) - - if self.currentgammascreen.isGammaEqual(): - self.gammaradiogroup.setButton(0) - else: - self.gammaradiogroup.setButton(1) - - self.gammaslider.setValue(self.currentgammascreen.getAllGamma()) - self.redslider.setValue(self.currentgammascreen.getRedGamma()) - self.greenslider.setValue(self.currentgammascreen.getGreenGamma()) - self.blueslider.setValue(self.currentgammascreen.getBlueGamma()) - - self.settingall = self.currentgammascreen.isGammaEqual() - self.gammaslider.setDisabled(not self.settingall) - self.redslider.setDisabled(self.settingall) - self.greenslider.setDisabled(self.settingall) - self.blueslider.setDisabled(self.settingall) - self._syncTestButton() - - def _syncTestButton(self): - currentbadfbrestore = self._badFbRestore() - self.testbutton.setEnabled(self.xsetup.mayModifyXorgConfig() and not (self.badfbrestore or currentbadfbrestore)) - if not isroot or (self.xsetup.mayModifyXorgConfig() and not (self.badfbrestore or currentbadfbrestore)): - self.testunavailablelabel.hide() - else: - self.testunavailablelabel.show() - - def _loadConfig(self): - self.config.setGroup("General") - t = self.config.readEntry("targetgamma",unicode(i18n("2.0"))) - if t in self.availabletargetgammas: - t = unicode(i18n('2.0')) - self.targetgamma = self.availabletargetgammas.index(t) - - def _saveConfig(self): - global isroot - if isroot: - return - self.config.setGroup("General") - self.config.writeEntry("targetgamma",self.availabletargetgammas[self.targetgamma]) - for s in self.xsetup.getUsedScreens(): - self.config.setGroup("Screen"+str(s.getScreenIndex())) - self._saveRandRConfig(s) - - # Write out the gamma values. - if self.settingall: - self.config.writeEntry("redgamma", str(s.getAllGamma())) - self.config.writeEntry("greengamma", str(s.getAllGamma())) - self.config.writeEntry("bluegamma", str(s.getAllGamma())) - else: - self.config.writeEntry("redgamma", str(s.getRedGamma())) - self.config.writeEntry("greengamma", str(s.getGreenGamma())) - self.config.writeEntry("bluegamma", str(s.getBlueGamma())) - - self.config.writeEntry("dpmsSeconds", self.dpmspage.seconds) - self.config.writeEntry("dpmsEnabled", ("off","on")[self.dpmspage.enabled]) - self.config.sync() - - def _saveRandRConfig(self,screen): - w,h = screen.getAvailableResolutions()[screen.getResolutionIndex()] - self.config.writeEntry("width",w) - self.config.writeEntry("height",h) - self.config.writeEntry("reflectX", int( (screen.getReflection() & screen.RR_Reflect_X)!=0) ) - self.config.writeEntry("reflectY", int((screen.getReflection() & screen.RR_Reflect_Y)!=0) ) - self.config.writeEntry("refresh", screen.getAvailableRefreshRates()[screen.getRefreshRateIndex()]) - rotationmap = {screen.RR_Rotate_0: "0", screen.RR_Rotate_90: "90", - screen.RR_Rotate_180:"180", screen.RR_Rotate_270: "270"} - self.config.writeEntry("rotate", rotationmap[screen.getRotation()]) - - def _selectGamma(self,i): - self.mediumpic.setPixmap(self.mediumimages[i]) - - def __loadImages(self): - if not self.compact_mode: - for g in ['14','16','18','20','22','24']: - self.mediumimages.append( QPixmap(self.imagedir+'gammapics/MGam'+g+'.png') ) - - self.previewscreen = QPixmap(self.imagedir+'monitor_screen_1280x1024.png') - self.previewscreenportrait = QPixmap(self.imagedir+'monitor_screen_1024x1280.png') - - def __reset(self): - # Reset the screen settings. - self.xsetup.reset() - self.dpmspage.reset() - self._syncGUI() - - # 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 - for s in self.xsetup.getUsedScreens(): - changed = changed or s.isResolutionSettingsChanged() - - changed = changed or self.xsetup.isXorgConfigChanged() - changed = changed or self.dpmspage.isChanged() - - if standalone: - self.enableButton(KDialogBase.User1,changed) # Reset button - self.enableButtonApply(changed) # Apply button - else: - self.emit(SIGNAL("changed(bool)"), (changed,) ) - - def _badFbRestore(self): - bad_fb_restore = False - for card in self.xsetup.getGfxCards(): - bad_fb_restore = bad_fb_restore or \ - ((card.getGfxCardModel() is not None) and card.getGfxCardModel().getBadFbRestore(card.isProprietaryDriver())) - return bad_fb_restore - -############################################################################ -class SizeOrientationPage(QWidget): - """ - A TabPage with all the settings for Size and Orientation of the screens, - also features Refreshrates and Dualheadsettings. - - Emits the following signals: - - changeSignal() - - ... - - TODO: - * Update __doc__ with emitted signals, connect these. - * Choose screen (more than one preview) - * Relative positioning. - * Call setRefreshCombo after switching screens. - """ - def __init__(self,parent,xsetup,compact): - QWidget.__init__(self,parent) - - global imagedir - self.xsetup = xsetup - self.imagedir = imagedir - self.parent = parent - self.current_screen = self.xsetup.getPrimaryScreen() - self.current_is_primary = True - self.compact_mode = compact - - self._buildGUI() - self._syncGUI() - - def _syncGUI(self): - if self.current_is_primary: - self.current_screen = self.xsetup.getPrimaryScreen() - else: - self.current_screen = self.xsetup.getSecondaryScreen() - - self._syncGUILayout() - self._syncGUIScreen() - - def _syncGUILayout(self): - # Secondary monitor radios. - available_layouts = self.xsetup.getAvailableLayouts() - - may = self.xsetup.mayModifyLayout() - - self.secondary_clone_radio.setEnabled(may and available_layouts & self.xsetup.LAYOUT_CLONE) - self.secondary_clone_radio.setShown(available_layouts & self.xsetup.LAYOUT_CLONE) - - self.secondary_dual_radio.setEnabled(may and available_layouts & self.xsetup.LAYOUT_DUAL) - self.secondary_dual_radio.setShown(available_layouts & self.xsetup.LAYOUT_DUAL) - - self.secondary_position_combo.setEnabled(may and self.xsetup.getLayout()==self.xsetup.LAYOUT_DUAL) - self.secondary_position_combo.setShown(available_layouts & self.xsetup.LAYOUT_DUAL) - - self.secondary_groupbox.setEnabled(may and available_layouts != self.xsetup.LAYOUT_SINGLE) - # If only the single layout is available, then we just hide the whole radio group - self.secondary_groupbox.setShown(available_layouts!=self.xsetup.LAYOUT_SINGLE) - - if self.xsetup.getLayout()!=self.xsetup.LAYOUT_SINGLE: - self.secondary_radios.setButton(self.secondary_option_ids[self.xsetup.getLayout()]) - else: - if available_layouts & XSetup.LAYOUT_CLONE: - self.secondary_radios.setButton(self.secondary_option_ids[XSetup.LAYOUT_CLONE]) - else: - self.secondary_radios.setButton(self.secondary_option_ids[XSetup.LAYOUT_DUAL]) - - self.secondary_groupbox.setChecked(self.xsetup.getLayout() != self.xsetup.LAYOUT_SINGLE) - - def _syncGUIScreen(self): - # Sync the size tab. - self.resize_slider.setScreen(self.current_screen) - - if self.xsetup.getLayout()!=self.xsetup.LAYOUT_DUAL: - self.resize_slider.setTitle(i18n("Screen size")) - else: - self.resize_slider.setTitle(i18n("Screen size #%1").arg(self.xsetup.getUsedScreens().index(self.current_screen)+1)) - - if self.xsetup.getLayout()==self.xsetup.LAYOUT_DUAL: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.dual_monitor_preview) - else: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.monitor_preview) - - # Sync the screen orientation. - width,height = self.current_screen.getAvailableResolutions()[self.current_screen.getResolutionIndex()] - - if not self.compact_mode: - self.monitor_preview.setResolution(width,height) - - if self.current_screen.getRotation()==Screen.RR_Rotate_0: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_0) - elif self.current_screen.getRotation()==Screen.RR_Rotate_90: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_90) - elif self.current_screen.getRotation()==Screen.RR_Rotate_270: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_270) - else: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_180) - - self.monitor_preview.setReflectX(self.current_screen.getReflection() & Screen.RR_Reflect_X) - self.monitor_preview.setReflectY(self.current_screen.getReflection() & Screen.RR_Reflect_Y) - - # Set the resolutions for the dual screen preview. - if self.xsetup.getAvailableLayouts() & XSetup.LAYOUT_DUAL: - for i in [0,1]: - screen = [self.xsetup.getPrimaryScreen(), self.xsetup.getSecondaryScreen()][i] - width,height = screen.getAvailableResolutions()[screen.getResolutionIndex()] - self.dual_monitor_preview.setScreenResolution(i,width,height) - self.dual_monitor_preview.setPosition(self.xsetup.getDualheadOrientation()) - - self._fillRefreshCombo() - - self.orientation_radio_group.setButton( \ - [Screen.RR_Rotate_0, Screen.RR_Rotate_90, Screen.RR_Rotate_270, - Screen.RR_Rotate_180].index(self.current_screen.getRotation())) - # This construct above just maps an rotation to a radiobutton index. - self.mirror_horizontal_checkbox.setChecked(self.current_screen.getReflection() & Screen.RR_Reflect_X) - self.mirror_vertical_checkbox.setChecked(self.current_screen.getReflection() & Screen.RR_Reflect_Y) - - width,height = self.current_screen.getAvailableResolutions()[self.current_screen.getResolutionIndex()] - if not self.compact_mode: - self.monitor_preview.setResolution(width,height) - - # Enable/disable the resolution/rotation/reflection widgets. - may_edit = self.xsetup.mayModifyResolution() - self.normal_orientation_radio.setEnabled(may_edit) - available_rotations = self.current_screen.getAvailableRotations() - - # Hide the whole group box if there is only one boring option. - self.orientation_group_box.setShown(available_rotations!=Screen.RR_Rotate_0) - - self.left_orientation_radio.setEnabled(available_rotations & Screen.RR_Rotate_90 and may_edit) - self.left_orientation_radio.setShown(available_rotations & Screen.RR_Rotate_90) - - self.right_orientation_radio.setEnabled(available_rotations & Screen.RR_Rotate_270 and may_edit) - self.right_orientation_radio.setShown(available_rotations & Screen.RR_Rotate_270) - - self.upside_orientation_radio.setEnabled(available_rotations & Screen.RR_Rotate_180 and may_edit) - self.upside_orientation_radio.setShown(available_rotations & Screen.RR_Rotate_180) - - self.mirror_horizontal_checkbox.setEnabled(available_rotations & Screen.RR_Reflect_X and may_edit) - self.mirror_horizontal_checkbox.setShown(available_rotations & Screen.RR_Reflect_X) - - self.mirror_vertical_checkbox.setEnabled(available_rotations & Screen.RR_Reflect_Y and may_edit) - self.mirror_vertical_checkbox.setShown(available_rotations & Screen.RR_Reflect_Y) - - self.resize_slider.setEnabled(may_edit) - self.size_refresh_combo.setEnabled(may_edit) - - # Set the dual orientation combo. - self.secondary_position_combo.setCurrentItem( - [XSetup.POSITION_LEFTOF, - XSetup.POSITION_RIGHTOF, - XSetup.POSITION_ABOVE, - XSetup.POSITION_BELOW].index(self.xsetup.getDualheadOrientation())) - - def _fillRefreshCombo(self): - # Update refresh combobox - self.size_refresh_combo.clear() - for rate in self.current_screen.getAvailableRefreshRates(): - self.size_refresh_combo.insertItem(i18n("%1 Hz").arg(rate)) - self.size_refresh_combo.setCurrentItem(self.current_screen.getRefreshRateIndex()) - self.current_screen.setRefreshRateIndex(self.size_refresh_combo.currentItem()) - - def slotMonitorFocussed(self,currentMonitor): - if currentMonitor==0: - self.current_screen = self.xsetup.getPrimaryScreen() - self.current_is_primary = True - else: - self.current_screen = self.xsetup.getSecondaryScreen() - self.current_is_primary = False - - self._syncGUIScreen() - - def _sendChangedSignal(self): - self.emit(PYSIGNAL("changedSignal()"),()) - - def _buildGUI(self): - """ Assemble all GUI elements """ - # Layout stuff. - top_layout = QHBoxLayout(self,0,KDialog.spacingHint()) - self.top_layout = top_layout - - # -- Left column with orientation and dualhead box. - vbox = QVBox(self) - top_layout.addWidget(vbox,0) - - # -- Orientation group - self.orientation_group_box = QVGroupBox(vbox) - self.orientation_group_box.setTitle(i18n("Monitor Orientation")) - self.orientation_group_box.setInsideSpacing(KDialog.spacingHint()) - self.orientation_group_box.setInsideMargin(KDialog.marginHint()) - self.orientation_radio_group = QButtonGroup() - self.orientation_radio_group.setRadioButtonExclusive(True) - - self.normal_orientation_radio = QRadioButton(self.orientation_group_box) - self.normal_orientation_radio.setText(i18n("Normal")) - self.left_orientation_radio = QRadioButton(self.orientation_group_box) - self.left_orientation_radio .setText(i18n("Left edge on top")) - self.right_orientation_radio = QRadioButton(self.orientation_group_box) - self.right_orientation_radio.setText(i18n("Right edge on top")) - self.upside_orientation_radio = QRadioButton(self.orientation_group_box) - self.upside_orientation_radio.setText(i18n("Upsidedown")) - - self.mirror_horizontal_checkbox = QCheckBox(self.orientation_group_box) - self.mirror_horizontal_checkbox.setText(i18n("Mirror horizontally")) - self.connect(self.mirror_horizontal_checkbox,SIGNAL("toggled(bool)"),self.slotMirrorHorizontallyToggled) - - self.mirror_vertical_checkbox = QCheckBox(self.orientation_group_box) - self.mirror_vertical_checkbox.setText(i18n("Mirror vertically")) - self.connect(self.mirror_vertical_checkbox,SIGNAL("toggled(bool)"),self.slotMirrorVerticallyToggled) - - self.orientation_radio_group.insert(self.normal_orientation_radio,0) - self.orientation_radio_group.insert(self.left_orientation_radio,1) - self.orientation_radio_group.insert(self.right_orientation_radio,2) - self.orientation_radio_group.insert(self.upside_orientation_radio,3) - self.connect(self.orientation_radio_group,SIGNAL("clicked(int)"),self.slotOrientationRadioClicked) - - # -- Dualhead Box. - self.secondary_groupbox = QVGroupBox(vbox) - self.secondary_groupbox.setCheckable(True) - self.secondary_groupbox.setTitle(i18n("Second screen")) - self.connect(self.secondary_groupbox,SIGNAL("toggled(bool)"),self.slotSecondMonitorToggled) - - self.secondary_radios = QVButtonGroup(None) # Invisible - self.connect(self.secondary_radios,SIGNAL("pressed(int)"),self.slotSecondMonitorRadioPressed) - - self.secondary_options = {} - self.secondary_option_ids = {} - - # Clone radio - self.secondary_clone_radio = QRadioButton(i18n("Clone primary screen"),self.secondary_groupbox) - radio_id = self.secondary_radios.insert(self.secondary_clone_radio) - self.secondary_options[radio_id] = self.xsetup.LAYOUT_CLONE - self.secondary_option_ids[self.xsetup.LAYOUT_CLONE] = radio_id - - # Dual radio - self.secondary_dual_radio = QRadioButton(i18n("Dual screen"),self.secondary_groupbox) - radio_id = self.secondary_radios.insert(self.secondary_dual_radio) - self.secondary_options[radio_id] = self.xsetup.LAYOUT_DUAL - self.secondary_option_ids[self.xsetup.LAYOUT_DUAL] = radio_id - - self.secondary_radios.setButton(radio_id) - - hbox = QHBox(self.secondary_groupbox) - spacer = QWidget(hbox) - spacer.setFixedSize(20,1) - hbox.setStretchFactor(spacer,0) - - self.secondary_position_combo = QComboBox(0,hbox,"") - self.secondary_position_combo.insertItem(i18n("1 left of 2")) - self.secondary_position_combo.insertItem(i18n("1 right of 2")) - self.secondary_position_combo.insertItem(i18n("1 above 2")) - self.secondary_position_combo.insertItem(i18n("1 below 2")) - self.connect(self.secondary_position_combo,SIGNAL("activated(int)"),self.slotSecondaryPositionChange) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - vbox = QVBox(self) - top_layout.addWidget(vbox,1) - - if not self.compact_mode: - # -- Right columns with preview, size and refresh widgets. - - # -- Preview Box. - self.monitor_preview_stack = QWidgetStack(vbox) - - self.monitor_preview = MonitorPreview(self.monitor_preview_stack,self.imagedir) - self.monitor_preview_stack.addWidget(self.monitor_preview) - self.connect(self.monitor_preview,PYSIGNAL("focussed()"),self.slotMonitorFocussed) - - self.dual_monitor_preview = DualMonitorPreview(self.monitor_preview_stack, DUAL_PREVIEW_SIZE, self.imagedir) - - self.monitor_preview_stack.addWidget(self.dual_monitor_preview) - self.connect(self.dual_monitor_preview,PYSIGNAL("pressed()"),self.slotMonitorFocussed) - self.connect(self.dual_monitor_preview,PYSIGNAL("positionChanged()"),self.slotDualheadPreviewPositionChanged) - - # -- Size & Refresh Box. - if not self.compact_mode: - hbox = QHBox(vbox) - else: - hbox = QVBox(vbox) - hbox.setSpacing(KDialog.spacingHint()) - - self.resize_slider = ResizeSlider(hbox) - self.connect(self.resize_slider,PYSIGNAL("resolutionChange(int)"),self.slotResolutionChange) - - hbox2 = QHBox(hbox) - self.refresh_label = QLabel(hbox2,"RefreshLabel") - self.refresh_label.setText(i18n("Refresh:")) - - self.size_refresh_combo = QComboBox(0,hbox2,"comboBox1") # gets filled in setRefreshRates() - self.connect(self.size_refresh_combo,SIGNAL("activated(int)"),self.slotRefreshRateChange) - if self.compact_mode: - spacer = QWidget(hbox2) - hbox2.setStretchFactor(spacer,1) - - spacer = QWidget(vbox) - vbox.setStretchFactor(spacer,1) - - self.clearWState(Qt.WState_Polished) - - def setNotification(self,text): - self.notify.setText(text) - - def slotOrientationRadioClicked(self,i): - self.current_screen.setRotation( - [Screen.RR_Rotate_0, Screen.RR_Rotate_90,Screen.RR_Rotate_270, Screen.RR_Rotate_180][i]) - - if self.current_screen.getRotation()==Screen.RR_Rotate_0: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_0) - elif self.current_screen.getRotation()==Screen.RR_Rotate_90: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_90) - elif self.current_screen.getRotation()==Screen.RR_Rotate_270: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_270) - else: - self.monitor_preview.setRotation(MonitorPreview.ROTATE_180) - - self._sendChangedSignal() - - def slotMirrorHorizontallyToggled(self,flag): - # Bit flippin' - if flag: - self.current_screen.setReflection(self.current_screen.getReflection() | Screen.RR_Reflect_X) - else: - self.current_screen.setReflection(self.current_screen.getReflection() & ~Screen.RR_Reflect_X) - self.monitor_preview.setReflectX(flag) - self._sendChangedSignal() - - def slotMirrorVerticallyToggled(self,flag): - # Bit flippin' - if flag: - self.current_screen.setReflection(self.current_screen.getReflection() | Screen.RR_Reflect_Y) - else: - self.current_screen.setReflection(self.current_screen.getReflection() & ~Screen.RR_Reflect_Y) - self.monitor_preview.setReflectY(flag) - self._sendChangedSignal() - - def slotResolutionChange(self,i): - self.current_screen.setResolutionIndex(i) - width,height = self.current_screen.getAvailableResolutions()[i] - - if not self.compact_mode: - self.monitor_preview.setResolution(width,height) - self.dual_monitor_preview.setScreenResolution( - self.xsetup.getUsedScreens().index(self.current_screen), - width,height) - - self._fillRefreshCombo() - self._sendChangedSignal() - - def slotRefreshRateChange(self,index): - self.current_screen.setRefreshRateIndex(index) - self._sendChangedSignal() - - def setScreen(self,screen): - self.current_screen = screen - self._syncGUI() - - def slotSecondMonitorToggled(self,enabled): - if enabled: - pressed_id = self.secondary_radios.selectedId() - self.xsetup.setLayout(self.secondary_options[pressed_id]) - else: - self.xsetup.setLayout(self.xsetup.LAYOUT_SINGLE) - - if self.xsetup.getLayout()!=self.xsetup.LAYOUT_DUAL: - self.current_screen = self.xsetup.getUsedScreens()[0] - - self.secondary_position_combo.setEnabled(self.xsetup.getLayout()==XSetup.LAYOUT_DUAL) - - self._syncGUIScreen() - self._sendChangedSignal() - - def slotSecondMonitorRadioPressed(self,pressedId): - self.xsetup.setLayout(self.secondary_options[pressedId]) - - if self.xsetup.getLayout()!=XSetup.LAYOUT_DUAL: - self.current_screen = self.xsetup.getUsedScreens()[0] - - self.secondary_position_combo.setEnabled(self.xsetup.getLayout()==XSetup.LAYOUT_DUAL) - - if self.xsetup.getLayout()==XSetup.LAYOUT_DUAL: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.dual_monitor_preview) - else: - if not self.compact_mode: - self.monitor_preview_stack.raiseWidget(self.monitor_preview) - - self._syncGUIScreen() - self._sendChangedSignal() - - def slotSecondaryPositionChange(self,index): - position = [XSetup.POSITION_LEFTOF,XSetup.POSITION_RIGHTOF,XSetup.POSITION_ABOVE,XSetup.POSITION_BELOW][index] - self.xsetup.setDualheadOrientation(position) - self.dual_monitor_preview.setPosition(position) - self._sendChangedSignal() - - def slotDualheadPreviewPositionChanged(self,position): - self.xsetup.setDualheadOrientation(position) - index = { - XSetup.POSITION_LEFTOF:0, - XSetup.POSITION_RIGHTOF:1, - XSetup.POSITION_ABOVE:2, - XSetup.POSITION_BELOW:3 - }[position] - self.secondary_position_combo.setCurrentItem(index) - self._sendChangedSignal() - - def setMargin(self,margin): - self.top_layout.setMargin(margin) - - def setSpacing(self,spacing): - self.top_layout.setSpacing(spacing) - -############################################################################ -class DpmsPage(QWidget): - - # Mapping values in seconds to human-readable labels. - intervals = ( - (60,i18n("1 minute")), - (120,i18n("2 minutes")), - (180,i18n("3 minutes")), - (300,i18n("5 minutes")), - (600,i18n("10 minutes")), - (900,i18n("15 minutes")), - (1200,i18n("20 minutes")), - (1500,i18n("25 minutes")), - (1800,i18n("30 minutes")), - (2700,i18n("45 minutes")), - (3600,i18n("1 hour")), - (7200,i18n("2 hours")), - (10800,i18n("3 hours")), - (14400,i18n("4 hours")), - (18000,i18n("5 hours"))) - - def __init__(self,parent = None,name = None,modal = 0,fl = 0): - global imagedir - QWidget.__init__(self,parent) - - # Where to find xset. - self.xset_bin = os.popen('which xset').read()[:-1] - - if not name: - self.setName("DPMSTab") - - dpms_tab_layout = QVBoxLayout(self,0,0,"DPMSTabLayout") - self.top_layout = dpms_tab_layout - - hbox = QHBox(self) - hbox.setSpacing(KDialog.spacingHint()) - - dpms_tab_layout.addWidget(hbox) - - self.dpmsgroup = QHGroupBox(hbox,"dpmsgroup") - self.dpmsgroup.setInsideSpacing(KDialog.spacingHint()) - self.dpmsgroup.setInsideMargin(KDialog.marginHint()) - self.dpmsgroup.setTitle(i18n("Enable power saving")) - self.dpmsgroup.setCheckable(1) - - self.connect(self.dpmsgroup,SIGNAL("toggled(bool)"),self.slotDpmsToggled) - - hbox2 = QHBox(self.dpmsgroup) - hbox2.setSpacing(KDialog.spacingHint()) - - dpmstext = QLabel(hbox2,"dpmstext") - dpmstext.setText(i18n("Switch off monitor after:")) - - self.dpmscombo = QComboBox(0,hbox2,"dpmscombo") - self.fillCombo(self.dpmscombo) - self.connect(self.dpmscombo,SIGNAL("activated(int)"),self.slotDpmsActivated) - - spacer = QWidget(hbox2) - hbox2.setStretchFactor(spacer,1) - - self.energystarpix = QLabel(hbox,"energystarpix") - self.energystarpix.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed,0,0,self.energystarpix.sizePolicy().hasHeightForWidth())) - self.energystarpix.setMinimumSize(QSize(150,77)) - self.energystarpix.setPixmap(QPixmap(imagedir+"../energystar.png")) - self.energystarpix.setScaledContents(1) - - bottomspacer = QSpacerItem(51,160,QSizePolicy.Minimum,QSizePolicy.Expanding) - dpms_tab_layout.addItem(bottomspacer) - - self.clearWState(Qt.WState_Polished) - - self.readDpms() - - def fillCombo(self,combo): - """ Fill the combobox with the values from our list """ - for interval in self.intervals: - combo.insertItem(interval[1]) - - def slotDpmsActivated(self,index): - """ Another dpms value has been chosen, update buttons at bottom. """ - self.emit(PYSIGNAL("changedSignal()"), ()) - - def slotDpmsToggled(self,bool): - """ Dpms checkbox has been toggled, update buttons at bottom. """ - self.emit(PYSIGNAL("changedSignal()"), ()) - - def readDpms(self): - # FIXME it is not the widget's job to read or change the values, just to present the GUI. - """ Read output from xset -q and parse DPMS settings from it. """ - # FIXME: localisation problem running this command. - lines = ExecWithCapture(self.xset_bin,[self.xset_bin,'-q']).split('\n') - - self.dpms_min = 1800 - self.dpms_enabled = False - - for line in lines: - if line.strip().startswith("Standby"): - self.dpms_min = int(line.strip().split()[5]) # TODO: More subtle exception handling. ;) - if line.strip().startswith("DPMS is"): - self.dpms_enabled = line.strip().split()[2]=="Enabled" - - if self.dpms_min==0: # 0 also means don't use Standby mode. - self.dpms_enabled = False - self.dpms_min = 1800 - - self.dpmsgroup.setChecked(self.dpms_enabled) - - for i in range(len(self.intervals)): - diff = abs(self.intervals[i][0] - self.dpms_min) - if i==0: - last_diff = diff - if (last_diff <= diff and i!=0) or (last_diff < diff): - i = i-1 - break - last_diff = diff - self.dpmscombo.setCurrentItem(i) - - def isChanged(self): - """ Check if something has changed since startup or last apply(). """ - if self.dpmsgroup.isChecked(): - if self.intervals[self.dpmscombo.currentItem()][0] != self.dpms_min: - return True - if self.dpmsgroup.isChecked() != self.dpms_enabled: - return True - return False - - else: - # self.dpmsgroup.isChecked() is False - return self.dpms_enabled # self.dpms_enabled != False - - def applyDpms(self): - """ Use xset to apply new dpms settings. """ - self.enabled = self.dpmsgroup.isChecked() - self.seconds = self.intervals[self.dpmscombo.currentItem()][0] - if self.enabled: - # Switch dpms on and set timeout interval. - cmd_on = "%s +dpms" % self.xset_bin - cmd_set = "%s dpms %i %i %i" % (self.xset_bin, self.seconds,self.seconds,self.seconds) - print cmd_set - if os.system(cmd_set) != 0: - print "DPMS command failed: ", cmd_set - else: - # Switch dpms off. - cmd_on = "%s -dpms" % self.xset_bin - if os.system(cmd_on) != 0: - print "DPMS command failed: ", cmd_on - self.readDpms() - self.emit(PYSIGNAL("changedSignal()"), ()) - - def apply(self): - self.applyDpms() - - def reset(self): - for i in range(len(self.intervals)): - if self.intervals[i][0] == self.dpms_min: - self.dpmscombo.setCurrentItem(i) - break - - self.dpmsgroup.setChecked(self.dpms_enabled) - - def setMargin(self,margin): - self.top_layout.setMargin(margin) - - def setSpacing(self,spacing): - self.top_layout.setSpacing(spacing) - -############################################################################ -def create_displayconfig(parent,name): - """ Factory function for KControl """ - global kapp - kapp = TDEApplication.kApplication() - return DisplayApp(parent, name) - -############################################################################ -def MakeAboutData(): - aboutdata = TDEAboutData("guidance",programname,version, \ - "Display and Graphics Configuration Tool", TDEAboutData.License_GPL, \ - "Copyright (C) 2003-2007 Simon Edwards", \ - "Thanks go to Phil Thompson, Jim Bublitz and David Boddie.") - 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"); - aboutdata.addCredit("Pete Andrews","Gamma calibration pictures/system",None, \ - "http://www.photoscientia.co.uk/Gamma.htm") - return aboutdata - -if standalone: - aboutdata = MakeAboutData() - TDECmdLineArgs.init(sys.argv,aboutdata) - - kapp = TDEApplication() - - displayapp = DisplayApp() - displayapp.exec_loop() |