2008-03-27 Carlos Alberto Cortez <calberto.cortez@gmail.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / WebBrowser.cs
1 // Permission is hereby granted, free of charge, to any person obtaining\r
2 // a copy of this software and associated documentation files (the\r
3 // "Software"), to deal in the Software without restriction, including\r
4 // without limitation the rights to use, copy, modify, merge, publish,\r
5 // distribute, sublicense, and/or sell copies of the Software, and to\r
6 // permit persons to whom the Software is furnished to do so, subject to\r
7 // the following conditions:\r
8 // \r
9 // The above copyright notice and this permission notice shall be\r
10 // included in all copies or substantial portions of the Software.\r
11 // \r
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
19 //\r
20 // Copyright (c) 2007, 2008 Novell, Inc.\r
21 //\r
22 // Authors:\r
23 //      Andreia Gaita   <avidigal@novell.com>\r
24
25 #if NET_2_0\r
26 \r
27 using System;\r
28 using System.ComponentModel;\r
29 using System.Runtime.InteropServices;\r
30 using System.Windows.Forms;\r
31 using System.IO;\r
32 using System.Drawing;\r
33 \r
34 namespace System.Windows.Forms\r
35 {\r
36         [MonoTODO ("Needs Implementation")]\r
37         [ClassInterface (ClassInterfaceType.AutoDispatch)]\r
38     [ComVisible(true)]\r
39     [Designer("System.Windows.Forms.Design.WebBrowserBaseDesigner, " + Consts.AssemblySystem_Design, \r
40                 "System.ComponentModel.Design.IDesigner")]\r
41     public class WebBrowser : WebBrowserBase\r
42     {
43                 private bool allowNavigation;\r
44                 private bool allowWebBrowserDrop;\r
45                 private bool isWebBrowserContextMenuEnabled;\r
46                 private object objectForScripting;\r
47                 private bool scriptErrorsSuppressed;\r
48                 private bool scrollBarsEnabled;\r
49                 private string statusText;\r
50                 private bool webBrowserShortcutsEnabled;\r
51 \r
52                 private HtmlDocument document;\r
53 \r
54                 #region Public Properties\r
55 \r
56                 [MonoTODO ("Stub, not implemented")]\r
57                 [DefaultValue(true)]\r
58                 public bool AllowNavigation {\r
59                         get { return allowNavigation; }\r
60                         set { allowNavigation = value; } \r
61                 }\r
62 \r
63                 [MonoTODO ("Stub, not implemented")]\r
64                 [DefaultValue (true)]\r
65                 public bool AllowWebBrowserDrop {\r
66                         get { return allowWebBrowserDrop; }\r
67                         set { allowWebBrowserDrop = value; }\r
68                 }\r
69 \r
70                 [BrowsableAttribute(false)]\r
71                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
72                 public bool CanGoBack {\r
73                         get { return this.WebHost.Navigation.CanGoBack; }\r
74                 }\r
75 \r
76                 [BrowsableAttribute(false)]\r
77                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
78                 public bool CanGoForward {\r
79                         get { return this.WebHost.Navigation.CanGoForward; }\r
80                 }\r
81 \r
82                 [BrowsableAttribute(false)]\r
83                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
84                 public HtmlDocument Document {\r
85                         get {\r
86                                 if (document == null && documentReady)\r
87                                         document = new HtmlDocument (this.WebHost);
88                                 return document; \r
89                         }\r
90                 }\r
91 \r
92                 [MonoTODO ("Stub, not implemented")]\r
93                 [BrowsableAttribute(false)]\r
94                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
95                 public Stream DocumentStream {\r
96                         get { return null; }\r
97                         set {  }\r
98                 }\r
99 \r
100                 [MonoTODO ("Stub, not implemented")]\r
101                 [BrowsableAttribute(false)]\r
102                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
103                 public string DocumentText {\r
104                         get { return String.Empty; }\r
105                         set { throw new NotSupportedException (); }\r
106                 }\r
107 \r
108                 [BrowsableAttribute(false)]\r
109                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
110                 public string DocumentTitle {\r
111                         get { return document.Title; }\r
112                         private set { document.Title = value; }\r
113                 }\r
114 \r
115                 [MonoTODO ("Stub, not implemented")]\r
116                 [BrowsableAttribute(false)]\r
117                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
118                 public string DocumentType {\r
119                         get { return String.Empty; }\r
120                 }\r
121 \r
122                 [MonoTODO ("Stub, not implemented")]\r
123                 [BrowsableAttribute(false)]\r
124                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
125                 public WebBrowserEncryptionLevel EncryptionLevel {\r
126                         get { return WebBrowserEncryptionLevel.Unknown; }\r
127                 }\r
128 \r
129                 [MonoTODO ("Stub, not implemented")]\r
130                 public override bool Focused {\r
131                         get { return base.Focused; }\r
132                 }\r
133 \r
134                 [MonoTODO ("Stub, not implemented")]\r
135                 [BrowsableAttribute(false)]\r
136                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
137                 public bool IsBusy {\r
138                         get { return false; }\r
139                 }\r
140 \r
141                 [MonoTODO ("Stub, not implemented")]\r
142                 [BrowsableAttribute(false)]\r
143                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
144                 public bool IsOffline {\r
145                         get { return true; }\r
146                 }\r
147 \r
148                 [MonoTODO ("Stub, not implemented")]\r
149                 [DefaultValue(true)]\r
150                 public bool IsWebBrowserContextMenuEnabled { \r
151                         get { return isWebBrowserContextMenuEnabled; } \r
152                         set { isWebBrowserContextMenuEnabled = value; } \r
153                 }\r
154 \r
155                 [MonoTODO ("Stub, not implemented")]\r
156                 [BrowsableAttribute(false)]\r
157                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
158                 public object ObjectForScripting {\r
159                         get { return objectForScripting; }\r
160                         set { objectForScripting = value; }\r
161                 }\r
162 \r
163                 [MonoTODO ("Stub, not implemented")]\r
164                 [BrowsableAttribute(false)]\r
165                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
166                 public WebBrowserReadyState ReadyState { \r
167                         get { return WebBrowserReadyState.Uninitialized; }\r
168                 }\r
169 \r
170                 [MonoTODO ("Stub, not implemented")]\r
171                 [DefaultValue(false)]\r
172                 public bool ScriptErrorsSuppressed {\r
173                         get { return scriptErrorsSuppressed; }\r
174                         set { scriptErrorsSuppressed = value; }\r
175                 }\r
176 \r
177                 [MonoTODO ("Stub, not implemented")]\r
178                 [DefaultValue(true)]\r
179                 public bool ScrollBarsEnabled {\r
180                         get { return scrollBarsEnabled; }\r
181                         set { scrollBarsEnabled = value; }\r
182                 }\r
183 \r
184                 [MonoTODO ("Stub, not implemented")]\r
185                 [BrowsableAttribute(false)]\r
186                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
187                 public virtual string StatusText {\r
188                         get { return statusText; }\r
189                 }\r
190 \r
191                 [BindableAttribute(true)] \r
192                 [DefaultValue(null)]\r
193                 [TypeConverter(typeof(UriTypeConverter))]\r
194                 public Uri Url {\r
195                         get { return new Uri(WebHost.Document.Url); }\r
196                         set { this.Navigate (value); }\r
197                 }\r
198 \r
199                 [MonoTODO ("Stub, not implemented")]\r
200                 [BrowsableAttribute(false)]\r
201                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
202                 public Version Version {\r
203                         get { return null; }\r
204                 }\r
205 \r
206                 [MonoTODO ("Stub, not implemented")]\r
207                 [DefaultValue(true)]\r
208                 public bool WebBrowserShortcutsEnabled {\r
209                         get { return webBrowserShortcutsEnabled; }\r
210                         set { webBrowserShortcutsEnabled = value; }\r
211                 }\r
212                 \r
213                 protected override Size DefaultSize {\r
214                         get {return base.DefaultSize;}\r
215                 }\r
216 \r
217                 \r
218                 [BrowsableAttribute(false)]\r
219                 [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Hidden)]\r
220                 [EditorBrowsable (EditorBrowsableState.Never)]\r
221                 public new Padding Padding {\r
222                         get {return base.Padding;}\r
223                         set {base.Padding = value; }\r
224                 }\r
225                 \r
226                 #endregion\r
227 \r
228                 [MonoTODO ("Stub, not implemented")]\r
229                 public WebBrowser ()\r
230                 {\r
231                 }\r
232 \r
233                 #region Public Methods\r
234 \r
235                 public bool GoBack ()\r
236                 {\r
237                         documentReady = false;\r
238                         document = null;\r
239                         return WebHost.Navigation.Back ();\r
240                 }\r
241 \r
242                 public bool GoForward ()\r
243                 {\r
244                         documentReady = false;\r
245                         document = null;\r
246                         return WebHost.Navigation.Forward ();\r
247                 }\r
248 \r
249                 public void GoHome ()\r
250                 {\r
251                         documentReady = false;\r
252                         document = null;\r
253                         WebHost.Navigation.Home ();\r
254                 }\r
255 \r
256                 public void Navigate (string urlString)\r
257                 {\r
258                         documentReady = false;\r
259                         document = null;\r
260                         WebHost.Navigation.Go (urlString);\r
261                 }\r
262 \r
263                 public void Navigate (Uri url)\r
264                 {\r
265                         documentReady = false;\r
266                         document = null;\r
267                         WebHost.Navigation.Go (url.ToString ());\r
268                 }\r
269 \r
270                 public void Navigate (string urlString, bool newWindow)\r
271                 {\r
272                         documentReady = false;\r
273                         document = null;\r
274                         WebHost.Navigation.Go (urlString);\r
275                 }\r
276 \r
277                 public void Navigate (string urlString, string targetFrameName)\r
278                 {\r
279                         documentReady = false;\r
280                         document = null;\r
281                         WebHost.Navigation.Go (urlString);\r
282                 }\r
283 \r
284                 public void Navigate (Uri url, bool newWindow)\r
285                 {\r
286                         documentReady = false;\r
287                         document = null;\r
288                         WebHost.Navigation.Go (url.ToString ());\r
289                 }\r
290 \r
291                 public void Navigate (Uri url, string targetFrameName)\r
292                 {\r
293                         documentReady = false;\r
294                         document = null;\r
295                         WebHost.Navigation.Go (url.ToString ());\r
296                 }\r
297 \r
298                 public void Navigate (string urlString, string targetFrameName, byte[] postData, string additionalHeaders)\r
299                 {\r
300                         documentReady = false;\r
301                         document = null;\r
302                         WebHost.Navigation.Go (urlString);\r
303                 }\r
304 \r
305                 public void Navigate (Uri url, string targetFrameName, byte[] postData, string additionalHeaders)\r
306                 {\r
307                         documentReady = false;\r
308                         document = null;\r
309                         WebHost.Navigation.Go (url.ToString ());\r
310                 }\r
311 \r
312                 public override void Refresh ()\r
313                 {\r
314                         Refresh (WebBrowserRefreshOption.IfExpired);\r
315                 }\r
316 \r
317                 public void Refresh (WebBrowserRefreshOption opt)\r
318                 {\r
319                         documentReady = false;\r
320                         document = null;\r
321                         switch (opt) {\r
322                                 case WebBrowserRefreshOption.Normal:\r
323                                         WebHost.Navigation.Reload (Mono.WebBrowser.ReloadOption.Proxy);\r
324                                         break;\r
325                                 case WebBrowserRefreshOption.IfExpired:\r
326                                         WebHost.Navigation.Reload (Mono.WebBrowser.ReloadOption.None);\r
327                                         break;\r
328                                 case WebBrowserRefreshOption.Completely:\r
329                                         WebHost.Navigation.Reload (Mono.WebBrowser.ReloadOption.Full);\r
330                                         break;\r
331                         }\r
332                 }\r
333 \r
334                 public void Stop ()\r
335                 {\r
336                         WebHost.Navigation.Stop ();\r
337                 }\r
338 \r
339                 public void GoSearch ()\r
340                 {\r
341                         throw new NotImplementedException ();\r
342                 }\r
343 \r
344                 public void Print ()\r
345                 {\r
346                         throw new NotImplementedException ();\r
347                 }\r
348 \r
349                 public void ShowPageSetupDialog ()\r
350                 {\r
351                         throw new NotImplementedException ();\r
352                 }\r
353 \r
354                 public void ShowPrintDialog()\r
355                 {\r
356                         throw new NotImplementedException ();\r
357                 }\r
358                 \r
359                 public void ShowPrintPreviewDialog()\r
360                 {\r
361                         throw new NotImplementedException ();\r
362                 }\r
363                 \r
364                 public void ShowPropertiesDialog()\r
365                 {\r
366                         throw new NotImplementedException ();\r
367                 }\r
368                 \r
369                 public void ShowSaveAsDialog()\r
370                 {\r
371                         throw new NotImplementedException ();\r
372                 }\r
373 \r
374                 #endregion\r
375 \r
376 \r
377                 #region Protected Overridden Methods\r
378                 [MonoTODO ("Stub, not implemented")]\r
379                 protected override void AttachInterfaces (object nativeActiveXObject)\r
380                 {\r
381                         base.AttachInterfaces (nativeActiveXObject);\r
382                 }\r
383 \r
384                 [MonoTODO ("Stub, not implemented")]\r
385                 protected override void CreateSink ()\r
386                 {\r
387                         base.CreateSink ();\r
388                 }\r
389 \r
390                 [MonoTODO ("Stub, not implemented")]\r
391                 protected override WebBrowserSiteBase CreateWebBrowserSiteBase ()\r
392                 {\r
393                         return base.CreateWebBrowserSiteBase ();\r
394                 }\r
395 \r
396                 [MonoTODO ("Stub, not implemented")]\r
397                 protected override void DetachInterfaces ()\r
398                 {\r
399                         base.DetachInterfaces ();\r
400                 }\r
401 \r
402                 [MonoTODO ("Stub, not implemented")]\r
403                 protected override void DetachSink ()\r
404                 {\r
405                         base.DetachSink ();\r
406                 }\r
407 \r
408                 [MonoTODO ("Stub, not implemented")]\r
409                 protected override void Dispose (bool disposing)\r
410                 {\r
411                         base.Dispose (disposing);\r
412                 }\r
413 \r
414                 [MonoTODO ("Stub, not implemented")]\r
415                 protected override void WndProc (ref Message m)\r
416                 {\r
417                         base.WndProc (ref m);\r
418                 }\r
419                 #endregion\r
420 \r
421                 #region OnXXX methods\r
422                 protected virtual void OnCanGoBackChanged(EventArgs e)\r
423                 {\r
424                         EventHandler eh = (EventHandler)(Events [CanGoBackChangedEvent]);\r
425                         if (eh != null)\r
426                                 eh (this, e);\r
427                 }\r
428 \r
429                 protected virtual void OnCanGoForwardChanged(EventArgs e)\r
430                 {\r
431                         EventHandler eh = (EventHandler)(Events [CanGoForwardChangedEvent]);\r
432                         if (eh != null)\r
433                                 eh (this, e);\r
434                 }\r
435 \r
436                 protected virtual void OnDocumentCompleted(WebBrowserDocumentCompletedEventArgs e)\r
437                 {\r
438                         WebBrowserDocumentCompletedEventHandler eh = (WebBrowserDocumentCompletedEventHandler)(Events [DocumentCompletedEvent]);\r
439                         if (eh != null)\r
440                                 eh (this, e);\r
441                 }\r
442 \r
443                 protected virtual void OnDocumentTitleChanged(EventArgs e)\r
444                 {\r
445                         EventHandler eh = (EventHandler)(Events [DocumentTitleChangedEvent]);\r
446                         if (eh != null)\r
447                                 eh (this, e);\r
448                 }\r
449 \r
450                 protected virtual void OnEncryptionLevelChanged(EventArgs e)\r
451                 {\r
452                         EventHandler eh = (EventHandler)(Events [EncryptionLevelChangedEvent]);\r
453                         if (eh != null)\r
454                                 eh (this, e);\r
455                 }\r
456 \r
457                 protected virtual void OnFileDownload(EventArgs e)\r
458                 {\r
459                         EventHandler eh = (EventHandler)(Events [FileDownloadEvent]);\r
460                         if (eh != null)\r
461                                 eh (this, e);\r
462                 }\r
463 \r
464                 protected virtual void OnNavigated(WebBrowserNavigatedEventArgs e)\r
465                 {\r
466                         WebBrowserNavigatedEventHandler eh = (WebBrowserNavigatedEventHandler)(Events [NavigatedEvent]);\r
467                         if (eh != null)\r
468                                 eh (this, e);\r
469                 }\r
470 \r
471                 protected virtual void OnNavigating(WebBrowserNavigatingEventArgs e)\r
472                 {\r
473                         WebBrowserNavigatingEventHandler eh = (WebBrowserNavigatingEventHandler)(Events [NavigatingEvent]);\r
474                         if (eh != null)\r
475                                 eh (this, e);\r
476                 }\r
477 \r
478                 protected virtual void OnNewWindow(CancelEventArgs e)\r
479                 {\r
480                         CancelEventHandler eh = (CancelEventHandler)(Events [NewWindowEvent]);\r
481                         if (eh != null)\r
482                                 eh (this, e);\r
483                 }\r
484 \r
485                 protected virtual void OnProgressChanged(WebBrowserProgressChangedEventArgs e)\r
486                 {\r
487                         WebBrowserProgressChangedEventHandler eh = (WebBrowserProgressChangedEventHandler)(Events [ProgressChangedEvent]);\r
488                         if (eh != null)\r
489                                 eh (this, e);\r
490                 }\r
491 \r
492                 protected virtual void OnStatusTextChanged(EventArgs e)\r
493                 {\r
494                         EventHandler eh = (EventHandler)(Events [StatusTextChangedEvent]);\r
495                         if (eh != null)\r
496                                 eh (this, e);\r
497                 }\r
498                 #endregion\r
499 \r
500                 #region Events\r
501                 static object CanGoBackChangedEvent = new object ();\r
502                 static object CanGoForwardChangedEvent = new object ();\r
503                 static object DocumentCompletedEvent = new object ();\r
504                 static object DocumentTitleChangedEvent = new object ();\r
505                 static object EncryptionLevelChangedEvent = new object ();\r
506                 static object FileDownloadEvent = new object ();\r
507                 static object NavigatedEvent = new object ();\r
508                 static object NavigatingEvent = new object ();\r
509                 static object NewWindowEvent = new object ();\r
510                 static object ProgressChangedEvent = new object ();\r
511                 static object StatusTextChangedEvent = new object ();\r
512                 \r
513                 [BrowsableAttribute(false)]\r
514                 public event EventHandler CanGoBackChanged {\r
515                         add { Events.AddHandler (CanGoBackChangedEvent, value); }\r
516                         remove { Events.RemoveHandler (CanGoBackChangedEvent, value); }\r
517                 }\r
518 \r
519                 [BrowsableAttribute(false)]\r
520                 public event EventHandler CanGoForwardChanged {\r
521                         add { Events.AddHandler (CanGoForwardChangedEvent, value); }\r
522                         remove { Events.RemoveHandler (CanGoForwardChangedEvent, value); }\r
523                 }\r
524 \r
525                 public event WebBrowserDocumentCompletedEventHandler DocumentCompleted {\r
526                         add { Events.AddHandler (DocumentCompletedEvent, value); }\r
527                         remove { Events.RemoveHandler (DocumentCompletedEvent, value); }\r
528                 }\r
529 \r
530                 [BrowsableAttribute(false)]\r
531                 public event EventHandler DocumentTitleChanged {\r
532                         add { Events.AddHandler (DocumentTitleChangedEvent, value); }\r
533                         remove { Events.RemoveHandler (DocumentTitleChangedEvent, value); }\r
534                 }\r
535 \r
536                 [BrowsableAttribute(false)]\r
537                 public event EventHandler EncryptionLevelChanged {\r
538                         add { Events.AddHandler (EncryptionLevelChangedEvent, value); }\r
539                         remove { Events.RemoveHandler (EncryptionLevelChangedEvent, value); }\r
540                 }\r
541 \r
542                 public event EventHandler FileDownload {\r
543                         add { Events.AddHandler (FileDownloadEvent, value); }\r
544                         remove { Events.RemoveHandler (FileDownloadEvent, value); }\r
545                 }\r
546 \r
547                 public event WebBrowserNavigatedEventHandler Navigated {\r
548                         add { Events.AddHandler (NavigatedEvent, value); }\r
549                         remove { Events.RemoveHandler (NavigatedEvent, value); }\r
550                 }\r
551 \r
552                 public event WebBrowserNavigatingEventHandler Navigating {\r
553                         add { Events.AddHandler (NavigatingEvent, value); }\r
554                         remove { Events.RemoveHandler (NavigatingEvent, value); }\r
555                 }\r
556 \r
557                 public event CancelEventHandler NewWindow {\r
558                         add { Events.AddHandler (NewWindowEvent, value); }\r
559                         remove { Events.RemoveHandler (NewWindowEvent, value); }\r
560                 }\r
561                 \r
562                 public event WebBrowserProgressChangedEventHandler ProgressChanged {\r
563                         add { Events.AddHandler (ProgressChangedEvent, value); }\r
564                         remove { Events.RemoveHandler (ProgressChangedEvent, value); }\r
565                 }\r
566 \r
567                 [BrowsableAttribute(false)]\r
568                 public event EventHandler StatusTextChanged {\r
569                         add { Events.AddHandler (StatusTextChangedEvent, value); }\r
570                         remove { Events.RemoveHandler (StatusTextChangedEvent, value); }\r
571                 }\r
572                 #endregion\r
573 \r
574 \r
575                 #region Internal\r
576                 internal override bool OnNewWindowInternal ()\r
577                 {\r
578                         CancelEventArgs c = new CancelEventArgs ();\r
579                         OnNewWindow (c);\r
580                         return c.Cancel;\r
581                 }\r
582 \r
583                 internal override void OnWebHostCompleted (object sender, EventArgs e)\r
584                 {\r
585                         documentReady = true;\r
586                         WebBrowserNavigatedEventArgs n = new WebBrowserNavigatedEventArgs (new Uri (WebHost.Document.Url));\r
587                         OnNavigated (n);\r
588                 }\r
589 \r
590                 #endregion\r
591 \r
592 \r
593                 [MonoTODO ("Stub, not implemented")]\r
594                 protected class WebBrowserSite : WebBrowserSiteBase\r
595                 {\r
596                         [MonoTODO ("Stub, not implemented")]\r
597                         public WebBrowserSite (WebBrowser host)\r
598                                 : base ()\r
599                         {\r
600                         }\r
601 \r
602                 }\r
603     }\r
604 }\r
605 \r
606 #endif