* TabControl.cs: Show the tooltip depending on the value
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / PrintPreviewControl.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) 2006 Novell, Inc.
21 //
22 // Authors:
23 //      Jonathan Chambers (jonathan.chambers@ansys.com)
24 //
25
26 using System;
27 using System.ComponentModel;
28 using System.ComponentModel.Design;
29 using System.ComponentModel.Design.Serialization;
30 using System.Collections;
31 using System.Diagnostics;
32 using System.Drawing;
33 using System.Drawing.Printing;
34 using System.Reflection;
35 using System.Runtime.InteropServices;
36
37 namespace System.Windows.Forms {
38         [DefaultPropertyAttribute("Document")]
39 #if NET_2_0
40         [ClassInterface (ClassInterfaceType.AutoDispatch)]
41         [ComVisible (true)]
42 #endif
43         public class PrintPreviewControl : Control {
44                 #region Local variables
45                 bool autozoom;
46                 int columns;
47                 int rows;
48                 int startPage;
49                 double zoom;
50                 int padding = ThemeEngine.Current.PrintPreviewControlPadding;
51                 PrintDocument document;
52                 internal PreviewPrintController controller;
53                 internal PreviewPageInfo[] page_infos;
54                 private VScrollBar vbar;
55                 private HScrollBar hbar;
56
57                 internal Rectangle ViewPort;
58                 internal Image[] image_cache;
59                 Size image_size;
60
61                 #endregion // Local variables
62
63                 #region Public Constructors
64                 public PrintPreviewControl() {
65                         autozoom = true;
66                         columns = 1;
67                         rows = 0;
68                         startPage = 1;
69
70                         this.BackColor = SystemColors.AppWorkspace;
71
72                         controller = new PreviewPrintController ();
73
74                         vbar = new ImplicitVScrollBar ();
75                         hbar = new ImplicitHScrollBar ();
76
77                         vbar.Visible = false;
78                         hbar.Visible = false;
79                         vbar.ValueChanged += new EventHandler (VScrollBarValueChanged);
80                         hbar.ValueChanged += new EventHandler (HScrollBarValueChanged);
81
82                         SuspendLayout ();
83                         Controls.AddImplicit (vbar);
84                         Controls.AddImplicit (hbar);
85                         ResumeLayout ();
86                 }
87                 #endregion // Public Constructors
88
89                 
90                 #region Public Instance Properties
91                 [DefaultValue(true)]
92                 public bool AutoZoom {
93                         get { return autozoom; }
94                         set {
95                                 autozoom = value;
96                                 InvalidateLayout ();
97                         }
98                 }
99                 [DefaultValue(1)]
100                 public int Columns {
101                         get { return columns; }
102                         set {
103                                 columns = value;
104                                 InvalidateLayout ();
105                         }
106                 }
107                 [DefaultValue(null)]
108                 public PrintDocument Document {
109                         get { return document; }
110                         set {
111                                 document = value;
112                         }
113                 }
114
115 #if NET_2_0
116                 [Localizable (true)]
117                 [AmbientValue (RightToLeft.Inherit)]
118                 public override RightToLeft RightToLeft {
119                         get { return base.RightToLeft; }
120                         set { base.RightToLeft = value; }
121                 }
122 #endif
123
124                 [DefaultValue(1)]
125                 public int Rows {
126                         get { return rows; }
127                         set {
128                                 rows = value;
129                                 InvalidateLayout ();
130                         }
131                 }
132                 [DefaultValue(0)]
133                 public int StartPage {
134                         get { return startPage; }
135                         set {
136                                 if (value < 1)
137                                         return;
138                                 if (document != null && value + (Rows + 1) * Columns > page_infos.Length + 1) {
139                                         value = page_infos.Length + 1 - (Rows + 1) * Columns;
140                                         if (value < 1)
141                                                 value = 1;
142                                 }
143
144                                 int start = StartPage;
145                                 startPage = value;
146                                 if (start != startPage) {
147                                         InvalidateLayout ();
148                                         OnStartPageChanged (EventArgs.Empty);
149                                 }
150                         }
151                 }
152
153                 [Bindable(false)]
154                 [Browsable(false)]
155                 [EditorBrowsable(EditorBrowsableState.Never)]
156                 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
157                 public override string Text {
158                         get { return base.Text; }
159                         set { base.Text = value; }
160                 }
161
162                 [DefaultValue(false)]
163                 public bool UseAntiAlias {
164                         get { return controller.UseAntiAlias; }
165                         set { controller.UseAntiAlias = value; }
166                 }
167
168 #if NET_2_0
169                 [DefaultValue (0.3)]
170 #endif
171                 public double Zoom {
172                         get { return zoom; }
173                         set {
174                                 if (value <= 0)
175                                         throw new ArgumentException ("zoom");
176                                 autozoom = false;
177                                 zoom = value;
178                                 InvalidateLayout ();                            
179                         }
180                 }
181                 #endregion // Public Instance Properties
182
183                 
184                 #region Public Instance Methods
185                 internal void GeneratePreview ()
186                 {
187                         if (document == null)
188                                 return;
189
190                         try {
191                                 if (page_infos == null) {
192                                         if (document.PrintController == null || !(document.PrintController is PrintControllerWithStatusDialog)) {
193                                                 document.PrintController = new PrintControllerWithStatusDialog (controller);
194                                         }
195                                         document.Print ();
196                                         page_infos = controller.GetPreviewPageInfo ();
197                                 }
198                                 
199                                 if (image_cache == null) {
200                                         image_cache = new Image[page_infos.Length];
201
202                                         if (page_infos.Length > 0) {
203                                                 image_size = ThemeEngine.Current.PrintPreviewControlGetPageSize (this);
204                                                 if (image_size.Width >= 0 && image_size.Width < page_infos[0].Image.Width
205                                                     && image_size.Height >= 0 && image_size.Height < page_infos[0].Image.Height) {
206
207                                                         for (int i = 0; i < page_infos.Length; i ++) {
208                                                                 image_cache[i] = new Bitmap (image_size.Width, image_size.Height);
209                                                                 Graphics g = Graphics.FromImage (image_cache[i]);
210                                                                 g.DrawImage (page_infos[i].Image, new Rectangle (new Point (0, 0), image_size), 0, 0, page_infos[i].Image.Width, page_infos[i].Image.Height, GraphicsUnit.Pixel);
211                                                                 g.Dispose ();
212                                                         }
213                                                 }
214                                         }
215                                 }
216                                 UpdateScrollBars();
217                         }
218                         catch (Exception e) {
219                                 page_infos = new PreviewPageInfo[0];
220                                 image_cache = new Image[0];
221                                 MessageBox.Show (e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
222                         }
223                 }
224
225                 public void InvalidatePreview()
226                 {
227                         if (page_infos != null) {
228                                 for (int i = 0; i < page_infos.Length; i++) {
229                                         if (page_infos[i].Image != null) {
230                                                 page_infos[i].Image.Dispose();
231                                         }
232                                 }
233                                 page_infos = null;
234                         }
235                         InvalidateLayout();
236                 }
237
238                 [EditorBrowsable(EditorBrowsableState.Never)]
239                 public override void ResetBackColor()
240                 {
241                         base.ResetBackColor();
242                 }
243
244                 [EditorBrowsable(EditorBrowsableState.Never)]
245                 public override void ResetForeColor()
246                 {
247                         base.ResetForeColor ();
248                 }
249                 #endregion // Public Instance Methods
250
251                 #region Protected Instance Properties
252                 protected override CreateParams CreateParams {
253                         get {
254                                 return base.CreateParams;
255                         }
256                 }
257
258                 #endregion // Protected Instance Methods
259
260                 #region Protected Instance Properties
261
262                 protected override void OnPaint(PaintEventArgs pevent)
263                 {
264                         if (page_infos == null || image_cache == null)
265                                 GeneratePreview ();
266                         ThemeEngine.Current.PrintPreviewControlPaint (pevent, this, image_size);
267                 }
268
269                 protected override void OnResize(EventArgs eventargs)
270                 {
271                         InvalidateLayout ();
272                         base.OnResize (eventargs);
273                 }
274
275                 protected virtual void OnStartPageChanged(EventArgs e)
276                 {
277                         EventHandler eh = (EventHandler)(Events [StartPageChangedEvent]);
278                         if (eh != null)
279                                 eh (this, e);
280                 }
281
282                 protected override void WndProc(ref Message m)
283                 {
284                         base.WndProc (ref m);
285                 }
286
287                 #endregion // Protected Instance Methods
288
289                 static object StartPageChangedEvent = new object ();
290
291                 public event EventHandler StartPageChanged {
292                         add { Events.AddHandler (StartPageChangedEvent, value); }
293                         remove { Events.RemoveHandler (StartPageChangedEvent, value); }
294                 }
295
296                 [Browsable(false)]
297                 [EditorBrowsable(EditorBrowsableState.Never)]
298                 public new event EventHandler TextChanged {
299                         add { base.TextChanged += value; }
300                         remove { base.TextChanged -= value; }
301                 }
302
303                 internal int vbar_value;
304                 internal int hbar_value;
305
306                 #region UIA Framework Property
307 #if NET_2_0
308                 internal ScrollBar UIAVScrollBar {
309                         get { return vbar; }
310                 }
311
312                 internal ScrollBar UIAHScrollBar {
313                         get { return hbar; }
314                 }
315 #endif
316                 #endregion
317
318                 private void VScrollBarValueChanged (object sender, EventArgs e)
319                 {
320                         int pixels;
321
322                         if (vbar.Value > vbar_value)
323                                 pixels = -1 * (vbar.Value - vbar_value);
324                         else
325                                 pixels = vbar_value - vbar.Value;
326
327                         vbar_value = vbar.Value;
328                         XplatUI.ScrollWindow (Handle, ViewPort, 0, pixels, false);
329                 }
330
331
332                 private void HScrollBarValueChanged (object sender, EventArgs e)
333                 {
334                         int pixels;
335
336                         if (hbar.Value > hbar_value)
337                                 pixels = -1 * (hbar.Value - hbar_value);
338                         else
339                                 pixels = hbar_value - hbar.Value;
340
341                         hbar_value = hbar.Value;
342                         XplatUI.ScrollWindow (Handle, ViewPort, pixels, 0, false);
343                 }
344
345                 private void UpdateScrollBars ()
346                 {
347                         ViewPort = ClientRectangle;
348                         if (AutoZoom)
349                                 return;
350
351                         int total_width, total_height;
352
353                         total_width = image_size.Width * Columns + (Columns + 1) * padding;
354                         total_height = image_size.Height * (Rows + 1) + (Rows + 2) * padding;
355
356                         bool vert = false;
357                         bool horz = false;
358
359                         if (total_width > ClientRectangle.Width) {
360                                 /* we need the hbar */
361                                 horz = true;
362                                 ViewPort.Height -= hbar.Height;
363                         }
364                         if (total_height > ViewPort.Height) {
365                                 /* we need the vbar */
366                                 vert = true;
367                                 ViewPort.Width -= vbar.Width;
368                         }
369                         if (!horz && total_width > ViewPort.Width) {
370                                 horz = true;
371                                 ViewPort.Height -= hbar.Height;
372                         }
373
374                         SuspendLayout ();
375
376                         if (vert) {
377                                 vbar.SetValues (total_height, ViewPort.Height);
378
379                                 vbar.Bounds = new Rectangle (ClientRectangle.Width - vbar.Width, 0, vbar.Width,
380                                                              ClientRectangle.Height -
381                                                              (horz ? SystemInformation.VerticalScrollBarWidth : 0));
382                                 vbar.Visible = true;
383                                 vbar_value = vbar.Value;
384                         }
385                         else {
386                                 vbar.Visible = false;
387                         }
388
389                         if (horz) {
390                                 hbar.SetValues (total_width, ViewPort.Width);
391
392                                 hbar.Bounds = new Rectangle (0, ClientRectangle.Height - hbar.Height,
393                                                              ClientRectangle.Width - (vert ?
394                                                                                       SystemInformation.HorizontalScrollBarHeight : 0),
395                                                              hbar.Height);
396                                 hbar.Visible = true;
397                                 hbar_value = hbar.Value;
398                         }
399                         else {
400                                 hbar.Visible = false;
401                         }
402
403                         ResumeLayout (false);
404                 }
405
406                 private void InvalidateLayout() {
407                         if (image_cache != null) {
408                                 for (int i = 0; i < image_cache.Length; i++) {
409                                         if (image_cache[i] !=null)
410                                                 image_cache[i].Dispose();
411                                 }
412                                 image_cache = null;
413                         }
414                         Invalidate ();
415                 }
416         }
417 }