GTG

Merge lp:~gtg-user/gtg/uri-support into lp:~gtg/gtg/old-trunk

Proposed by Luca Invernizzi
Status: Merged
Merged at revision: 880
Proposed branch: lp:~gtg-user/gtg/uri-support
Merge into: lp:~gtg/gtg/old-trunk
Diff against target: 276 lines (+98/-32)
5 files modified
CHANGELOG (+1/-0)
GTG/__init__.py (+10/-0)
GTG/gtg.py (+21/-11)
GTG/gtk/browser/browser.py (+2/-1)
GTG/gtk/manager.py (+64/-20)
To merge this branch: bzr merge lp:~gtg-user/gtg/uri-support
Reviewer Review Type Date Requested Status
Gtg developers Pending
Review via email: mp+32643@code.launchpad.net

This proposal supersedes a proposal from 2010-08-09.

Description of the change

GTG support for URIs of the format gtg://<gtg-task-id>
These URIs are useful for putting tasks links in other programs (e.g, in a tomboy note).
I'm currently using it in the Zeitgeist backend, to let the tasks registered in Zeitgeist and shown through the Activity Journal to be clickable.

On every start, GTG checks if GNOME knows about this kind of URI and, if not, puts itself as an application capable of handling those. Therefore, you can use
xdg-open gtg://<gtg-task-id>.

Tomboy has the same kind of feature through a note:// URI.

To post a comment you must log in.
Revision history for this message
Luca Invernizzi (invernizzi) wrote : Posted in a previous version of this proposal

Ps: the last commits messages have the very meaningful name of "a" because I had to do a series of cherrypicking. Only the file that's picked matters.

lp:~gtg-user/gtg/uri-support updated
874. By Luca Invernizzi

GTG can be opened just with some TaskEditor windows

Revision history for this message
Luca Invernizzi (invernizzi) wrote :

I've just added the support for opening GTG without the task browser (if some uris are given).
If the browser was already open, it stays open, and if ./gtg is executed while in browserless mode, it opens the browser.
We're getting tomboysh :)

lp:~gtg-user/gtg/uri-support updated
875. By Luca Invernizzi

