~ted/ubuntu/lucid/tomboy/with-patch

« back to all changes in this revision

Viewing changes to Tomboy/Plugins/ExportToHTML.cs

Tags: upstream-0.7.2
Import upstream version 0.7.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
using System;
3
 
using System.IO;
4
 
using System.Collections;
5
 
using System.Reflection;
6
 
using System.Text;
7
 
using System.Xml;
8
 
using System.Xml.XPath;
9
 
using System.Xml.Xsl;
10
 
using Mono.Unix;
11
 
 
12
 
using Tomboy;
13
 
 
14
 
[PluginInfo(
15
 
        "Export to HTML", Defines.VERSION,
16
 
        PluginInfoAttribute.OFFICIAL_AUTHOR,
17
 
        "Exports individual notes to HTML.",
18
 
        WebSite = Defines.TOMBOY_WEBSITE
19
 
        )]
20
 
public class ExportToHTMLPlugin : NotePlugin
21
 
{
22
 
        const string stylesheet_name = "ExportToHTML.xsl";
23
 
        static XslTransform xsl;
24
 
 
25
 
        Gtk.ImageMenuItem item;
26
 
 
27
 
        static ExportToHTMLPlugin ()
28
 
        {
29
 
                Assembly asm = Assembly.GetExecutingAssembly ();
30
 
                string asm_dir = System.IO.Path.GetDirectoryName (asm.Location);
31
 
                string stylesheet_file = Path.Combine (asm_dir, stylesheet_name);
32
 
 
33
 
                xsl = new XslTransform ();
34
 
 
35
 
                if (File.Exists (stylesheet_file)) {
36
 
                        Logger.Log ("ExportToHTMLPlugin: Using user-custom {0} file.",
37
 
                                           stylesheet_name);
38
 
                        xsl.Load (stylesheet_file);
39
 
                } else {
40
 
                        Stream resource = asm.GetManifestResourceStream (stylesheet_name);
41
 
                        if (resource != null) {
42
 
                                XmlTextReader reader = new XmlTextReader (resource);
43
 
                                xsl.Load (reader, null, null);
44
 
                                resource.Close ();
45
 
                        } else {
46
 
                                Logger.Log ("Unable to find HTML export template '{0}'.",
47
 
                                                   stylesheet_name);
48
 
                        }
49
 
                }
50
 
        }
51
 
 
52
 
        protected override void Initialize ()
53
 
        {
54
 
                item = 
55
 
                        new Gtk.ImageMenuItem (Catalog.GetString ("Export to HTML"));
56
 
                item.Image = new Gtk.Image (Gtk.Stock.Save, Gtk.IconSize.Menu);
57
 
                item.Activated += ExportButtonClicked;
58
 
                item.Show ();
59
 
                AddPluginMenuItem (item);
60
 
        }
61
 
 
62
 
        protected override void Shutdown ()
63
 
        {
64
 
                // Disconnect the event handlers so
65
 
                // there aren't any memory leaks.
66
 
                item.Activated -= ExportButtonClicked;
67
 
        }
68
 
 
69
 
        protected override void OnNoteOpened () 
70
 
        {
71
 
                // Do nothing.
72
 
        }
73
 
 
74
 
        void ExportButtonClicked (object sender, EventArgs args)
75
 
        {
76
 
                ExportToHTMLDialog dialog = new ExportToHTMLDialog (Note.Title + ".html");
77
 
                int response = dialog.Run();
78
 
                string output_path = dialog.Filename;
79
 
 
80
 
                if (response != (int) Gtk.ResponseType.Ok) {
81
 
                        dialog.Destroy ();
82
 
                        return;
83
 
                }
84
 
 
85
 
                Logger.Log ("Exporting Note '{0}' to '{1}'...", Note.Title, output_path);
86
 
 
87
 
                StreamWriter writer = null;
88
 
                string error_message = null;
89
 
 
90
 
                try {
91
 
                        try {
92
 
                                // FIXME: Warn about file existing.  Allow overwrite.
93
 
                                File.Delete (output_path); 
94
 
                        } catch {
95
 
                        }
96
 
 
97
 
                        writer = new StreamWriter (output_path);
98
 
                        WriteHTMLForNote (writer, Note, dialog.ExportLinked, dialog.ExportLinkedAll);
99
 
                        
100
 
                        // Save the dialog preferences now that the note has
101
 
                        // successfully been exported
102
 
                        dialog.SavePreferences ();
103
 
                        dialog.Destroy ();
104
 
                        dialog = null;
105
 
                        
106
 
                        try {
107
 
                                Uri output_uri = new Uri (output_path);
108
 
                                Gnome.Url.Show (output_uri.AbsoluteUri);
109
 
                        } catch (Exception ex) {
110
 
                                Logger.Log ("Could not open exported note in a web browser: {0}", 
111
 
                                            ex);
112
 
 
113
 
                                string detail = String.Format (
114
 
                                        Catalog.GetString ("Your note was exported to \"{0}\"."),
115
 
                                        output_path);
116
 
 
117
 
                                // Let the user know the note was saved successfully
118
 
                                // even though showing the note in a web browser failed.
119
 
                                HIGMessageDialog msg_dialog =
120
 
                                        new HIGMessageDialog (
121
 
                                                Window,
122
 
                                                Gtk.DialogFlags.DestroyWithParent,
123
 
                                                Gtk.MessageType.Info,
124
 
                                                Gtk.ButtonsType.Ok,
125
 
                                                Catalog.GetString ("Note exported successfully"),
126
 
                                                detail);
127
 
                                msg_dialog.Run ();
128
 
                                msg_dialog.Destroy ();
129
 
                        }
130
 
                } catch (UnauthorizedAccessException) {
131
 
                        error_message = Catalog.GetString ("Access denied.");
132
 
                } catch (DirectoryNotFoundException) {
133
 
                        error_message = Catalog.GetString ("Folder does not exist.");
134
 
                } catch (Exception e) {
135
 
                        Logger.Log ("Could not export: {0}", e);
136
 
                        
137
 
                        error_message = e.Message;
138
 
                } finally {
139
 
                        if (writer != null) 
140
 
                                writer.Close ();
141
 
                }
142
 
 
143
 
                if (error_message != null)
144
 
                {
145
 
                        Logger.Log ("Could not export: {0}", error_message);
146
 
 
147
 
                        string msg = String.Format (
148
 
                                Catalog.GetString ("Could not save the file \"{0}\""), 
149
 
                                output_path);
150
 
 
151
 
                        HIGMessageDialog msg_dialog = 
152
 
                                new HIGMessageDialog (
153
 
                                        dialog,
154
 
                                        Gtk.DialogFlags.DestroyWithParent,
155
 
                                        Gtk.MessageType.Error,
156
 
                                        Gtk.ButtonsType.Ok,
157
 
                                        msg,
158
 
                                        error_message);
159
 
                        msg_dialog.Run ();
160
 
                        msg_dialog.Destroy ();
161
 
                }
162
 
 
163
 
                if (dialog != null)
164
 
                        dialog.Destroy ();
165
 
        }
166
 
 
167
 
        public void WriteHTMLForNote (TextWriter writer, 
168
 
                               Note note,
169
 
                               bool export_linked,
170
 
                               bool export_linked_all) 
171
 
        {
172
 
                // NOTE: Don't use the XmlDocument version, which strips
173
 
                // whitespace between elements for some reason.  Also,
174
 
                // XPathDocument is faster.
175
 
                StringWriter s_writer = new StringWriter ();
176
 
                NoteArchiver.Write (s_writer, note.Data);
177
 
                StringReader reader = new StringReader (s_writer.ToString ());
178
 
                s_writer.Close ();
179
 
                XPathDocument doc = new XPathDocument (reader);
180
 
                reader.Close ();
181
 
 
182
 
                XsltArgumentList args = new XsltArgumentList ();
183
 
                args.AddParam ("export-linked", "", export_linked);
184
 
                args.AddParam ("export-linked-all", "", export_linked_all);
185
 
                args.AddParam ("root-note", "", note.Title);
186
 
 
187
 
                if ((bool) Preferences.Get (Preferences.ENABLE_CUSTOM_FONT)) {
188
 
                        string font_face = (string) Preferences.Get (Preferences.CUSTOM_FONT_FACE);
189
 
                        Pango.FontDescription font_desc = 
190
 
                                Pango.FontDescription.FromString (font_face);
191
 
                        string font = String.Format ("font-family:'{0}';", font_desc.Family);
192
 
 
193
 
                        args.AddParam ("font", "", font);
194
 
                }
195
 
 
196
 
                NoteNameResolver resolver = new NoteNameResolver (note.Manager);
197
 
                xsl.Transform (doc, args, writer, resolver);
198
 
        }
199
 
}
200
 
 
201
 
