gtg team mailing list archive
-
gtg team
-
Mailing list archive
-
Message #00260
[Merge] lp:~gtg-user/gtg/tomboy into lp:gtg
Luca Invernizzi has proposed merging lp:~gtg-user/gtg/tomboy into lp:gtg.
Requested reviews:
Gtg developers (gtg)
Related bugs:
#432503 add tomboy support (merge request)
https://bugs.launchpad.net/bugs/432503
--
https://code.launchpad.net/~gtg-user/gtg/tomboy/+merge/12363
Your team Gtg developers is subscribed to branch lp:gtg.
=== modified file '.bzrignore'
--- .bzrignore 2009-08-24 10:01:19 +0000
+++ .bzrignore 2009-09-24 17:30:26 +0000
@@ -37,3 +37,5 @@
_trial_temp
doc/api
**/**.glade.h
+**/**.gladep
+**/**.gladep.bak
=== modified file 'GTG/core/plugins/api.py'
--- GTG/core/plugins/api.py 2009-09-24 13:15:17 +0000
+++ GTG/core/plugins/api.py 2009-09-24 17:30:26 +0000
@@ -236,6 +236,10 @@
def show_window(self):
"""Shows the main GTG window (task browser)"""
self.__window.show()
+
+ def get_window(self):
+ """Returns the window for which the plug-in has been created"""
+ return self.__window
#=== General Methods ==========================================================
@@ -426,4 +430,4 @@
"""
if func in self.__filter_cbs:
self.__filter_cbs.remove(func)
-#=== Filtering methods ========================================================
\ No newline at end of file
+#=== Filtering methods ========================================================
=== modified file 'GTG/core/plugins/engine.py'
--- GTG/core/plugins/engine.py 2009-09-24 13:15:17 +0000
+++ GTG/core/plugins/engine.py 2009-09-24 17:30:26 +0000
@@ -176,9 +176,8 @@
# deactivate the enabled plugins
def deactivatePlugins(self, plugins, plugin_api):
for plugin in plugins:
- if not plugin['state'] and not plugin['error'] and plugin['active']:
+ if plugin['state'] and not plugin['error'] and plugin['active']:
plugin['instance'].deactivate(plugin_api)
- plugin['instance'] = None
plugin['active'] = False
# loads the plug-in features for a task
@@ -187,19 +186,31 @@
if plugin['state'] and plugin['active']:
plugin['instance'].onTaskOpened(plugin_api)
+ # signals to the plug-ins that the task window is being closed
+ def onTaskClose(self, plugins, plugin_api):
+ for plugin in plugins:
+ if plugin['state'] and plugin['active']:
+ if hasattr(plugin['instance'],'onTaskClosed'):
+ plugin['instance'].onTaskClosed(plugin_api)
+
# rechecks the plug-ins to see if any changes where done to the state
def recheckPlugins(self, plugins, plugin_api):
for plugin in plugins:
if plugin['instance'] != None and plugin['state'] == False and plugin['active']:
try:
- self.deactivatePlugins([plugin],plugin_api)
+ #print "deactivating plugin: " + plgin['name']
+ plugin['instance'].deactivate(plugin_api)
+ plugin['instance'] = None
+ plugin['active'] = False
except Exception, e:
print "Error: %s" % e
elif plugin['instance'] == None and plugin['state'] == True and not plugin['active']:
try:
#print "activating plugin: " + plgin['name']
if not plugin['error']:
- self.activatePlugins([plugin],plugin_api)
+ plugin['instance'] = plugin['class']()
+ plugin['instance'].activate(plugin_api)
+ plugin['active'] = True
else:
plugin['state'] = False
except Exception, e:
=== modified file 'GTG/core/plugins/manager.py'
--- GTG/core/plugins/manager.py 2009-09-24 13:15:17 +0000
+++ GTG/core/plugins/manager.py 2009-09-24 17:30:26 +0000
@@ -134,12 +134,6 @@
for plgin in self.plugins:
if model[path][1] == plgin['name'] and model[path][2] == plgin['version']:
plgin['state'] = not plgin['state']
- #we instantly apply the plugin activation/deactivation
- #to respect HIG
- if plgin['state'] :
- self.pengine.activatePlugins([plgin], self.plugin_api)
- else :
- self.pengine.deactivatePlugins([plgin], self.plugin_api)
def pluginExtraInfo(self, treeview, plugins):
@@ -215,4 +209,4 @@
self.config_btn.set_sensitive(False)
def plugin_configure_dialog(self, widget, data=None):
- self.current_plugin['instance'].configure_dialog(self.plugin_api)
+ self.current_plugin['instance'].configure_dialog(self.plugin_api)
\ No newline at end of file
=== modified file 'GTG/info.py'
--- GTG/info.py 2009-08-29 14:17:46 +0000
+++ GTG/info.py 2009-09-24 17:30:26 +0000
@@ -26,6 +26,7 @@
"\tJean-François Fortin Tam <nekohayo@xxxxxxxxx>", \
"\tJonathan Lange <jml@xxxxxxxxx>", \
"\tPaulo Cabido <paulo.cabido@xxxxxxxxx>", \
+ "\tLuca Invernizzi <invernizzi.l@xxxxxxxxx>", \
]
ARTISTS = ["Kalle Persson <kalle@xxxxxxxxxxxxxxx>", \
"Bertrand Rousseau <bertrand.rousseau@xxxxxxxxx>"]
@@ -40,7 +41,7 @@
Finnish: Mika Tapojärvi
French: Lionel Dricot, Rafik Ouerchefani, Bertrand Rousseau, Pititjo
German: Philip Stewart, Thomas Pitlik
-Italian: Luca Falavigna
+Italian: Luca Falavigna, Luca Invernizzi
Malay: melayubuntu
Polish: Tomasz Maciejewski
Portuguese: Paulo Cabido
=== modified file 'GTG/plugins/rtm-sync.gtg-plugin'
--- GTG/plugins/rtm-sync.gtg-plugin 2009-09-20 14:10:30 +0000
+++ GTG/plugins/rtm-sync.gtg-plugin 2009-09-24 17:30:26 +0000
@@ -3,6 +3,6 @@
Name=Remember the milk
Description=Plugin for synchronising Getting Things Gnome! with the web service Remember the milk ( http://www.rememberthemilk.com ).\n\nLegal note: This product uses the Remember The Milk API but is not endorsed or certified by Remember The Milk.
Authors=Luca Invernizzi <invernizzi.l@xxxxxxxxx>
-Version=0.1.2
-Dependencies=python-xml,python-simplejson
+Version=0.1.1
+Dependencies=minidom,subprocess,BaseDirectory,threading,gobject,gtk,time,pickle,datetime,logging,md5,urllib,warnings,simplejson
Enabled=False
=== modified file 'GTG/plugins/rtm_sync/pyrtm/rtm.py'
--- GTG/plugins/rtm_sync/pyrtm/rtm.py 2009-09-20 14:10:30 +0000
+++ GTG/plugins/rtm_sync/pyrtm/rtm.py 2009-09-24 17:30:26 +0000
@@ -12,10 +12,8 @@
import warnings
import urllib
import logging
-import time
from hashlib import md5
from GTG import _
-import httplib
warnings.simplefilter('default', ImportWarning)
@@ -93,7 +91,7 @@
params['format'] = 'json'
params['api_sig'] = self._sign(params)
- json = openURL(SERVICE_URL, params)
+ json = openURL(SERVICE_URL, params).read()
LOG.debug("JSON response: \n%s" % json)
@@ -180,28 +178,11 @@
for key in keys:
yield key, dictionary[key]
-def openURL(url, queryArgs = None):
+def openURL(url, queryArgs=None):
if queryArgs:
url = url + '?' + urllib.urlencode(queryArgs)
- LOG.debug("URL> %s", url)
- time_to_wait = 0
- while True:
- try:
- if time_to_wait !=0:
- time.sleep(time_to_wait)
- http_connection = httplib.HTTPConnection("api.rememberthemilk.com",80)
- http_connection.request("GET", url)
- http_response = http_connection.getresponse()
- http_response_data = http_response.read()
- break
- except httplib.IncompleteRead as exception:
- #rtm server issues incomplete responses if we hammer it too much
- # this way we can be fast *and* safe
- if time_to_wait == 0:
- time_to_wait = 2
- else:
- raise exception
- return http_response_data
+ LOG.debug("URL> %s", url)
+ return urllib.urlopen(url)
class dottedDict(object):
"Make dictionary items accessible via the object-dot notation."
@@ -267,7 +248,7 @@
'getList':
[(), ()],
'removeContact':
- [('timeline', 'group_id', 'contact_id'), ()]
+ [('timeline', 'group_id', 'contact_id'), ()],
},
'lists': {
'add':
=== modified file 'GTG/plugins/rtm_sync/syncengine.py'
--- GTG/plugins/rtm_sync/syncengine.py 2009-09-21 17:30:00 +0000
+++ GTG/plugins/rtm_sync/syncengine.py 2009-09-24 17:30:26 +0000
@@ -90,11 +90,11 @@
try:
self.synchronizeWorker()
except rtm.RTMAPIError as exception:
- self.close_gui(exception)
+ self.close_gui(exception.message)
except rtm.RTMError as exception:
- self.close_gui(exception)
- except Exception as exception:
- self.close_gui(_("Synchronization failed." + str(exception)))
+ self.close_gui(exception.message)
+ except:
+ self.close_gui(_("Synchronization failed."))
def synchronizeWorker(self):
self.update_status(_("Downloading task list..."))
@@ -157,9 +157,8 @@
for gtg_id in gtg_removed:
rtm_id = gtg_to_rtm_id_dict[gtg_id]
rtm_task = filterAttr(self.rtm_list, 'id', rtm_id)
- if len(rtm_task) > 0:
- self.update_substatus(_("Deleting ") + rtm_task[0].title)
- map(lambda task: task.delete(), rtm_task)
+ self.update_substatus(_("Deleting ") + rtm_task.title)
+ map(lambda task: task.delete(), rtm_task)
#Delete from gtg the tasks that have been removed in rtm
if len(rtm_removed) > 0:
@@ -168,10 +167,9 @@
for rtm_id in rtm_removed:
gtg_id = rtm_to_gtg_id_dict[rtm_id]
gtg_task = filterAttr(self.gtg_list, 'id', gtg_id)
- if len (gtg_task) > 0:
- self.update_substatus(_("Deleting ") + gtg_task[0].title)
- map(lambda task: task.delete(), gtg_task)
- gtg_common.discard(gtg_id)
+ self.update_substatus(_("Deleting ") + gtg_task.title)
+ map(lambda task: task.delete(), gtg_task)
+ gtg_common.discard(gtg_id)
#tasks that must be added to RTM
#NOTE: should we check if the title is already present in the
=== added directory 'GTG/plugins/tomboy'
=== added file 'GTG/plugins/tomboy.gtg-plugin'
--- GTG/plugins/tomboy.gtg-plugin 1970-01-01 00:00:00 +0000
+++ GTG/plugins/tomboy.gtg-plugin 2009-09-24 17:30:26 +0000
@@ -0,0 +1,7 @@
+[GTG Plugin]
+Module=tomboy
+Name=Tomboy plugin
+Description=This plugin lets you add as many links as you like to tomboy notes in your tasks.
+Authors=Luca Invernizzi <invernizzi.l@xxxxxxxxx>
+Version=0.1.1
+Enabled=True
=== added file 'GTG/plugins/tomboy/__init__.py'
--- GTG/plugins/tomboy/__init__.py 1970-01-01 00:00:00 +0000
+++ GTG/plugins/tomboy/__init__.py 2009-09-24 17:30:26 +0000
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2009 - Luca Invernizzi <invernizzi.l@xxxxxxxxx>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+import sys
+import os
+sys.path.insert(0, os.getcwd())
+from tomboy import pluginTomboy
=== added file 'GTG/plugins/tomboy/combobox_enhanced.py'
--- GTG/plugins/tomboy/combobox_enhanced.py 1970-01-01 00:00:00 +0000
+++ GTG/plugins/tomboy/combobox_enhanced.py 2009-09-24 17:30:26 +0000
@@ -0,0 +1,76 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2009 - Luca Invernizzi <invernizzi.l@xxxxxxxxx>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+import gtk
+import gobject
+
+def ifKeyPressedCallback( widget, key, callback):
+ def keyPress(combobox, event):
+ keyname = gtk.gdk.keyval_name(event.keyval)
+ if keyname == key:
+ callback()
+ widget.connect("key-press-event", keyPress)
+
+def ifClipboardTextIsInListCallback (clipboard_obj, list_obj, callback):
+ def clipboardCallback(clipboard_obj, text, list_obj):
+ if len(filter(lambda x: x == text, list_obj)) != 0:
+ callback(text)
+ clipboard_obj.request_text(clipboardCallback, list_obj)
+
+def listStoreFromList(list_obj):
+ list_store = gtk.ListStore(gobject.TYPE_STRING)
+ for elem in list_obj:
+ iter = list_store.append()
+ list_store.set(iter, 0, elem)
+ return list_store
+
+def completionFromListStore (list_store):
+ completion = gtk.EntryCompletion()
+ completion.set_minimum_key_length(0)
+ completion.set_text_column(0)
+ completion.set_inline_completion(True)
+ completion.set_model(list_store)
+ return completion
+
+def smartifyComboboxEntry(combobox, list_obj, callback):
+ entry = gtk.Entry()
+ #check if Clipboard contains an element of the list
+ clipboard = gtk.Clipboard()
+ ifClipboardTextIsInListCallback(clipboard, list_obj, entry.set_text)
+ #pressing Enter will cause the callback
+ ifKeyPressedCallback(entry, "Return", callback)
+ #wrap the combo-box if it's too long
+ if len(list_obj) > 15:
+ combobox.set_wrap_width(5)
+ #populate the combo-box
+ if len(list_obj) > 0:
+ list_store = listStoreFromList(list_obj)
+ entry.set_completion(completionFromListStore(list_store))
+ combobox.set_model(list_store)
+ combobox.set_active(0)
+ combobox.add(entry)
+ combobox.connect('changed', setText, entry )
+ #render the combo-box drop down menu
+ cell = gtk.CellRendererText()
+ combobox.pack_start(cell, True)
+ combobox.add_attribute(cell, 'text', 0)
+ return entry
+
+def setText(combobox, entry):
+ model = combobox.get_model()
+ index = combobox.get_active()
+ if index > -1:
+ entry.set_text(model[index][0])
+
=== added file 'GTG/plugins/tomboy/tomboy.glade'
--- GTG/plugins/tomboy/tomboy.glade 1970-01-01 00:00:00 +0000
+++ GTG/plugins/tomboy/tomboy.glade 2009-09-24 17:30:26 +0000
@@ -0,0 +1,110 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkDialog" id="InsertNoteDialog">
+ <property name="width_request">300</property>
+ <property name="title" translatable="yes">Insert Note</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <property name="modal">False</property>
+ <property name="resizable">True</property>
+ <property name="destroy_with_parent">False</property>
+ <property name="decorated">True</property>
+ <property name="skip_taskbar_hint">False</property>
+ <property name="skip_pager_hint">False</property>
+ <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+ <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+ <property name="focus_on_map">True</property>
+ <property name="urgency_hint">False</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="btn_cancel">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="btn_add">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-add</property>
+ <property name="use_stock">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="response_id">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label_caption">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Insert the title of the tomboy note </property>
+ <property name="use_underline">False</property>
+ <property name="use_markup">False</property>
+ <property name="justify">GTK_JUSTIFY_LEFT</property>
+ <property name="wrap">False</property>
+ <property name="selectable">False</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkComboBox" id="titles_combobox">
+ <property name="visible">True</property>
+ <property name="add_tearoffs">False</property>
+ <property name="has_frame">True</property>
+ <property name="focus_on_click">True</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+</glade-interface>
=== added file 'GTG/plugins/tomboy/tomboy.py'
--- GTG/plugins/tomboy/tomboy.py 1970-01-01 00:00:00 +0000
+++ GTG/plugins/tomboy/tomboy.py 2009-09-24 17:30:26 +0000
@@ -0,0 +1,229 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2009 - Luca Invernizzi <invernizzi.l@xxxxxxxxx>
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+import gtk
+import gobject
+import os
+import sys
+import dbus
+from GTG import _
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+import combobox_enhanced
+
+
+class pluginTomboy:
+
+ def __init__(self):
+ #These tokens are used to identify the beginning and the end of the
+ #tomboy note point of insertion
+ self.token_start = 'TOMBOY__'
+ self.token_end = '|'
+ self.path = os.path.dirname(os.path.abspath(__file__))
+
+ #Function called upon plug-in activation
+ def activate(self, plugin_api):
+ self.plugin_api = plugin_api
+
+ #Return a textual token to represent the Tomboy widget. It's useful
+ # since the task is saved as pure text
+ def widgetTotext(self, widget):
+ return self.token_start+ widget.tomboy_note_title+self.token_end
+
+ # Converts all tomboy note widgets in the equivalent text
+ def onTaskClosed(self, plugin_api):
+ for anchor in self.anchors:
+ widgets = anchor.get_widgets()
+ if anchor.get_deleted():
+ #The note has been deleted, skip
+ continue
+ iter_start = self.textview.buff.get_iter_at_child_anchor(anchor)
+ iter_end = iter_start.copy()
+ iter_end.forward_char()
+ if type(widgets) == list and len(widgets) !=0:
+ #the anchor still contains a widget.
+ widget = widgets[0]
+ self.textview.buff.delete(iter_start, iter_end)
+ self.textview.buff.insert(iter_start,
+ self.widgetTotext(widget))
+
+ # adds a item(button) to the ToolBar, with a nice icon
+ def addButtonToToolbar(self, plugin_api):
+ tb_Taskbutton_image = gtk.Image()
+ tb_Taskbutton_image_path =\
+ "/usr/share/icons/hicolor/16x16/apps/tomboy.png"
+ tb_Taskbutton_pixbuf=gtk.gdk.\
+ pixbuf_new_from_file_at_size(tb_Taskbutton_image_path, 16, 16)
+ tb_Taskbutton_image.set_from_pixbuf(tb_Taskbutton_pixbuf)
+ tb_Taskbutton_image.show()
+ self.tb_Taskbutton = gtk.ToolButton(tb_Taskbutton_image)
+ self.tb_Taskbutton.set_label(_("Add Tomboy note"))
+ self.tb_Taskbutton.connect('clicked', self.onTbTaskButton, plugin_api)
+ plugin_api.add_task_toolbar_item(gtk.SeparatorToolItem())
+ plugin_api.add_task_toolbar_item(self.tb_Taskbutton)
+
+
+ # Converts all the textual tokens in tomboy note widgets
+ def convertTokensToWidgets(self):
+ self.anchors=[]
+ start_iter = self.textview.buff.get_start_iter()
+ end_iter = self.textview.buff.get_end_iter()
+ text = self.textview.buff.get_slice(start_iter, end_iter)
+ text_offset = 0
+ token_position = text.find(self.token_start)
+ token_ending = text.find(self.token_end, token_position)
+ while not token_position < 0 and not token_ending < 0:
+ #delete the text of the token
+ tomboy_note_title = text[token_position + len(self.token_start):
+ token_ending]
+ start_iter = self.textview.buff.get_iter_at_offset(text_offset +
+ token_position)
+ end_iter = self.textview.buff.get_iter_at_offset(text_offset+
+ token_ending+1)
+ self.textview.buff.delete(start_iter, end_iter)
+ #add the widget
+ widget =self.widgetCreate(tomboy_note_title)
+ anchor = self.textviewInsertWidget(widget, start_iter)
+ self.anchors.append(anchor)
+ #find the next
+ start_iter = self.textview.buff.get_iter_at_child_anchor(anchor)
+ start_iter.forward_char()
+ end_iter = self.textview.buff.get_end_iter()
+ text = self.textview.buff.get_slice(start_iter, end_iter)
+ text_offset = start_iter.get_offset()
+ token_position = text.find(self.token_start)
+ token_ending = text.find(self.token_end)
+
+ def onTaskOpened(self, plugin_api):
+ #NOTE: get_textview() only works in this function
+ # (see GTG/core/plugins/api.py docs)
+ self.textview = plugin_api.get_textview()
+ self.addButtonToToolbar(plugin_api)
+ self.convertTokensToWidgets()
+
+ def deactivate(self, plugin_api):
+ #nothing to do at all
+ pass
+
+ def close_dialog(self, widget, data=None):
+ self.dialog.destroy()
+ return True
+
+ #opens a dbus connection to tomboy
+ def getTomboyObject(self):
+ bus = dbus.SessionBus()
+ obj = bus.get_object("org.gnome.Tomboy",
+ "/org/gnome/Tomboy/RemoteControl")
+ return dbus.Interface(obj, "org.gnome.Tomboy.RemoteControl")
+
+ #gets the list of the titles of the notes
+ def getTomboyNoteTitleList(self):
+ tomboy = self.getTomboyObject()
+ return map(lambda note: str(tomboy.GetNoteTitle(note)),
+ tomboy.ListAllNotes())
+
+ def onTbTaskButton(self, widget, plugin_api):
+ title_list = self.getTomboyNoteTitleList()
+ #Create the dialog
+ glade_file = os.path.join(self.path, "tomboy.glade")
+ wTree = gtk.glade.XML(glade_file, "InsertNoteDialog")
+ #objects
+ self.dialog = wTree.get_widget("InsertNoteDialog")
+ btn_add = wTree.get_widget("btn_add")
+ btn_cancel = wTree.get_widget("btn_cancel")
+ self.combobox = wTree.get_widget("titles_combobox")
+ self.label_caption = wTree.get_widget("label_caption")
+ #connections
+ self.dialog.connect("delete_event", self.close_dialog)
+ btn_cancel.connect("clicked", self.close_dialog)
+ btn_add.connect("clicked", self.noteChosen)
+ self.combobox_entry = combobox_enhanced.\
+ smartifyComboboxEntry(self.combobox,title_list,self.noteChosen)
+ self.dialog.show_all()
+
+ #A title has been chosen by the user. If the note exists, it will be
+ # linked, otherwise the user will have the option to create the note.
+ def noteChosen(self, widget=None, data=None):
+ tomboy = self.getTomboyObject()
+ supposed_title = self.combobox_entry.get_text()
+ if filter(lambda x: tomboy.GetNoteTitle(x)==supposed_title,
+ tomboy.ListAllNotes()) == []:
+ self.label_caption.set_text(_("That note does not exist!"))
+ dialog = gtk.MessageDialog(parent = self.dialog,
+ flags = gtk.DIALOG_DESTROY_WITH_PARENT,
+ type = gtk.MESSAGE_QUESTION,
+ buttons=gtk.BUTTONS_YES_NO,
+ message_format=_("That note does not \
+exist. Do you want to create a new one?"))
+ response = dialog.run()
+ dialog.destroy()
+ if response == gtk.RESPONSE_YES:
+ tomboy.CreateNamedNote(supposed_title)
+ else:
+ return
+ #note insertion
+ mark_start = self.textview.buff.get_insert()
+ iter_start = self.textview.buff.get_iter_at_mark(mark_start)
+ tomboy_widget =self.widgetCreate(supposed_title)
+ anchor = self.textviewInsertWidget(tomboy_widget, iter_start)
+ self.anchors.append(anchor)
+ self.dialog.destroy()
+
+ #Opens a note in tomboy application via dbus
+ def tomboyDisplayNote(self, widget, data = None):
+ tomboy = self.getTomboyObject()
+ note = tomboy.FindNote(widget.tomboy_note_title)
+ tomboy.DisplayNote(note)
+
+ #inserts a widget in the textview
+ def textviewInsertWidget(self, widget, iter):
+ anchor = self.textview.buff.create_child_anchor(iter)
+ widget.show()
+ self.textview.add_child_at_anchor(widget, anchor)
+ return anchor
+
+ #creates the tomboy widget
+ def widgetCreate(self, tomboy_note_title):
+ image = gtk.Image()
+ image_path = "/usr/share/icons/hicolor/16x16/apps/tomboy.png"
+ pixbuf=gtk.gdk.\
+ pixbuf_new_from_file_at_size(image_path, 16, 16)
+ image.show()
+ image.set_from_pixbuf(pixbuf)
+ image.set_alignment(0.5,1.0)
+ label = gtk.Label()
+ label.show()
+ label.set_alignment(0.5, 1.0)
+ eventbox = gtk.EventBox()
+ eventbox.set_events(gtk.gdk.BUTTON_PRESS_MASK)
+ eventbox.connect('button_press_event', self.tomboyDisplayNote)
+ eventbox.show()
+ window = self.plugin_api.get_window()
+ hbox = gtk.HBox()
+ hbox.show()
+ hbox.add(image)
+ hbox.add(label)
+ eventbox.add(hbox)
+ window.realize()
+ style=window.get_style()
+ color = str(style.text[gtk.STATE_PRELIGHT])
+ label.set_markup("<span underline='low' color='" + color +"'>" + tomboy_note_title + "</span>")
+ eventbox.tomboy_note_title = tomboy_note_title
+ #cursor changes to a hand
+ def realize_callback(widget):
+ eventbox.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
+ eventbox.connect("realize", realize_callback)
+ return eventbox
+
=== modified file 'GTG/taskeditor/editor.py'
--- GTG/taskeditor/editor.py 2009-09-24 14:51:45 +0000
+++ GTG/taskeditor/editor.py 2009-09-24 17:30:26 +0000
@@ -479,6 +479,7 @@
#Will be linked to this destruction method that will save the task
def destruction(self,a=None) :#pylint: disable-msg=W0613
#Save should be also called when buffer is modified
+ self.pengine.onTaskClose(self.plugins, self.te_plugin_api)
self.save()
self.closing(self.task.get_id())
=== modified file 'GTG/taskeditor/taskview.py'
--- GTG/taskeditor/taskview.py 2009-09-24 15:45:17 +0000
+++ GTG/taskeditor/taskview.py 2009-09-24 17:30:26 +0000
@@ -39,8 +39,7 @@
separators = [' ', '.', ',', '/', '\n', '\t', '!', '?', ';', '\0']
url_separators = [' ', ',', '\n', '\t', '\0']
-bullet1_ltr = 'â'
-bullet1_rtl = 'â'
+bullet1 = 'â'
bullet2 = 'â³'
@@ -151,11 +150,6 @@
self.modified_sigid = self.buff.connect("changed" , self.modified)
self.connect("backspace",self.backspace)
self.tobe_refreshed = False
-
- if self.get_direction() == gtk.TEXT_DIR_RTL :
- self.bullet1 = bullet1_rtl
- else :
- self.bullet1 = bullet1_ltr
#This function is called to refresh the editor
@@ -883,7 +877,7 @@
indentation = indentation + (level-1)*spaces
#adding the symbol
if level == 1 :
- indentation = "%s%s "%(indentation,self.bullet1)
+ indentation = "%s%s "%(indentation,bullet1)
buff.insert(itera,indentation)
indenttag = self.create_indent_tag(buff,level)
self.__apply_tag_to_mark(start,end,tag=indenttag)
@@ -985,7 +979,7 @@
#Then, if indent > 0, we increment it
#First step : we preserve it.
else :
- if not line.lstrip("%s "%self.bullet1) :
+ if not line.lstrip("%s "%bullet1) :
self.deindent(itera,newlevel=0)
tv.emit_stop_by_name('insert-text')
=== modified file 'locales/gtg.pot'
--- locales/gtg.pot 2009-09-12 23:03:15 +0000
+++ locales/gtg.pot 2009-09-24 17:30:26 +0000
@@ -8,7 +8,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2009-09-13 01:03+0200\n"
+"POT-Creation-Date: 2009-09-18 15:51+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@xxxxxx>\n"
@@ -632,6 +632,22 @@
msgid "due"
msgstr ""
+#: GTG/plugins/tomboy/tomboy.py:67
+msgid "Add Tomboy note"
+msgstr ""
+
+#: GTG/plugins/tomboy/tomboy.py:170
+msgid "That note does not exist!"
+msgstr ""
+
+#: GTG/plugins/tomboy/tomboy.glade.h:1
+msgid "Insert Note"
+msgstr ""
+
+#: GTG/plugins/tomboy/tomboy.glade.h:2
+msgid "Insert the title of the tomboy note "
+msgstr ""
+
#: GTG/plugins/rtm_sync/utility.py:54
msgid "saving critical object failed"
msgstr ""
@@ -666,11 +682,11 @@
"now. When done, press OK"
msgstr ""
-#: GTG/plugins/rtm_sync/pyrtm/rtm.py:56
+#: GTG/plugins/rtm_sync/pyrtm/rtm.py:57
msgid "Invalid state"
msgstr ""
-#: GTG/plugins/rtm_sync/pyrtm/rtm.py:105
+#: GTG/plugins/rtm_sync/pyrtm/rtm.py:106
msgid "API call failed"
msgstr ""
Follow ups