Experimenting with direct-dial
[gc-dialer] / src / hildonize.py
index 84a3de3..339eb2a 100644 (file)
@@ -1,5 +1,11 @@
 #!/usr/bin/env python
 
+"""
+Open Issues
+       @bug not all of a message is shown
+       @bug Buttons are too small
+"""
+
 
 import gobject
 import gtk
@@ -41,24 +47,26 @@ except AttributeError:
        get_app_class = _null_get_app_class
 
 
-def _hildon_set_application_title(window, title):
-       pass
+def _hildon_set_application_name(name):
+       gtk.set_application_name(name)
 
 
-def _null_set_application_title(window, title):
-       window.set_title(title)
+def _null_set_application_name(name):
+       pass
 
 
-if IS_HILDON_SUPPORTED:
-       set_application_title = _hildon_set_application_title
-else:
-       set_application_title = _null_set_application_title
+try:
+       gtk.set_application_name
+       set_application_name = _hildon_set_application_name
+except AttributeError:
+       set_application_name = _null_set_application_name
 
 
 def _fremantle_hildonize_window(app, window):
        oldWindow = window
        newWindow = hildon.StackableWindow()
-       oldWindow.get_child().reparent(newWindow)
+       if oldWindow.get_child() is not None:
+               oldWindow.get_child().reparent(newWindow)
        app.add_window(newWindow)
        return newWindow
 
@@ -66,7 +74,8 @@ def _fremantle_hildonize_window(app, window):
 def _hildon_hildonize_window(app, window):
        oldWindow = window
        newWindow = hildon.Window()
-       oldWindow.get_child().reparent(newWindow)
+       if oldWindow.get_child() is not None:
+               oldWindow.get_child().reparent(newWindow)
        app.add_window(newWindow)
        return newWindow
 
@@ -86,16 +95,14 @@ except AttributeError:
                hildonize_window = _null_hildonize_window
 
 
-def _fremantle_hildonize_menu(window, gtkMenu, buttons):
+def _fremantle_hildonize_menu(window, gtkMenu):
        appMenu = hildon.AppMenu()
-       for button in buttons:
-               appMenu.append(button)
        window.set_app_menu(appMenu)
        gtkMenu.get_parent().remove(gtkMenu)
        return appMenu
 
 
-def _hildon_hildonize_menu(window, gtkMenu, ignoredButtons):
+def _hildon_hildonize_menu(window, gtkMenu):
        hildonMenu = gtk.Menu()
        for child in gtkMenu.get_children():
                child.reparent(hildonMenu)
@@ -104,7 +111,7 @@ def _hildon_hildonize_menu(window, gtkMenu, ignoredButtons):
        return hildonMenu
 
 
-def _null_hildonize_menu(window, gtkMenu, ignoredButtons):
+def _null_hildonize_menu(window, gtkMenu):
        return gtkMenu
 
 
@@ -122,6 +129,54 @@ except AttributeError:
                hildonize_menu = _null_hildonize_menu
 
 
+def _hildon_set_button_auto_selectable(button):
+       button.set_theme_size(hildon.HILDON_SIZE_AUTO_HEIGHT)
+
+
+def _null_set_button_auto_selectable(button):
+       pass
+
+
+try:
+       hildon.HILDON_SIZE_AUTO_HEIGHT
+       gtk.Button.set_theme_size
+       set_button_auto_selectable = _hildon_set_button_auto_selectable
+except AttributeError:
+       set_button_auto_selectable = _null_set_button_auto_selectable
+
+
+def _hildon_set_button_finger_selectable(button):
+       button.set_theme_size(hildon.HILDON_SIZE_FINGER_HEIGHT)
+
+
+def _null_set_button_finger_selectable(button):
+       pass
+
+
+try:
+       hildon.HILDON_SIZE_FINGER_HEIGHT
+       gtk.Button.set_theme_size
+       set_button_finger_selectable = _hildon_set_button_finger_selectable
+except AttributeError:
+       set_button_finger_selectable = _null_set_button_finger_selectable
+
+
+def _hildon_set_button_thumb_selectable(button):
+       button.set_theme_size(hildon.HILDON_SIZE_THUMB_HEIGHT)
+
+
+def _null_set_button_thumb_selectable(button):
+       pass
+
+
+try:
+       hildon.HILDON_SIZE_THUMB_HEIGHT
+       gtk.Button.set_theme_size
+       set_button_thumb_selectable = _hildon_set_button_thumb_selectable
+except AttributeError:
+       set_button_thumb_selectable = _null_set_button_thumb_selectable
+
+
 def _hildon_set_cell_thumb_selectable(renderer):
        renderer.set_property("scale", 1.5)
 
@@ -136,6 +191,20 @@ else:
        set_cell_thumb_selectable = _null_set_cell_thumb_selectable
 
 
