Reset the rotation mode on expose event in case the MCE accelerometer monitoring...
[drlaunch] / src / portrait.py
index 8e0b2e7..c66b338 100644 (file)
 
 import dbus
 import dbus.glib
+from dbus.mainloop.glib import DBusGMainLoop
 
 import hildon
 import osso
 
 # Replace this with your own gettext() functionality
-#import gpodder
-#_ = gpodder.gettext
+_ = str
 
 
 class FremantleRotation(object):
@@ -40,10 +40,10 @@ class FremantleRotation(object):
     You can set the mode for rotation to AUTOMATIC (default), NEVER or
     ALWAYS with the set_mode() method.
     """
-
     AUTOMATIC, NEVER, ALWAYS = range(3)
 
-    MODE_CAPTIONS = ('Automatic', 'Landscape', 'Portrait')
+    # Human-readable captions for the above constants
+    MODE_CAPTIONS = (_('Automatic'), _('Landscape'), _('Portrait'))
 
     # Privately-used constants
     _PORTRAIT, _LANDSCAPE = ('portrait', 'landscape')
@@ -60,16 +60,20 @@ class FremantleRotation(object):
     _KBD_OPEN = 'open'
     _KBD_CLOSED = 'closed'
 
-    def __init__(self, app_name, main_window=None, version='1.0', mode=0):
+    def __init__(self, app_name, main_window=None, version='1.0', mode=0,
+       dontrotate=False):
         """Create a new rotation manager
 
         app_name    ... The name of your application (for osso.Context)
         main_window ... The root window (optional, hildon.StackableWindow)
         version     ... The version of your application (optional, string)
         mode        ... Initial mode for this manager (default: AUTOMATIC)
+       dontrotate  ... Don't rotate the window. (def: False)
         """
+       self.dontrotate = dontrotate # V13
         self._orientation = None
         self._main_window = main_window
+        self._stack = hildon.WindowStack.get_default()
         self._mode = -1
         self._last_dbus_orientation = None
         self._keyboard_state = self._get_keyboard_state()
@@ -77,7 +81,23 @@ class FremantleRotation(object):
         self._osso_context = osso.Context(app_id, version, False)
         program = hildon.Program.get_instance()
         program.connect('notify::is-topmost', self._on_topmost_changed)
-        system_bus = dbus.Bus.get_system()
+
+       # Hack for dbus. See:
+       # https://garage.maemo.org/pipermail/pymaemo-developers/2010-April/001445.html
+       # https://garage.maemo.org/pipermail/pymaemo-developers/2010-April/001454.html
+       # https://garage.maemo.org/pipermail/pymaemo-developers/2010-April/thread.html
+       # https://bugs.maemo.org/show_bug.cgi?id=8611
+       #
+       # If we use dbus.Bus.get_system() or dbus.SystemBus() then the
+       # program fails whenever bluezwitch is installed. This could
+       # also happen whenever another widget is using System Bus (sure?).
+       # 
+        #V13 system_bus = dbus.Bus.get_system()
+       dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+       busaddress='unix:path=/var/run/dbus/system_bus_socket'
+       system_bus=dbus.bus.BusConnection(busaddress)
+       self.system_bus=system_bus
+
         system_bus.add_signal_receiver(self._on_orientation_signal, \
                 signal_name='sig_device_orientation_ind', \
                 dbus_interface='com.nokia.mce.signal', \
@@ -88,11 +108,6 @@ class FremantleRotation(object):
                 path='/org/freedesktop/Hal/devices/platform_slide')
         self.set_mode(mode)
 
-       self._send_mce_request(self._ENABLE_ACCEL)
-
-    def set_mode(self, new_mode):
-       self._mode=new_mode
-
     def get_mode(self):
         """Get the currently-set rotation mode
 
@@ -100,6 +115,41 @@ class FremantleRotation(object):
         """
         return self._mode
 
+    def set_mode(self, new_mode):
+        """Set the rotation mode
+
+        You can set the rotation mode to AUTOMATIC (use hardware rotation
+        info), ALWAYS (force portrait) and NEVER (force landscape).
+        """
+        if new_mode not in (self.AUTOMATIC, self.ALWAYS, self.NEVER):
+            raise ValueError('Unknown rotation mode')
+
+        if self._mode != new_mode:
+            if self._mode == self.AUTOMATIC:
+                # Remember the current "automatic" orientation for later
+                self._last_dbus_orientation = self._orientation
+                # Tell MCE that we don't need the accelerometer anymore
+                self._send_mce_request(self._DISABLE_ACCEL)
+
+            if new_mode == self.NEVER:
+                self._orientation_changed(self._LANDSCAPE)
+            elif new_mode == self.ALWAYS and \
+                    self._keyboard_state != self._KBD_OPEN:
+                self._orientation_changed(self._PORTRAIT)
+            elif new_mode == self.AUTOMATIC:
+                # Restore the last-known "automatic" orientation
+                self._orientation_changed(self._last_dbus_orientation)
+                # Tell MCE that we need the accelerometer again
+                self._send_mce_request(self._ENABLE_ACCEL)
+
+            self._mode = new_mode
+
+    def reset_mode(self):
+       if self._mode==self.AUTOMATIC:
+           self._send_mce_request(self._ENABLE_ACCEL)
+       else:
+           self._send_mce_request(self._DISABLE_ACCEL)
+
     def _send_mce_request(self, request):
         rpc = osso.Rpc(self._osso_context)
         rpc.rpc_run(self._MCE_SERVICE, \
@@ -116,7 +166,7 @@ class FremantleRotation(object):
             else:
                 self._send_mce_request(self._DISABLE_ACCEL)
 
-    def NO_get_main_window(self):
+    def _get_main_window(self):
         if self._main_window:
             # If we have gotten the main window as parameter, return it and
             # don't try "harder" to find another window using the stack
@@ -136,9 +186,6 @@ class FremantleRotation(object):
             # Ignore repeated requests
             return
 
-       if orientation == None:
-           return
-
         flags = 0
 
         if orientation != self._LANDSCAPE:
@@ -147,14 +194,17 @@ class FremantleRotation(object):
         if orientation == self._PORTRAIT:
             flags |= hildon.PORTRAIT_MODE_REQUEST
 
-#        window = self._get_main_window()
-#        if window is not None:
-#            hildon.hildon_gtk_window_set_portrait_flags(window, flags)
+        window = self._get_main_window()
+        if window is not None and self.dontrotate==False:
+            hildon.hildon_gtk_window_set_portrait_flags(window, flags)
 
         self._orientation = orientation
 
        self.on_orientation_changed(orientation)
 
+    def on_orientation_changed(self, orientation):
+       pass
+
     def _get_keyboard_state(self):
         # For sbox, if the device does not exist assume that it's closed
         try: