add a mirror mode
[lilass.git] / qt_dialogue.py
1 # DSL - easy Display Setup for Laptops
2 # Copyright (C) 2012 Ralf Jung <post@ralfj.de>
3 #
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.
8 #
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.
13 #
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.
17 from dsl import RelativeScreenPosition, ScreenSetup, res2user
18 from PyQt4 import QtCore, QtGui
19
20 def makeLayout(layout, members):
21     for m in members:
22         if isinstance(m, QtGui.QLayout):
23             layout.addLayout(m)
24         else:
25             layout.addWidget(m)
26     return layout
27
28 class PositionSelection(QtGui.QDialog):
29     def __init__(self, internalResolutions, externalResolutions, commonResolutions):
30         # set up main window
31         super(PositionSelection, self).__init__()
32         self.setWindowTitle('DSL - easy Display Setup for Laptops')
33         
34         ## position selection
35         posBox = QtGui.QGroupBox('Position of external screen', self)
36         self.posLeft = QtGui.QRadioButton('Left of internal screen', posBox)
37         self.posRight = QtGui.QRadioButton('Right of internal screen', posBox)
38         self.posRight.setChecked(True)
39         self.posRight.setFocus()
40         self.extOnly = QtGui.QRadioButton('Use external screen exclusively', posBox)
41         self.mirror = QtGui.QRadioButton('Mirror internal screen', posBox)
42         positions = [self.posLeft, self.posRight, self.extOnly, self.mirror]
43         posBox.setLayout(makeLayout(QtGui.QVBoxLayout(), positions))
44         for pos in positions:
45             pos.toggled.connect(self.updateForm)
46         
47         ## primary screen
48         self.primBox = QtGui.QGroupBox('Which should be the primary screen?', self)
49         self.primExt = QtGui.QRadioButton('The external screen', self.primBox)
50         self.primInt = QtGui.QRadioButton('The internal screen', self.primBox)
51         self.primInt.setChecked(True)
52         self.primBox.setLayout(makeLayout(QtGui.QVBoxLayout(), [self.primExt, self.primInt]))
53         
54         ## resolution selection
55         resBox = QtGui.QGroupBox('Screen resolutions', self)
56         # external screen
57         self.extResLabel = QtGui.QLabel('Resolution of external screen:', resBox)
58         self.extResolutions = externalResolutions
59         self.extResolutionsBox = QtGui.QComboBox(resBox)
60         for res in externalResolutions:
61             self.extResolutionsBox.addItem(res2user(res))
62         self.extResolutionsBox.setCurrentIndex(0) # select first resolution
63         self.extRow = makeLayout(QtGui.QHBoxLayout(), [self.extResLabel, self.extResolutionsBox])
64         # internal screen
65         self.intResLabel = QtGui.QLabel('Resolution of internal screen:', resBox)
66         self.intResolutions = internalResolutions
67         self.intResolutionsBox = QtGui.QComboBox(resBox)
68         for res in internalResolutions:
69             self.intResolutionsBox.addItem(res2user(res))
70         self.intResolutionsBox.setCurrentIndex(0) # select first resolution
71         self.intRow = makeLayout(QtGui.QHBoxLayout(), [self.intResLabel, self.intResolutionsBox])
72         # both screens
73         self.mirrorResLabel = QtGui.QLabel('Resolution of both screens:', resBox)
74         self.mirrorResolutions = commonResolutions
75         self.mirrorResolutionsBox = QtGui.QComboBox(resBox)
76         for res in commonResolutions:
77             self.mirrorResolutionsBox.addItem(res2user(res))
78         self.mirrorResolutionsBox.setCurrentIndex(0) # select first resolution
79         self.mirrorRow = makeLayout(QtGui.QHBoxLayout(), [self.mirrorResLabel, self.mirrorResolutionsBox])
80         # show them all
81         resBox.setLayout(makeLayout(QtGui.QVBoxLayout(), [self.extRow, self.intRow, self.mirrorRow]))
82         
83         # last row: buttons
84         buttons = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel, QtCore.Qt.Horizontal, self)
85         buttons.accepted.connect(self.accept)
86         buttons.rejected.connect(self.reject)
87         
88         # add them all to the window
89         self.setLayout(makeLayout(QtGui.QVBoxLayout(), [posBox, self.primBox, resBox, buttons]))
90         
91         # make sure we are consistent
92         self.updateForm()
93     
94     def updateForm(self):
95         self.primBox.setEnabled(self.posLeft.isChecked() or self.posRight.isChecked())
96         self.extResolutionsBox.setEnabled(not self.mirror.isChecked())
97         self.extResLabel.setEnabled(not self.mirror.isChecked())
98         self.intResolutionsBox.setEnabled(self.posLeft.isChecked() or self.posRight.isChecked())
99         self.intResLabel.setEnabled(self.posLeft.isChecked() or self.posRight.isChecked())
100         self.mirrorResolutionsBox.setEnabled(self.mirror.isChecked())
101         self.mirrorResLabel.setEnabled(self.mirror.isChecked())
102     
103     def run(self):
104         self.exec_()
105         if not self.result(): return None
106         if self.mirror.isChecked():
107             return ScreenSetup(RelativeScreenPosition.MIRROR,
108                 self.mirrorResolutions[self.mirrorResolutionsBox.currentIndex()],
109                 self.mirrorResolutions[self.mirrorResolutionsBox.currentIndex()],
110                 extIsPrimary = True)
111         else:
112             return ScreenSetup(self.getRelativeScreenPosition(),
113                 self.intResolutions[self.intResolutionsBox.currentIndex()],
114                 self.extResolutions[self.extResolutionsBox.currentIndex()],
115                 self.primExt.isChecked())
116     
117     def getRelativeScreenPosition(self):
118         if self.posLeft.isChecked():
119             return RelativeScreenPosition.LEFT
120         elif self.posRight.isChecked():
121             return RelativeScreenPosition.RIGHT
122         elif self.extOnly.isChecked():
123             return RelativeScreenPosition.EXTERNAL_ONLY
124         else:
125             raise Exception("Nothing is checked?")