3
using System.Collections;
4
using System.Runtime.InteropServices;
5
using System.Diagnostics;
13
// TODO: Indent everything in this namespace in a seperate commit
14
namespace Tomboy.GalagoPresence
21
public GalagoManager ()
23
Galago.Global.Init ("tomboy", Galago.InitFlags.Client);
26
///// Connecting these cause crashes with the current 0.3.2 bindings...
28
//Galago.Core.OnPersonAdded += OnPersonAdded;
29
//Galago.Core.OnPersonRemoved += OnPersonRemoved;
30
// This is just property change
31
//Galago.Core.OnUpdated += OnUpdated;
41
public event EventHandler PeopleChanged;
42
public event EventHandler PresenceChanged;
44
void OnUpdated (object sender, EventArgs args)
46
Logger.Log ("Got Presence Updated!");
47
if (PresenceChanged != null)
48
PresenceChanged (this, args);
51
void OnPersonAdded (object sender, Galago.PersonAddedArgs args)
53
Logger.Log ("Person Added!");
56
if (PeopleChanged != null)
57
PeopleChanged (this, args);
60
void OnPersonRemoved (object sender, Galago.PersonRemovedArgs args)
62
Logger.Log ("Person Removed!");
65
if (PeopleChanged != null)
66
PeopleChanged (this, args);
69
void UpdateTrie (bool refresh_query)
71
trie = new TrieTree (false /* !case_sensitive */);
72
ArrayList people = new ArrayList ();
74
Logger.Log ("Loading up the person trie, Part 1...");
76
foreach (Person person in Galago.Global.GetPeople (Galago.Origin.Remote,
78
string name = person.DisplayName;
81
people.Add (new PersonLink (LinkType.PersonDisplayName, person));
84
foreach (Account account in person.GetAccounts(true)) {
85
if (account.DisplayName != null) {
86
people.Add (new PersonLink (LinkType.AccountDisplayName,
90
if (account.Username != null &&
91
account.Username != account.DisplayName) {
92
people.Add (new PersonLink (LinkType.AccountUserName,
98
Logger.Log ("Loading up the person trie, Part 2...");
100
foreach (PersonLink plink in people) {
101
trie.AddKeyword (plink.LinkText, plink);
104
Logger.Log ("Done.");
121
public PersonLink (LinkType type, Person person)
123
this.link_type = type;
124
this.person = person;
127
Logger.Log ("Added person {0}: {1}", link_type, LinkText);
130
public PersonLink (LinkType type, Account account)
132
this.link_type = type;
133
this.person = account.Person;
134
this.account = account;
136
Logger.Log ("Added account {0}: {1}", link_type, LinkText);
139
public string LinkText
144
case LinkType.PersonDisplayName:
145
return person.DisplayName;
146
case LinkType.AccountUserName:
147
return account.Username;
148
case LinkType.AccountDisplayName:
149
return account.DisplayName;
155
Account GetBestAccount ()
160
if (person != null) {
161
Account best = person.PriorityAccount;
163
Logger.Log ("Using priority account '{0}' for {1}",
172
public void SendMessage ()
174
Account best = GetBestAccount ();
176
throw new Exception ("No accounts associated with this person");
178
Process p = new Process ();
179
p.StartInfo.FileName = "gaim-remote";
180
p.StartInfo.Arguments =
182
best.Service.Id + ":goim?screenname=" + best.Username;
183
p.StartInfo.UseShellExecute = false;
188
[DllImport("libgalago-gtk")]
189
static extern IntPtr galago_gdk_pixbuf_new_from_presence (IntPtr presence,
194
public Gdk.Pixbuf GetPresenceIcon ()
196
Account best = GetBestAccount ();
198
best.Presence != null) {
199
IntPtr icon = galago_gdk_pixbuf_new_from_presence (best.Presence.Handle,
202
if (icon != IntPtr.Zero)
203
return new Gdk.Pixbuf (icon);
209
class PersonTag : NoteTag
211
GalagoManager galago;
213
public PersonTag (string tag_name, GalagoManager galago)
216
this.galago = galago;
219
public override void Initialize (string element_name)
221
base.Initialize (element_name);
223
Underline = Pango.Underline.Single;
225
CanSerialize = false;
229
protected override bool OnActivate (NoteEditor editor,
233
string persona = start.GetText (end);
234
PersonLink plink = (PersonLink) galago.Trie.Lookup (persona);
237
plink.SendMessage ();
238
} catch (Exception e) {
239
string title = Catalog.GetString ("Cannot contact '{0}'");
240
title = String.Format (title, persona);
242
string message = Catalog.GetString ("Error running gaim-remote: {0}");
243
message = String.Format (message, e.Message);
245
Logger.Log (message);
247
HIGMessageDialog dialog =
248
new HIGMessageDialog (editor.Toplevel as Gtk.Window,
249
Gtk.DialogFlags.DestroyWithParent,
250
Gtk.MessageType.Info,
263
public class GalagoPresenceNoteAddin : NoteAddin
265
static GalagoManager galago;
266
Gtk.TextTag person_tag;
267
Gtk.TextTag link_tag;
270
static GalagoPresenceNoteAddin ()
272
galago = new GalagoManager ();
275
public GalagoPresenceNoteAddin ()
280
public override void Initialize ()
282
person_tag = Note.TagTable.Lookup ("link:person");
283
if (person_tag == null) {
284
person_tag = new PersonTag ("link:person", galago);
286
Logger.Log ("Adding link:person tag...");
287
Note.TagTable.Add (person_tag);
290
link_tag = Note.TagTable.Lookup ("link:internal");
291
url_tag = Note.TagTable.Lookup ("link:url");
294
public override void Shutdown ()
296
galago.PeopleChanged -= OnPeopleChanged;
297
galago.PresenceChanged -= OnPresenceChanged;
300
public override void OnNoteOpened ()
302
galago.PeopleChanged += OnPeopleChanged;
303
galago.PresenceChanged += OnPresenceChanged;
305
Buffer.InsertText += OnInsertText;
306
Buffer.DeleteRange += OnDeleteRange;
308
// Highlight existing people in note
309
HighlightInBlock (Buffer.StartIter, Buffer.EndIter);
312
void OnPeopleChanged (object sender, EventArgs args)
314
// Highlight people in note
315
UnhighlightInBlock (Buffer.StartIter, Buffer.EndIter);
316
HighlightInBlock (Buffer.StartIter, Buffer.EndIter);
319
void OnPresenceChanged (object sender, EventArgs args)
321
// Highlight people in note
322
UnhighlightInBlock (Buffer.StartIter, Buffer.EndIter);
323
HighlightInBlock (Buffer.StartIter, Buffer.EndIter);
326
void HighlightInBlock (Gtk.TextIter start, Gtk.TextIter end)
328
foreach (TrieHit hit in galago.Trie.FindMatches (start.GetText (end))) {
329
Gtk.TextIter match_start =
330
Buffer.GetIterAtOffset(start.Offset + hit.Start);
332
// Don't create links inside note or URL links
333
if (match_start.HasTag (url_tag) ||
334
match_start.HasTag (link_tag))
337
Gtk.TextIter match_end = match_start;
338
match_end.ForwardChars (hit.End - hit.Start);
340
Logger.Log ("Matching Person '{0}' at {1}-{2}...",
344
Buffer.ApplyTag (person_tag, match_start, match_end);
348
void UnhighlightInBlock (Gtk.TextIter start, Gtk.TextIter end)
350
Buffer.RemoveTag (person_tag, start, end);
353
void GetBlockExtents (ref Gtk.TextIter start, ref Gtk.TextIter end)
355
// FIXME: Should only be processing the largest match string
356
// size, so we don't slow down for large paragraphs
358
start.LineOffset = 0;
359
end.ForwardToLineEnd ();
362
void OnDeleteRange (object sender, Gtk.DeleteRangeArgs args)
364
Gtk.TextIter start = args.Start;
365
Gtk.TextIter end = args.End;
367
GetBlockExtents (ref start, ref end);
369
UnhighlightInBlock (start, end);
370
HighlightInBlock (start, end);
373
void OnInsertText (object sender, Gtk.InsertTextArgs args)
375
Gtk.TextIter start = args.Pos;
376
start.BackwardChars (args.Length);
378
Gtk.TextIter end = args.Pos;
380
GetBlockExtents (ref start, ref end);
382
UnhighlightInBlock (start, end);
383
HighlightInBlock (start, end);