1 # DSL - easy Display Setup for Laptops
2 # Copyright (C) 2012-2015 Ralf Jung <post@ralfj.de>
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License as published by
6 # the Free Software Foundation; either version 2 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 from screen import RelativeScreenPosition, ScreenSetup
21 # Be fine with PyQt4 not being installed
22 from PyQt5 import QtCore, QtWidgets, uic
24 class PositionSelection(QtWidgets.QDialog):
25 def __init__(self, situation):
27 super(PositionSelection, self).__init__()
28 self._situation = situation
29 uifile = os.path.join(os.path.dirname(__file__), 'qt_dialogue.ui')
30 uic.loadUi(uifile, self)
32 # fill relative position box
33 for pos in RelativeScreenPosition:
34 self.relPos.addItem(pos.text, pos)
36 # keep resolutions in sync when in mirror mode
37 def syncIfMirror(source, target):
40 target.setCurrentIndex(idx)
41 source.currentIndexChanged.connect(_slot)
42 syncIfMirror(self.intRes, self.extRes)
43 syncIfMirror(self.extRes, self.intRes)
45 # connect the update function
46 self.intEnabled.toggled.connect(self.updateEnabledControls)
47 self.extEnabled.toggled.connect(self.updateEnabledControls)
48 self.relPos.currentIndexChanged.connect(self.updateEnabledControls)
50 # if situation has a lastSetup, use its values as initial state
51 if situation.lastSetup:
52 last = situation.lastSetup
53 self.intEnabled.setChecked(last.intResolution is not None)
54 self.extEnabled.setChecked(last.extResolution is not None)
56 print("YO:",last.relPosition.value-1)
57 self.relPos.setCurrentIndex(last.relPosition.value-1)
59 # make sure we are in a correct state
60 self.updateEnabledControls()
62 def getRelativeScreenPosition(self):
63 idx = self.relPos.currentIndex()
64 return self.relPos.itemData(idx)
66 def fillResolutionBox(self, box, resolutions):
67 # if the count did not change, update in-place (this avoids flicker)
68 if box.count() == len(resolutions):
69 for idx, res in enumerate(resolutions):
70 box.setItemText(idx, str(res))
71 box.setItemData(idx, res)
74 while box.count() > 0:
77 for res in resolutions:
78 box.addItem(str(res), res)
80 def updateEnabledControls(self):
81 intEnabled = self.intEnabled.isChecked()
82 extEnabled = self.extEnabled.isChecked()
83 bothEnabled = intEnabled and extEnabled
84 self.isMirror = bothEnabled and self.getRelativeScreenPosition() == RelativeScreenPosition.MIRROR # only if both are enabled, we can really mirror
85 # configure screen controls
86 self.intRes.setEnabled(intEnabled)
87 self.intPrimary.setEnabled(intEnabled and not self.isMirror)
88 self.extRes.setEnabled(extEnabled)
89 self.extPrimary.setEnabled(extEnabled and not self.isMirror)
90 if not intEnabled and extEnabled:
91 self.extPrimary.setChecked(True)
92 elif not extEnabled and intEnabled:
93 self.intPrimary.setChecked(True)
94 # which resolutions do we offer?
96 commonRes = self._situation.commonResolutions()
97 self.fillResolutionBox(self.intRes, commonRes)
98 self.fillResolutionBox(self.extRes, commonRes)
99 self.intRes.setCurrentIndex(self.extRes.currentIndex())
101 self.fillResolutionBox(self.intRes, self._situation.internalResolutions())
102 self.fillResolutionBox(self.extRes, self._situation.externalResolutions())
103 # configure position control
104 self.posGroup.setEnabled(bothEnabled)
105 self.posLabel1.setEnabled(bothEnabled)
106 self.posLabel2.setEnabled(bothEnabled)
107 self.relPos.setEnabled(bothEnabled)
108 # avoid having no screen
109 self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).setEnabled(intEnabled or extEnabled)
113 if not self.result(): return None
114 intRes = self.intRes.itemData(self.intRes.currentIndex()) if self.intEnabled.isChecked() else None
115 extRes = self.extRes.itemData(self.extRes.currentIndex()) if self.extEnabled.isChecked() else None
116 return ScreenSetup(intRes, extRes, self.getRelativeScreenPosition(), self.extPrimary.isChecked())
123 from PyQt5 import QtWidgets
124 self.app = QtWidgets.QApplication(sys.argv)
127 def error(self, message):
128 from PyQt5 import QtWidgets
129 QtWidgets.QMessageBox.critical(None, 'Fatal error', message)
131 def setup(self, situation):
132 return PositionSelection(situation).run()