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