diff -ruN zim-0.46/data/applications/fennec.desktop zim-0.46-maemo/data/applications/fennec.desktop --- zim-0.46/data/applications/fennec.desktop 1970-01-01 01:00:00.000000000 +0100 +++ zim-0.46-maemo/data/applications/fennec.desktop 2010-03-19 12:20:44.000000000 +0100 @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Name=Firefox (maemo) +Exec=fennec %u +TryExec=fennec +Terminal=false +Type=Application +Icon=fennec +X-Zim-AppType=web_browser diff -ruN zim-0.46/data/applications/hildon-mime-summon.desktop zim-0.46-maemo/data/applications/hildon-mime-summon.desktop --- zim-0.46/data/applications/hildon-mime-summon.desktop 1970-01-01 01:00:00.000000000 +0100 +++ zim-0.46-maemo/data/applications/hildon-mime-summon.desktop 2010-03-18 22:03:25.000000000 +0100 @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=hildon-mime-summon +TryExec=hildon-mime-summon +Icon=file-manager +NoDisplay=true +X-Zim-AppType=file_browser +Name=hildon-mime-summon (maemo) diff -ruN zim-0.46/data/applications/microb.desktop zim-0.46-maemo/data/applications/microb.desktop --- zim-0.46/data/applications/microb.desktop 1970-01-01 01:00:00.000000000 +0100 +++ zim-0.46-maemo/data/applications/microb.desktop 2010-03-19 13:34:16.000000000 +0100 @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=browser --url %u +TryExec=browser +Icon=qgn_list_browser +NoDisplay=true +X-Zim-AppType=web_browser +Name=Microb (maemo) diff -ruN zim-0.46/data/applications/modest.desktop zim-0.46-maemo/data/applications/modest.desktop --- zim-0.46/data/applications/modest.desktop 1970-01-01 01:00:00.000000000 +0100 +++ zim-0.46-maemo/data/applications/modest.desktop 2010-03-19 12:47:44.000000000 +0100 @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=modest-mailto.sh +TryExec=modest-mailto.sh +Icon=qgn_list_messagin +NoDisplay=true +X-Zim-AppType=email_client +Name=Modest (maemo) diff -ruN zim-0.46/data/applications/tear.desktop zim-0.46-maemo/data/applications/tear.desktop --- zim-0.46/data/applications/tear.desktop 1970-01-01 01:00:00.000000000 +0100 +++ zim-0.46-maemo/data/applications/tear.desktop 2010-03-19 12:47:21.000000000 +0100 @@ -0,0 +1,9 @@ +[Desktop Entry] +Version=1.0 +Name=Tear (maemo) +Exec=tear %u +TryExec=tear +Terminal=false +Type=Application +Icon=tear +X-Zim-AppType=web_browser diff -ruN zim-0.46/data/manual/About.txt zim-0.46-maemo/data/manual/About.txt --- zim-0.46/data/manual/About.txt 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/data/manual/About.txt 2010-03-16 22:51:50.000000000 +0100 @@ -1,5 +1,7 @@ Content-Type: text/x-zim-wiki Wiki-Format: zim 0.4 +Content-Type: text/x-zim-wiki +Wiki-Format: zim 0.4 ====== About Zim ====== diff -ruN zim-0.46/data/manual/Bugs.txt zim-0.46-maemo/data/manual/Bugs.txt --- zim-0.46/data/manual/Bugs.txt 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/data/manual/Bugs.txt 2010-03-16 23:37:25.000000000 +0100 @@ -7,4 +7,5 @@ Bugs can be reported in the bug tracker at http://bugs.launchpad.net/zim. Please see the [[FAQ]] before filing a bug report. - +Please, report bugs under maemo devices in the garage page at http://zim.garage +.maemo.org diff -ruN zim-0.46/data/manual/Help/Auto_Formatting.txt zim-0.46-maemo/data/manual/Help/Auto_Formatting.txt --- zim-0.46/data/manual/Help/Auto_Formatting.txt 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/data/manual/Help/Auto_Formatting.txt 2010-03-16 23:04:45.000000000 +0100 @@ -37,4 +37,4 @@ Also when you type a internet url like http://perl.org it will automatically be identified as a link. ===== Bullets and Checkboxes ===== -Another example of auto-formatting is that "* " at the beginning of a line gets converted to a bullet automatically. Typing either "[ ] ", "[*] " or "[x] " will give your different kinds of [[Check Boxes]]. +Another example of auto-formatting is that "* " at the beginning of a line gets converted to a bullet automatically. Typing either "[] ", "[*] ", "[x] " or "() ", "(*) ", "(x) " will give your different kinds of [[Check Boxes]]. diff -ruN zim-0.46/data/manual/Help/Check_Boxes.txt zim-0.46-maemo/data/manual/Help/Check_Boxes.txt --- zim-0.46/data/manual/Help/Check_Boxes.txt 2010-02-19 17:48:35.000000000 +0100 +++ zim-0.46-maemo/data/manual/Help/Check_Boxes.txt 2010-03-16 23:06:10.000000000 +0100 @@ -14,7 +14,7 @@ As you can see in this example checkboxes can have 3 states: [ ] open, [*] checked as 'OK' and [x] checked as 'NOK'. States can be toggle by clicking the checkbox with either the left mouse button or using the keyboard with '''' and '''' respectively. -To start a checkbox list type on an empty line '''[]''', this will automatically inert an open checkbox. Similarly you can type checked checkboxes using '''[*]''' and '''[x]''' respectively. Lines that start with a checkbox behave like bullet list items, so you can indent by typing '''' after the checkbox and when you press '''' the new line will start with an empty checkbox automatically. +To start a checkbox list type on an empty line '''[]or'''/'''()or''', this will automatically insert an open checkbox. Similarly you can type checked checkboxes using '''[*]''' or '''(*)''' and '''[x]''' or '''(x)''' respectively, followed by '''''' or ''''''. Lines that start with a checkbox behave like bullet list items, so you can indent by typing '''' after the checkbox and when you press '''' the new line will start with an empty checkbox automatically. There is an option in the [[Preferences]] to have checkbox lists behave recursively. This means that the state of items with a sublist reflects the state of all child items. Checking the parent will check all child items, and checking the last child item will check the parent item automatically. diff -ruN zim-0.46/data/manual/Help/Notebooks.txt zim-0.46-maemo/data/manual/Help/Notebooks.txt --- zim-0.46/data/manual/Help/Notebooks.txt 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/data/manual/Help/Notebooks.txt 2010-03-16 23:07:32.000000000 +0100 @@ -9,7 +9,7 @@ See [[Usage]] for more tips on how to use notebooks for specific tasks. -**When you run zim for the first time** you will get asked for a new folder to store the notebook. This will no become the defaul notebook, everytime you start zim this notebook is opened directly. If you whish to use more than one notebook you can create additional notebooks from the the "Open notebook" dialog (see the "//File//->//Open Another Notebook//" menu item). +**When you run zim for the first time** you will get asked for a new folder to store the notebook. This will now become the defaul notebook, everytime you start zim this notebook is opened directly. If you whish to use more than one notebook you can create additional notebooks from the the "Open notebook" dialog (see the "//File//->//Open Another Notebook//" menu item). ===== Open Notebook Dialog ===== The "Open notebook" dialog allows you to select from multiple notebooks, or to add new notebooks. When you **add** a notebook you will be asked for the folder to store the notebook. This can either be an new (empty) folder or an existing notebook folder. diff -ruN zim-0.46/data/manual/Help/Searching.txt zim-0.46-maemo/data/manual/Help/Searching.txt --- zim-0.46/data/manual/Help/Searching.txt 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/data/manual/Help/Searching.txt 2010-03-16 22:52:13.000000000 +0100 @@ -1,5 +1,7 @@ Content-Type: text/x-zim-wiki Wiki-Format: zim 0.4 +Content-Type: text/x-zim-wiki +Wiki-Format: zim 0.4 ====== Searching ====== diff -ruN zim-0.46/data/manual/Plugins/Insert_Screenshot.txt zim-0.46-maemo/data/manual/Plugins/Insert_Screenshot.txt --- zim-0.46/data/manual/Plugins/Insert_Screenshot.txt 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/data/manual/Plugins/Insert_Screenshot.txt 2010-03-16 23:09:37.000000000 +0100 @@ -5,4 +5,4 @@ This plugin adds a dialog that allows you to aquire a screenshot of the desktop or of a particular window and directly insert the image into the current zim page. This plugin is based on the "scrot" applications to take the actual screenshots. -**Dependencies:** This plugin requires the "scrot" application to be installed. In specific the "scrot" command should be available in the system path. +**Dependencies:** This plugin requires the "scrot" (or "screenshot-tool" in maemo devices) application to be installed. In specific the "scrot" command should be available in the system path. diff -ruN zim-0.46/data/manual/Usage/Getting_Things_Done.txt zim-0.46-maemo/data/manual/Usage/Getting_Things_Done.txt --- zim-0.46/data/manual/Usage/Getting_Things_Done.txt 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/data/manual/Usage/Getting_Things_Done.txt 2010-03-16 23:00:55.000000000 +0100 @@ -70,14 +70,11 @@ As an extension I also use the [[Plugins:Calendar|Calendar plugin]] to have a journal page for each day with notes from meetings etc. Action items from meetings may live there, but this usage is a bit at odds with the use of the INBOX page. At least I can reference discussion notes of a certain date from a project page etc. === Summary === -* Each action belongs to an open project - "Chores" is the collection -bucket for small tasks +* Each action belongs to an open project - "Chores" is the collection bucket for small tasks * Open projects go in the "Projects" namespace -* Open projects should have a clearly defined goal which can be -evaluated and stamped "finished" at a certain point in time +* Open projects should have a clearly defined goal which can be evaluated and stamped "finished" at a certain point in time * Otherwise they go in either "SomeDay" or "Archive" -* Each action should have a checkbox - possible follow up actions can -have normal bullets if they are not actionable yet +* Each action should have a checkbox - possible follow up actions can have normal bullets if they are not actionable yet * Tags on action are used to generate lists * Some tickler lists can have their own pages, like "Loans" diff -ruN zim-0.46/data/modest-mailto.sh zim-0.46-maemo/data/modest-mailto.sh --- zim-0.46/data/modest-mailto.sh 1970-01-01 01:00:00.000000000 +0100 +++ zim-0.46-maemo/data/modest-mailto.sh 2010-03-19 12:21:04.000000000 +0100 @@ -0,0 +1,2 @@ +#!/bin/sh +dbus-send --session --type=method_call --dest=com.nokia.modest --print-reply /com/nokia/modest com.nokia.modest.MailTo string:"$1" diff -ruN zim-0.46/xdg/hildon/zim.desktop zim-0.46-maemo/xdg/hildon/zim.desktop --- zim-0.46/xdg/hildon/zim.desktop 1970-01-01 01:00:00.000000000 +0100 +++ zim-0.46-maemo/xdg/hildon/zim.desktop 2010-03-16 22:52:30.000000000 +0100 @@ -0,0 +1,8 @@ +[Desktop Entry] +Version=1.0.0 +Encoding=UTF-8 +Type=Application +Name=Zim +Comment=A desktop wiki and all purpose TODO and GTD application +Exec=/usr/bin/zim --no-daemon +Icon=zim diff -ruN zim-0.46/zim/gui/imagegeneratordialog.py zim-0.46-maemo/zim/gui/imagegeneratordialog.py --- zim-0.46/zim/gui/imagegeneratordialog.py 2010-03-09 22:06:12.000000000 +0100 +++ zim-0.46-maemo/zim/gui/imagegeneratordialog.py 2010-03-24 21:37:01.000000000 +0100 @@ -7,7 +7,7 @@ from zim.fs import * from zim.gui.widgets import Dialog, ImageView, Button, QuestionDialog, scrolled_text_view - +from zim.gui import maemo logger = logging.getLogger('zim.gui') @@ -22,14 +22,18 @@ # TODO: use uistate to remember pane position def __init__(self, ui, title, generator, image=None, **opt): - Dialog.__init__(self, ui, title, defaultwindowsize=(450, 300), **opt) + if maemo: + WSIZE=(600,480) + else: + WSIZE=(450,300) + Dialog.__init__(self, ui, title, defaultwindowsize=WSIZE, **opt) self.generator = generator self.imagefile = None self.logfile = None self._existing_file = None self.vpane = gtk.VPaned() - self.vpane.set_position(100) + self.vpane.set_position(150) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkboard=False) diff -ruN zim-0.46/zim/gui/__init__.py zim-0.46-maemo/zim/gui/__init__.py --- zim-0.46/zim/gui/__init__.py 2010-03-23 18:23:14.000000000 +0100 +++ zim-0.46-maemo/zim/gui/__init__.py 2010-03-24 21:37:01.000000000 +0100 @@ -28,6 +28,13 @@ import logging import gobject import gtk +try: + import hildon + gtkWindow=hildon.Window + maemo=True +except: + gtkWindow=gtk.Window + maemo=False import zim from zim import NotebookInterface, NotebookLookupError @@ -153,7 +160,18 @@ TOOLBAR_ICONS_SMALL = 'small' TOOLBAR_ICONS_TINY = 'tiny' -ui_preferences = ( +if maemo: + ui_preferences = ( + # key, type, category, label, default + ('tearoff_menus', 'bool', None, None, False), + # T: Option in the preferences dialog not shown. + # Maemo can't have tearoff_menus + ('toggle_on_ctrlspace', 'bool', None, None, True), + # T: Option in the preferences dialog not shown. + # There is no ALT key on maemo devices + ) +else: + ui_preferences = ( # key, type, category, label, default ('tearoff_menus', 'bool', 'Interface', _('Add \'tearoff\' strips to the menus'), False), # T: Option in the preferences dialog @@ -295,6 +313,13 @@ 'file_browser': ['xdg-open', 'startfile'], 'web_browser': ['xdg-open', 'startfile'] } + if maemo: + apps = { + 'email_client': ['modest', 'startfile'], + 'file_browser': ['hildon-mime-summon', 'startfile'], + 'web_browser': ['webbrowser', 'webbrowser'] + } + for type in apps.keys(): prefs = self.preferences['GtkInterface'] if type in prefs and prefs[type] \ @@ -335,6 +360,16 @@ self.uimanager.ensure_update() # prevent flashing when the toolbar is after showing the window # and do this before connecting signal below for accelmap + if maemo: + # Move the menu to the hildon menu + menu=gtk.Menu() + for child in self.mainwindow.menubar.get_children(): + child.reparent(menu) + self.mainwindow.set_menu(menu) + # Hardware fullscreen key is F6 in Nxxx devices + self.mainwindow.connect('key-press-event', + lambda o, event: event.keyval == gtk.keysyms.F6 + and self.mainwindow.toggle_fullscreen()) accelmap = config_file('accelmap').file logger.debug('Accelmap: %s', accelmap.path) @@ -601,8 +636,10 @@ for p in preferences: key, type, category, label, default = p self.preferences[section].setdefault(key, default) - register.setdefault(category, []) - register[category].append((section, key, type, label)) + # Preferences with None category won't be shown in the preferences dialog + if category: + register.setdefault(category, []) + register[category].append((section, key, type, label)) def get_path_context(self): '''Returns the current 'context' for actions that want a path to start @@ -1271,7 +1308,7 @@ gobject.type_register(GtkInterface) -class MainWindow(gtk.Window): +class MainWindow(gtkWindow): '''Main window of the application, showing the page index in the side pane and a pageview with the current page. Alse includes the menubar, toolbar, statusbar etc. @@ -1279,7 +1316,7 @@ def __init__(self, ui, fullscreen=False, geometry=None): '''Constructor''' - gtk.Window.__init__(self) + gtkWindow.__init__(self) self._fullscreen = False self.ui = ui @@ -1340,6 +1377,9 @@ 'toggle-overwrite', self.do_textview_toggle_overwrite) vbox2.add(self.pageview) + # maemo window menu requires this approach because it is a popup dialog + self.pageindex.treeview.connect('focus-in-event', lambda sender, e, me: me.pageview.disable_actiongroup(), self) + # create statusbar hbox = gtk.HBox(spacing=0) vbox.pack_start(hbox, False, True, False) @@ -1421,13 +1461,14 @@ space = gtk.gdk.unicode_to_keyval(ord(' ')) group = gtk.AccelGroup() - group.connect_group( # - space, gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE, - self.do_switch_focus) if self.ui.preferences['GtkInterface']['toggle_on_ctrlspace']: group.connect_group( # space, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE, self.do_switch_focus) + else: + group.connect_group( # + space, gtk.gdk.MOD1_MASK, gtk.ACCEL_VISIBLE, + self.do_switch_focus) self.add_accel_group(group) self._switch_focus_accelgroup = group @@ -1697,7 +1738,10 @@ self.uistate.setdefault('show_menubar', True) self.uistate.setdefault('show_menubar_fullscreen', True) self.uistate.setdefault('show_toolbar', True) - self.uistate.setdefault('show_toolbar_fullscreen', False) + if maemo: + self.uistate.setdefault('show_toolbar_fullscreen', True) + else: + self.uistate.setdefault('show_toolbar_fullscreen', False) self.uistate.setdefault('show_statusbar', True) self.uistate.setdefault('show_statusbar_fullscreen', False) self.uistate.setdefault('pathbar_type', PATHBAR_RECENT) @@ -1813,11 +1857,11 @@ MenuButton.popup_menu(self, event) -class PageWindow(gtk.Window): +class PageWindow(gtkWindow): '''Secondairy window, showing a single page''' def __init__(self, ui, page): - gtk.Window.__init__(self) + gtkWindow.__init__(self) self.ui = ui self.set_title(page.name + ' - Zim') @@ -2169,7 +2213,7 @@ label = gtk.Label() short = _('Delete page "%s"?') % self.path.basename # T: Heading in 'delete page' dialog - %s is the page name - long = _('Page "%s" and all of it\'s sub-pages and attachments will be deleted') % self.path.name + long = _('Page "%s" and all of it\'s sub-pages\nand attachments will be deleted') % self.path.name # T: Text in 'delete page' dialog - %s is the page name label.set_markup(''+short+'\n\n'+long) hbox.add(label) diff -ruN zim-0.46/zim/gui/notebookdialog.py zim-0.46-maemo/zim/gui/notebookdialog.py --- zim-0.46/zim/gui/notebookdialog.py 2010-02-21 12:03:36.000000000 +0100 +++ zim-0.46-maemo/zim/gui/notebookdialog.py 2010-03-24 23:42:00.000000000 +0100 @@ -18,6 +18,7 @@ from zim.notebook import get_notebook_list, init_notebook from zim.config import data_file from zim.gui.widgets import Dialog, IconButton +from zim.gui import maemo logger = logging.getLogger('zim.gui.notebookdialog') @@ -348,11 +349,12 @@ label = gtk.Label(_('Please select a name and a folder for the notebook.')) # T: Label in Add Notebook dialog label.set_alignment(0.0, 0.5) self.vbox.pack_start(label, False) - - if name is None and folder is None: name = 'Notes' - folder = '~/Notes' + if maemo: + folder = '~/MyDocs/Notes' + else: + folder = '~/Notes' self.add_fields(( ('name', 'string', _('Name'), name), # T: input field in 'Add Notebook' dialog ('folder', 'dir', _('Folder'), folder), # T: input field in 'Add Notebook' dialog diff -ruN zim-0.46/zim/gui/pageview.py zim-0.46-maemo/zim/gui/pageview.py --- zim-0.46/zim/gui/pageview.py 2010-03-22 22:47:03.000000000 +0100 +++ zim-0.46-maemo/zim/gui/pageview.py 2010-03-26 16:20:07.000000000 +0100 @@ -31,6 +31,7 @@ from zim.gui.applications import OpenWithMenu from zim.gui.clipboard import Clipboard, \ PARSETREE_ACCEPT_TARGETS, parsetree_from_selectiondata +from zim.gui import maemo logger = logging.getLogger('zim.gui.pageview') @@ -56,10 +57,11 @@ KEYVALS_TAB = map(gtk.gdk.keyval_from_name, ('Tab', 'KP_Tab')) KEYVALS_LEFT_TAB = map(gtk.gdk.keyval_from_name, ('ISO_Left_Tab',)) +# Maemo hildon input method keyboard doesn't emit keypress events except for TAB, ENTER and BACKSPACE #~ CHARS_END_OF_WORD = (' ', ')', '>', '.', '!', '?') -CHARS_END_OF_WORD = (' ', ')', '>') +CHARS_END_OF_WORD = ('\t',' ', ')', '>') KEYVALS_END_OF_WORD = map( - gtk.gdk.unicode_to_keyval, map(ord, CHARS_END_OF_WORD)) + gtk.gdk.unicode_to_keyval, map(ord, CHARS_END_OF_WORD[1:])) + KEYVALS_TAB KEYVALS_ASTERISK = ( gtk.gdk.unicode_to_keyval(ord('*')), gtk.gdk.keyval_from_name('KP_Multiply')) @@ -121,7 +123,38 @@ ('toggle_format_strike', 'gtk-strikethrough', _('_Strike'), '', _('Strike')), ) -ui_preferences = ( +if maemo: + ui_preferences = ( + # key, type, category, label, default + ('follow_on_enter', 'bool', None, + None, True), + # T: option in preferences dialog not shown + # There is no ALT key on maemo devices + ('read_only_cursor', 'bool', 'Interface', + _('Show the cursor also for pages that can not be edited'), False), + # T: option in preferences dialog + ('autolink_camelcase', 'bool', 'Editing', + _('Automatically turn "CamelCase" words into links'), True), + # T: option in preferences dialog + ('autolink_files', 'bool', 'Editing', + _('Automatically turn file paths into links'), True), + # T: option in preferences dialog + ('autoselect', 'bool', 'Editing', + _('Automatically select the current word when you apply formatting'), True), + # T: option in preferences dialog + ('unindent_on_backspace', 'bool', None, + None, True), + # T: option in preferences dialog not shown + # There is no hardware TAB key on maemo devices + ('recursive_indentlist', 'bool', 'Editing', + _('(Un-)Indenting a list item also change any sub-items'), True), + # T: option in preferences dialog + ('recursive_checklist', 'bool', 'Editing', + _('Checking a checkbox also change any sub-items'), False), + # T: option in preferences dialog + ) +else: + ui_preferences = ( # key, type, category, label, default ('follow_on_enter', 'bool', 'Interface', _('Use the key to follow links\n(If disabled you can still use )'), True), @@ -193,6 +226,10 @@ '[]': UNCHECKED_BOX, '[*]': CHECKED_BOX, '[x]': XCHECKED_BOX, + # Maemo devices have no hardware [] keys, allow () to be used for the same purpose + '()': UNCHECKED_BOX, + '(*)': CHECKED_BOX, + '(x)': XCHECKED_BOX, } CHECKBOXES = (UNCHECKED_BOX, CHECKED_BOX, XCHECKED_BOX) @@ -1346,13 +1383,17 @@ self.smart_remove_tags(_is_link_tag, start, end) self.set_editmode_from_cursor() - def toggle_checkbox(self, iter, checkbox_type=CHECKED_BOX): + def toggle_checkbox(self, iter, checkbox_type = None): bullet = self.get_bullet_at_iter(iter) if bullet in (UNCHECKED_BOX, CHECKED_BOX, XCHECKED_BOX): - if bullet == checkbox_type: - icon = bullet_types[UNCHECKED_BOX] + if checkbox_type: + if bullet == checkbox_type: + icon = bullet_types[UNCHECKED_BOX] + else: + icon = bullet_types[checkbox_type] else: - icon = bullet_types[checkbox_type] + next = (list(CHECKBOXES).index(bullet) + 1) % len(CHECKBOXES) + icon = bullet_types[CHECKBOXES[next]] else: return False @@ -2145,6 +2186,8 @@ if event.keyval in KEYVALS_ENTER: char = '\n' + elif event.keyval in KEYVALS_TAB: + char = '\t' else: char = unichr(gtk.gdk.keyval_to_unicode(event.keyval)) @@ -2346,7 +2389,7 @@ buffer.apply_tag(tag, start, end) return True - if char == ' ' and start.starts_line() and word in autoformat_bullets: + if (char == ' ' or char == chr(9)) and start.starts_line() and word in autoformat_bullets: # format bullet and checkboxes end.forward_char() # also overwrite the space triggering the action mark = buffer.create_mark(None, end) @@ -2820,6 +2863,7 @@ ## Create search box self.find_bar = FindBar(textview=self.view) + self.find_bar.connect('focus-in-event', lambda sender, e, me: me.disable_actiongroup(), self) self.pack_end(self.find_bar, False) self.find_bar.hide() @@ -2849,19 +2893,9 @@ # HACK, this makes sure we do not hijack keybindings like # ^C and ^V while we are not focus (e.g. paste in find bar) - def set_actiongroup_sensitive(o, e, sensitive): - # Immitate logic in self.set_readonly() - if sensitive: - for action in self.actiongroup.list_actions(): - action.set_sensitive( - action.zim_readonly or not self.readonly) - else: - for action in self.actiongroup.list_actions(): - action.set_sensitive(False) - - self.view.connect('focus-in-event', set_actiongroup_sensitive, True) - self.view.connect('focus-out-event', set_actiongroup_sensitive, False) - + # Under maemo the menu gets the focus, so we can't just use the + # focus-out event, and must wire the focus-in event of the affected widgets + self.view.connect('focus-in-event', lambda sender, e, me: me.enable_actiongroup(), self) # Extra keybinding for undo - default is Z (see HIG) def do_undo(*a): @@ -2881,6 +2915,14 @@ self.ui.connect('open-notebook', self.on_open_notebook) self.ui.connect_object('readonly-changed', PageView.set_readonly, self) + def enable_actiongroup(self): + for action in self.actiongroup.list_actions(): + action.set_sensitive(action.zim_readonly or not self.readonly) + + def disable_actiongroup(self): + for action in self.actiongroup.list_actions(): + action.set_sensitive(False) + def grab_focus(self): self.view.grab_focus() @@ -3839,9 +3881,9 @@ return True -class FindWidget(object): +class FindWidget(gtk.Widget): '''Base class for FindBar and FindAndReplaceDialog''' - + def __init__(self, textview): self.textview = textview @@ -3850,39 +3892,49 @@ 'changed', self.__class__.on_find_entry_changed, self) self.find_entry.connect_object( 'activate', self.__class__.on_find_entry_activate, self) - + self.find_entry.connect('focus-in-event', self.__emit_focus_in_event) + self.next_button = Button(_('_Next'), gtk.STOCK_GO_FORWARD) # T: button in find bar and find & replace dialog self.next_button.connect_object( 'clicked', self.__class__.find_next, self) + self.next_button.connect('focus-in-event', self.__emit_focus_in_event) self.next_button.set_sensitive(False) self.previous_button = Button(_('_Previous'), gtk.STOCK_GO_BACK) # T: button in find bar and find & replace dialog self.previous_button.connect_object( 'clicked', self.__class__.find_previous, self) + self.previous_button.connect('focus-in-event', self.__emit_focus_in_event) self.previous_button.set_sensitive(False) self.case_option_checkbox = gtk.CheckButton(_('Match _case')) # T: checkbox option in find bar and find & replace dialog self.case_option_checkbox.connect_object( 'toggled', self.__class__.on_find_entry_changed, self) + self.case_option_checkbox.connect('focus-in-event', self.__emit_focus_in_event) self.word_option_checkbox = gtk.CheckButton(_('Whole _word')) # T: checkbox option in find bar and find & replace dialog self.word_option_checkbox.connect_object( 'toggled', self.__class__.on_find_entry_changed, self) + self.word_option_checkbox.connect('focus-in-event', self.__emit_focus_in_event) self.regex_option_checkbox = gtk.CheckButton(_('_Regular expression')) # T: checkbox option in find bar and find & replace dialog self.regex_option_checkbox.connect_object( 'toggled', self.__class__.on_find_entry_changed, self) + self.regex_option_checkbox.connect('focus-in-event', self.__emit_focus_in_event) self.highlight_checkbox = gtk.CheckButton(_('_Highlight')) # T: checkbox option in find bar and find & replace dialog self.highlight_checkbox.connect_object( 'toggled', self.__class__.on_highlight_toggled, self) + self.highlight_checkbox.connect('focus-in-event', self.__emit_focus_in_event) + def __emit_focus_in_event(self, o, e): + self.emit('focus-in-event', e) + @property def _flags(self): flags = 0 @@ -3966,8 +4018,27 @@ self.pack_start(self.find_entry, False) self.pack_start(self.previous_button, False) self.pack_start(self.next_button, False) - self.pack_start(self.case_option_checkbox, False) - self.pack_start(self.highlight_checkbox, False) + if maemo: + # Nxx0 devices have not enough space for so many widgets, so let's put options in a menu button. + options_button = gtk.MenuToolButton(None,None) + options_menu = gtk.Menu() + item1 = gtk.CheckMenuItem(self.case_option_checkbox.get_label()) + item1.connect('toggled', lambda sender, me: me.case_option_checkbox.set_active(sender.get_active()),self) + item1.show() + options_menu.append(item1) + item2 = gtk.CheckMenuItem(self.highlight_checkbox.get_label()) + item2.connect('toggled', lambda sender, me: me.highlight_checkbox.set_active(sender.get_active()),self) + item2.show() + options_menu.append(item2) + options_menu.show() + options_button.set_menu(options_menu) + self.pack_start(options_button, False) + # HACK: remove button + b = options_button.get_children()[0] + b.remove(b.get_children()[0]) + else: + self.pack_start(self.case_option_checkbox, False) + self.pack_start(self.highlight_checkbox, False) close_button = IconButton(gtk.STOCK_CLOSE, relief=False) close_button.connect_object('clicked', self.__class__.hide, self) diff -ruN zim-0.46/zim/gui/preferencesdialog.py zim-0.46-maemo/zim/gui/preferencesdialog.py --- zim-0.46/zim/gui/preferencesdialog.py 2010-03-09 22:06:12.000000000 +0100 +++ zim-0.46-maemo/zim/gui/preferencesdialog.py 2010-03-24 22:46:32.000000000 +0100 @@ -2,6 +2,7 @@ # Copyright 2009 Jaap Karssenberg +import pango import gtk import logging @@ -10,6 +11,7 @@ get_application, get_helper_applications, CustomCommandDialog from zim.gui.widgets import Dialog, Button, BrowserTreeView from zim.gui.pageview import PageView +from zim.gui import maemo logger = logging.getLogger('zim.gui.preferencesdialog') @@ -25,7 +27,8 @@ Dialog.__init__(self, ui, _('Preferences')) # T: Dialog title gtknotebook = gtk.Notebook() self.vbox.add(gtknotebook) - + if maemo: + self.resize(800,480) # Dynamic tabs for category, preferences in ui.preferences_register.items(): table = gtk.Table() @@ -171,33 +174,22 @@ vbox = gtk.VBox() self.add(vbox) - def heading(text): - label = gtk.Label() - label.set_markup('%s' % text) - label.set_alignment(0.0, 0.5) - return label - - vbox.pack_start(heading(_('Name')), False) - # T: Heading in plugins tab of preferences dialog - self.name_label = gtk.Label() - self.name_label.set_alignment(0.0, 0.5) - vbox.pack_start(self.name_label, False) - vbox.pack_start(heading('\n'+_('Description')), False) - # T: Heading in plugins tab of preferences dialog - self.description_label = gtk.Label() - self.description_label.set_alignment(0.0, 0.5) - vbox.pack_start(self.description_label, False) # FIXME run through plain format to make links - vbox.pack_start(heading('\n'+_('Dependencies')),False) - # T: Heading in plugins tab of preferences dialog - self.dep_label = gtk.Label() - self.dep_label.set_alignment(0.0, 0.5) - vbox.pack_start(self.dep_label, False) - - vbox.pack_start(heading('\n'+_('Author')), False) - # T: Heading in plugins tab of preferences dialog - self.author_label= gtk.Label() - self.author_label.set_alignment(0.0, 0.5) - vbox.pack_start(self.author_label, False) # FIXME idem + # Textview with scrollbars to show plugins info. Required by small screen devices + textview = gtk.TextView() + textview.set_cursor_visible(False) + textview.set_editable(False) + bold_tag = gtk.TextTag('bold') + bold_tag.set_property('weight', pango.WEIGHT_BOLD) + red_tag = gtk.TextTag('red') + red_tag.set_property('foreground', '#FF0000') + self.plugin_info_textbuffer = textview.get_buffer() + self.plugin_info_textbuffer.get_tag_table().add(bold_tag) + self.plugin_info_textbuffer.get_tag_table().add(red_tag) + swindow = gtk.ScrolledWindow() + swindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + swindow.add(textview) + + vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) @@ -218,30 +210,28 @@ active = treeview.get_model()[path][0] klass = treeview.get_model()[path][3] self._klass = klass - + # Insert plugin info into textview with proper formatting + self.plugin_info_textbuffer.delete(self.plugin_info_textbuffer.get_start_iter(), self.plugin_info_textbuffer.get_end_iter()) + self.plugin_info_textbuffer.insert_with_tags_by_name(self.plugin_info_textbuffer.get_end_iter(), _('Name'), 'bold') + self.plugin_info_textbuffer.insert(self.plugin_info_textbuffer.get_end_iter(), '\n'+klass.plugin_info['name'].strip() + '\n\n') + self.plugin_info_textbuffer.insert_with_tags_by_name(self.plugin_info_textbuffer.get_end_iter(), _('Description'), 'bold') + self.plugin_info_textbuffer.insert(self.plugin_info_textbuffer.get_end_iter(), '\n'+klass.plugin_info['description'].strip() + '\n\n') + self.plugin_info_textbuffer.insert_with_tags_by_name(self.plugin_info_textbuffer.get_end_iter(), _('Dependencies'), 'bold') + #construct dependency list, missing dependencies are marked red - space = False - depend_label = '' - def format_dependency(dependency): - text, ok = dependency - text = text.replace('>', '>').replace('<', '<') # encode XML - if ok: - text += ' - ' + _('OK') # T: dependency is OK - else: - text = '%s - %s' % (text, _('Failed')) - # T: dependency failed - return u'\u2022 ' + text + '\n' # unicode bullet - dependencies = klass.check_dependencies() - if dependencies: - dep_text = ''.join(map(format_dependency, dependencies)) + if not(dependencies): + self.plugin_info_textbuffer.insert(self.plugin_info_textbuffer.get_end_iter(), '\n'+_('No dependencies')) else: - dep_text = _('No dependencies') # T: label in plugin info in preferences dialog - - self.name_label.set_text(klass.plugin_info['name'].strip()) - self.description_label.set_text(klass.plugin_info['description'].strip()) - self.dep_label.set_markup(dep_text) - self.author_label.set_text(klass.plugin_info['author'].strip() + '\n') + for dependency in dependencies: + text, ok = dependency + if ok: + self.plugin_info_textbuffer.insert(self.plugin_info_textbuffer.get_end_iter(),u'\n\u2022 ' + text + ' - ' + _('OK')) # T: dependency is OK + else: + self.plugin_info_textbuffer.insert_with_tags_by_name(self.plugin_info_textbuffer.get_end_iter(), u'\n\u2022 ' + text +' - ' + _('Failed'), 'red') # T: dependency failed + + self.plugin_info_textbuffer.insert_with_tags_by_name(self.plugin_info_textbuffer.get_end_iter(), '\n\n' + _('Author'), 'bold') + self.plugin_info_textbuffer.insert(self.plugin_info_textbuffer.get_end_iter(), '\n'+klass.plugin_info['author'].strip()) self.configure_button.set_sensitive(active and bool(klass.plugin_preferences)) self.plugin_help_button.set_sensitive('help' in klass.plugin_info) diff -ruN zim-0.46/zim/gui/widgets.py zim-0.46-maemo/zim/gui/widgets.py --- zim-0.46/zim/gui/widgets.py 2010-03-23 20:28:23.000000000 +0100 +++ zim-0.46-maemo/zim/gui/widgets.py 2010-03-24 22:35:39.000000000 +0100 @@ -14,6 +14,7 @@ import logging import sys +from zim.gui import maemo from zim.fs import * import zim.errors import zim.config @@ -325,6 +326,7 @@ self.button.set_active(False) self.button.handler_unblock(self._clicked_signal) + # Need to register classes defining / overriding gobject signals gobject.type_register(MenuButton) @@ -584,8 +586,9 @@ title=format_title(title), flags=gtk.DIALOG_NO_SEPARATOR, ) - self.set_border_width(10) - self.vbox.set_spacing(5) + if not(maemo): + self.set_border_width(10) + self.vbox.set_spacing(5) if hasattr(ui, 'uistate') and isinstance(ui.uistate, zim.config.ConfigDict): assert isinstance(defaultwindowsize, tuple) @@ -593,7 +596,10 @@ self.uistate = ui.uistate[key] #~ print '>>', self.uistate self.uistate.setdefault('windowsize', defaultwindowsize, check=self.uistate.is_coord) - w, h = self.uistate['windowsize'] + if not(maemo): + w, h = self.uistate['windowsize'] + else: + w, h = defaultwindowsize self.set_default_size(w, h) else: self.uistate = { # used in tests/debug @@ -855,9 +861,10 @@ else: self.destroyed = True - w, h = self.get_size() - self.uistate['windowsize'] = (w, h) - self.save_uistate() + if not(maemo): + w, h = self.get_size() + self.uistate['windowsize'] = (w, h) + self.save_uistate() if self.destroyed: self.destroy() @@ -995,9 +1002,12 @@ # else Ok will do Dialog.__init__(self, ui, title, buttons=buttons, button=button, help_text=help_text, help=help) - if self.uistate['windowsize'] == (-1, -1): + if self.uistate['windowsize'] == (-1, -1) and not(maemo): self.uistate['windowsize'] = (500, 400) self.set_default_size(500, 400) + elif maemo: + self.uistate['windowsize'] = (800, 480) + self.set_default_size(800, 480) self.filechooser = gtk.FileChooserWidget(action=action) self.filechooser.set_do_overwrite_confirmation(True) self.filechooser.connect('file-activated', lambda o: self.response_ok()) @@ -1176,6 +1186,7 @@ #def do_destroy(self): # logger.debug('Closed ProgressBarDialog') + # Need to register classes defining gobject signals gobject.type_register(ProgressBarDialog) diff -ruN zim-0.46/zim/__init__.py zim-0.46-maemo/zim/__init__.py --- zim-0.46/zim/__init__.py 2010-03-24 21:57:50.000000000 +0100 +++ zim-0.46-maemo/zim/__init__.py 2010-03-25 00:19:51.000000000 +0100 @@ -19,6 +19,7 @@ ''' import os +import os.path import sys import gettext import gobject @@ -31,6 +32,7 @@ from zim.errors import Error from zim.config import data_dir, config_file, log_basedirs, ZIM_DATA_DIR +logger = logging.getLogger('zim') if os.name == 'nt': # Windows specific environment variables @@ -45,9 +47,11 @@ home = os.environ['HOMEDRIVE'] + os.environ['HOMEPATH'] os.environ['HOME'] = home -assert os.environ['USER'], 'ERROR: environment variable $USER not set' assert zim.fs.isdir(os.environ['HOME']), 'ERROR: environment variable $HOME not set correctly' - +if not(os.environ.has_key('USER')): + #Maemo doesn't define $USER + os.environ['USER'] = os.path.basename(os.environ['HOME']) + logger.info('Environment variable $USER not set') if ZIM_DATA_DIR: # We are running from a source dir - use the locale data included there @@ -59,10 +63,6 @@ gettext.install('zim', localedir, unicode=True, names=('_', 'gettext', 'ngettext')) - -logger = logging.getLogger('zim') - - ZIM_EXECUTABLE = 'zim' diff -ruN zim-0.46/zim/plugins/calendar.py zim-0.46-maemo/zim/plugins/calendar.py --- zim-0.46/zim/plugins/calendar.py 2010-02-19 17:48:36.000000000 +0100 +++ zim-0.46-maemo/zim/plugins/calendar.py 2010-03-16 22:52:30.000000000 +0100 @@ -9,7 +9,7 @@ from datetime import date as dateclass from zim.plugins import PluginClass -from zim.gui import Dialog +from zim.gui import maemo, Dialog from zim.gui.widgets import Button from zim.notebook import Path @@ -60,7 +60,7 @@ date_path_re = re.compile(r'^(.*:)?\d{4}:\d{2}:\d{2}$') - + class CalendarPlugin(PluginClass): plugin_info = { @@ -280,6 +280,13 @@ hbox = gtk.HBox() self.vbox.add(hbox) button = Button(_('_Today'), gtk.STOCK_JUMP_TO) # T: button label - button.connect('clicked', - lambda o: self.calendar_widget.select_date(dateclass.today())) + button.connect('clicked', self.do_today ) hbox.pack_end(button, False) + button = Button(stock=gtk.STOCK_CLOSE) # T: button label + button.connect('clicked', + lambda o: self.destroy()) + hbox.pack_start(button, False) + + def do_today(self, event): + self.calendar_widget.select_date(dateclass.today()) + if maemo: self.destroy() diff -ruN zim-0.46/zim/plugins/linkmap/gui.py zim-0.46-maemo/zim/plugins/linkmap/gui.py --- zim-0.46/zim/plugins/linkmap/gui.py 2010-02-04 23:22:13.000000000 +0100 +++ zim-0.46-maemo/zim/plugins/linkmap/gui.py 2010-03-16 22:52:30.000000000 +0100 @@ -6,6 +6,7 @@ from zim._lib import xdot from zim.gui.widgets import Dialog, IconButton +from zim.gui import maemo from zim.plugins.linkmap import LinkMap @@ -44,7 +45,10 @@ def __init__(self, ui, linkmap): Dialog.__init__(self, ui, 'LinkMap', buttons=gtk.BUTTONS_CLOSE) - self.set_default_size(400, 400) + if maemo: + self.resize(800,480) + else: + self.set_default_size(400, 400) self.linkmap = linkmap hbox = gtk.HBox(spacing=5) diff -ruN zim-0.46/zim/plugins/linkmap/__init__.py zim-0.46-maemo/zim/plugins/linkmap/__init__.py --- zim-0.46/zim/plugins/linkmap/__init__.py 2010-03-09 22:06:12.000000000 +0100 +++ zim-0.46-maemo/zim/plugins/linkmap/__init__.py 2010-03-24 21:46:11.000000000 +0100 @@ -39,7 +39,6 @@ def disconnect(self): pass - class LinkMap(object): def __init__(self, notebook, path, depth=2): diff -ruN zim-0.46/zim/plugins/scrot.py zim-0.46-maemo/zim/plugins/scrot.py --- zim-0.46/zim/plugins/scrot.py 2010-03-09 22:06:12.000000000 +0100 +++ zim-0.46-maemo/zim/plugins/scrot.py 2010-03-24 22:38:21.000000000 +0100 @@ -9,6 +9,7 @@ from zim.plugins import PluginClass from zim.gui.widgets import Dialog, ErrorDialog from zim.applications import Application +from zim.gui import maemo ui_xml = ''' @@ -35,7 +36,8 @@ plugin_info = { 'name': _('Insert Screenshot'), # T: plugin name 'description': _('''\ -This plugin is a wrapper for the "scrot" application. +This plugin is a wrapper for the "scrot" ("screenshot-tool" +on maemo) application. It allows taking a screenshot and directly insert it in a zim page. @@ -53,7 +55,11 @@ @classmethod def check_dependencies(klass): - return [('scrot',Application(('scrot',)).tryexec())] + if maemo: + dependency = ('screenshot-tool', Application(('screenshot-tool',)).tryexec()) + else: + dependency = ('scrot',Application(('scrot',)).tryexec()) + return [dependency] def insert_screenshot(self): dialog = InsertScreenshotDialog.unique(self, self.ui) @@ -66,10 +72,11 @@ def __init__(self, ui): Dialog.__init__(self, ui, _('Insert Screenshot')) # T: dialog title - self.screen_radio = gtk.RadioButton(None, _('Capture whole screen')) # T: option in 'insert screenshot' dialog - self.select_radio = gtk.RadioButton(self.screen_radio, _('Select window or region')) # T: option in 'insert screenshot' dialog - self.vbox.add(self.screen_radio) - self.vbox.add(self.select_radio) + if not(maemo): + self.screen_radio = gtk.RadioButton(None, _('Capture whole screen')) # T: option in 'insert screenshot' dialog + self.select_radio = gtk.RadioButton(self.screen_radio, _('Select window or region')) # T: option in 'insert screenshot' dialog + self.vbox.add(self.screen_radio) + self.vbox.add(self.select_radio) hbox = gtk.HBox() self.vbox.add(hbox) @@ -81,23 +88,29 @@ hbox.add(gtk.Label(' '+_('seconds'))) # T: label behind timer def do_response_ok(self): + if maemo: + SCROT_COMMAND = 'screenshot-tool' + else: + SCROT_COMMAND = 'scrot' + tmpfile = TmpFile('insert-screenshot.png') options = () - if self.select_radio.get_active(): - options += ('--select', '--border') - # Interactively select a window or rectangle with the mouse. - # When selecting a window, grab wm border too - else: - options += ('--multidisp',) - # For multiple heads, grab shot from each and join them together. + if not(maemo): + if self.select_radio.get_active(): + options += ('--select', '--border') + # Interactively select a window or rectangle with the mouse. + # When selecting a window, grab wm border too + else: + options += ('--multidisp',) + # For multiple heads, grab shot from each and join them together. delay = self.time_spin.get_value_as_int() if delay > 0: - options += ('--delay', str(delay)) + options += ('-d', str(delay)) # Wait NUM seconds before taking a shot. - scrot = Application(('scrot',) + options) + scrot = Application((SCROT_COMMAND,) + options) def callback(status, tmpfile): if status == scrot.STATUS_OK: @@ -109,7 +122,7 @@ self.ui.mainwindow.pageview.insert_image(file, interactive=False) else: ErrorDialog(self.ui, - _('Some error occured while running "scrot"')).run() + _('Some error occured while running "')+SCROT_COMMAND+'"').run() # T: Error message in "insert screenshot" dialog tmpfile.dir.touch() diff -ruN zim-0.46/zim/plugins/tasklist.py zim-0.46-maemo/zim/plugins/tasklist.py --- zim-0.46/zim/plugins/tasklist.py 2010-03-09 22:06:12.000000000 +0100 +++ zim-0.46-maemo/zim/plugins/tasklist.py 2010-03-24 21:37:28.000000000 +0100 @@ -8,6 +8,7 @@ import re import datetime +from zim.gui import maemo from zim.parsing import parse_date from zim.plugins import PluginClass from zim.notebook import Path @@ -44,6 +45,7 @@ # FUTURE: add an interface for this plugin in the WWW frontend + class TaskListPlugin(PluginClass): plugin_info = { @@ -82,9 +84,10 @@ def __init__(self, plugin): Dialog.__init__(self, plugin.ui, _('Task List'), # T: dialog title - buttons=gtk.BUTTONS_CLOSE, help=':Help:Plugins:Task List') + buttons=gtk.BUTTONS_CLOSE, help=':Plugins:Task List') self.plugin = plugin - + if maemo: + self.resize(800,480) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.hpane = gtk.HPaned() @@ -94,6 +97,7 @@ # Task list self.task_list = TaskListTreeView(self.ui) + self.task_list.set_headers_visible(True) scrollwindow = gtk.ScrolledWindow() scrollwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scrollwindow.set_shadow_type(gtk.SHADOW_IN) @@ -239,7 +243,11 @@ column = gtk.TreeViewColumn(name, cell_renderer, text=i) column.set_resizable(True) column.set_sort_column_id(i) - if i == self.TASK_COL: column.set_expand(True) + if i == self.TASK_COL: + column.set_expand(True) + if maemo: + column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) + column.set_fixed_width(250) self.append_column(column) # Add some rendering for the Prio column