QueryResponses.cs, DumpIndex.cs, IQueryResult.cs, QueryExecutor.cs, QueryResult.cs...
[beagle.git] / ContactViewer / ContactWindow.cs
blob7c2e08e3f6ec9e8c9f3dbdb34296839887e76909
1 //
2 // ContactWindow.cs
3 //
4 // Copyright (C) 2006 Pierre Östlund
5 //
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in all
16 // copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 // SOFTWARE.
27 using Gtk;
28 using Glade;
29 using System;
30 using System.Collections;
31 using System.Text.RegularExpressions;
33 using Beagle.Util;
34 using Mono.Unix;
36 namespace ContactViewer {
38 public class ContactWindow {
39 private Glade.XML gxml;
40 private UIManager ui_manager;
42 [Widget] Gtk.TreeView ContactList;
43 [Widget] Gtk.ComboBox ListIdentifier;
44 [Widget] Gtk.Statusbar Statusbar;
45 [Widget] Gtk.Window MainWindow;
46 [Widget] Gtk.EventBox MenubarHolder;
47 [Widget] Gtk.EventBox ContactHolder;
49 private ListStore contact_store;
50 private ListStore contact_show_type_store;
52 private Uri uri;
53 private MorkDatabase database;
54 //private ContactManager contact_manager;
56 public ContactWindow (ContactManager contact_manager, Uri uri)
58 this.uri = uri;
59 //this.contact_manager = contact_manager;
61 ShowWindow ();
64 public void ShowWindow ()
66 Application.Init ();
68 gxml = new Glade.XML ("contactviewer.glade", "MainWindow");
69 gxml.Autoconnect (this);
71 ActionEntry[] entries = new ActionEntry [] {
72 new ActionEntry ("FileMenuAction", null, "_File", null, null, null),
73 new ActionEntry ("OpenAction", Gtk.Stock.Open,
74 "_Open", "<control>O", Catalog.GetString ("Open..."), new EventHandler (OnOpenDatabase)),
75 new ActionEntry ("QuitAction", Gtk.Stock.Quit,
76 "_Quit", "<control>Q", Catalog.GetString ("Quit"), new EventHandler (OnQuit)),
77 new ActionEntry ("HelpMenuAction", null, "_Help", null, null, null),
78 new ActionEntry ("AboutAction", Gnome.Stock.About,
79 "_About", null, Catalog.GetString ("About"), new EventHandler (OnAbout))
82 ActionGroup grp = new ActionGroup ("MainGroup");
83 grp.Add (entries);
85 ui_manager = new UIManager ();
86 ui_manager.InsertActionGroup(grp, 0);
87 ui_manager.AddUiFromResource ("menu.xml");
88 MenubarHolder.Add (ui_manager.GetWidget ("/MainMenu"));
90 // Fix the TreeView that will contain all contacts
91 contact_store = new ListStore (typeof (string), typeof (string));
93 ContactList.Model = contact_store;
94 ContactList.RulesHint = true;
95 ContactList.AppendColumn (Catalog.GetString ("Contacts"), new CellRendererText (), "text", 1);
96 ContactList.ButtonReleaseEvent += OnContactSelected;
98 // This ListStore will let the user choose what to see in the contact list
99 contact_show_type_store = new ListStore (typeof (string), typeof (string));
100 contact_show_type_store.AppendValues ("DisplayName", Catalog.GetString ("Display name"));
101 contact_show_type_store.AppendValues ("PrimaryEmail", Catalog.GetString ("Primary E-mail"));
102 contact_show_type_store.AppendValues ("SecondEmail", Catalog.GetString ("Secondary E-mail"));
103 contact_show_type_store.AppendValues ("NickName", Catalog.GetString ("Nickname"));
105 CellRendererText cell = new CellRendererText ();
106 ListIdentifier.PackStart (cell, false);
107 ListIdentifier.AddAttribute (cell, "text", 1);
108 ListIdentifier.Model = contact_show_type_store;
109 ListIdentifier.Active = 0;
110 ListIdentifier.Changed += OnContactListTypeChanged;
112 MainWindow.Icon = Beagle.Images.GetPixbuf ("contact-icon.png");
113 MainWindow.DeleteEvent += OnDeleteEvent;
115 LoadDatabase ();
116 Application.Run ();
119 public void LoadDatabase ()
121 // Load the database file
122 try {
123 database = new MorkDatabase (uri.AbsolutePath);
124 database.Read ();
125 database.EnumNamespace = "ns:addrbk:db:row:scope:card:all";
126 } catch (Exception e) {
127 MessageDialog dialog = new MessageDialog (
128 MainWindow,
129 DialogFlags.DestroyWithParent,
130 MessageType.Error,
131 ButtonsType.Ok,
132 false,
133 String.Format (Catalog.GetString ("Unable to open mork database:\n\n {0}"), e.Message));
135 dialog.Run ();
136 dialog.Destroy ();
137 Environment.Exit (1);
140 // Populate the gui with nice stuff
141 Clear ();
142 FillContactList ();
144 try {
145 Match m = Regex.Match (uri.Query, @"\?id=(?<id>[0-9A-Fa-f]+)");
146 ShowContact (m.Result ("${id}"));
147 } catch {
148 Gtk.MessageDialog dialog = new MessageDialog (
149 MainWindow,
150 DialogFlags.DestroyWithParent,
151 MessageType.Warning,
152 ButtonsType.Ok,
153 Catalog.GetString ("The specified ID does not exist in this database!"));
155 dialog.Run ();
156 dialog.Destroy ();
160 public void FillContactList ()
162 TreeIter iter;
163 int count = 0;
165 if (!ListIdentifier.GetActiveIter (out iter))
166 return;
168 contact_store.Clear ();
170 // Add contacts to treeview
171 foreach (string id in database) {
172 Hashtable tbl = database.Compile (id, database.EnumNamespace);
174 if (tbl ["table"] != null && tbl ["table"] as string == "BF") {
175 contact_store.AppendValues (tbl ["id"], tbl [contact_show_type_store.GetValue (iter, 0)]);
176 count++;
180 SetStatusMessage (String.Format (Catalog.GetPluralString ("Added {0} contact", "Added {0} contacts", count), count));
183 public void ShowContact (string id)
185 TreeIter iter;
186 Hashtable tbl = database.Compile (id, database.EnumNamespace);
188 if (ContactHolder.Child != null)
189 ContactHolder.Remove (ContactHolder.Child);
191 ContactHolder.Add (new Contact (tbl));
192 MainWindow.ShowAll ();
194 // Update selection in the contact list as well
195 if (contact_store.GetIterFirst (out iter)) {
196 do {
197 if (contact_store.GetValue (iter, 0) as string == id) {
198 ContactList.Selection.SelectIter (iter);
199 break;
201 } while (contact_store.IterNext (ref iter));
204 SetStatusMessage (String.Format (Catalog.GetString ("Viewing {0}"),
205 (ContactHolder.Child as Contact).GetString ("DisplayName")));
208 public void Clear ()
210 if (ContactHolder.Child != null)
211 ContactHolder.Remove (ContactHolder.Child);
213 contact_store.Clear ();
216 public void SetStatusMessage (string message)
218 Statusbar.Pop (0);
219 Statusbar.Push (0, message);
222 protected virtual void OnContactSelected (object o, ButtonReleaseEventArgs args)
224 TreeIter iter;
225 TreeModel model;
227 if (!ContactList.Selection.GetSelected (out model, out iter))
228 return;
230 ShowContact ((string) model.GetValue (iter, 0));
233 protected virtual void OnContactListTypeChanged (object o, EventArgs args)
235 FillContactList ();
238 protected virtual void OnOpenDatabase (object o, EventArgs args)
240 Uri uri;
241 ResponseType response;
242 FileChooserDialog chooser;
244 chooser = new FileChooserDialog (Catalog.GetString ("Select a mork database file"),
245 MainWindow, FileChooserAction.Open);
246 chooser.LocalOnly = true;
247 chooser.AddButton (Gtk.Stock.Cancel, ResponseType.Cancel);
248 chooser.AddButton (Gtk.Stock.Ok, ResponseType.Ok);
250 response = (ResponseType) chooser.Run ();
251 uri = new Uri (chooser.Uri);
252 chooser.Destroy ();
254 if (response == ResponseType.Ok) {
255 this.uri = uri;
256 LoadDatabase ();
260 protected virtual void OnAbout (object o, EventArgs args)
262 #pragma warning disable 612 // don't warn that Gnome.About is deprecated.
263 Gnome.About about = new Gnome.About ("Contact Viewer",
264 ExternalStringsHack.Version,
265 "Copyright (C) 2006 Pierre \u00D6stlund",
266 null, new string [] { "Pierre \u00D6stlund" },
267 null, null, Beagle.Images.GetPixbuf ("system-search.png"));
269 about.Run ();
270 about.Dispose ();
271 #pragma warning restore 612
274 protected virtual void OnQuit (object o, EventArgs args)
276 Application.Quit ();
279 protected virtual void OnDeleteEvent (object o, DeleteEventArgs args)
281 Application.Quit ();
285 public class Contact : VBox {
286 private Hashtable contact;
288 public Contact (Hashtable contact) :
289 base (false, 10)
291 HBox hbox;
292 Table table;
293 Button button;
294 HButtonBox hbuttonbox;
296 this.contact = contact;
298 // Create header containing an icon and display name
299 hbox = new HBox ();
300 hbox.Spacing = 10;
301 hbox.PackStart (Beagle.Images.GetWidget ("person.png"), false, false, 0);
302 hbox.PackStart (new VLabel (String.Format ("<b><span size='large'>{0} \"{1}\" {2}</span></b>",
303 GetString ("FirstName"), GetString ("NickName"), GetString ("LastName")), false));
304 PackStart (hbox, false, false, 0);
305 PackStart (new HSeparator (), false, false, 0);
307 // Create a table containing some user information
308 table = new Table (5, 2, false);
309 PackStart (table, false, false, 0);
311 table.Attach (new VLabel (String.Format ("<b>{0}</b>", Catalog.GetString ("Primary E-Mail:")), false),
312 0, 1, 0, 1, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink, 10, 0);
313 table.Attach (new VLabel (GetString ("PrimaryEmail"), true), 1, 2, 0, 1);
315 table.Attach (new VLabel (String.Format ("<b>{0}</b>", Catalog.GetString ("Screen name:")), false),
316 0, 1, 1, 2, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink, 10, 0);
317 table.Attach (new VLabel (GetString ("_AimScreenName"), true), 1, 2, 1, 2);
319 table.Attach (new VLabel (String.Format ("<b>{0}</b>", Catalog.GetString ("Home phone:")), false),
320 0, 1, 2, 3, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink, 10, 0);
321 table.Attach (new VLabel (GetString ("HomePhone"), true), 1, 2, 2, 3);
323 table.Attach (new VLabel (String.Format ("<b>{0}</b>", Catalog.GetString ("Mobile phone:")), false),
324 0, 1, 3, 4, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink, 10, 0);
325 table.Attach (new VLabel (GetString ("CellularNumber"), true), 1, 2, 3, 4);
327 table.Attach (new VLabel (String.Format ("<b>{0}</b>", Catalog.GetString ("Web page:")), false),
328 0, 1, 4, 5, AttachOptions.Shrink | AttachOptions.Fill, AttachOptions.Shrink, 10, 0);
329 table.Attach (new VLabel (GetString ("WebPage2"), true), 1, 2, 4, 5);
331 // Add a button row with some informational buttons
332 hbuttonbox = new HButtonBox ();
333 hbuttonbox.Layout = ButtonBoxStyle.End;
334 PackEnd (hbuttonbox, false, false, 0);
336 button = new Button (Catalog.GetString ("Send E-Mail"));
337 button.Clicked += OnSendEmail;
338 hbuttonbox.Add (button);
340 button = new Button (Catalog.GetString ("Details..."));
341 button.Clicked += OnDetails;
342 hbuttonbox.Add (button);
345 public string GetString (string str)
347 if (!contact.ContainsKey (str))
348 return "N/A";
350 return contact [str] as string;
353 protected virtual void OnSendEmail (object o, EventArgs args)
355 string mail = null;
356 SafeProcess process;
358 if (contact ["PrimaryEmail"] != null)
359 mail = contact ["PrimaryEmail"] as string;
360 else if (contact ["SecondEmail"] != null)
361 mail = contact ["SecondMail"] as string;
362 else {
363 MessageDialog dialog = new MessageDialog (
364 null,
365 DialogFlags.DestroyWithParent,
366 MessageType.Warning,
367 ButtonsType.Ok,
368 Catalog.GetString ("Could not find a valid E-mail address!"));
370 dialog.Run ();
371 dialog.Destroy ();
372 return;
375 process = new SafeProcess ();
376 process.Arguments = new string [2];
377 process.Arguments [0] = Thunderbird.ExecutableName;
378 process.Arguments [1] = String.Format ("mailto:{0}", mail);
379 process.Start ();
382 protected virtual void OnDetails (object o, EventArgs args)
384 new DetailedWindow (contact);
387 public class VLabel : Label {
389 public VLabel (string label, bool selectable) :
390 base (label)
392 Xalign = 0.0f;
393 UseMarkup = true;
394 Selectable = selectable;
400 public class DetailedWindow {
401 private Glade.XML gxml;
403 [Widget] Gtk.Button Close;
404 [Widget ("DetailedWindow")] Gtk.Window Window;
405 [Widget] Gtk.TextView Notes;
406 [Widget] Gtk.ComboBox PreferredType;
408 string[] widget_names = new string[] {"FirstName", "LastName", "DisplayName",
409 "NickName", "PrimaryEmail", "SecondEmail", "_AimScreenName", "WorkPhone",
410 "HomePhone", "FaxNumber", "PagerNumber", "CellularNumber", "HomeAddress",
411 "HomeAddress2", "HomeCity", "HomeCountry", "WebPage2", "HomeZipCode",
412 "HomeState", "WorkState", "WorkZipCode", "JobTitle", "Department", "Company",
413 "WorkAddress", "WorkAddress2", "WorkCity", "WorkCountry", "WebPage1",
414 "Custom1", "Custom2", "Custom3", "Custom4"};
416 public DetailedWindow (Hashtable contact)
418 gxml = new Glade.XML (null, "contactviewer.glade", "DetailedWindow", null);
419 gxml.Autoconnect (this);
421 // Fill all Entry-boxes with information
422 foreach (string name in widget_names)
423 (gxml.GetWidget (name) as Gtk.Entry).Text = (contact [name] != null ? (contact [name] as string) : "");;
425 // Also fill the special cases
426 Notes.Buffer.Text = (contact ["Notes"] != null ? (contact ["Notes"] as string) : "");
428 try {
429 int tmp = Convert.ToInt32 (contact ["PreferMailFormat"]);
430 PreferredType.Active = (tmp >= 0 && tmp <= 2 ? tmp : 0);
431 } catch {
432 PreferredType.Active = 0;
435 Close.Clicked += OnClose;
437 Window.Icon = Beagle.Images.GetPixbuf ("contact-icon.png");
438 Window.Show ();
441 protected virtual void OnClose (object o, EventArgs args)
443 Window.Hide ();