+def _hildon_set_pix_cell_thumb_selectable(renderer):
+       renderer.set_property("stock-size", 48)
+
+
+def _null_set_pix_cell_thumb_selectable(renderer):
+       pass
+
+
+if IS_HILDON_SUPPORTED:
+       set_pix_cell_thumb_selectable = _hildon_set_pix_cell_thumb_selectable
+else:
+       set_pix_cell_thumb_selectable = _null_set_pix_cell_thumb_selectable
+
+
 def _fremantle_show_information_banner(parent, message):
        hildon.hildon_banner_show_information(parent, "", message)
 
@@ -211,30 +280,16 @@ else:
        hildonize_text_entry = _null_hildonize_text_entry
 
 
-def _hildon_mark_window_rotatable(window):
-       # gtk documentation is unclear whether this does a "=" or a "|="
-       window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
-
-
-def _null_mark_window_rotatable(window):
-       pass
-
-
-try:
-       hildon.HILDON_PORTRAIT_MODE_SUPPORT
-       mark_window_rotatable = _hildon_mark_window_rotatable
-except AttributeError:
-       mark_window_rotatable = _null_mark_window_rotatable
-
-
 def _hildon_window_to_portrait(window):
        # gtk documentation is unclear whether this does a "=" or a "|="
-       window.set_flags(hildon.HILDON_PORTRAIT_MODE_SUPPORT)
+       flags = hildon.PORTRAIT_MODE_SUPPORT | hildon.PORTRAIT_MODE_REQUEST
+       hildon.hildon_gtk_window_set_portrait_flags(window, flags)
 
 
 def _hildon_window_to_landscape(window):
        # gtk documentation is unclear whether this does a "=" or a "&= ~"
-       window.unset_flags(hildon.HILDON_PORTRAIT_MODE_REQUEST)
+       flags = hildon.PORTRAIT_MODE_SUPPORT
+       hildon.hildon_gtk_window_set_portrait_flags(window, flags)
 
 
 def _null_window_to_portrait(window):
@@ -246,8 +301,9 @@ def _null_window_to_landscape(window):
 
 
 try:
-       hildon.HILDON_PORTRAIT_MODE_SUPPORT
-       hildon.HILDON_PORTRAIT_MODE_REQUEST
+       hildon.PORTRAIT_MODE_SUPPORT
+       hildon.PORTRAIT_MODE_REQUEST
+       hildon.hildon_gtk_window_set_portrait_flags
 
        window_to_portrait = _hildon_window_to_portrait
        window_to_landscape = _hildon_window_to_landscape
@@ -303,6 +359,28 @@ else:
        hildonize_combo_entry = _null_hildonize_combo_entry
 
 
+def _null_create_seekbar():
+       adjustment = gtk.Adjustment(0, 0, 101, 1, 5, 1)
+       seek = gtk.HScale(adjustment)
+       seek.set_draw_value(False)
+       return seek
+
+
+def _fremantle_create_seekbar():
+       seek = hildon.Seekbar()
+       seek.set_range(0.0, 100)
+       seek.set_draw_value(False)
+       seek.set_update_policy(gtk.UPDATE_DISCONTINUOUS)
+       return seek
+
+
+try:
+       hildon.Seekbar
+       create_seekbar = _fremantle_create_seekbar
+except AttributeError:
+       create_seekbar = _null_create_seekbar
+
+
 def _fremantle_hildonize_scrollwindow(scrolledWindow):
        pannableWindow = hildon.PannableArea()
 
@@ -311,8 +389,9 @@ def _fremantle_hildonize_scrollwindow(scrolledWindow):
        pannableWindow.add(child)
 
        parent = scrolledWindow.get_parent()
-       parent.remove(scrolledWindow)
-       parent.add(pannableWindow)
+       if parent is not None:
+               parent.remove(scrolledWindow)
+               parent.add(pannableWindow)
 
        return pannableWindow
 
@@ -356,15 +435,16 @@ def _hildon_request_number(parent, title, range, default):
        try:
                dialog.show_all()
                response = dialog.run()
+
+               if response == gtk.RESPONSE_OK:
+                       return spinner.get_value()
+               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
+                       raise RuntimeError("User cancelled request")
+               else:
+                       raise RuntimeError("Unrecognized response %r", response)
        finally:
                dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               return spinner.get_value()
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
+               dialog.destroy()
 
 
 def _null_request_number(parent, title, range, default):
@@ -384,15 +464,16 @@ def _null_request_number(parent, title, range, default):
        try:
                dialog.show_all()
                response = dialog.run()
+
+               if response == gtk.RESPONSE_OK:
+                       return spinner.get_value_as_int()
+               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
+                       raise RuntimeError("User cancelled request")
+               else:
+                       raise RuntimeError("Unrecognized response %r", response)
        finally:
                dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               return spinner.get_value_as_int()
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
+               dialog.destroy()
 
 
 try:
