merged Sys.Web.Services 2.0 support in my branch:
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / PrintDialog.cs
1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 //
20 // Copyright (c) 2005-2006 Novell, Inc.
21 //
22 // Authors:
23 //      Someone
24 //      Jonathan Chambers (jonathan.chambers@ansys.com)
25 //      Jordi Mas i Hernandez (jordimash@gmail.com)
26 //
27
28 using System;
29 using System.ComponentModel;
30 using System.ComponentModel.Design;
31 using System.ComponentModel.Design.Serialization;
32 using System.Collections;
33 using System.Diagnostics;
34 using System.Drawing;
35 using System.Drawing.Printing;
36 using System.Reflection;
37
38 namespace System.Windows.Forms
39 {
40 #if NET_2_0
41         [Designer ("System.Windows.Forms.Design.PrintDialogDesigner, " + Consts.AssemblySystem_Design,
42                    "System.ComponentModel.Design.IDesigner")]
43 #endif
44         [DefaultProperty("Document")]
45         public sealed class PrintDialog : CommonDialog {
46                 PrintDocument document;
47 #if NET_2_0
48                 bool allow_current_page;
49 #endif
50                 bool allow_print_to_file;
51                 bool allow_selection;
52                 bool allow_some_pages;
53                 bool show_help;
54                 bool show_network;
55                 bool print_to_file;
56                 PrinterSettings current_settings;
57
58                 private Button cancel_button;
59                 private Button accept_button;
60                 private Button help_button;
61                 private ComboBox printer_combo;
62                 private RadioButton radio_all;
63                 private RadioButton radio_pages;
64                 private RadioButton radio_sel;
65                 private PrinterSettings.StringCollection installed_printers;
66                 private PrinterSettings default_printer_settings;
67                 private TextBox txtFrom;
68                 private TextBox txtTo;
69                 private Label labelTo;
70                 private Label labelFrom;
71                 private CheckBox chkbox_print;
72                 private NumericUpDown updown_copies;
73                 private CheckBox chkbox_collate;
74                 private Label label_status;
75                 private Label label_type;
76                 private Label label_where;
77                 private Label label_comment;
78
79                 public PrintDialog ()
80                 {
81                         help_button = null;
82                         installed_printers = System.Drawing.Printing.PrinterSettings.InstalledPrinters;
83
84                         form.Text = "Print";
85                         CreateFormControls ();
86                         Reset ();
87                 }
88
89                 public override void Reset ()
90                 {
91                         current_settings = null;
92                         AllowPrintToFile = true;
93                         AllowSelection = false;
94                         AllowSomePages = false;
95                         PrintToFile = false;
96                         ShowHelp = false;
97                         ShowNetwork = true;
98                 }
99
100 #if NET_2_0
101                 [DefaultValue (false)]
102                 public bool AllowCurrentPage {
103                         get {
104                                 return allow_current_page;
105                         }
106
107                         set {
108                                 allow_current_page = value;
109                                 radio_pages.Enabled = value;
110                         }
111                 }
112 #endif
113
114                 [DefaultValue(true)]
115                 public bool AllowPrintToFile {
116                         get {
117                                 return allow_print_to_file;
118                         }
119
120                         set {
121                                 allow_print_to_file = value;
122                                 chkbox_print.Enabled = value;
123                         }
124                 }
125
126                 [DefaultValue(false)]
127                 public bool AllowSelection {
128                         get {
129                                 return allow_selection;
130                         }
131
132                         set {
133                                 allow_selection = value;
134                                 radio_sel.Enabled = value;
135                         }
136                 }
137
138                 [DefaultValue(false)]
139                 public bool AllowSomePages {
140                         get {
141                                 return allow_some_pages;
142                         }
143
144                         set {
145                                 allow_some_pages = value;
146                                 radio_pages.Enabled = value;
147                                 txtFrom.Enabled = value;
148                                 txtTo.Enabled = value;
149                                 labelTo.Enabled = value;
150                                 labelFrom.Enabled = value;
151
152                                 if (current_settings != null) {
153                                         txtFrom.Text = current_settings.FromPage.ToString ();
154                                         txtTo.Text = current_settings.ToPage.ToString ();
155                                 }
156                         }
157                 }
158
159                 [DefaultValue(null)]
160                 public PrintDocument Document {
161                         get {
162                                 return document;
163                         }
164
165                         set {
166                                 document = value;
167                                 current_settings = value == null ? new PrinterSettings () : value.PrinterSettings;
168                         }
169                 }
170
171                 [Browsable(false)]
172                 [DefaultValue(null)]
173                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
174                 public PrinterSettings PrinterSettings {
175                         get {
176                                 return current_settings;
177                         }
178
179                         set {
180                                 if (value != null && value == current_settings)
181                                         return;
182
183                                 current_settings = value == null ? new PrinterSettings () : value;
184                                 document = null;
185                         }
186                 }
187
188                 [DefaultValue(false)]
189                 public bool PrintToFile {
190                         get {
191                                 return print_to_file;
192                         }
193
194                         set {
195                                 print_to_file = value;
196                         }
197                 }
198
199                 [DefaultValue(true)]
200                 public bool ShowNetwork {
201                         get {
202                                 return show_network;
203                         }
204
205                         set {
206                                 show_network = value;
207                         }
208                 }
209
210                 [DefaultValue(false)]
211                 public bool ShowHelp {
212                         get {
213                                 return show_help;
214                         }
215
216                         set {
217                                 show_help = value;
218                                 ShowHelpButton ();
219                         }
220                 }
221
222                 protected override bool RunDialog (IntPtr hwnd)
223                 {
224                         if (allow_some_pages && current_settings.FromPage > current_settings.ToPage)
225                                 throw new ArgumentException ("FromPage out of range");
226
227                         if (allow_some_pages) {
228                                 txtFrom.Text = current_settings.FromPage.ToString ();
229                                 txtTo.Text = current_settings.ToPage.ToString ();
230                         }
231
232                         if (current_settings.PrintRange == PrintRange.SomePages && allow_some_pages)
233                                 radio_pages.Checked = true;
234                         else if (current_settings.PrintRange == PrintRange.Selection && allow_selection)
235                                 radio_sel.Checked = true;
236                         else
237                                 radio_all.Checked = true;
238
239                         updown_copies.Value = current_settings.Copies == 0 ? 1 : (int) current_settings.Copies;
240                         chkbox_collate.Checked = current_settings.Collate;
241                         chkbox_collate.Enabled = (updown_copies.Value > 1) ? true : false;
242
243                         if (show_help) {
244                                 ShowHelpButton ();
245                         }
246
247                         SetPrinterDetails ();
248
249                         return true;
250                 }
251
252                 private void OnClickCancelButton (object sender, EventArgs e)
253                 {
254                         form.DialogResult = DialogResult.Cancel;
255                 }
256
257                 void ShowErrorMessage (string message, Control control_to_focus)
258                 {
259                         MessageBox.Show (message, "Print", MessageBoxButtons.OK, MessageBoxIcon.Warning);
260                         if (control_to_focus != null)
261                                 control_to_focus.Focus ();
262                 }
263
264                 private void OnClickOkButton (object sender, EventArgs e)
265                 {
266                         if (updown_copies.Text.Length < 1) {
267                                 ShowErrorMessage ("The 'Copies' value cannot be empty and must be a positive value.", 
268                                                 updown_copies);
269                                 return;
270                         }
271
272                         int from = -1, to = -1;
273
274                         if (allow_some_pages && radio_pages.Checked) {
275                                 if (txtFrom.Text.Length < 1) {
276                                         ShowErrorMessage ("The 'From' value cannot be empty and must be a positive value.",
277                                                         txtFrom);
278                                         return;
279                                 }
280
281                                 try {
282                                         from = Int32.Parse (txtFrom.Text);
283                                         to = Int32.Parse (txtTo.Text);
284                                 }
285                                 catch {
286                                         ShowErrorMessage ("From/To values should be numeric", txtFrom);
287                                         return;
288                                 }
289                                         
290                                 if (from > to) {
291                                         ShowErrorMessage ("'From' value cannot be greater than 'To' value.", txtFrom);
292                                         return;
293                                 }
294                                         
295                                 if (to < current_settings.MinimumPage || to > current_settings.MaximumPage) {
296                                         ShowErrorMessage ("'To' value is not within the page range\n" +
297                                                         "Enter a number between " + current_settings.MinimumPage +
298                                                         " and " + current_settings.MaximumPage + ".", txtTo);
299                                         return;
300                                 }
301                                         
302                                 if (from < current_settings.MinimumPage || from > current_settings.MaximumPage) {
303                                         ShowErrorMessage ("'From' value is not within the page range\n" +
304                                                         "Enter a number between " + current_settings.MinimumPage +
305                                                         " and " + current_settings.MaximumPage + ".", txtFrom);
306                                         return;
307                                 }
308                         }
309                         
310                         if (radio_all.Checked == true)
311                                 current_settings.PrintRange = PrintRange.AllPages;
312                         else if (radio_pages.Checked == true)
313                                 current_settings.PrintRange = PrintRange.SomePages;
314                         else
315                                 current_settings.PrintRange = PrintRange.Selection;
316
317                         current_settings.Copies = (short) updown_copies.Value;
318                         if (current_settings.PrintRange == PrintRange.SomePages) {
319                                 current_settings.FromPage = from;
320                                 current_settings.ToPage = to;
321                         }
322                         current_settings.Collate = chkbox_collate.Checked;
323
324                         if (allow_print_to_file) {
325                                 current_settings.PrintToFile = chkbox_print.Checked;
326                         }
327
328                         form.DialogResult = DialogResult.OK;
329
330                         if (printer_combo.SelectedItem != null)
331                                 current_settings.PrinterName = (string) printer_combo.SelectedItem;
332
333                         if (document != null) {
334                                 document.PrintController = new PrintControllerWithStatusDialog (document.PrintController);
335                                 document.PrinterSettings = current_settings;
336                         }
337                 }
338
339                 private void ShowHelpButton ()
340                 {
341                         if (help_button == null) {
342                                 help_button = new Button ();
343                                 help_button.TabIndex = 60;
344
345                                 help_button.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Left)));
346                                 help_button.FlatStyle = FlatStyle.System;
347                                 help_button.Location = new Point (20, 270);
348                                 help_button.Text = "&Help";
349                                 help_button.FlatStyle = FlatStyle.System;
350                                 form.Controls.Add (help_button);
351                         }
352
353                         help_button.Visible = show_help;
354                 }
355
356                 private void OnUpDownValueChanged (object sender, System.EventArgs e)
357                 {
358                         chkbox_collate.Enabled = (updown_copies.Value > 1) ? true : false;
359                 }
360
361                 void OnPagesCheckedChanged (object obj, EventArgs args)
362                 {
363                         if (radio_pages.Checked && !txtTo.Focused)
364                                 txtFrom.Focus ();
365                 }
366
367                 private void CreateFormControls ()
368                 {
369                         form.SuspendLayout ();
370
371                         GroupBox group_box_prn = new GroupBox ();
372                         group_box_prn.Location = new Point (10, 8);
373                         group_box_prn.Text = "Printer";
374                         group_box_prn.Size = new Size (420, 145);
375
376                         GroupBox group_box_range = new GroupBox ();
377                         group_box_range.Location = new Point (10, 155);
378                         group_box_range.Text = "Print range";
379                         group_box_range.Size = new Size (240, 100);
380
381                         GroupBox group_box_copies = new GroupBox ();
382                         group_box_copies.Location = new Point (265, 155);
383                         group_box_copies.Text = "Copies";
384                         group_box_copies.Size = new Size (165, 100);
385
386                         // Accept button
387                         accept_button = new Button ();
388                         form.AcceptButton = accept_button;
389                         accept_button.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
390                         accept_button.FlatStyle = FlatStyle.System;
391                         accept_button.Location = new Point (265, 270);
392                         accept_button.Text = "OK";
393                         accept_button.FlatStyle = FlatStyle.System;
394                         accept_button.Click += new EventHandler (OnClickOkButton);
395
396                         // Cancel button
397                         cancel_button = new Button ();
398                         form.CancelButton = cancel_button;
399                         cancel_button.Anchor = ((AnchorStyles)((AnchorStyles.Bottom | AnchorStyles.Right)));
400                         cancel_button.FlatStyle = FlatStyle.System;
401                         cancel_button.Location = new Point (350, 270);
402                         cancel_button.Text = "Cancel";
403                         cancel_button.FlatStyle = FlatStyle.System;
404                         cancel_button.Click += new EventHandler (OnClickCancelButton);
405
406                         // Static controls
407                         Label label = new Label ();
408                         label.AutoSize = true;
409                         label.Text = "&Name:";
410                         label.Location = new Point (20, 33);
411                         group_box_prn.Controls.Add (label);
412
413                         label = new Label ();
414                         label.Text = "Status:";
415                         label.AutoSize = true;
416                         label.Location = new Point (20, 60);
417                         group_box_prn.Controls.Add (label);
418
419                         label_status = new Label ();
420                         label_status.AutoSize = true;
421                         label_status.Location = new Point (80, 60);
422                         group_box_prn.Controls.Add (label_status);
423
424                         label = new Label ();
425                         label.Text = "Type:";
426                         label.AutoSize = true;
427                         label.Location = new Point (20, 80);
428                         group_box_prn.Controls.Add (label);
429
430                         label_type = new Label ();
431                         label_type.AutoSize = true;
432                         label_type.Location = new Point (80, 80);
433                         group_box_prn.Controls.Add (label_type);
434
435                         label = new Label ();
436                         label.Text = "Where:";
437                         label.AutoSize = true;
438                         label.Location = new Point (20, 100);
439                         group_box_prn.Controls.Add (label);
440                         
441                         label_where = new Label ();
442                         label_where.AutoSize = true;
443                         label_where.Location = new Point (80, 100);
444                         group_box_prn.Controls.Add (label_where);
445
446                         label = new Label ();
447                         label.Text = "Comment:";
448                         label.AutoSize = true;
449                         label.Location = new Point (20, 120);
450                         group_box_prn.Controls.Add (label);
451
452                         label_comment = new Label ();
453                         label_comment.AutoSize = true;
454                         label_comment.Location = new Point (80, 120);
455                         group_box_prn.Controls.Add (label_comment);
456
457                         radio_all = new RadioButton ();
458                         radio_all.TabIndex = 21;
459                         radio_all.Location = new Point (20, 20);
460                         radio_all.Text = "&All";
461                         radio_all.Checked = true;
462                         group_box_range.Controls.Add (radio_all);
463
464                         radio_pages = new RadioButton ();
465                         radio_pages.TabIndex = 22;
466                         radio_pages.Location = new Point (20, 46);
467                         radio_pages.Text = "Pa&ges";
468                         radio_pages.Width = 60;
469                         radio_pages.CheckedChanged += new EventHandler (OnPagesCheckedChanged);
470                         group_box_range.Controls.Add (radio_pages);
471
472                         radio_sel = new RadioButton ();
473                         radio_sel.TabIndex = 23;
474                         radio_sel.Location = new Point (20, 72);
475                         radio_sel.Text = "&Selection";
476                         group_box_range.Controls.Add (radio_sel);
477
478                         labelFrom = new Label ();
479                         labelFrom.Text = "&from:";
480                         labelFrom.TabIndex = 24;
481                         labelFrom.AutoSize = true;
482                         labelFrom.Location = new Point (80, 50);
483                         group_box_range.Controls.Add (labelFrom);
484
485                         txtFrom = new TextBox ();
486                         txtFrom.TabIndex = 25;
487                         txtFrom.Location = new Point (120, 50);
488                         txtFrom.Width = 40;
489                         txtFrom.TextChanged += new EventHandler (OnPagesTextChanged);
490                         group_box_range.Controls.Add (txtFrom);
491
492                         labelTo = new Label ();
493                         labelTo.Text = "&to:";
494                         labelTo.TabIndex = 26;
495                         labelTo.AutoSize = true;
496                         labelTo.Location = new Point (170, 50);
497                         group_box_range.Controls.Add (labelTo);
498
499                         txtTo = new TextBox ();
500                         txtTo.TabIndex = 27;
501                         txtTo.Location = new Point (190, 50);
502                         txtTo.Width = 40;
503                         txtTo.TextChanged += new EventHandler (OnPagesTextChanged);
504                         group_box_range.Controls.Add (txtTo);
505
506                         chkbox_print = new CheckBox ();
507                         chkbox_print.Location = new Point (305, 115);
508                         chkbox_print.Text = "Print to fil&e";
509
510                         label = new Label ();
511                         label.Text = "Number of &copies:";
512                         label.AutoSize = true;
513                         label.Location = new Point (20, 20);
514                         group_box_copies.Controls.Add (label);
515
516                         updown_copies = new NumericUpDown ();
517                         updown_copies.TabIndex = 31;
518                         updown_copies.Location = new Point (120, 20);
519                         updown_copies.Minimum = 1;
520                         group_box_copies.Controls.Add (updown_copies);
521                         updown_copies.ValueChanged += new System.EventHandler (OnUpDownValueChanged);
522                         updown_copies.Size = new System.Drawing.Size (40, 20);
523
524                         chkbox_collate = new CheckBox ();
525                         chkbox_collate.TabIndex = 32;
526                         chkbox_collate.Location = new Point (20, 40);
527                         chkbox_collate.Text = "C&ollate";
528                         chkbox_collate.Width = 80;
529                         group_box_copies.Controls.Add (chkbox_collate);
530
531
532
533                         // Printer combo
534                         printer_combo = new ComboBox ();
535                         printer_combo.DropDownStyle = ComboBoxStyle.DropDownList;
536                         printer_combo.Location = new Point (80, 32);
537                         printer_combo.Width = 220;
538                         printer_combo.SelectedIndexChanged += new EventHandler (OnPrinterSelectedIndexChanged);
539
540                         default_printer_settings = new PrinterSettings ();
541                         for (int i = 0; i < installed_printers.Count; i++) {
542                                 printer_combo.Items.Add (installed_printers[i]);
543                                 if (installed_printers[i] == default_printer_settings.PrinterName)
544                                         printer_combo.SelectedItem = installed_printers[i];
545                         }
546                         printer_combo.TabIndex = 11;
547                         chkbox_print.TabIndex = 12;
548                         group_box_prn.Controls.Add (printer_combo);
549                         group_box_prn.Controls.Add (chkbox_print);
550
551                         form.Size =  new Size (450, 327); // 384
552                         form.FormBorderStyle = FormBorderStyle.FixedDialog;
553                         form.MaximizeBox = false;
554                         group_box_prn.TabIndex = 10;
555                         group_box_range.TabIndex = 20;
556                         group_box_copies.TabIndex = 30;
557                         accept_button.TabIndex = 40;
558                         cancel_button.TabIndex = 50;
559                         form.Controls.Add (group_box_prn);
560                         form.Controls.Add (group_box_range);
561                         form.Controls.Add (group_box_copies);
562                         form.Controls.Add (accept_button);
563                         form.Controls.Add (cancel_button);
564                         form.ResumeLayout (false);
565                 }
566
567                 void OnPagesTextChanged (object sender, EventArgs args)
568                 {
569                         radio_pages.Checked = true;
570                 }
571
572                 private void OnPrinterSelectedIndexChanged (object sender,  System.EventArgs e)
573                 {                       
574                         SetPrinterDetails ();
575                 }
576
577                 private void SetPrinterDetails ()
578                 {
579                         try
580                         {
581                                 string printer, port = string.Empty, type = string.Empty;
582                                 string status = string.Empty, comment = string.Empty;
583                                 Type sysprn = Type.GetType ("System.Drawing.Printing.SysPrn, System.Drawing");
584                                 MethodInfo dlg_info = sysprn.GetMethod ("GetPrintDialogInfo", BindingFlags.Static | BindingFlags.NonPublic);
585
586                                 printer = (string) printer_combo.SelectedItem;
587
588                                 if (printer != null) {
589                                         object[] args  = new object [5];
590                                         args[0] = printer;
591                                         args[1] = port;
592                                         args[2] = type;
593                                         args[3] = status;
594                                         args[4] = comment;
595                                         dlg_info.Invoke (null, args);
596                                         port = (string) args[1];
597                                         type = (string) args[2];
598                                         status = (string) args[3];
599                                         comment = (string) args[4];
600                                 }
601
602                                 label_status.Text = status;
603                                 label_type.Text = type;
604                                 label_where.Text = port;
605                                 label_comment.Text = comment;
606
607                                 accept_button.Enabled = true;
608                         }
609                         catch  {
610                                 accept_button.Enabled = false;
611                         }
612                 }
613         }
614 }