merge w/ trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CHANGELOG'
2--- CHANGELOG 2010-08-04 00:30:22 +0000
3+++ CHANGELOG 2010-08-25 16:29:47 +0000
4@@ -4,6 +4,7 @@
5 * Fixed bug with data consistency #579189, by Marko Kevac
6 * Added samba bugzilla to the bugzilla plugin, by Jelmer Vernoij
7 * Fixed bug #532392, a start date is later than a due date, by Volodymyr Floreskul
8+ * support for gtg:// URIs by Luca Invernizzi
9
10 2010-03-01 Getting Things GNOME! 0.2.2
11 * Autostart on login, by Luca Invernizzi
12
13=== modified file 'GTG/__init__.py'
14--- GTG/__init__.py 2010-03-12 11:16:15 +0000
15+++ GTG/__init__.py 2010-08-25 16:29:47 +0000
16@@ -92,3 +92,13 @@
17
18 if os.path.isdir(os.path.join(config_home, 'gtg/plugins')):
19 PLUGIN_DIR.append(os.path.join(config_home, 'gtg/plugins'))
20+
21+#Register GTG URI (temporary, it should be created by a schema upon installing)
22+import gconf
23+domain = "/desktop/gnome/url-handlers/gtg/"
24+client = gconf.client_get_default()
25+#this should work both in debugging mode and in deployed mode
26+client.set_string(os.path.join(domain, "command"), "gtg %s")
27+client.set_bool(os.path.join(domain, "enabled"), True)
28+client.set_bool(os.path.join(domain, "needs_terminal"), False)
29+
30
31=== modified file 'GTG/gtg.py'
32--- GTG/gtg.py 2010-08-03 17:07:31 +0000
33+++ GTG/gtg.py 2010-08-25 16:29:47 +0000
34@@ -46,8 +46,8 @@
35
36 #=== IMPORT ===================================================================
37 import os
38+import sys
39 import logging
40-
41 import dbus
42
43 #our own imports
44@@ -55,7 +55,7 @@
45 from GTG import _
46 from GTG.core import CoreConfig
47 from GTG.core.datastore import DataStore
48-#from GTG.gtk.crashhandler import signal_catcher
49+from GTG.gtk.crashhandler import signal_catcher
50 from GTG.gtk.manager import Manager
51 from GTG.tools.logger import Log
52
53@@ -66,8 +66,11 @@
54 #that's why we put the pid file in the data directory :
55 #we allow one instance of gtg by data directory.
56
57-def check_instance(directory):
58- """Check if gtg is already running."""
59+def check_instance(directory, uri_list = []):
60+ """
61+ Check if gtg is already running.
62+ If so, open the tasks whose ids are in the uri_list
63+ """
64 pidfile = os.path.join(directory, "gtg.pid")
65 if not os.path.exists(pidfile):
66 open(pidfile, "w").close()
67@@ -83,6 +86,10 @@
68 d=dbus.SessionBus().get_object(CoreConfig.BUSNAME,\
69 CoreConfig.BUSINTERFACE)
70 d.show_task_browser()
71+ #if the user has specified a task to open, do that
72+ for uri in uri_list:
73+ if uri.startswith("gtg://"):
74+ d.open_task_editor(uri[6:])
75 raise SystemExit
76
77 #write the pid file
78@@ -102,10 +109,10 @@
79 #To be more user friendly and get the logs of crashes, we show an apport
80 # hooked window upon crashes
81 if options.no_crash_handler == False:
82- #FIXME: Why is this disabled? Please comment when disabling functionality so we know. :-)
83- #with signal_catcher(manager.close_browser):
84- pass
85- manager.main(once_thru=options.boot_test)
86+ with signal_catcher(manager.close_browser):
87+ manager.main(once_thru=options.boot_test, uri_list = args)
88+ else:
89+ manager.main(once_thru=options.boot_test, uri_list = args)
90 core_main_quit(config, ds)
91
92 def core_main_init(options = None, args = None):
93@@ -116,10 +123,11 @@
94 if options.debug:
95 Log.setLevel(logging.DEBUG)
96 Log.debug("Debug output enabled.")
97- Log.set_debugging_mode(True)
98-
99+ else:
100+ Log.setLevel(logging.INFO)
101+ Log.set_debugging_mode(options.debug)
102 config = CoreConfig()
103- check_instance(config.get_data_dir())
104+ check_instance(config.get_data_dir(), args)
105 backends_list = BackendFactory().get_saved_backends_list()
106 # Load data store
107 ds = DataStore()
108@@ -145,6 +153,8 @@
109 # Ending the application: we save configuration
110 config.save()
111 ds.save(quit = True)
112+ sys.exit(0)
113+
114
115 #=== EXECUTION ================================================================
116
117
118=== modified file 'GTG/gtk/browser/browser.py'
119--- GTG/gtk/browser/browser.py 2010-08-23 01:33:43 +0000
120+++ GTG/gtk/browser/browser.py 2010-08-25 16:29:47 +0000
121@@ -139,7 +139,8 @@
122 #Expand all the tasks in the taskview
123 self.task_tv.expand_all()
124 self.on_select_tag()
125- self.window.show()
126+
127+ self.window.hide()
128
129 ### INIT HELPER FUNCTIONS #####################################################
130 #
131
132=== modified file 'GTG/gtk/manager.py'
133--- GTG/gtk/manager.py 2010-08-03 17:07:31 +0000
134+++ GTG/gtk/manager.py 2010-08-25 16:29:47 +0000
135@@ -39,10 +39,12 @@
136 from GTG.core.plugins.engine import PluginEngine
137 from GTG.core.plugins.api import PluginAPI
138 from GTG.tools.logger import Log
139-
140-
141-
142-class Manager:
143+from GTG.gtk.backends_dialog import BackendsDialog
144+from GTG.backends.backendsignals import BackendSignals
145+
146+
147+
148+class Manager(object):
149
150
151 ############## init #####################################################
152@@ -58,6 +60,7 @@
153 # right now
154
155 self.browser = None
156+ self.gtk_terminate = False #if true, the gtk main is not started
157 self.pengine = None
158 self.plugins = None
159 self.plugin_api = None
160@@ -65,11 +68,9 @@
161
162 #Shared clipboard
163 self.clipboard = clipboard.TaskClipboard(self.req)
164-
165- #Browser
166- #FIXME : the browser should not be built by default and should be a
167- # window like another and not necessary (like the editor)
168- self.open_browser()
169+
170+ #Browser (still hidden)
171+ self.browser = TaskBrowser(self.req, self, self.config)
172
173 #Plugins (that needs to be after the browser, this is ugly)
174 self.__init_plugin_engine()
175@@ -80,6 +81,7 @@
176 #Preferences and Backends windows
177 # Initialize dialogs
178 self.preferences_dialog = None
179+ self.edit_backends_dialog = None
180
181 #DBus
182 DBusTaskWrapper(self.req, self)
183@@ -125,9 +127,8 @@
184 ############## Browser #################################################
185
186 def open_browser(self):
187- if not self.browser:
188- self.browser = TaskBrowser(self.req, self, self.config)
189 Log.debug("Browser is open")
190+ self.browser.show()
191
192 #FIXME : the browser should not be the center of the universe.
193 # In fact, we should build a system where view can register themselves
194@@ -190,12 +191,30 @@
195 #else, it close_task would be called once again
196 #by editor.close
197 editor.close()
198-# else:
199- #FIXME: this one should be a debug statement
200-# print "the %s editor was already unregistered" %tid
201+ self.check_quit_condition()
202+
203+ def check_quit_condition(self):
204+ '''
205+ checking if we need to shut down the whole GTG (if no window is open)
206+ '''
207+ if not self.is_browser_visible() and not self.opened_task:
208+ #no need to live
209+ print "AAAAAAAAAAA"
210+ self.quit()
211+ print self.opened_task
212
213 ################ Others dialog ############################################
214
215+ def open_edit_backends(self, sender = None, backend_id = None):
216+ if not self.edit_backends_dialog:
217+ self.edit_backends_dialog = BackendsDialog(self.req)
218+ self.edit_backends_dialog.activate()
219+ if backend_id != None:
220+ self.edit_backends_dialog.show_config_for_backend(backend_id)
221+
222+ def configure_backend(self, backend_id):
223+ self.open_edit_backends(None, backend_id)
224+
225 def open_preferences(self, config_priv, sender=None):
226 if not hasattr(self, "preferences"):
227 self.preferences = PreferencesDialog(self.pengine, self.p_apis, \
228@@ -209,17 +228,42 @@
229 for t in tids:
230 if t in self.opened_task:
231 self.close_task(t)
232+
233+### URIS ###################################################################
234+
235+ def open_uri_list(self, unused, uri_list):
236+ '''
237+ Open the Editor windows of the tasks associated with the uris given.
238+ Uris are of the form gtg://<taskid>
239+ '''
240+ print self.req.get_all_tasks_list()
241+ for uri in uri_list:
242+ if uri.startswith("gtg://"):
243+ self.open_task(uri[6:])
244+ #if no window was opened, we just quit
245+ self.check_quit_condition()
246+
247
248 ### MAIN ###################################################################
249- def main(self, once_thru=False):
250+
251+ def main(self, once_thru = False, uri_list = []):
252+ if uri_list:
253+ #before opening the requested tasks, we make sure that all of them
254+ #are loaded.
255+ BackendSignals().connect('default-backend-loaded',
256+ self.open_uri_list,
257+ uri_list)
258+ else:
259+ self.open_browser()
260+
261 gobject.threads_init()
262- if once_thru:
263- gtk.main_iteration()
264- else:
265- gtk.main()
266+ if not self.gtk_terminate:
267+ if once_thru:
268+ gtk.main_iteration()
269+ else:
270+ gtk.main()
271 return 0
272
273-
274 def quit(self,sender=None):
275 gtk.main_quit()
276 #save opened tasks and their positions.

Subscribers

People subscribed via source and target branches

to status/vote changes: