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.
 '''
     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
 
 import collections
 
+from qt_frontend import QtFrontend
 from cli_frontend import CLIFrontend
 from zenity_frontend import ZenityFrontend
 
 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()
 
 # 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
+