move QtFrontend to the Qt dialogue
authorRalf Jung <post@ralfj.de>
Tue, 28 Jul 2015 19:43:19 +0000 (21:43 +0200)
committerRalf Jung <post@ralfj.de>
Tue, 28 Jul 2015 19:43:19 +0000 (21:43 +0200)
gui.py
qt_dialogue.py [deleted file]
qt_frontend.py [new file with mode: 0644]

diff --git a/gui.py b/gui.py
index 62decc6b326c61e87a90ce02c673594340059f6a..4847668630baea6c0642a1eac74ea47e5ea32f30 100644 (file)
--- a/gui.py
+++ b/gui.py
@@ -28,34 +28,12 @@ def setup(internalResolutions, externalResolutions):
     The user should be asked about his display setup preferences.
     The function returns None if the user cancelled, and an instance of dsl.ScreenSetup otherwise.
 '''
-import sys
 import collections
 
+from qt_frontend import QtFrontend
 from cli_frontend import CLIFrontend
 from zenity_frontend import ZenityFrontend
 
-# Qt frontend
-class QtFrontend:
-    def __init__(self):
-        from PyQt4 import QtGui
-        self.app = QtGui.QApplication(sys.argv)
-        print("Qt loaded")
-    
-    def error(self, message):
-        from PyQt4 import QtGui
-        QtGui.QMessageBox.critical(None, 'Fatal error', message)
-    
-    def setup(self, situation):
-        from qt_dialogue import PositionSelection
-        return PositionSelection(situation).run()
-    
-    @staticmethod
-    def isAvailable():
-        try:
-            import PyQt4
-            return True
-        except ImportError:
-            return False
 
 # list of available frontends
 frontends = collections.OrderedDict()
diff --git a/qt_dialogue.py b/qt_dialogue.py
deleted file mode 100644 (file)
index 26f6717..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-# DSL - easy Display Setup for Laptops
-# Copyright (C) 2012-2015 Ralf Jung <post@ralfj.de>
-#
-# 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.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-import os
-from screen import RelativeScreenPosition, ScreenSetup
-from PyQt4 import QtCore, QtGui, uic
-
-class PositionSelection(QtGui.QDialog):
-    def __init__(self, situation):
-        # set up main window
-        super(PositionSelection, self).__init__()
-        self._situation = situation
-        uifile = os.path.join(os.path.dirname(__file__), 'qt_dialogue.ui')
-        uic.loadUi(uifile, self)
-        
-        # fill relative position box
-        for pos in RelativeScreenPosition:
-            self.relPos.addItem(pos.text, pos)
-        
-        # keep resolutions in sync when in mirror mode
-        def syncIfMirror(source, target):
-            def _slot(idx):
-                if self.isMirror:
-                    target.setCurrentIndex(idx)
-            source.currentIndexChanged.connect(_slot)
-        syncIfMirror(self.intRes, self.extRes)
-        syncIfMirror(self.extRes, self.intRes)
-
-        # connect the update function, and make sure we are in a correct state
-        self.intEnabled.toggled.connect(self.updateEnabledControls)
-        self.extEnabled.toggled.connect(self.updateEnabledControls)
-        self.relPos.currentIndexChanged.connect(self.updateEnabledControls)
-        self.updateEnabledControls()
-    
-    def getRelativeScreenPosition(self):
-        idx = self.relPos.currentIndex()
-        return self.relPos.itemData(idx)
-    
-    def fillResolutionBox(self, box, resolutions):
-        # if the count did not change, update in-place (this avoids flicker)
-        if box.count() == len(resolutions):
-            for idx, res in enumerate(resolutions):
-                box.setItemText(idx, str(res))
-                box.setItemData(idx, res)
-        else:
-            # first clear it
-            while box.count() > 0:
-                box.removeItem(0)
-            # then fill it
-            for res in resolutions:
-                box.addItem(str(res), res)
-    
-    def updateEnabledControls(self):
-        intEnabled = self.intEnabled.isChecked()
-        extEnabled = self.extEnabled.isChecked()
-        bothEnabled = intEnabled and extEnabled
-        self.isMirror = bothEnabled and self.getRelativeScreenPosition() == RelativeScreenPosition.MIRROR # only if both are enabled, we can really mirror
-        # configure screen controls
-        self.intRes.setEnabled(intEnabled)
-        self.intPrimary.setEnabled(intEnabled and not self.isMirror)
-        self.extRes.setEnabled(extEnabled)
-        self.extPrimary.setEnabled(extEnabled and not self.isMirror)
-        if not intEnabled and extEnabled:
-            self.extPrimary.setChecked(True)
-        elif not extEnabled and intEnabled:
-            self.intPrimary.setChecked(True)
-        # which resolutions do we offer?
-        if self.isMirror:
-            commonRes = self._situation.commonResolutions()
-            self.fillResolutionBox(self.intRes, commonRes)
-            self.fillResolutionBox(self.extRes, commonRes)
-            self.intRes.setCurrentIndex(self.extRes.currentIndex())
-        else:
-            self.fillResolutionBox(self.intRes, self._situation.internalResolutions())
-            self.fillResolutionBox(self.extRes, self._situation.externalResolutions())
-        # configure position control
-        self.posGroup.setEnabled(bothEnabled)
-        self.posLabel1.setEnabled(bothEnabled)
-        self.posLabel2.setEnabled(bothEnabled)
-        self.relPos.setEnabled(bothEnabled)
-        # avoid having no screen
-        self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(intEnabled or extEnabled)
-    
-    def run(self):
-        self.exec_()
-        if not self.result(): return None
-        intRes = self.intRes.itemData(self.intRes.currentIndex()) if self.intEnabled.isChecked() else None
-        extRes = self.extRes.itemData(self.extRes.currentIndex()) if self.extEnabled.isChecked() else None
-        return ScreenSetup(intRes, extRes, self.getRelativeScreenPosition(), self.extPrimary.isChecked())
diff --git a/qt_frontend.py b/qt_frontend.py
new file mode 100644 (file)
index 0000000..62e3b84
--- /dev/null
@@ -0,0 +1,130 @@
+# DSL - easy Display Setup for Laptops
+# Copyright (C) 2012-2015 Ralf Jung <post@ralfj.de>
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+import sys, os
+from screen import RelativeScreenPosition, ScreenSetup
+
+try:
+    # Be fine with PyQt4 not being installed
+    from PyQt4 import QtCore, QtGui, uic
+
+    class PositionSelection(QtGui.QDialog):
+        def __init__(self, situation):
+            # set up main window
+            super(PositionSelection, self).__init__()
+            self._situation = situation
+            uifile = os.path.join(os.path.dirname(__file__), 'qt_dialogue.ui')
+            uic.loadUi(uifile, self)
+            
+            # fill relative position box
+            for pos in RelativeScreenPosition:
+                self.relPos.addItem(pos.text, pos)
+            
+            # keep resolutions in sync when in mirror mode
+            def syncIfMirror(source, target):
+                def _slot(idx):
+                    if self.isMirror:
+                        target.setCurrentIndex(idx)
+                source.currentIndexChanged.connect(_slot)
+            syncIfMirror(self.intRes, self.extRes)
+            syncIfMirror(self.extRes, self.intRes)
+
+            # connect the update function, and make sure we are in a correct state
+            self.intEnabled.toggled.connect(self.updateEnabledControls)
+            self.extEnabled.toggled.connect(self.updateEnabledControls)
+            self.relPos.currentIndexChanged.connect(self.updateEnabledControls)
+            self.updateEnabledControls()
+        
+        def getRelativeScreenPosition(self):
+            idx = self.relPos.currentIndex()
+            return self.relPos.itemData(idx)
+        
+        def fillResolutionBox(self, box, resolutions):
+            # if the count did not change, update in-place (this avoids flicker)
+            if box.count() == len(resolutions):
+                for idx, res in enumerate(resolutions):
+                    box.setItemText(idx, str(res))
+                    box.setItemData(idx, res)
+            else:
+                # first clear it
+                while box.count() > 0:
+                    box.removeItem(0)
+                # then fill it
+                for res in resolutions:
+                    box.addItem(str(res), res)
+        
+        def updateEnabledControls(self):
+            intEnabled = self.intEnabled.isChecked()
+            extEnabled = self.extEnabled.isChecked()
+            bothEnabled = intEnabled and extEnabled
+            self.isMirror = bothEnabled and self.getRelativeScreenPosition() == RelativeScreenPosition.MIRROR # only if both are enabled, we can really mirror
+            # configure screen controls
+            self.intRes.setEnabled(intEnabled)
+            self.intPrimary.setEnabled(intEnabled and not self.isMirror)
+            self.extRes.setEnabled(extEnabled)
+            self.extPrimary.setEnabled(extEnabled and not self.isMirror)
+            if not intEnabled and extEnabled:
+                self.extPrimary.setChecked(True)
+            elif not extEnabled and intEnabled:
+                self.intPrimary.setChecked(True)
+            # which resolutions do we offer?
+            if self.isMirror:
+                commonRes = self._situation.commonResolutions()
+                self.fillResolutionBox(self.intRes, commonRes)
+                self.fillResolutionBox(self.extRes, commonRes)
+                self.intRes.setCurrentIndex(self.extRes.currentIndex())
+            else:
+                self.fillResolutionBox(self.intRes, self._situation.internalResolutions())
+                self.fillResolutionBox(self.extRes, self._situation.externalResolutions())
+            # configure position control
+            self.posGroup.setEnabled(bothEnabled)
+            self.posLabel1.setEnabled(bothEnabled)
+            self.posLabel2.setEnabled(bothEnabled)
+            self.relPos.setEnabled(bothEnabled)
+            # avoid having no screen
+            self.buttonBox.button(QtGui.QDialogButtonBox.Ok).setEnabled(intEnabled or extEnabled)
+        
+        def run(self):
+            self.exec_()
+            if not self.result(): return None
+            intRes = self.intRes.itemData(self.intRes.currentIndex()) if self.intEnabled.isChecked() else None
+            extRes = self.extRes.itemData(self.extRes.currentIndex()) if self.extEnabled.isChecked() else None
+            return ScreenSetup(intRes, extRes, self.getRelativeScreenPosition(), self.extPrimary.isChecked())
+except ImportError:
+    pass
+
+# Qt frontend
+class QtFrontend:
+    def __init__(self):
+        from PyQt4 import QtGui
+        self.app = QtGui.QApplication(sys.argv)
+        print("Qt loaded")
+    
+    def error(self, message):
+        from PyQt4 import QtGui
+        QtGui.QMessageBox.critical(None, 'Fatal error', message)
+    
+    def setup(self, situation):
+        return PositionSelection(situation).run()
+    
+    @staticmethod
+    def isAvailable():
+        try:
+            import PyQt4
+            return True
+        except ImportError:
+            return False
+