Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

410 lines
10 KiB
C#

// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// Copyright (c) 2006 Novell, Inc.
//
// Authors:
// Jonathan Chambers (jonathan.chambers@ansys.com)
//
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Printing;
using System.Reflection;
using System.Runtime.InteropServices;
namespace System.Windows.Forms {
[DefaultPropertyAttribute("Document")]
[ClassInterface (ClassInterfaceType.AutoDispatch)]
[ComVisible (true)]
public class PrintPreviewControl : Control {
#region Local variables
bool autozoom;
int columns;
int rows;
int startPage;
double zoom;
int padding = ThemeEngine.Current.PrintPreviewControlPadding;
PrintDocument document;
internal PreviewPrintController controller;
internal PreviewPageInfo[] page_infos;
private VScrollBar vbar;
private HScrollBar hbar;
internal Rectangle ViewPort;
internal Image[] image_cache;
Size image_size;
#endregion // Local variables
#region Public Constructors
public PrintPreviewControl() {
autozoom = true;
columns = 1;
rows = 0;
startPage = 1;
this.BackColor = SystemColors.AppWorkspace;
controller = new PreviewPrintController ();
vbar = new ImplicitVScrollBar ();
hbar = new ImplicitHScrollBar ();
vbar.Visible = false;
hbar.Visible = false;
vbar.ValueChanged += new EventHandler (VScrollBarValueChanged);
hbar.ValueChanged += new EventHandler (HScrollBarValueChanged);
SuspendLayout ();
Controls.AddImplicit (vbar);
Controls.AddImplicit (hbar);
ResumeLayout ();
}
#endregion // Public Constructors
#region Public Instance Properties
[DefaultValue(true)]
public bool AutoZoom {
get { return autozoom; }
set {
autozoom = value;
InvalidateLayout ();
}
}
[DefaultValue(1)]
public int Columns {
get { return columns; }
set {
columns = value;
InvalidateLayout ();
}
}
[DefaultValue(null)]
public PrintDocument Document {
get { return document; }
set {
document = value;
}
}
[Localizable (true)]
[AmbientValue (RightToLeft.Inherit)]
public override RightToLeft RightToLeft {
get { return base.RightToLeft; }
set { base.RightToLeft = value; }
}
[DefaultValue(1)]
public int Rows {
get { return rows; }
set {
rows = value;
InvalidateLayout ();
}
}
[DefaultValue(0)]
public int StartPage {
get { return startPage; }
set {
if (value < 1)
return;
if (document != null && value + (Rows + 1) * Columns > page_infos.Length + 1) {
value = page_infos.Length + 1 - (Rows + 1) * Columns;
if (value < 1)
value = 1;
}
int start = StartPage;
startPage = value;
if (start != startPage) {
InvalidateLayout ();
OnStartPageChanged (EventArgs.Empty);
}
}
}
[Bindable(false)]
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override string Text {
get { return base.Text; }
set { base.Text = value; }
}
[DefaultValue(false)]
public bool UseAntiAlias {
get { return controller.UseAntiAlias; }
set { controller.UseAntiAlias = value; }
}
[DefaultValue (0.3)]
public double Zoom {
get { return zoom; }
set {
if (value <= 0)
throw new ArgumentException ("zoom");
autozoom = false;
zoom = value;
InvalidateLayout ();
}
}
#endregion // Public Instance Properties
#region Public Instance Methods
internal void GeneratePreview ()
{
if (document == null)
return;
try {
if (page_infos == null) {
if (document.PrintController == null || !(document.PrintController is PrintControllerWithStatusDialog)) {
document.PrintController = new PrintControllerWithStatusDialog (controller);
}
document.Print ();
page_infos = controller.GetPreviewPageInfo ();
}
if (image_cache == null) {
image_cache = new Image[page_infos.Length];
if (page_infos.Length > 0) {
image_size = ThemeEngine.Current.PrintPreviewControlGetPageSize (this);
if (image_size.Width >= 0 && image_size.Width < page_infos[0].Image.Width
&& image_size.Height >= 0 && image_size.Height < page_infos[0].Image.Height) {
for (int i = 0; i < page_infos.Length; i ++) {
image_cache[i] = new Bitmap (image_size.Width, image_size.Height);
Graphics g = Graphics.FromImage (image_cache[i]);
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);
g.Dispose ();
}
}
}
}
UpdateScrollBars();
}
catch (Exception e) {
page_infos = new PreviewPageInfo[0];
image_cache = new Image[0];
MessageBox.Show (e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void InvalidatePreview()
{
if (page_infos != null) {
for (int i = 0; i < page_infos.Length; i++) {
if (page_infos[i].Image != null) {
page_infos[i].Image.Dispose();
}
}
page_infos = null;
}
InvalidateLayout();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override void ResetBackColor()
{
base.ResetBackColor();
}
[EditorBrowsable(EditorBrowsableState.Never)]
public override void ResetForeColor()
{
base.ResetForeColor ();
}
#endregion // Public Instance Methods
#region Protected Instance Properties
protected override CreateParams CreateParams {
get {
return base.CreateParams;
}
}
#endregion // Protected Instance Methods
#region Protected Instance Properties
protected override void OnPaint(PaintEventArgs pevent)
{
if (page_infos == null || image_cache == null)
GeneratePreview ();
ThemeEngine.Current.PrintPreviewControlPaint (pevent, this, image_size);
}
protected override void OnResize(EventArgs eventargs)
{
InvalidateLayout ();
base.OnResize (eventargs);
}
protected virtual void OnStartPageChanged(EventArgs e)
{
EventHandler eh = (EventHandler)(Events [StartPageChangedEvent]);
if (eh != null)
eh (this, e);
}
protected override void WndProc(ref Message m)
{
base.WndProc (ref m);
}
#endregion // Protected Instance Methods
static object StartPageChangedEvent = new object ();
public event EventHandler StartPageChanged {
add { Events.AddHandler (StartPageChangedEvent, value); }
remove { Events.RemoveHandler (StartPageChangedEvent, value); }
}
[Browsable(false)]
[EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler TextChanged {
add { base.TextChanged += value; }
remove { base.TextChanged -= value; }
}
internal int vbar_value;
internal int hbar_value;
#region UIA Framework Property
internal ScrollBar UIAVScrollBar {
get { return vbar; }
}
internal ScrollBar UIAHScrollBar {
get { return hbar; }
}
#endregion
private void VScrollBarValueChanged (object sender, EventArgs e)
{
int pixels;
if (vbar.Value > vbar_value)
pixels = -1 * (vbar.Value - vbar_value);
else
pixels = vbar_value - vbar.Value;
vbar_value = vbar.Value;
XplatUI.ScrollWindow (Handle, ViewPort, 0, pixels, false);
}
private void HScrollBarValueChanged (object sender, EventArgs e)
{
int pixels;
if (hbar.Value > hbar_value)
pixels = -1 * (hbar.Value - hbar_value);
else
pixels = hbar_value - hbar.Value;
hbar_value = hbar.Value;
XplatUI.ScrollWindow (Handle, ViewPort, pixels, 0, false);
}
private void UpdateScrollBars ()
{
ViewPort = ClientRectangle;
if (AutoZoom)
return;
int total_width, total_height;
total_width = image_size.Width * Columns + (Columns + 1) * padding;
total_height = image_size.Height * (Rows + 1) + (Rows + 2) * padding;
bool vert = false;
bool horz = false;
if (total_width > ClientRectangle.Width) {
/* we need the hbar */
horz = true;
ViewPort.Height -= hbar.Height;
}
if (total_height > ViewPort.Height) {
/* we need the vbar */
vert = true;
ViewPort.Width -= vbar.Width;
}
if (!horz && total_width > ViewPort.Width) {
horz = true;
ViewPort.Height -= hbar.Height;
}
SuspendLayout ();
if (vert) {
vbar.SetValues (total_height, ViewPort.Height);
vbar.Bounds = new Rectangle (ClientRectangle.Width - vbar.Width, 0, vbar.Width,
ClientRectangle.Height -
(horz ? SystemInformation.VerticalScrollBarWidth : 0));
vbar.Visible = true;
vbar_value = vbar.Value;
}
else {
vbar.Visible = false;
}
if (horz) {
hbar.SetValues (total_width, ViewPort.Width);
hbar.Bounds = new Rectangle (0, ClientRectangle.Height - hbar.Height,
ClientRectangle.Width - (vert ?
SystemInformation.HorizontalScrollBarHeight : 0),
hbar.Height);
hbar.Visible = true;
hbar_value = hbar.Value;
}
else {
hbar.Visible = false;
}
ResumeLayout (false);
}
private void InvalidateLayout() {
if (image_cache != null) {
for (int i = 0; i < image_cache.Length; i++) {
if (image_cache[i] !=null)
image_cache[i].Dispose();
}
image_cache = null;
}
Invalidate ();
}
}
}