5 namespace Tomboy
.Bugzilla
7 public class BugzillaPreferences
: Gtk
.VBox
9 Gtk
.TreeView icon_tree
;
10 Gtk
.ListStore icon_store
;
12 Gtk
.Button add_button
;
13 Gtk
.Button remove_button
;
15 string last_opened_dir
;
17 static string IMAGE_DIR
= "~/.tomboy/BugzillaIcons";
18 static string image_dir
= null;
20 static BugzillaPreferences ()
22 // TODO: Get this in a safer way
23 image_dir
= IMAGE_DIR
.Replace ("~", Environment
.GetEnvironmentVariable ("HOME"));
26 public BugzillaPreferences ()
29 last_opened_dir
= Environment
.GetEnvironmentVariable ("HOME");
31 Gtk
.Label l
= new Gtk
.Label (Catalog
.GetString (
32 "You can use any bugzilla just by dragging links " +
33 "into notes. If you want a special icon for " +
34 "certain hosts, add them here."));
38 PackStart (l
, false, false, 0);
40 icon_store
= CreateIconStore ();
42 icon_tree
= new Gtk
.TreeView (icon_store
);
43 icon_tree
.HeadersVisible
= true;
44 icon_tree
.Selection
.Mode
= Gtk
.SelectionMode
.Single
;
45 icon_tree
.Selection
.Changed
+= SelectionChanged
;
47 Gtk
.CellRenderer renderer
;
49 Gtk
.TreeViewColumn host_col
= new Gtk
.TreeViewColumn ();
50 host_col
.Title
= Catalog
.GetString ("Host Name");
51 host_col
.Sizing
= Gtk
.TreeViewColumnSizing
.Autosize
;
52 host_col
.Resizable
= true;
53 host_col
.Expand
= true;
54 host_col
.MinWidth
= 200;
56 renderer
= new Gtk
.CellRendererText ();
57 host_col
.PackStart (renderer
, true);
58 host_col
.AddAttribute (renderer
, "text", 1 /* host name */);
59 host_col
.SortColumnId
= 1; /* host name */
60 host_col
.SortIndicator
= false;
61 host_col
.Reorderable
= false;
62 host_col
.SortOrder
= Gtk
.SortType
.Ascending
;
64 icon_tree
.AppendColumn (host_col
);
66 Gtk
.TreeViewColumn icon_col
= new Gtk
.TreeViewColumn ();
67 icon_col
.Title
= Catalog
.GetString ("Icon");
68 icon_col
.Sizing
= Gtk
.TreeViewColumnSizing
.Fixed
;
69 icon_col
.MaxWidth
= 50;
70 icon_col
.MinWidth
= 50;
71 icon_col
.Resizable
= false;
73 renderer
= new Gtk
.CellRendererPixbuf ();
74 icon_col
.PackStart (renderer
, false);
75 icon_col
.AddAttribute (renderer
, "pixbuf", 0 /* icon */);
77 icon_tree
.AppendColumn (icon_col
);
79 Gtk
.ScrolledWindow sw
= new Gtk
.ScrolledWindow ();
80 sw
.ShadowType
= Gtk
.ShadowType
.In
;
81 sw
.HeightRequest
= 200;
82 sw
.WidthRequest
= 300;
83 sw
.SetPolicy (Gtk
.PolicyType
.Automatic
, Gtk
.PolicyType
.Automatic
);
86 PackStart (sw
, true, true, 0);
88 add_button
= new Gtk
.Button (Gtk
.Stock
.Add
);
89 add_button
.Clicked
+= AddClicked
;
91 remove_button
= new Gtk
.Button (Gtk
.Stock
.Remove
);
92 remove_button
.Sensitive
= false;
93 remove_button
.Clicked
+= RemoveClicked
;
95 Gtk
.HButtonBox hbutton_box
= new Gtk
.HButtonBox ();
96 hbutton_box
.Layout
= Gtk
.ButtonBoxStyle
.Start
;
97 hbutton_box
.Spacing
= 6;
99 hbutton_box
.PackStart (add_button
);
100 hbutton_box
.PackStart (remove_button
);
101 PackStart (hbutton_box
, false, false, 0);
106 Gtk
.ListStore
CreateIconStore ()
108 Gtk
.ListStore store
= new Gtk
.ListStore (
109 typeof (Gdk
.Pixbuf
), // icon
110 typeof (string), // host
111 typeof (string)); // file path
112 store
.SetSortColumnId (1, Gtk
.SortType
.Ascending
);
117 void UpdateIconStore ()
119 // Read ~/.tomboy/BugzillaIcons/"
121 if (!Directory
.Exists (image_dir
))
124 icon_store
.Clear (); // clear out the old entries
126 string [] icon_files
= Directory
.GetFiles (image_dir
);
127 foreach (string icon_file
in icon_files
) {
128 FileInfo file_info
= new FileInfo (icon_file
);
130 Gdk
.Pixbuf pixbuf
= null;
132 pixbuf
= new Gdk
.Pixbuf (icon_file
);
133 } catch (Exception e
) {
134 Logger
.Warn ("Error loading Bugzilla Icon {0}: {1}", icon_file
, e
.Message
);
140 string host
= ParseHost (file_info
);
142 Gtk
.TreeIter iter
= icon_store
.Append ();
143 icon_store
.SetValue (iter
, 0, pixbuf
);
144 icon_store
.SetValue (iter
, 1, host
);
145 icon_store
.SetValue (iter
, 2, icon_file
);
150 string ParseHost (FileInfo file_info
)
152 string name
= file_info
.Name
;
153 string ext
= file_info
.Extension
;
155 if (ext
== null || ext
== String
.Empty
)
158 int ext_pos
= name
.IndexOf (ext
);
162 string host
= name
.Substring (0, ext_pos
);
163 if (host
== null || host
== String
.Empty
)
169 protected override void OnRealized ()
176 void SelectionChanged (object sender
, EventArgs args
)
178 remove_button
.Sensitive
=
179 icon_tree
.Selection
.CountSelectedRows() > 0;
182 void AddClicked (object sender
, EventArgs args
)
184 Gtk
.FileChooserDialog dialog
= new Gtk
.FileChooserDialog (
185 Catalog
.GetString ("Select an icon..."),
186 null, Gtk
.FileChooserAction
.Open
, new object[] {});
187 dialog
.AddButton (Gtk
.Stock
.Cancel
, Gtk
.ResponseType
.Cancel
);
188 dialog
.AddButton (Gtk
.Stock
.Open
, Gtk
.ResponseType
.Ok
);
190 dialog
.DefaultResponse
= Gtk
.ResponseType
.Ok
;
191 dialog
.LocalOnly
= true;
192 dialog
.SetCurrentFolder (last_opened_dir
);
194 Gtk
.FileFilter filter
= new Gtk
.FileFilter ();
195 filter
.AddPixbufFormats ();
197 dialog
.Filter
= filter
;
200 Gtk
.Label l
= new Gtk
.Label (Catalog
.GetString ("_Host name:"));
201 Gtk
.Entry host_entry
= new Gtk
.Entry ();
202 l
.MnemonicWidget
= host_entry
;
203 Gtk
.HBox hbox
= new Gtk
.HBox (false, 6);
204 hbox
.PackStart (l
, false, false, 0);
205 hbox
.PackStart (host_entry
, true, true, 0);
208 dialog
.ExtraWidget
= hbox
;
215 response
= dialog
.Run ();
216 icon_file
= dialog
.Filename
;
217 host
= host_entry
.Text
.Trim ();
219 if (response
== (int) Gtk
.ResponseType
.Ok
220 && host
== String
.Empty
) {
221 // Let the user know that they
222 // have to specify a host name.
223 HIGMessageDialog warn
=
224 new HIGMessageDialog (
226 Gtk
.DialogFlags
.DestroyWithParent
,
227 Gtk
.MessageType
.Warning
,
229 Catalog
.GetString ("No host name specified"),
230 Catalog
.GetString ("You must specify the Bugzilla " +
231 "host name to use with this icon."));
235 host_entry
.GrabFocus ();
237 } else if (response
!= (int) Gtk
.ResponseType
.Ok
) {
242 // Keep track of the last directory the user had open
243 last_opened_dir
= dialog
.CurrentFolder
;
247 // Copy the file to the BugzillaIcons directory
249 if (!CopyToBugizllaIconsDir (icon_file
, host
, out err_msg
)) {
250 HIGMessageDialog err
=
251 new HIGMessageDialog (
253 Gtk
.DialogFlags
.DestroyWithParent
,
254 Gtk
.MessageType
.Error
,
256 Catalog
.GetString ("Error saving icon"),
257 Catalog
.GetString ("Could not save the icon file. " +
266 bool CopyToBugizllaIconsDir (string file_path
,
272 FileInfo file_info
= new FileInfo (file_path
);
273 string ext
= file_info
.Extension
;
274 string saved_path
= System
.IO
.Path
.Combine (image_dir
, host
+ ext
);
276 if (!Directory
.Exists (image_dir
)) {
277 Directory
.CreateDirectory (image_dir
);
280 File
.Copy (file_path
, saved_path
);
281 } catch (Exception e
) {
286 ResizeIfNeeded (saved_path
);
290 void ResizeIfNeeded (string file_path
)
292 // FIXME: Resize the icon to not be larger than 16x16
295 void RemoveClicked (object sender
, EventArgs args
)
297 // Remove the icon file and call UpdateIconStore ().
299 if (!icon_tree
.Selection
.GetSelected (out iter
))
302 string icon_path
= icon_store
.GetValue (iter
, 2) as string;
304 HIGMessageDialog dialog
=
305 new HIGMessageDialog (
307 Gtk
.DialogFlags
.DestroyWithParent
,
308 Gtk
.MessageType
.Question
,
309 Gtk
.ButtonsType
.None
,
310 Catalog
.GetString ("Really remove this icon?"),
311 Catalog
.GetString ("If you remove an icon it is " +
312 "permanently lost."));
316 button
= new Gtk
.Button (Gtk
.Stock
.Cancel
);
317 button
.CanDefault
= true;
319 dialog
.AddActionWidget (button
, Gtk
.ResponseType
.Cancel
);
320 dialog
.DefaultResponse
= Gtk
.ResponseType
.Cancel
;
322 button
= new Gtk
.Button (Gtk
.Stock
.Delete
);
323 button
.CanDefault
= true;
325 dialog
.AddActionWidget (button
, 666);
327 int result
= dialog
.Run ();
330 File
.Delete (icon_path
);
332 } catch (Exception e
) {
333 Logger
.Error ("Error removing icon {0}: {1}",