class NoteNameResolver : XmlResolver
202
 
{
203
 
        NoteManager manager;
204
 
 
205
 
        public NoteNameResolver (NoteManager manager)
206
 
        {
207
 
                this.manager = manager;
208
 
        }
209
 
 
210
 
        public override System.Net.ICredentials Credentials 
211
 
        {
212
 
                set { }
213
 
        }
214
 
 
215
 
        public override object GetEntity (Uri absolute_uri, string role, Type of_object_to_return)
216
 
        {
217
 
                Note note = manager.FindByUri (absolute_uri.ToString ());
218
 
                if (note == null)
219
 
                        return null;
220
 
 
221
 
                StringWriter writer = new StringWriter ();
222
 
                NoteArchiver.Write (writer, note.Data);
223
 
                Stream stream = WriterToStream (writer);
224
 
                writer.Close ();
225
 
 
226
 
                Logger.Log ("GetEntity: Returning Stream");
227
 
                return stream;
228
 
        }
229
 
 
230
 
        // Using UTF-16 does not work - the document is not processed.
231
 
        // Also, the byte order marker (BOM in short, locate at U+FEFF,
232
 
        // 0xef 0xbb 0xbf in UTF-8) must be included, otherwise parsing fails
233
 
        // as well. This way the buffer contains an exact representation of
234
 
        // the on-disk representation of notes.
235
 
        //
236
 
        // See http://en.wikipedia.org/wiki/Byte_Order_Mark for more
237
 
        // information about the BOM.
238
 
        MemoryStream WriterToStream (TextWriter writer)
239
 
        {
240
 
                UTF8Encoding encoding = new UTF8Encoding ();
241
 
                string s = writer.ToString ();
242
 
                int bytes_required = 3 + encoding.GetByteCount (s);
243
 
                byte[] buffer = new byte [bytes_required];
244
 
                buffer[0] = 0xef;
245
 
                buffer[1] = 0xbb;
246
 
                buffer[2] = 0xbf;
247
 
                encoding.GetBytes (s, 0, s.Length, buffer, 3);
248
 
                return new MemoryStream (buffer);
249
 
        }
250
 
 
251
 
        public override Uri ResolveUri (Uri baseUri, string relativeUri)
252
 
        {
253
 
                Note note = manager.Find (relativeUri);
254
 
                if (note != null)
255
 
                        return new Uri (note.Uri);
256
 
 
257
 
                return null;
258
 
        }
259
 
}
260
 
 
261
 