@@ -418,22 +499,26 @@ def _hildon_touch_selector(parent, title, items, defaultIndex):
        try:
                dialog.show_all()
                response = dialog.run()
+
+               if response == gtk.RESPONSE_OK:
+                       return selector.get_active(0)
+               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
+                       raise RuntimeError("User cancelled request")
+               else:
+                       raise RuntimeError("Unrecognized response %r", response)
        finally:
                dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               return selector.get_active(0)
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
+               dialog.destroy()
 
 
-def _on_null_touch_selector_activated(treeView, path, column, dialog):
+def _on_null_touch_selector_activated(treeView, path, column, dialog, pathData):
        dialog.response(gtk.RESPONSE_OK)
+       pathData[0] = path
 
 
 def _null_touch_selector(parent, title, items, defaultIndex = -1):
+       parentSize = parent.get_size()
+
        model = gtk.ListStore(gobject.TYPE_STRING)
        for item in items:
                model.append((item, ))
@@ -441,7 +526,7 @@ def _null_touch_selector(parent, title, items, defaultIndex = -1):
        cell = gtk.CellRendererText()
        set_cell_thumb_selectable(cell)
        column = gtk.TreeViewColumn(title)
-       column .pack_start(cell, expand=True)
+       column.pack_start(cell, expand=True)
        column.add_attribute(cell, "text", 0)
 
        treeView = gtk.TreeView()
@@ -455,7 +540,6 @@ def _null_touch_selector(parent, title, items, defaultIndex = -1):
        scrolledWin = gtk.ScrolledWindow()
        scrolledWin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolledWin.add(treeView)
-       hildonize_scrollwindow(scrolledWin)
 
        dialog = gtk.Dialog(
                title,
@@ -465,25 +549,27 @@ def _null_touch_selector(parent, title, items, defaultIndex = -1):
        )
        dialog.set_default_response(gtk.RESPONSE_CANCEL)
        dialog.get_child().add(scrolledWin)
-       parentSize = parent.get_size()
        dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
-       treeView.connect("row-activated", _on_null_touch_selector_activated, dialog)
+
+       scrolledWin = hildonize_scrollwindow(scrolledWin)
+       pathData = [None]
+       treeView.connect("row-activated", _on_null_touch_selector_activated, dialog, pathData)
 
        try:
                dialog.show_all()
                response = dialog.run()
+
+               if response == gtk.RESPONSE_OK:
+                       if pathData[0] is None:
+                               raise RuntimeError("No selection made")
+                       return pathData[0][0]
+               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
+                       raise RuntimeError("User cancelled request")
+               else:
+                       raise RuntimeError("Unrecognized response %r", response)
        finally:
                dialog.hide()
-
-       if response == gtk.RESPONSE_OK:
-               model, itr = selection.get_selected()
-               if itr is None:
-                       raise RuntimeError("No selection made")
-               return model.get_path(itr)[0]
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
+               dialog.destroy()
 
 
 try:
@@ -496,7 +582,10 @@ except AttributeError:
 
 def _hildon_touch_selector_entry(parent, title, items, defaultItem):
        # Got a segfault when using append_text_column with TouchSelectorEntry, so using this way
-       selector = hildon.hildon_touch_selector_entry_new_text()
+       try:
+               selector = hildon.TouchSelectorEntry(text=True)
+       except TypeError:
+               selector = hildon.hildon_touch_selector_entry_new_text()
        defaultIndex = -1
        for i, item in enumerate(items):
                selector.append_text(item)
@@ -518,30 +607,39 @@ def _hildon_touch_selector_entry(parent, title, items, defaultItem):
                dialog.hide()
 
        if response == gtk.RESPONSE_OK:
-               selectedIndex = selector.get_active(0)
-               if 0 < selectedIndex:
-                       return items[selectedIndex]
-               else:
-                       return selector.get_entry().get_text()
+               return selector.get_entry().get_text()
        elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
                raise RuntimeError("User cancelled request")
        else:
                raise RuntimeError("Unrecognized response %r", response)
 
 
-def _on_null_touch_selector_entry_entry_activated(entry, dialog, customEntry, result):
+def _on_null_touch_selector_entry_entry_changed(entry, result, selection, defaultIndex):
+       custom = entry.get_text().strip()
+       if custom:
+               result[0] = custom
+               selection.unselect_all()
+       else:
+               result[0] = None
+               selection.select_path((defaultIndex, ))
+
+
+def _on_null_touch_selector_entry_entry_activated(customEntry, dialog, result):
        dialog.response(gtk.RESPONSE_OK)
-       result.append(customEntry.get_text())
+       result[0] = customEntry.get_text()
 
 
-def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, selection, result):
+def _on_null_touch_selector_entry_tree_activated(treeView, path, column, dialog, result):
        dialog.response(gtk.RESPONSE_OK)
