3
using System.Collections;
4
using System.Runtime.InteropServices;
5
using System.Diagnostics;
17
public GalagoManager ()
19
Galago.Global.Init ("tomboy", Galago.InitFlags.Client);
22
///// Connecting these cause crashes with the current 0.3.2 bindings...
24
//Galago.Core.OnPersonAdded += OnPersonAdded;
25
//Galago.Core.OnPersonRemoved += OnPersonRemoved;
26
// This is just property change
27
//Galago.Core.OnUpdated += OnUpdated;
37
public event EventHandler PeopleChanged;
38
public event EventHandler PresenceChanged;
40
void OnUpdated (object sender, EventArgs args)
42
Logger.Log ("Got Presence Updated!");
43
if (PresenceChanged != null)
44
PresenceChanged (this, args);
47
void OnPersonAdded (object sender, Galago.PersonAddedArgs args)
49
Logger.Log ("Person Added!");
52
if (PeopleChanged != null)
53
PeopleChanged (this, args);
56
void OnPersonRemoved (object sender, Galago.PersonRemovedArgs args)
58
Logger.Log ("Person Removed!");
61
if (PeopleChanged != null)
62
PeopleChanged (this, args);
65
void UpdateTrie (bool refresh_query)
67
trie = new TrieTree (false /* !case_sensitive */);
68
ArrayList people = new ArrayList ();
70
Logger.Log ("Loading up the person trie, Part 1...");
72
foreach (Person person in Galago.Global.GetPeople (Galago.Origin.Remote,
74
string name = person.DisplayName;
77
people.Add (new PersonLink (LinkType.PersonDisplayName, person));
80
foreach (Account account in person.GetAccounts(true)) {
81
if (account.DisplayName != null) {
82
people.Add (new PersonLink (LinkType.AccountDisplayName,
86
if (account.Username != null &&
87
account.Username != account.DisplayName) {
88
people.Add (new PersonLink (LinkType.AccountUserName,
94
Logger.Log ("Loading up the person trie, Part 2...");
96
foreach (PersonLink plink in people) {
97
trie.AddKeyword (plink.LinkText, plink);
100
Logger.Log ("Done.");
117
public PersonLink (LinkType type, Person person)
119
this.link_type = type;
120
this.person = person;
123
Logger.Log ("Added person {0}: {1}", link_type, LinkText);
126
public PersonLink (LinkType type, Account account)
128
this.link_type = type;
129
this.person = account.Person;
130
this.account = account;
132
Logger.Log ("Added account {0}: {1}", link_type, LinkText);
135
public string LinkText
140
case LinkType.PersonDisplayName:
141
return person.DisplayName;
142
case LinkType.AccountUserName:
143
return account.Username;
144
case LinkType.AccountDisplayName:
145
return account.DisplayName;
151
Account GetBestAccount ()
156
if (person != null) {
157
Account best = person.PriorityAccount;
159
Logger.Log ("Using priority account '{0}' for {1}",
168
public void SendMessage ()
170
Account best = GetBestAccount ();
172
throw new Exception ("No accounts associated with this person");
174
Process p = new Process ();
175
p.StartInfo.FileName = "gaim-remote";
176
p.StartInfo.Arguments =
178
best.Service.Id + ":goim?screenname=" + best.Username;
179
p.StartInfo.UseShellExecute = false;
184
[DllImport("libgalago-gtk")]
185
static extern IntPtr galago_gdk_pixbuf_new_from_presence (IntPtr presence,
190
public Gdk.Pixbuf GetPresenceIcon ()
192
Account best = GetBestAccount ();
194
best.Presence != null) {
195
IntPtr icon = galago_gdk_pixbuf_new_from_presence (best.Presence.Handle,
198
if (icon != IntPtr.Zero)
199
return new Gdk.Pixbuf (icon);
205
class PersonTag : NoteTag
207
GalagoManager galago;
209
public PersonTag (string tag_name, GalagoManager galago)
212
this.galago = galago;
215
public override void Initialize (string element_name)
217
base.Initialize (element_name);
219
Underline = Pango.Underline.Single;
221
CanSerialize = false;
225
protected override bool OnActivate (NoteEditor editor,
229
string persona = start.GetText (end);
230
PersonLink plink = (PersonLink) galago.Trie.Lookup (persona);
233
plink.SendMessage ();
234
} catch (Exception e) {
235
string title = Catalog.GetString ("Cannot contact '{0}'");
236
title = String.Format (title, persona);
238
string message = Catalog.GetString ("Error running gaim-remote: {0}");
239
message = String.Format (message, e.Message);
241
Logger.Log (message);
243
HIGMessageDialog dialog =
244
new HIGMessageDialog (editor.Toplevel as Gtk.Window,
245
Gtk.DialogFlags.DestroyWithParent,
246
Gtk.MessageType.Info,
259
"Galago Presence Plugin", Defines.VERSION,
260
PluginInfoAttribute.OFFICIAL_AUTHOR,
261
"See online presence of buddies mentioned in a note.",
262
WebSite = Defines.TOMBOY_WEBSITE
264
class GalagoPresencePlugin : NotePlugin
266
static GalagoManager galago;
267
Gtk.TextTag person_tag;
268
Gtk.TextTag link_tag;
271
static GalagoPresencePlugin ()
273
galago = new GalagoManager ();
276
public GalagoPresencePlugin ()
281
protected override void Initialize ()
283
person_tag = Note.TagTable.Lookup ("link:person");
284
if (person_tag == null) {
285
person_tag = new PersonTag ("link:person", galago);
287
Logger.Log ("Adding link:person tag...");
288
Note.TagTable.Add (person_tag);
291
link_tag = Note.TagTable.Lookup ("link:internal");
292
url_tag = Note.TagTable.Lookup ("link:url");
295
protected override void Shutdown ()
297
galago.PeopleChanged -= OnPeopleChanged;
298
galago.PresenceChanged -= OnPresenceChanged;
301
protected override void OnNoteOpened ()
303
galago.PeopleChanged += OnPeopleChanged;
304
galago.PresenceChanged += OnPresenceChanged;
306
Buffer.InsertText += OnInsertText;
307
Buffer.DeleteRange += OnDeleteRange;
309
// Highlight existing people in note
310
HighlightInBlock (Buffer.StartIter, Buffer.EndIter);
313
void OnPeopleChanged (object sender, EventArgs args)
315
// Highlight people in note
316
UnhighlightInBlock (Buffer.StartIter, Buffer.EndIter);
317
HighlightInBlock (Buffer.StartIter, Buffer.EndIter);
320
void OnPresenceChanged (object sender, EventArgs args)
322
// Highlight people in note
323
UnhighlightInBlock (Buffer.StartIter, Buffer.EndIter);
324
HighlightInBlock (Buffer.StartIter, Buffer.EndIter);
327
void HighlightInBlock (Gtk.TextIter start, Gtk.TextIter end)
329
foreach (TrieHit hit in galago.Trie.FindMatches (start.GetText (end))) {
330
Gtk.TextIter match_start =
331
Buffer.GetIterAtOffset(start.Offset + hit.Start);
333
// Don't create links inside note or URL links
334
if (match_start.HasTag (url_tag) ||
335
match_start.HasTag (link_tag))
338
Gtk.TextIter match_end = match_start;
339
match_end.ForwardChars (hit.End - hit.Start);
341
Logger.Log ("Matching Person '{0}' at {1}-{2}...",
345
Buffer.ApplyTag (person_tag, match_start, match_end);
349
void UnhighlightInBlock (Gtk.TextIter start, Gtk.TextIter end)
351
Buffer.RemoveTag (person_tag, start, end);
354
void GetBlockExtents (ref Gtk.TextIter start, ref Gtk.TextIter end)
356
// FIXME: Should only be processing the largest match string
357
// size, so we don't slow down for large paragraphs
359
start.LineOffset = 0;
360
end.ForwardToLineEnd ();
363
void OnDeleteRange (object sender, Gtk.DeleteRangeArgs args)
365
Gtk.TextIter start = args.Start;
366
Gtk.TextIter end = args.End;
368
GetBlockExtents (ref start, ref end);
370
UnhighlightInBlock (start, end);
371
HighlightInBlock (start, end);
374
void OnInsertText (object sender, Gtk.InsertTextArgs args)
376
Gtk.TextIter start = args.Pos;
377
start.BackwardChars (args.Length);
379
Gtk.TextIter end = args.Pos;
381
GetBlockExtents (ref start, ref end);
383
UnhighlightInBlock (start, end);
384
HighlightInBlock (start, end);