rendered paste bodyusing System;
using System.Collections;
using System.Text;
using Mono.Unix;
using System.Runtime.InteropServices;
namespace Tomboy
{
public class TomboyTray : Gtk.EventBox
{
NoteManager manager;
Gtk.Tooltips tips;
Gtk.Image image;
PreferencesDialog prefs_dlg;
SyncDialog sync_dlg;
int icon_size_last = -1;
static Gdk.Pixbuf note_icon;
static TomboyTray ()
{
// Cache this since we use it a lot.
note_icon = GuiUtils.GetIcon ("tomboy", 16);
}
public TomboyTray (NoteManager manager)
: base ()
{
this.manager = manager;
this.image = new Gtk.Image ();
this.CanFocus = true;
this.ButtonPressEvent += ButtonPress;
this.Add (image);
this.ShowAll ();
string tip_text = Catalog.GetString ("Tomboy Notes");
if ((bool) Preferences.Get (Preferences.ENABLE_KEYBINDINGS)) {
string shortcut =
GConfKeybindingToAccel.GetShortcut (
Preferences.KEYBINDING_SHOW_NOTE_MENU);
if (shortcut != null)
tip_text += String.Format (" ({0})", shortcut);
}
tips = new Gtk.Tooltips ();
tips.SetTip (this, tip_text, null);
tips.Enable ();
tips.Sink ();
SetupDragAndDrop ();
InitSomeStuff ();
}
void ButtonPress (object sender, Gtk.ButtonPressEventArgs args)
{
Gtk.Widget parent = (Gtk.Widget) sender;
switch (args.Event.Button) {
case 1:
Gtk.Menu recent_menu = MakeRecentNotesMenu (parent);
GuiUtils.PopupMenu (recent_menu, args.Event);
args.RetVal = true;
break;
case 2:
// Give some visual feedback
Gtk.Drag.Highlight (this);
args.RetVal = PastePrimaryClipboard ();
Gtk.Drag.Unhighlight (this);
break;
}
}
void PrependTimestampedText (Note note, DateTime timestamp, string text)
{
NoteBuffer buffer = note.Buffer;
StringBuilder insert_text = new StringBuilder ();
insert_text.Append ("\n"); // initial newline
string date_format = Catalog.GetString ("dddd, MMMM d, h:mm tt");
insert_text.Append (timestamp.ToString (date_format));
insert_text.Append ("\n"); // begin content
insert_text.Append (text);
insert_text.Append ("\n"); // trailing newline
buffer.Undoer.FreezeUndo ();
// Insert the date and list of links...
Gtk.TextIter cursor = buffer.StartIter;
cursor.ForwardLines (1); // skip title
buffer.Insert (ref cursor, insert_text.ToString ());
// Make the date string a small font...
cursor = buffer.StartIter;
cursor.ForwardLines (2); // skip title & leading newline
Gtk.TextIter end = cursor;
end.ForwardToLineEnd (); // end of date
buffer.ApplyTag ("datetime", cursor, end);
// Select the text we've inserted (avoid trailing newline)...
end = cursor;
end.ForwardChars (insert_text.Length - 1);
buffer.MoveMark (buffer.SelectionBound, cursor);
buffer.MoveMark (buffer.InsertMark, end);
buffer.Undoer.ThawUndo ();
}
bool PastePrimaryClipboard ()
{
Gtk.Clipboard clip = GetClipboard (Gdk.Selection.Primary);
string text = clip.WaitForText ();
if (text == null || text.Trim() == string.Empty)
return false;
Note link_note = manager.Find (Catalog.GetString ("Start Here"));
if (link_note == null)
return false;
link_note.Window.Present ();
PrependTimestampedText (link_note,
DateTime.Now,
text);
return true;
}
Gtk.Menu MakeRecentNotesMenu (Gtk.Widget parent)
{
Gtk.Menu menu = new Gtk.Menu ();
menu.AttachToWidget (parent, GuiUtils.DetachMenu);
bool enable_keybindings = (bool)
Preferences.Get (Preferences.ENABLE_KEYBINDINGS);
Gtk.ImageMenuItem item;
item = new Gtk.ImageMenuItem (Catalog.GetString ("Create _New Note"));
item.Image = new Gtk.Image (Gtk.Stock.New, Gtk.IconSize.Menu);
item.Activated += CreateNewNote;
menu.Append (item);
if (enable_keybindings)
GConfKeybindingToAccel.AddAccelerator (
item,
Preferences.KEYBINDING_CREATE_NEW_NOTE);
// FIXME: Pull this from GConf
int min_size = 5;
int max_size = 18;
int list_size = 0;
DateTime two_days_ago = DateTime.Today.AddDays (-2);
// List the i most recently changed notes, and any
// currently opened notes...
foreach (Note note in manager.Notes) {
if (note.IsSpecial)
continue;
if ((note.IsOpened && note.Window.IsMapped) ||
note.ChangeDate > two_days_ago ||
list_size < min_size) {
item = MakeNoteMenuItem (note);
menu.Append (item);
if (++list_size == max_size)
break;
}
}
Note start = manager.Find (Catalog.GetString ("Start Here"));
if (start != null) {
item = MakeNoteMenuItem (start);
menu.Append (item);
if (enable_keybindings)
GConfKeybindingToAccel.AddAccelerator (
item,
Preferences.KEYBINDING_OPEN_START_HERE);
}
menu.Append (new Gtk.SeparatorMenuItem ());
item = new Gtk.ImageMenuItem (Catalog.GetString ("_Table of Contents"));
item.Image = new Gtk.Image (Gtk.Stock.SortAscending, Gtk.IconSize.Menu);
item.Activated += ViewRecentChanges;
menu.Append (item);
if (enable_keybindings)
GConfKeybindingToAccel.AddAccelerator (
item,
Preferences.KEYBINDING_OPEN_RECENT_CHANGES);
item = new Gtk.ImageMenuItem (Catalog.GetString ("_Search Notes..."));
item.Image = new Gtk.Image (Gtk.Stock.Find, Gtk.IconSize.Menu);
item.Activated += SearchNotes;
menu.Append (item);
//item = new Gtk.ImageMenuItem (Catalog.GetString ("S_ynchronize..."));
//item.Image = new Gtk.Image (Gtk.Stock.Find, Gtk.IconSize.Menu);
//item.Activated += SyncNotes;
//menu.Append (item);
if (enable_keybindings)
GConfKeybindingToAccel.AddAccelerator (
item,
Preferences.KEYBINDING_OPEN_SEARCH);
menu.ShowAll ();
return menu;
}
Gtk.ImageMenuItem MakeNoteMenuItem (Note note)
{
string display_name = note.Title;
if (note.IsNew)
display_name += Catalog.GetString (" (new)");
display_name = FormatForLabel (display_name);
Gtk.ImageMenuItem item = new Gtk.ImageMenuItem (display_name);
item.Image = new Gtk.Image (note_icon);
item.Data ["Note"] = note;
item.Activated += ShowNote;
return item;
}
string FormatForLabel (string name)
{
// Replace underscores ("_") with double-underscores ("__")
// so Note menuitems are not created with mnemonics.
return name.Replace ("_", "__");
}
void ShowNote (object sender, EventArgs args)
{
Note note = (Note) ((Gtk.Widget) sender).Data ["Note"];
if (note != null)
note.Window.Present ();
}
void CreateNewNote (object sender, EventArgs args)
{
try {
Note new_note = manager.Create ();
new_note.Window.Show ();
} catch (Exception e) {
HIGMessageDialog dialog =
new HIGMessageDialog (
null,
0,
Gtk.MessageType.Error,
Gtk.ButtonsType.Ok,
Catalog.GetString ("Cannot create new note"),
e.Message);
dialog.Run ();
dialog.Destroy ();
}
}
void SearchNotes (object sender, EventArgs args)
{
NoteFindDialog find_dialog = NoteFindDialog.GetInstance (manager);
find_dialog.Present ();
}
void ViewRecentChanges (object sender, EventArgs args)
{
Gtk.Window recent = new NoteRecentChanges (manager);
recent.Show ();
}
// Used by TomboyApplet to modify the icon background.
public Gtk.Image Image
{
get { return image; }
}
public void ShowMenu (bool select_first_item)
{
Gtk.Menu recent_menu = MakeRecentNotesMenu (this);
if (select_first_item)
recent_menu.SelectFirst (false);
GuiUtils.PopupMenu (recent_menu, null);
}
void OnPreferencesResponse (object sender, Gtk.ResponseArgs args)
{
((Gtk.Widget) sender).Destroy ();
prefs_dlg = null;
}
public void ShowPreferences ()
{
if (prefs_dlg == null) {
prefs_dlg = new PreferencesDialog ();
prefs_dlg.Response += OnPreferencesResponse;
}
prefs_dlg.Present ();
}
void OnSyncResponse (object sender, Gtk.ResponseArgs args)
{
((Gtk.Widget) sender).Destroy ();
sync_dlg = null;
}
public void ShowSync ()
{
//Console.WriteLine("showSync");
if (sync_dlg == null) {
sync_dlg = new SyncDialog ();
sync_dlg.Response += OnSyncResponse;
}
sync_dlg.Present ();
}
public void ShowAbout ()
{
string [] authors = new string [] {
"Alex Graveley <alex@beatniksoftware.com>"
};
string [] documenters = new string [] {
"Alex Graveley <alex@beatniksoftware.com>"
};
string translators = Catalog.GetString ("translator-credits");
if (translators == "translator-credits")
translators = null;
Gtk.AboutDialog about = new Gtk.AboutDialog ();
about.Name = "Tomboy";
about.Version = Defines.VERSION;
about.Logo = GuiUtils.GetIcon ("tomboy", 48);
about.Copyright =
Catalog.GetString ("Copyright \xa9 2004-2006 Alex Graveley");
about.Comments = Catalog.GetString ("A simple and easy to use desktop " +
"note-taking application.");
about.Website = "http://www.beatniksoftware.com/tomboy";
about.WebsiteLabel = Catalog.GetString("Homepage & Donations");
about.Authors = authors;
about.Documenters = documenters;
about.TranslatorCredits = translators;
about.IconName = "tomboy";
about.Run ();
about.Destroy ();
}
// Support dropping text/uri-lists and _NETSCAPE_URLs currently.
void SetupDragAndDrop ()
{
Gtk.TargetEntry [] targets =
new Gtk.TargetEntry [] {
new Gtk.TargetEntry ("text/uri-list", 0, 0),
new Gtk.TargetEntry ("_NETSCAPE_URL", 0, 0)
};
Gtk.Drag.DestSet (this,
Gtk.DestDefaults.All,
targets,
Gdk.DragAction.Copy);
DragDataReceived += OnDragDataReceived;
}
// Pop up Start Here and insert dropped links, in the form:
// Wednesday, December 8, 6:45 AM
// http://luna/kwiki/index.cgi?AdelaideUniThoughts
// http://www.beatniksoftware.com/blog/
// And select the inserted text.
//
// FIXME: Make undoable, make sure our date-sizing tag never "bleeds".
//
void OnDragDataReceived (object sender, Gtk.DragDataReceivedArgs args)
{
UriList uri_list = new UriList (args.SelectionData);
if (uri_list.Count == 0)
return;
StringBuilder insert_text = new StringBuilder ();
bool more_than_one = false;
foreach (Uri uri in uri_list) {
if (more_than_one)
insert_text.Append ("\n");
if (uri.IsFile)
insert_text.Append (uri.LocalPath);
else
insert_text.Append (uri.ToString ());
more_than_one = true;
}
Note link_note = manager.Find (Catalog.GetString ("Start Here"));
if (link_note != null) {
link_note.Window.Present ();
PrependTimestampedText (link_note,
DateTime.Now,
insert_text.ToString ());
}
}
protected override void OnSizeAllocated (Gdk.Rectangle rect)
{
base.OnSizeAllocated (rect);
int icon_size = Math.Min (rect.Height, rect.Width);
if (icon_size_last != icon_size) {
icon_size_last = icon_size;
image.Pixbuf = GuiUtils.GetIcon (GetIconName (), icon_size);
}
}
void ReloadIcon ()
{
icon_size_last = -1;
QueueResize ();
}
// NOTHING TO SEE HERE
void InitSomeStuff ()
{
manager.NoteDeleted += OnNoteDeletedUpdateIcon;
manager.NoteAdded += OnNoteAddedUpdateIcon;
manager.NoteRenamed += OnNoteRenamedUpdateIcon;
}
void OnNoteDeletedUpdateIcon (object sender, Note changed)
{
if (changed.Title == "Tintin")
ReloadIcon ();
}
void OnNoteAddedUpdateIcon (object sender, Note changed)
{
if (changed.Title == "Tintin")
ReloadIcon ();
}
void OnNoteRenamedUpdateIcon (Note note, string old_title)
{
if (note.Title == "Tintin" || old_title == "Tintin")
ReloadIcon ();
}
string GetIconName ()
{
if (manager.Find ("Tintin") != null)
return "tintin";
return "tomboy";
}
// GO ABOUT YOUR BUSINESS
}
//
// This is a helper to take the XKeybinding string from GConf, and
// convert it to a widget accelerator label, so note menu items can
// display their global X keybinding.
//
// FIXME: It would be totally sweet to allow setting the accelerator
// visually through the menuitem, and have the new value be stored in
// GConf.
//
public class GConfKeybindingToAccel
{
static Gtk.AccelGroup accel_group;
static GConfKeybindingToAccel ()
{
accel_group = new Gtk.AccelGroup ();
}
public static string GetShortcut (string gconf_path)
{
try {
string binding = (string) Preferences.Get (gconf_path);
if (binding == null ||
binding == String.Empty ||
binding == "disabled")
return null;
binding = binding.Replace ("<", "");
binding = binding.Replace (">", "-");
return binding;
} catch {
return null;
}
}
[DllImport("libtomboy")]
static extern bool egg_accelerator_parse_virtual (string keystring,
out uint keysym,
out uint virtual_mods);
[DllImport("libtomboy")]
static extern void egg_keymap_resolve_virtual_modifiers (IntPtr keymap,
uint virtual_mods,
out Gdk.ModifierType real_mods);
public static bool GetAccelKeys (string gconf_path,
out uint keyval,
out Gdk.ModifierType mods)
{
keyval = 0;
mods = 0;
try {
string binding = (string) Preferences.Get (gconf_path);
if (binding == null ||
binding == String.Empty ||
binding == "disabled")
return false;
uint virtual_mods = 0;
if (!egg_accelerator_parse_virtual (binding,
out keyval,
out virtual_mods))
return false;
Gdk.Keymap keymap = Gdk.Keymap.Default;
egg_keymap_resolve_virtual_modifiers (keymap.Handle,
virtual_mods,
out mods);
return true;
} catch {
return false;
}
}
public static void AddAccelerator (Gtk.MenuItem item, string gconf_path)
{
uint keyval;
Gdk.ModifierType mods;
if (GetAccelKeys (gconf_path, out keyval, out mods))
item.AddAccelerator ("activate",
accel_group,
keyval,
mods,
Gtk.AccelFlags.Visible);
}
}
}