-       model, itr = selection.get_selected()
+       model = treeView.get_model()
+       itr = model.get_iter(path)
        if itr is not None:
-               result.append(model.get_value(itr, 0))
+               result[0] = model.get_value(itr, 0)
 
 
 def _null_touch_selector_entry(parent, title, items, defaultItem):
+       parentSize = parent.get_size()
+
        model = gtk.ListStore(gobject.TYPE_STRING)
        defaultIndex = -1
        for i, item in enumerate(items):
@@ -552,7 +650,7 @@ def _null_touch_selector_entry(parent, title, items, defaultItem):
        cell = gtk.CellRendererText()
        set_cell_thumb_selectable(cell)
        column = gtk.TreeViewColumn(title)
-       column .pack_start(cell, expand=True)
+       column.pack_start(cell, expand=True)
        column.add_attribute(cell, "text", 0)
 
        treeView = gtk.TreeView()
@@ -568,46 +666,55 @@ def _null_touch_selector_entry(parent, title, items, defaultItem):
        customEntry = gtk.Entry()
 
        layout = gtk.VBox()
-       layout.pack_start(customEntry)
+       layout.pack_start(customEntry, expand=False)
        layout.pack_start(scrolledWin)
 
-       hildonize_scrollwindow(layout)
-
        dialog = gtk.Dialog(
                title,
                parent,
                gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
-               (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
+               (gtk.STOCK_OK, gtk.RESPONSE_OK, gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL),
        )
        dialog.set_default_response(gtk.RESPONSE_CANCEL)
        dialog.get_child().add(layout)
-       parentSize = parent.get_size()
        dialog.resize(parentSize[0], max(parentSize[1]-100, 100))
 
+       scrolledWin = hildonize_scrollwindow(scrolledWin)
+
+       result = [None]
        if 0 < defaultIndex:
                selection.select_path((defaultIndex, ))
+               result[0] = defaultItem
        else:
                customEntry.set_text(defaultItem)
-       result = []
-       customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, customEntry, result)
-       treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, selection, result)
+
+       customEntry.connect("activate", _on_null_touch_selector_entry_entry_activated, dialog, result)
+       customEntry.connect("changed", _on_null_touch_selector_entry_entry_changed, result, selection, defaultIndex)
+       treeView.connect("row-activated", _on_null_touch_selector_entry_tree_activated, dialog, result)
 
        try:
                dialog.show_all()
                response = dialog.run()
-       finally:
-               dialog.hide()
 
-       if response == gtk.RESPONSE_OK:
-               model, itr = selection.get_selected()
-               if len(result) != 1:
-                       raise RuntimeError("No selection made")
+               if response == gtk.RESPONSE_OK:
+                       _, itr = selection.get_selected()
+                       if itr is not None:
+                               return model.get_value(itr, 0)
+                       else:
+                               enteredText = customEntry.get_text().strip()
+                               if enteredText:
+                                       return enteredText
+                               elif result[0] is not None:
+                                       return result[0]
+                               else:
+                                       raise RuntimeError("No selection made")
+               elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
+                       raise RuntimeError("User cancelled request")
                else:
-                       return result[0]
-       elif response == gtk.RESPONSE_CANCEL or response == gtk.RESPONSE_DELETE_EVENT:
-               raise RuntimeError("User cancelled request")
-       else:
-               raise RuntimeError("Unrecognized response %r", response)
+                       raise RuntimeError("Unrecognized response %r", response)
+       finally:
+               dialog.hide()
+               dialog.destroy()
 
 
 try:
@@ -626,12 +733,21 @@ if __name__ == "__main__":
        win = gtk.Window()
        win.add(label)
        win = hildonize_window(app, win)
-       if False:
+       if False and IS_FREMANTLE_SUPPORTED:
+               appMenu = hildon.AppMenu()
+               for i in xrange(5):
+                       b = gtk.Button(str(i))
+                       appMenu.append(b)
+               win.set_app_menu(appMenu)
+               win.show_all()
+               appMenu.show_all()
+               gtk.main()
+       elif False:
                print touch_selector(win, "Test", ["A", "B", "C", "D"], 2)
-       if True:
+       elif False:
                print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "C")
                print touch_selector_entry(win, "Test", ["A", "B", "C", "D"], "Blah")
-       if False:
+       elif False:
                import pprint
                name, value = "", ""
                goodLocals = [
@@ -639,11 +755,11 @@ if __name__ == "__main__":
                        if not name.startswith("_")
                ]
                pprint.pprint(goodLocals)
-       if False:
+       elif False:
                import time
                show_information_banner(win, "Hello World")
                time.sleep(5)
-       if False:
+       elif False:
                import time
                banner = show_busy_banner_start(win, "Hello World")
                time.sleep(5)