class ExportToHTMLDialog : Gtk.FileChooserDialog
262
 
{
263
 
        Gtk.CheckButton export_linked;
264
 
        Gtk.CheckButton export_linked_all;
265
 
 
266
 
        public ExportToHTMLDialog (string default_file) : 
267
 
                base (Catalog.GetString ("Destination for HTML Export"),
268
 
                          null, Gtk.FileChooserAction.Save, new object[] {})
269
 
        {
270
 
                AddButton (Gtk.Stock.Cancel, Gtk.ResponseType.Cancel);
271
 
                AddButton (Gtk.Stock.Save, Gtk.ResponseType.Ok);
272
 
                
273
 
                DefaultResponse = Gtk.ResponseType.Ok;
274
 
                
275
 
                Gtk.Table table = new Gtk.Table (2, 2, false);
276
 
                
277
 
                export_linked = new Gtk.CheckButton (Catalog.GetString ("Export linked notes"));
278
 
                export_linked.Toggled += OnExportLinkedToggled;
279
 
                table.Attach (export_linked, 0, 2, 0, 1, Gtk.AttachOptions.Fill, 0, 0, 0);
280
 
                
281
 
                export_linked_all =
282
 
                        new Gtk.CheckButton (Catalog.GetString ("Include all other linked notes"));
283
 
                table.Attach (export_linked_all,
284
 
                                1, 2, 1, 2, Gtk.AttachOptions.Expand | Gtk.AttachOptions.Fill, 0, 20, 0);
285
 
                
286
 
                ExtraWidget = table;
287
 
                
288
 
                DoOverwriteConfirmation = true;
289
 
                LocalOnly = true;
290
 
 
291
 
                ShowAll ();
292
 
                LoadPreferences (default_file);
293
 
        }
294
 
 
295
 
        public bool ExportLinked 
296
 
        {
297
 
                get { return export_linked.Active; }
298
 
                set { export_linked.Active = value; }
299
 
        }
300
 
        
301
 
        public bool ExportLinkedAll
302
 
        {
303
 
                get { return export_linked_all.Active; }
304
 
                set { export_linked_all.Active = value; }
305
 
        }
306
 
        
307
 
        public void SavePreferences () 
308
 
        {
309
 
                string dir = System.IO.Path.GetDirectoryName (Filename);
310
 
                Preferences.Set (Preferences.EXPORTHTML_LAST_DIRECTORY, dir);
311
 
 
312
 
                Preferences.Set (Preferences.EXPORTHTML_EXPORT_LINKED, ExportLinked);
313
 
                Preferences.Set (Preferences.EXPORTHTML_EXPORT_LINKED_ALL, ExportLinkedAll);
314
 
        }
315
 
        
316
 
        protected void LoadPreferences (string default_file) 
317
 
        {
318
 
                string last_dir = (string) Preferences.Get (Preferences.EXPORTHTML_LAST_DIRECTORY);
319
 
                if (last_dir == "")
320
 
                        last_dir = Environment.GetEnvironmentVariable ("HOME");
321
 
                SetCurrentFolder (last_dir);
322
 
                CurrentName = default_file;
323
 
 
324
 
                ExportLinked = (bool) Preferences.Get (Preferences.EXPORTHTML_EXPORT_LINKED);
325
 
                ExportLinkedAll = (bool) Preferences.Get (Preferences.EXPORTHTML_EXPORT_LINKED_ALL);
326
 
        }
327
 
        
328
 
        protected void OnExportLinkedToggled (object sender, EventArgs args)
329
 
        {
330
 
                if (export_linked.Active)
331
 
                        export_linked_all.Sensitive = true;
332
 
                else
333
 
                        export_linked_all.Sensitive = false;
334
 
        }
335
 
}