F-Spot Flickr plugin's welcome message uses improper punctuation. Fixed bug 606631.
[f-spot:mainline.git] / src / Extensions / Exporters / FSpot.Exporters.Flickr / FSpot.Exporters.Flickr / FlickrExport.cs
1 //
2 // FlickrExport.cs
3 //
4 // Author:
5 //   Lorenzo Milesi <maxxer@yetopen.it>
6 //   Stephane Delcroix <stephane@delcroix.org>
7 //   Stephen Shaw <sshaw@decriptor.com>
8 //
9 // Copyright (C) 2008-2009 Novell, Inc.
10 // Copyright (C) 2008-2009 Lorenzo Milesi
11 // Copyright (C) 2008-2009 Stephane Delcroix
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33 using System;
34 using System.Collections;
35 using System.Collections.Generic;
36 using System.IO;
37 using System.Threading;
38
39 using Mono.Unix;
40
41 using FlickrNet;
42
43 using FSpot;
44 using FSpot.Core;
45 using FSpot.Filters;
46 using FSpot.Widgets;
47 using FSpot.UI.Dialog;
48
49 using Hyena;
50 using Hyena.Widgets;
51
52
53 namespace FSpot.Exporters.Flickr
54 {
55         public class TwentyThreeHQExport : FlickrExport
56         {
57                 public override void Run (IBrowsableCollection selection)
58                 {
59                         Run (SupportedService.TwentyThreeHQ, selection, false);
60                 }
61         }
62
63         public class ZooomrExport : FlickrExport
64         {
65                 public override void Run (IBrowsableCollection selection)
66                 {
67                         Run (SupportedService.Zooomr, selection, false);
68                 }
69         }
70
71         public class FlickrExport : FSpot.Extensions.IExporter {
72                 IBrowsableCollection selection;
73
74                 [GtkBeans.Builder.Object] Gtk.Dialog         dialog;
75                 [GtkBeans.Builder.Object] Gtk.CheckButton    scale_check;
76                 [GtkBeans.Builder.Object] Gtk.CheckButton    tag_check;
77                 [GtkBeans.Builder.Object] Gtk.CheckButton    hierarchy_check;
78                 [GtkBeans.Builder.Object] Gtk.CheckButton    ignore_top_level_check;
79                 [GtkBeans.Builder.Object] Gtk.CheckButton    open_check;
80                 [GtkBeans.Builder.Object] Gtk.SpinButton     size_spin;
81                 [GtkBeans.Builder.Object] Gtk.ScrolledWindow thumb_scrolledwindow;
82                 [GtkBeans.Builder.Object] Gtk.Button         auth_flickr;
83                 [GtkBeans.Builder.Object] Gtk.ProgressBar    used_bandwidth;
84                 [GtkBeans.Builder.Object] Gtk.Button         do_export_flickr;
85                 [GtkBeans.Builder.Object] Gtk.Label          auth_label;
86                 [GtkBeans.Builder.Object] Gtk.RadioButton    public_radio;
87                 [GtkBeans.Builder.Object] Gtk.CheckButton    family_check;
88                 [GtkBeans.Builder.Object] Gtk.CheckButton    friend_check;
89
90                 private GtkBeans.Builder builder;
91                 private string dialog_name = "flickr_export_dialog";
92                 System.Threading.Thread command_thread;
93                 ThreadProgressDialog progress_dialog;
94                 ProgressItem progress_item;
95
96                 public const string EXPORT_SERVICE = "flickr/";
97                 public const string SCALE_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "scale";
98                 public const string SIZE_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "size";
99                 public const string BROWSER_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "browser";
100                 public const string TAGS_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "tags";
101                 public const string PUBLIC_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "public";
102                 public const string FAMILY_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "family";
103                 public const string FRIENDS_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "friends";
104                 public const string TAG_HIERARCHY_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "tag_hierarchy";
105                 public const string IGNORE_TOP_LEVEL_KEY = Preferences.APP_FSPOT_EXPORT + EXPORT_SERVICE + "ignore_top_level";
106
107                 bool open;
108                 bool scale;
109
110                 bool is_public;
111                 bool is_friend;
112                 bool is_family;
113
114                 string token;
115
116                 int photo_index;
117                 int size;
118                 Auth auth;
119
120                 FlickrRemote fr;
121                 private FlickrRemote.Service current_service;
122
123                 string auth_text;
124                 private State state;
125
126                 private enum State {
127                         Disconnected,
128                         Connected,
129                         InAuth,
130                         Authorized
131                 }
132
133                 private State CurrentState {
134                         get { return state; }
135                         set {
136                                 switch (value) {
137                                 case State.Disconnected:
138                                         auth_label.Text = auth_text;
139                                         auth_flickr.Sensitive = true;
140                                         do_export_flickr.Sensitive = false;
141                                         auth_flickr.Label = Catalog.GetString ("Authorize");
142                                         used_bandwidth.Visible = false;
143                                         break;
144                                 case State.Connected:
145                                         auth_flickr.Sensitive = true;
146                                         do_export_flickr.Sensitive = false;
147                                         auth_label.Text = string.Format (Catalog.GetString ("Return to this window after you have finished the authorization process on {0} and click the \"Complete Authorization\" button below"), current_service.Name);
148                                         auth_flickr.Label = Catalog.GetString ("Complete Authorization");
149                                         used_bandwidth.Visible = false;
150                                         break;
151                                 case State.InAuth:
152                                         auth_flickr.Sensitive = false;
153                                         auth_label.Text = string.Format (Catalog.GetString ("Logging into {0}"), current_service.Name);
154                                         auth_flickr.Label = Catalog.GetString ("Checking credentials...");
155                                         do_export_flickr.Sensitive = false;
156                                         used_bandwidth.Visible = false;
157                                         break;
158                                 case State.Authorized:
159                                         do_export_flickr.Sensitive = true;
160                                         auth_flickr.Sensitive = true;
161                                         auth_label.Text = System.String.Format (Catalog.GetString ("Welcome, {0}. You are connected to {1}."),
162                                                                                 auth.User.Username,
163                                                                                 current_service.Name);
164                                         auth_flickr.Label = String.Format (Catalog.GetString ("Sign in as a different user"), auth.User.Username);
165                                         used_bandwidth.Visible = !fr.Connection.PeopleGetUploadStatus().IsPro &&
166                                                                         fr.Connection.PeopleGetUploadStatus().BandwidthMax > 0;
167                                         if (used_bandwidth.Visible) {
168                                                 used_bandwidth.Fraction = fr.Connection.PeopleGetUploadStatus().PercentageUsed;
169                                                 used_bandwidth.Text = string.Format (Catalog.GetString("Used {0} of your allowed {1} monthly quota"),
170                                                                         GLib.Format.SizeForDisplay (fr.Connection.PeopleGetUploadStatus().BandwidthUsed),
171                                                                         GLib.Format.SizeForDisplay (fr.Connection.PeopleGetUploadStatus().BandwidthMax));
172                                         }
173                                         break;
174                                 }
175                                 state = value;
176                         }
177                 }
178
179                 public FlickrExport (IBrowsableCollection selection, bool display_tags) :
180                         this (SupportedService.Flickr, selection, display_tags)
181                 { }
182
183
184                 public FlickrExport (SupportedService service, IBrowsableCollection selection, bool display_tags) : this ()
185                 {
186                         Run (service, selection, display_tags);
187                 }
188
189                 public FlickrExport ()
190                 {
191
192                 }
193
194                 public virtual void Run (IBrowsableCollection selection)
195                 {
196                         Run (SupportedService.Flickr, selection, false);
197                 }
198
199                 public void Run (SupportedService service, IBrowsableCollection selection, bool display_tags)
200                 {
201                         this.selection = selection;
202                         this.current_service = FlickrRemote.Service.FromSupported (service);
203
204                         var view = new TrayView (selection);
205                         view.DisplayTags = display_tags;
206                         view.DisplayDates = false;
207
208                         builder = new GtkBeans.Builder (null, "flickr_export.ui", null);
209                         builder.Autoconnect (this);
210
211                         Dialog.Modal = false;
212                         Dialog.TransientFor = null;
213
214                         thumb_scrolledwindow.Add (view);
215                         HandleSizeActive (null, null);
216
217                         public_radio.Toggled += HandlePublicChanged;
218                         tag_check.Toggled += HandleTagChanged;
219                         hierarchy_check.Toggled += HandleHierarchyChanged;
220                         HandleTagChanged (null, null);
221                         HandleHierarchyChanged (null, null);
222
223                         Dialog.ShowAll ();
224                         Dialog.Response += HandleResponse;
225                         auth_flickr.Clicked += HandleClicked;
226                         auth_text = string.Format (auth_label.Text, current_service.Name);
227                         auth_label.Text = auth_text;
228                         used_bandwidth.Visible = false;
229
230                         LoadPreference (SCALE_KEY);
231                         LoadPreference (SIZE_KEY);
232                         LoadPreference (BROWSER_KEY);
233                         LoadPreference (TAGS_KEY);
234                         LoadPreference (TAG_HIERARCHY_KEY);
235                         LoadPreference (IGNORE_TOP_LEVEL_KEY);
236                         LoadPreference (PUBLIC_KEY);
237                         LoadPreference (FAMILY_KEY);
238                         LoadPreference (FRIENDS_KEY);
239                         LoadPreference (current_service.PreferencePath);
240
241                         do_export_flickr.Sensitive = false;
242                         fr = new FlickrRemote (token, current_service);
243                         if (token != null && token.Length > 0) {
244                                 StartAuth ();
245                         }
246                 }
247
248                 public bool StartAuth ()
249                 {
250                         CurrentState = State.InAuth;
251                         if (command_thread == null || ! command_thread.IsAlive) {
252                                 command_thread = new Thread (new ThreadStart (CheckAuthorization));
253                                 command_thread.Start ();
254                         }
255                         return true;
256                 }
257
258                 public void CheckAuthorization ()
259                 {
260                         AuthorizationEventArgs args = new AuthorizationEventArgs ();
261
262                         try {
263                                 args.Auth = fr.CheckLogin ();
264                         } catch (FlickrException e) {
265                                 args.Exception = e;
266                         } catch (Exception e) {
267                                 HigMessageDialog md =
268                                         new HigMessageDialog (Dialog,
269                                                               Gtk.DialogFlags.Modal |
270                                                               Gtk.DialogFlags.DestroyWithParent,
271                                                               Gtk.MessageType.Error, Gtk.ButtonsType.Ok,
272                                                               Catalog.GetString ("Unable to log on"), e.Message);
273
274                                 md.Run ();
275                                 md.Destroy ();
276                                 return;
277                         }
278
279                         ThreadAssist.ProxyToMain (() => {
280                                 do_export_flickr.Sensitive = args.Auth != null;
281                                 if (args.Auth != null) {
282                                         token = args.Auth.Token;
283                                         auth = args.Auth;
284                                         CurrentState = State.Authorized;
285                                         Preferences.Set (current_service.PreferencePath, token);
286                                 } else {
287                                         CurrentState = State.Disconnected;
288                                 }
289                         });
290                 }
291
292                 private class AuthorizationEventArgs : System.EventArgs {
293                         Exception e;
294                         Auth auth;
295
296                         public Exception Exception {
297                                 get { return e; }
298                                 set { e = value; }
299                         }
300
301                         public Auth Auth {
302                                 get { return auth; }
303                                 set { auth = value; }
304                         }
305
306                         public AuthorizationEventArgs ()
307                         {
308                         }
309                 }
310
311                 public void HandleSizeActive (object sender, System.EventArgs args)
312                 {
313                         size_spin.Sensitive = scale_check.Active;
314                 }
315
316                 private void Logout ()
317                 {
318                         token = null;
319                         auth = null;
320                         fr = new FlickrRemote (token, current_service);
321                         Preferences.Set (current_service.PreferencePath, String.Empty);
322                         CurrentState = State.Disconnected;
323                 }
324
325                 private void Login ()
326                 {
327                         try {
328                                 fr = new FlickrRemote (token, current_service);
329                                 fr.TryWebLogin();
330                                 CurrentState = State.Connected;
331                         } catch (Exception e) {
332                                 if (e is FlickrApiException && (e as FlickrApiException).Code == 98) {
333                                         Logout ();
334                                         Login ();
335                                 } else {
336                                         HigMessageDialog md =
337                                                 new HigMessageDialog (Dialog,
338                                                                       Gtk.DialogFlags.Modal |
339                                                                       Gtk.DialogFlags.DestroyWithParent,
340                                                                       Gtk.MessageType.Error, Gtk.ButtonsType.Ok,
341                                                                       Catalog.GetString ("Unable to log on"), e.Message);
342
343                                         md.Run ();
344                                         md.Destroy ();
345                                         CurrentState = State.Disconnected;
346                                 }
347                         }
348                 }
349
350                 private void HandleProgressChanged (ProgressItem item)
351                 {
352                         //System.Console.WriteLine ("Changed value = {0}", item.Value);
353                         progress_dialog.Fraction = (photo_index - 1.0 + item.Value) / (double) selection.Count;
354                 }
355
356                 FileInfo info;
357                 private void HandleFlickrProgress (object sender, UploadProgressEventArgs args)
358                 {
359                         if (args.UploadComplete) {
360                                 progress_dialog.Fraction = photo_index / (double) selection.Count;
361                                 progress_dialog.ProgressText = String.Format (Catalog.GetString ("Waiting for response {0} of {1}"),
362                                                                               photo_index, selection.Count);
363                         }
364                         progress_dialog.Fraction = (photo_index - 1.0 + (args.Bytes / (double) info.Length)) / (double) selection.Count;
365                 }
366
367                 private class DateComparer : IComparer
368                 {
369                         public int Compare (object left, object right)
370                         {
371                                 return DateTime.Compare ((left as IPhoto).Time, (right as IPhoto).Time);
372                         }
373                 }
374
375                 private void Upload () {
376                         progress_item = new ProgressItem ();
377                         progress_item.Changed += HandleProgressChanged;
378                         fr.Connection.OnUploadProgress += HandleFlickrProgress;
379
380                         List<string> ids = new List<string> ();
381                         IPhoto [] photos = selection.Items;
382                         Array.Sort (photos, new DateComparer ());
383
384                         for (int index = 0; index < photos.Length; index++) {
385                                 try {
386                                         IPhoto photo = photos [index];
387                                         progress_dialog.Message = System.String.Format (
388                                                 Catalog.GetString ("Uploading picture \"{0}\""), photo.Name);
389
390                                         progress_dialog.Fraction = photo_index / (double)selection.Count;
391                                         photo_index++;
392                                         progress_dialog.ProgressText = System.String.Format (
393                                                 Catalog.GetString ("{0} of {1}"), photo_index,
394                                                 selection.Count);
395
396                                         info = new FileInfo (photo.DefaultVersion.Uri.LocalPath);
397                                         FilterSet stack = new FilterSet ();
398                                         if (scale)
399                                                 stack.Add (new ResizeFilter ((uint)size));
400
401                                         string id = fr.Upload (photo, stack, is_public, is_family, is_friend);
402                                         ids.Add (id);
403
404                                         if (App.Instance.Database != null && photo is FSpot.Photo)
405                                                 App.Instance.Database.Exports.Create ((photo as FSpot.Photo).Id,
406                                                                               (photo as FSpot.Photo).DefaultVersionId,
407                                                                               ExportStore.FlickrExportType,
408                                                                               auth.User.UserId + ":" + auth.User.Username + ":" + current_service.Name + ":" + id);
409
410                                 } catch (System.Exception e) {
411                                         progress_dialog.Message = String.Format (Catalog.GetString ("Error Uploading To {0}: {1}"),
412                                                                                  current_service.Name,
413                                                                                  e.Message);
414                                         progress_dialog.ProgressText = Catalog.GetString ("Error");
415                                         Log.Exception (e);
416
417                                         if (progress_dialog.PerformRetrySkip ()) {
418                                                 index--;
419                                                 photo_index--;
420                                         }
421                                 }
422                         }
423                         progress_dialog.Message = Catalog.GetString ("Done Sending Photos");
424                         progress_dialog.Fraction = 1.0;
425                         progress_dialog.ProgressText = Catalog.GetString ("Upload Complete");
426                         progress_dialog.ButtonLabel = Gtk.Stock.Ok;
427
428                         if (open && ids.Count != 0) {
429                                 string view_url;
430                                 if (current_service.Name == "Zooomr.com")
431                                         view_url = string.Format ("http://www.{0}/photos/{1}/", current_service.Name, auth.User.Username);
432                                 else {
433                                         view_url = string.Format ("http://www.{0}/tools/uploader_edit.gne?ids", current_service.Name);
434                                         bool first = true;
435
436                                         foreach (string id in ids) {
437                                                 view_url = view_url + (first ? "=" : ",") + id;
438                                                 first = false;
439                                         }
440                                 }
441
442                                 GtkBeans.Global.ShowUri (Dialog.Screen, view_url);
443                         }
444                 }
445
446                 private void HandleClicked (object sender, System.EventArgs args)
447                 {
448                         switch (CurrentState) {
449                         case State.Disconnected:
450                                 Login ();
451                                 break;
452                         case State.Connected:
453                                 StartAuth ();
454                                 break;
455                         case State.InAuth:
456                                 break;
457                         case State.Authorized:
458                                 Logout ();
459                                 Login ();
460                                 break;
461                         }
462                 }
463
464                 private void HandlePublicChanged (object sender, EventArgs args)
465                 {
466                         bool sensitive = ! public_radio.Active;
467                         friend_check.Sensitive = sensitive;
468                         family_check.Sensitive = sensitive;
469                 }
470
471                 private void HandleTagChanged (object sender, EventArgs args)
472                 {
473                         hierarchy_check.Sensitive = tag_check.Active;
474                 }
475
476                 private void HandleHierarchyChanged (object sender, EventArgs args)
477                 {
478                         ignore_top_level_check.Sensitive = hierarchy_check.Active;
479                 }
480
481                 private void HandleResponse (object sender, Gtk.ResponseArgs args)
482                 {
483                         if (args.ResponseId != Gtk.ResponseType.Ok) {
484                                 if (command_thread != null && command_thread.IsAlive)
485                                         command_thread.Abort ();
486
487                                 Dialog.Destroy ();
488                                 return;
489                         }
490
491                         if (fr.CheckLogin() == null) {
492                                 do_export_flickr.Sensitive = false;
493                                 HigMessageDialog md =
494                                         new HigMessageDialog (Dialog,
495                                                               Gtk.DialogFlags.Modal |
496                                                               Gtk.DialogFlags.DestroyWithParent,
497                                                               Gtk.MessageType.Error, Gtk.ButtonsType.Ok,
498                                                               Catalog.GetString ("Unable to log on."),
499                                                               string.Format (Catalog.GetString ("F-Spot was unable to log on to {0}.  Make sure you have given the authentication using {0} web browser interface."),
500                                                                              current_service.Name));
501                                 md.Run ();
502                                 md.Destroy ();
503                                 return;
504                         }
505
506                         fr.ExportTags = tag_check.Active;
507                         fr.ExportTagHierarchy = hierarchy_check.Active;
508                         fr.ExportIgnoreTopLevel = ignore_top_level_check.Active;
509                         open = open_check.Active;
510                         scale = scale_check.Active;
511                         is_public = public_radio.Active;
512                         is_family = family_check.Active;
513                         is_friend = friend_check.Active;
514                         if (scale)
515                                 size = size_spin.ValueAsInt;
516
517                         command_thread = new Thread (new ThreadStart (Upload));
518                         command_thread.Name = Catalog.GetString ("Uploading Pictures");
519
520                         Dialog.Destroy ();
521                         progress_dialog = new ThreadProgressDialog (command_thread, selection.Count);
522                         progress_dialog.Start ();
523
524                         // Save these settings for next time
525                         Preferences.Set (SCALE_KEY, scale);
526                         Preferences.Set (SIZE_KEY, size);
527                         Preferences.Set (BROWSER_KEY, open);
528                         Preferences.Set (TAGS_KEY, tag_check.Active);
529                         Preferences.Set (PUBLIC_KEY, public_radio.Active);
530                         Preferences.Set (FAMILY_KEY, family_check.Active);
531                         Preferences.Set (FRIENDS_KEY, friend_check.Active);
532                         Preferences.Set (TAG_HIERARCHY_KEY, hierarchy_check.Active);
533                         Preferences.Set (IGNORE_TOP_LEVEL_KEY, ignore_top_level_check.Active);
534                         Preferences.Set (current_service.PreferencePath, fr.Token);
535                 }
536
537                 void LoadPreference (string key)
538                 {
539                         switch (key) {
540                         case SCALE_KEY:
541                                 if (scale_check.Active != Preferences.Get<bool> (key))
542                                         scale_check.Active = Preferences.Get<bool> (key);
543                                 break;
544                                 
545                         case SIZE_KEY:
546                                 size_spin.Value = (double) Preferences.Get<int> (key);
547                                 break;
548                                 
549                         case BROWSER_KEY:
550                                 if (open_check.Active != Preferences.Get<bool> (key))
551                                         open_check.Active = Preferences.Get<bool> (key);
552                                 break;
553                                 
554                         case TAGS_KEY:
555                                 if (tag_check.Active != Preferences.Get<bool> (key))
556                                         tag_check.Active = Preferences.Get<bool> (key);
557                                 break;
558                                 
559                         case TAG_HIERARCHY_KEY:
560                                 if (hierarchy_check.Active != Preferences.Get<bool> (key))
561                                         hierarchy_check.Active = Preferences.Get<bool> (key);
562                                 break;
563                                 
564                         case IGNORE_TOP_LEVEL_KEY:
565                                 if (ignore_top_level_check.Active != Preferences.Get<bool> (key))
566                                         ignore_top_level_check.Active = Preferences.Get<bool> (key);
567                                 break;
568
569                         case FlickrRemote.TOKEN_FLICKR:
570                         case FlickrRemote.TOKEN_23HQ:
571                         case FlickrRemote.TOKEN_ZOOOMR:
572                                 token = Preferences.Get<string> (key);
573                                 break;
574                                 
575                         case PUBLIC_KEY:
576                                 if (public_radio.Active != Preferences.Get<bool> (key))
577                                         public_radio.Active = Preferences.Get<bool> (key);
578                                 break;
579                                 
580                         case FAMILY_KEY:
581                                 if (family_check.Active != Preferences.Get<bool> (key))
582                                         family_check.Active = Preferences.Get<bool> (key);
583                                 break;
584                                 
585                         case FRIENDS_KEY:
586                                 if (friend_check.Active != Preferences.Get<bool> (key))
587                                         friend_check.Active = Preferences.Get<bool> (key);
588                                 break;
589                                 /*
590                         case Preferences.EXPORT_FLICKR_EMAIL:
591
592                                 /*
593                         case Preferences.EXPORT_FLICKR_EMAIL:
594                                 email_entry.Text = (string) val;
595                                 break;
596                                 */
597                         }
598                 }
599
600                 private Gtk.Dialog Dialog {
601                         get {
602                                 if (dialog == null)
603                                         dialog = new Gtk.Dialog (builder.GetRawObject (dialog_name));
604
605                                 return dialog;
606                         }
607                 }
608         }
609 }