mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-08-17 17:02:51 +08:00
Unix builds / Ubuntu 18.04 wxGTK 3 compatible 3.0 (push) Canceled after 0s
Unix builds / Ubuntu 24.04 wxGTK ASAN not compatible (push) Canceled after 0s
Unix builds / Ubuntu 18.04 wxGTK UTF-8 (push) Canceled after 0s
Unix builds / Ubuntu 18.04 wxQt (push) Canceled after 0s
Unix builds / Ubuntu 18.04 wxX11 (push) Canceled after 0s
Unix builds / Ubuntu 20.04 wxGTK 3 with clang (push) Canceled after 0s
Unix builds / Ubuntu 22.04 wxGTK with wx containers (push) Canceled after 0s
Unix builds / Ubuntu 18.04 wxDFB (push) Canceled after 0s
Unix builds / Ubuntu 24.04 wxGTK UBSAN (push) Canceled after 0s
Unix builds / Ubuntu 18.04 wxGTK 3 static with gcc 4.8 (push) Canceled after 0s
Unix builds / Ubuntu 18.04 wxGTK 2 (push) Canceled after 0s
CMake builds / Ubuntu 22.04 wxGTK 3 (push) Canceled after 0s
CMake builds / macOS latest wxGTK 3 Unix Makefiles (push) Canceled after 0s
CMake builds / MSW/MSVC wxMSW (push) Canceled after 0s
CMake builds / MSW/Clang wxMSW (push) Canceled after 0s
CMake builds / macOS latest wxOSX Ninja (push) Canceled after 0s
CMake builds / macOS 14 wxOSX Xcode (push) Canceled after 0s
CMake builds / macOS 14 wxIOS (push) Canceled after 0s
CMake builds / MSW/MSVC wxQt 5.15 (push) Canceled after 0s
CMake builds / MSW/MSVC wxQt 6.10 (push) Canceled after 0s
Mac builds / wxMac ARM ASAN not compatible (push) Canceled after 0s
Mac builds / wxMac Universal C++14 (push) Canceled after 0s
Mac builds / wxiOS Simulator on Silicon Mac (push) Canceled after 0s
Mac builds / wxiOS (push) Canceled after 0s
Mac builds / wxMac Intel C++17 (push) Canceled after 0s
Mac Xcode builds / iOS Simulator static (push) Canceled after 0s
Mac Xcode builds / macOS dynamic Release (push) Canceled after 0s
Mac Xcode builds / iOS static Debug (push) Canceled after 0s
MSW builds / wxMSW vs2022 DLL Debug x64 (push) Canceled after 0s
MSW builds / wxMSW vs2022 DLL Release x64 (push) Canceled after 0s
MSW builds / wxMSW vs2022 Debug Win32 (push) Canceled after 0s
MSW builds / wxMSW vs2022 Release arm64 (push) Canceled after 0s
MSW builds / wxMSW vs2026 DLL Release x64 (push) Canceled after 0s
MSW cross-builds / wxMSW 64 bits not compatible (push) Canceled after 0s
MSW cross-builds / wxMSW/Univ (push) Canceled after 0s
MSW cross-builds / wxMSW 32 bits (push) Canceled after 0s
Code Checks / Check Spelling (push) Canceled after 0s
Code Checks / Check Whitespace (push) Canceled after 0s
Code Checks / Check Mixed EOL (push) Canceled after 0s
Code Checks / Check C++ Style (push) Canceled after 0s
Code Checks / Check All Headers In allheaders.h (push) Canceled after 0s
This avoids the chronic problem of wxSysColourChangedEvent handlers inadvertently failing to call Skip() and thus blocking important internal processing, including propagating to child windows.
2335 lines
68 KiB
C++
2335 lines
68 KiB
C++
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/common/prntbase.cpp
|
|
// Purpose: Printing framework base class implementation
|
|
// Author: Julian Smart
|
|
// Created: 04/01/98
|
|
// Copyright: (c) Julian Smart
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// For compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
#if wxUSE_PRINTING_ARCHITECTURE
|
|
|
|
#include "wx/dcprint.h"
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/utils.h"
|
|
#include "wx/dc.h"
|
|
#include "wx/app.h"
|
|
#include "wx/math.h"
|
|
#include "wx/msgdlg.h"
|
|
#include "wx/layout.h"
|
|
#include "wx/choice.h"
|
|
#include "wx/button.h"
|
|
#include "wx/bmpbuttn.h"
|
|
#include "wx/settings.h"
|
|
#include "wx/dcmemory.h"
|
|
#include "wx/dcclient.h"
|
|
#include "wx/stattext.h"
|
|
#include "wx/intl.h"
|
|
#include "wx/textctrl.h"
|
|
#include "wx/textdlg.h"
|
|
#include "wx/sizer.h"
|
|
#include "wx/module.h"
|
|
#endif // !WX_PRECOMP
|
|
|
|
#include "wx/prntbase.h"
|
|
#include "wx/printdlg.h"
|
|
#include "wx/print.h"
|
|
#include "wx/dcprint.h"
|
|
#include "wx/artprov.h"
|
|
#include "wx/display.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
#include "wx/msw/printdlg.h"
|
|
#include "wx/msw/dcprint.h"
|
|
#elif defined(__WXMAC__)
|
|
#include "wx/osx/printdlg.h"
|
|
#include "wx/osx/private/print.h"
|
|
#include "wx/osx/dcprint.h"
|
|
#elif defined(__WXQT__)
|
|
#include "wx/qt/dcprint.h"
|
|
#include "wx/qt/printdlg.h"
|
|
#else
|
|
#include "wx/generic/prntdlgg.h"
|
|
#include "wx/dcps.h"
|
|
#endif
|
|
|
|
// The value traditionally used as the default max page number and meaning
|
|
// "infinitely many". It should probably be documented and exposed, but for now
|
|
// at least use it here instead of hardcoding the number.
|
|
static const int DEFAULT_MAX_PAGES = 32000;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrintFactory
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxPrintFactory *wxPrintFactory::m_factory = nullptr;
|
|
|
|
void wxPrintFactory::SetPrintFactory( wxPrintFactory *factory )
|
|
{
|
|
delete wxPrintFactory::m_factory;
|
|
wxPrintFactory::m_factory = factory;
|
|
}
|
|
|
|
wxPrintFactory *wxPrintFactory::GetFactory()
|
|
{
|
|
if (!wxPrintFactory::m_factory)
|
|
wxPrintFactory::m_factory = new wxNativePrintFactory;
|
|
|
|
return wxPrintFactory::m_factory;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxNativePrintFactory
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxPrinterBase *wxNativePrintFactory::CreatePrinter( wxPrintDialogData *data )
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return new wxWindowsPrinter( data );
|
|
#elif defined(__WXMAC__)
|
|
return new wxMacPrinter( data );
|
|
#elif defined(__WXQT__)
|
|
return new wxQtPrinter( data );
|
|
#else
|
|
return new wxPostScriptPrinter( data );
|
|
#endif
|
|
}
|
|
|
|
wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
|
|
wxPrintout *printout, wxPrintDialogData *data )
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return new wxWindowsPrintPreview( preview, printout, data );
|
|
#elif defined(__WXMAC__)
|
|
return new wxMacPrintPreview( preview, printout, data );
|
|
#elif defined(__WXQT__)
|
|
return new wxQtPrintPreview( preview, printout, data );
|
|
#else
|
|
return new wxPostScriptPrintPreview( preview, printout, data );
|
|
#endif
|
|
}
|
|
|
|
wxPrintPreviewBase *wxNativePrintFactory::CreatePrintPreview( wxPrintout *preview,
|
|
wxPrintout *printout, wxPrintData *data )
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return new wxWindowsPrintPreview( preview, printout, data );
|
|
#elif defined(__WXMAC__)
|
|
return new wxMacPrintPreview( preview, printout, data );
|
|
#elif defined(__WXQT__)
|
|
return new wxQtPrintPreview( preview, printout, data );
|
|
#else
|
|
return new wxPostScriptPrintPreview( preview, printout, data );
|
|
#endif
|
|
}
|
|
|
|
wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
|
|
wxPrintDialogData *data )
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return new wxWindowsPrintDialog( parent, data );
|
|
#elif defined(__WXMAC__)
|
|
return new wxMacPrintDialog( parent, data );
|
|
#elif defined(__WXQT__)
|
|
return new wxQtPrintDialog( parent, data );
|
|
#else
|
|
return new wxGenericPrintDialog( parent, data );
|
|
#endif
|
|
}
|
|
|
|
wxPrintDialogBase *wxNativePrintFactory::CreatePrintDialog( wxWindow *parent,
|
|
wxPrintData *data )
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return new wxWindowsPrintDialog( parent, data );
|
|
#elif defined(__WXMAC__)
|
|
return new wxMacPrintDialog( parent, data );
|
|
#elif defined(__WXQT__)
|
|
return new wxQtPrintDialog( parent, data );
|
|
#else
|
|
return new wxGenericPrintDialog( parent, data );
|
|
#endif
|
|
}
|
|
|
|
wxPageSetupDialogBase *wxNativePrintFactory::CreatePageSetupDialog( wxWindow *parent,
|
|
wxPageSetupDialogData *data )
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return new wxWindowsPageSetupDialog( parent, data );
|
|
#elif defined(__WXMAC__)
|
|
return new wxMacPageSetupDialog( parent, data );
|
|
#elif defined(__WXQT__)
|
|
return new wxQtPageSetupDialog( parent, data );
|
|
#else
|
|
return new wxGenericPageSetupDialog( parent, data );
|
|
#endif
|
|
}
|
|
|
|
bool wxNativePrintFactory::HasPrintSetupDialog()
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return false;
|
|
#elif defined(__WXMAC__)
|
|
return false;
|
|
#else
|
|
// Only here do we need to provide the print setup
|
|
// dialog ourselves, the other platforms either have
|
|
// none, don't make it accessible or let you configure
|
|
// the printer from the wxPrintDialog anyway.
|
|
return true;
|
|
#endif
|
|
|
|
}
|
|
|
|
wxDialog *wxNativePrintFactory::CreatePrintSetupDialog( wxWindow *parent,
|
|
wxPrintData *data )
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
wxUnusedVar(parent);
|
|
wxUnusedVar(data);
|
|
return nullptr;
|
|
#elif defined(__WXMAC__)
|
|
wxUnusedVar(parent);
|
|
wxUnusedVar(data);
|
|
return nullptr;
|
|
#elif defined(__WXQT__)
|
|
wxUnusedVar(parent);
|
|
wxUnusedVar(data);
|
|
return nullptr;
|
|
#else
|
|
// Only here do we need to provide the print setup
|
|
// dialog ourselves, the other platforms either have
|
|
// none, don't make it accessible or let you configure
|
|
// the printer from the wxPrintDialog anyway.
|
|
return new wxGenericPrintSetupDialog( parent, data );
|
|
#endif
|
|
}
|
|
|
|
wxDCImpl* wxNativePrintFactory::CreatePrinterDCImpl( wxPrinterDC *owner, const wxPrintData& data )
|
|
{
|
|
#if defined(__WXGTK__) || ( defined(__WXUNIVERSAL__) && !defined(__WXMAC__) )
|
|
return new wxPostScriptDCImpl( owner, data );
|
|
#else
|
|
return new wxPrinterDCImpl( owner, data );
|
|
#endif
|
|
}
|
|
|
|
bool wxNativePrintFactory::HasOwnPrintToFile()
|
|
{
|
|
// Only relevant for PostScript and here the
|
|
// setup dialog provides no "print to file"
|
|
// option. In the GNOME setup dialog, the
|
|
// setup dialog has its own print to file.
|
|
return false;
|
|
}
|
|
|
|
bool wxNativePrintFactory::HasPrinterLine()
|
|
{
|
|
// Only relevant for PostScript for now
|
|
return true;
|
|
}
|
|
|
|
wxString wxNativePrintFactory::CreatePrinterLine()
|
|
{
|
|
// Only relevant for PostScript for now
|
|
|
|
// We should query "lpstat -d" here
|
|
return _("Generic PostScript");
|
|
}
|
|
|
|
bool wxNativePrintFactory::HasStatusLine()
|
|
{
|
|
// Only relevant for PostScript for now
|
|
return true;
|
|
}
|
|
|
|
wxString wxNativePrintFactory::CreateStatusLine()
|
|
{
|
|
// Only relevant for PostScript for now
|
|
|
|
// We should query "lpstat -r" or "lpstat -p" here
|
|
return _("Ready");
|
|
}
|
|
|
|
wxPrintNativeDataBase *wxNativePrintFactory::CreatePrintNativeData()
|
|
{
|
|
#if defined(__WXMSW__) && !defined(__WXUNIVERSAL__)
|
|
return new wxWindowsPrintNativeData;
|
|
#elif defined(__WXMAC__)
|
|
return wxOSXCreatePrintData();
|
|
#elif defined(__WXQT__)
|
|
return new wxQtPrintNativeData;
|
|
#else
|
|
return new wxPostScriptPrintNativeData;
|
|
#endif
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrintNativeDataBase
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase, wxObject);
|
|
|
|
wxPrintNativeDataBase::~wxPrintNativeDataBase() = default;
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrintFactoryModule
|
|
//----------------------------------------------------------------------------
|
|
|
|
class wxPrintFactoryModule: public wxModule
|
|
{
|
|
public:
|
|
wxPrintFactoryModule() {}
|
|
bool OnInit() override { return true; }
|
|
void OnExit() override { wxPrintFactory::SetPrintFactory( nullptr ); }
|
|
|
|
private:
|
|
wxDECLARE_DYNAMIC_CLASS(wxPrintFactoryModule);
|
|
};
|
|
|
|
wxIMPLEMENT_DYNAMIC_CLASS(wxPrintFactoryModule, wxModule);
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrinterBase
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_CLASS(wxPrinterBase, wxObject);
|
|
|
|
wxPrinterBase::wxPrinterBase(wxPrintDialogData *data)
|
|
{
|
|
m_currentPrintout = nullptr;
|
|
sm_abortWindow = nullptr;
|
|
sm_abortIt = false;
|
|
if (data)
|
|
m_printDialogData = (*data);
|
|
sm_lastError = wxPRINTER_NO_ERROR;
|
|
}
|
|
|
|
wxWindow *wxPrinterBase::sm_abortWindow = nullptr;
|
|
bool wxPrinterBase::sm_abortIt = false;
|
|
wxPrinterError wxPrinterBase::sm_lastError = wxPRINTER_NO_ERROR;
|
|
|
|
wxPrinterBase::~wxPrinterBase()
|
|
{
|
|
}
|
|
|
|
wxPrintAbortDialog *wxPrinterBase::CreateAbortWindow(wxWindow *parent, wxPrintout * printout)
|
|
{
|
|
return new wxPrintAbortDialog(parent, printout->GetTitle());
|
|
}
|
|
|
|
void wxPrinterBase::ReportError(wxWindow *parent, wxPrintout *WXUNUSED(printout), const wxString& message)
|
|
{
|
|
wxMessageBox(message, _("Printing Error"), wxOK, parent);
|
|
}
|
|
|
|
wxPrintDialogData& wxPrinterBase::GetPrintDialogData() const
|
|
{
|
|
return const_cast<wxPrintDialogData&>(m_printDialogData);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrinter
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_CLASS(wxPrinter, wxPrinterBase);
|
|
|
|
wxPrinter::wxPrinter(wxPrintDialogData *data)
|
|
{
|
|
m_pimpl = wxPrintFactory::GetFactory()->CreatePrinter( data );
|
|
}
|
|
|
|
wxPrinter::~wxPrinter()
|
|
{
|
|
delete m_pimpl;
|
|
}
|
|
|
|
wxPrintAbortDialog *wxPrinter::CreateAbortWindow(wxWindow *parent, wxPrintout *printout)
|
|
{
|
|
return m_pimpl->CreateAbortWindow( parent, printout );
|
|
}
|
|
|
|
void wxPrinter::ReportError(wxWindow *parent, wxPrintout *printout, const wxString& message)
|
|
{
|
|
m_pimpl->ReportError( parent, printout, message );
|
|
}
|
|
|
|
bool wxPrinter::Setup(wxWindow *parent)
|
|
{
|
|
return m_pimpl->Setup( parent );
|
|
}
|
|
|
|
bool wxPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt)
|
|
{
|
|
if ( !prompt && m_printDialogData.GetToPage() == 0 )
|
|
{
|
|
// If the dialog is not shown, set the pages range to print everything
|
|
// by default (as otherwise we wouldn't print anything at all which is
|
|
// certainly not a reasonable default behaviour).
|
|
wxPrintPageRanges ranges;
|
|
const auto all = printout->GetPagesInfo(ranges);
|
|
if ( ranges.empty() )
|
|
{
|
|
// If the printout didn't specify any pages neither, print them all.
|
|
ranges.push_back(all);
|
|
}
|
|
|
|
m_pimpl->GetPrintDialogData().SetPageRanges(ranges);
|
|
}
|
|
|
|
return m_pimpl->Print( parent, printout, prompt );
|
|
}
|
|
|
|
wxDC* wxPrinter::PrintDialog(wxWindow *parent)
|
|
{
|
|
return m_pimpl->PrintDialog( parent );
|
|
}
|
|
|
|
wxPrintDialogData& wxPrinter::GetPrintDialogData() const
|
|
{
|
|
return m_pimpl->GetPrintDialogData();
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// wxPrintDialogBase: the dialog for printing.
|
|
// ---------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_ABSTRACT_CLASS(wxPrintDialogBase, wxDialog);
|
|
|
|
wxPrintDialogBase::wxPrintDialogBase(wxWindow *parent,
|
|
wxWindowID id,
|
|
const wxString &title,
|
|
const wxPoint &pos,
|
|
const wxSize &size,
|
|
long style)
|
|
: wxDialog( parent, id, title.empty() ? wxString(_("Print")) : title,
|
|
pos, size, style )
|
|
{
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// wxPrintDialog: the dialog for printing
|
|
// ---------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_CLASS(wxPrintDialog, wxObject);
|
|
|
|
wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintDialogData* data)
|
|
{
|
|
m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
|
|
}
|
|
|
|
wxPrintDialog::wxPrintDialog(wxWindow *parent, wxPrintData* data)
|
|
{
|
|
m_pimpl = wxPrintFactory::GetFactory()->CreatePrintDialog( parent, data );
|
|
}
|
|
|
|
wxPrintDialog::~wxPrintDialog()
|
|
{
|
|
delete m_pimpl;
|
|
}
|
|
|
|
int wxPrintDialog::ShowModal()
|
|
{
|
|
return m_pimpl->ShowModal();
|
|
}
|
|
|
|
wxPrintDialogData& wxPrintDialog::GetPrintDialogData()
|
|
{
|
|
return m_pimpl->GetPrintDialogData();
|
|
}
|
|
|
|
wxPrintData& wxPrintDialog::GetPrintData()
|
|
{
|
|
return m_pimpl->GetPrintData();
|
|
}
|
|
|
|
wxDC *wxPrintDialog::GetPrintDC()
|
|
{
|
|
return m_pimpl->GetPrintDC();
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// wxPageSetupDialogBase: the page setup dialog
|
|
// ---------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_ABSTRACT_CLASS(wxPageSetupDialogBase, wxDialog);
|
|
|
|
wxPageSetupDialogBase::wxPageSetupDialogBase(wxWindow *parent,
|
|
wxWindowID id,
|
|
const wxString &title,
|
|
const wxPoint &pos,
|
|
const wxSize &size,
|
|
long style)
|
|
: wxDialog( parent, id, title.empty() ? wxString(_("Page setup")) : title,
|
|
pos, size, style )
|
|
{
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// wxPageSetupDialog: the page setup dialog
|
|
// ---------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_CLASS(wxPageSetupDialog, wxObject);
|
|
|
|
wxPageSetupDialog::wxPageSetupDialog(wxWindow *parent, wxPageSetupDialogData *data )
|
|
{
|
|
m_pimpl = wxPrintFactory::GetFactory()->CreatePageSetupDialog( parent, data );
|
|
}
|
|
|
|
wxPageSetupDialog::~wxPageSetupDialog()
|
|
{
|
|
delete m_pimpl;
|
|
}
|
|
|
|
int wxPageSetupDialog::ShowModal()
|
|
{
|
|
return m_pimpl->ShowModal();
|
|
}
|
|
|
|
wxPageSetupDialogData& wxPageSetupDialog::GetPageSetupDialogData()
|
|
{
|
|
return m_pimpl->GetPageSetupDialogData();
|
|
}
|
|
|
|
// old name
|
|
wxPageSetupDialogData& wxPageSetupDialog::GetPageSetupData()
|
|
{
|
|
return m_pimpl->GetPageSetupDialogData();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrintAbortDialog
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxBEGIN_EVENT_TABLE(wxPrintAbortDialog, wxDialog)
|
|
EVT_BUTTON(wxID_CANCEL, wxPrintAbortDialog::OnCancel)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
wxPrintAbortDialog::wxPrintAbortDialog(wxWindow *parent,
|
|
const wxString& documentTitle,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style,
|
|
const wxString& name)
|
|
: wxDialog(parent, wxID_ANY, _("Printing"), pos, size, style, name)
|
|
{
|
|
wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
|
|
mainSizer->Add(new wxStaticText(this, wxID_ANY, _("Please wait while printing...")),
|
|
wxSizerFlags().Expand().DoubleBorder());
|
|
|
|
wxFlexGridSizer *gridSizer = new wxFlexGridSizer(2, FromDIP(wxSize(20, 0)));
|
|
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Document:")));
|
|
gridSizer->AddGrowableCol(1);
|
|
gridSizer->Add(new wxStaticText(this, wxID_ANY, documentTitle));
|
|
gridSizer->Add(new wxStaticText(this, wxID_ANY, _("Progress:")));
|
|
m_progress = new wxStaticText(this, wxID_ANY, _("Preparing"));
|
|
m_progress->SetMinSize(FromDIP(wxSize(250, -1)));
|
|
gridSizer->Add(m_progress);
|
|
mainSizer->Add(gridSizer, wxSizerFlags().Expand().DoubleBorder(wxLEFT | wxRIGHT));
|
|
|
|
mainSizer->Add(CreateStdDialogButtonSizer(wxCANCEL),
|
|
wxSizerFlags().Expand().DoubleBorder());
|
|
|
|
SetSizerAndFit(mainSizer);
|
|
}
|
|
|
|
void wxPrintAbortDialog::SetProgress(int currentPage, int totalPages,
|
|
int currentCopy, int totalCopies)
|
|
{
|
|
wxString text;
|
|
if ( totalPages == DEFAULT_MAX_PAGES )
|
|
{
|
|
// This means that the user has not supplied a total number of pages so it
|
|
// is better not to show this value.
|
|
text.Printf(_("Printing page %d"), currentPage);
|
|
}
|
|
else
|
|
{
|
|
// We have a valid total number of pages so we show it.
|
|
text.Printf(_("Printing page %d of %d"), currentPage, totalPages);
|
|
}
|
|
if ( totalCopies > 1 )
|
|
text += wxString::Format(_(" (copy %d of %d)"), currentCopy, totalCopies);
|
|
m_progress->SetLabel(text);
|
|
}
|
|
|
|
void wxPrintAbortDialog::OnCancel(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxCHECK_RET( wxPrinterBase::sm_abortWindow != nullptr, "OnCancel called twice" );
|
|
wxPrinterBase::sm_abortIt = true;
|
|
wxPrinterBase::sm_abortWindow->Destroy();
|
|
wxPrinterBase::sm_abortWindow = nullptr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrintout
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_ABSTRACT_CLASS(wxPrintout, wxObject);
|
|
|
|
wxPrintout::wxPrintout(const wxString& title)
|
|
: m_printoutTitle(title)
|
|
{
|
|
m_printoutDC = nullptr;
|
|
m_pageWidthMM = 0;
|
|
m_pageHeightMM = 0;
|
|
m_pageWidthPixels = 0;
|
|
m_pageHeightPixels = 0;
|
|
m_PPIScreenX = 0;
|
|
m_PPIScreenY = 0;
|
|
m_PPIPrinterX = 0;
|
|
m_PPIPrinterY = 0;
|
|
m_preview = nullptr;
|
|
}
|
|
|
|
wxPrintout::~wxPrintout()
|
|
{
|
|
}
|
|
|
|
bool wxPrintout::OnBeginDocument(int WXUNUSED(startPage), int WXUNUSED(endPage))
|
|
{
|
|
return GetDC()->StartDoc(m_printoutTitle);
|
|
}
|
|
|
|
void wxPrintout::OnEndDocument()
|
|
{
|
|
GetDC()->EndDoc();
|
|
}
|
|
|
|
void wxPrintout::OnBeginPrinting()
|
|
{
|
|
}
|
|
|
|
void wxPrintout::OnEndPrinting()
|
|
{
|
|
}
|
|
|
|
bool wxPrintout::HasPage(int page)
|
|
{
|
|
return (page == 1);
|
|
}
|
|
|
|
void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toPage)
|
|
{
|
|
*minPage = 1;
|
|
*maxPage = DEFAULT_MAX_PAGES;
|
|
*fromPage = 1;
|
|
*toPage = 1;
|
|
}
|
|
|
|
wxPrintPageRange wxPrintout::GetPagesInfo(wxPrintPageRanges& ranges)
|
|
{
|
|
int minPage = 0;
|
|
int maxPage = 0;
|
|
int fromPage = 0;
|
|
int toPage = 0;
|
|
|
|
GetPageInfo(&minPage, &maxPage, &fromPage, &toPage);
|
|
|
|
// We intentionally ignore fromPage and toPage here as we want to keep
|
|
// using the page ranges as they were set by the user in the print dialog
|
|
// but existing code dating from before support for multiple print ranges
|
|
// always returns something from its GetPageInfo() -- which is incompatible
|
|
// with multiple pages ranges selection (in fact, it's not even compatible
|
|
// with a single range selection because the values returned in these
|
|
// parameters used to be ignored in at least wxMSW anyhow).
|
|
wxUnusedVar(ranges);
|
|
|
|
return { minPage, maxPage };
|
|
}
|
|
|
|
bool wxPrintout::SetUp(wxDC& dc)
|
|
{
|
|
wxCHECK_MSG( dc.IsOk(), false, "should have a valid DC to set up" );
|
|
|
|
SetPPIScreen(wxDisplay::GetStdPPI());
|
|
|
|
// We need to know printer PPI. In most ports, this can be retrieved from
|
|
// the printer DC, but in others it is computed (probably for legacy
|
|
// reasons) outside of wxDC code, so don't override it if it had been
|
|
// already set.
|
|
if ( !m_PPIPrinterX || !m_PPIPrinterY )
|
|
{
|
|
SetPPIPrinter(dc.GetPPI());
|
|
if ( !m_PPIPrinterX || !m_PPIPrinterY )
|
|
{
|
|
// But if we couldn't get it in any way, we can't continue.
|
|
return false;
|
|
}
|
|
}
|
|
|
|
SetDC(&dc);
|
|
|
|
dc.GetSize(&m_pageWidthPixels, &m_pageHeightPixels);
|
|
// This is ugly, but wxDCImpl itself has GetPaperRect() method while wxDC
|
|
// doesn't (only wxPrinterDC does), so use GetImpl() to avoid having to use
|
|
// a dynamic cast.
|
|
m_paperRectPixels = dc.GetImpl()->GetPaperRect();
|
|
dc.GetSizeMM(&m_pageWidthMM, &m_pageHeightMM);
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxPrintout::FitThisSizeToPaper(const wxSize& imageSize)
|
|
{
|
|
// Set the DC scale and origin so that the given image size fits within the
|
|
// entire page and the origin is at the top left corner of the page. Note
|
|
// that with most printers, portions of the page will be non-printable. Use
|
|
// this if you're managing your own page margins.
|
|
if (!m_printoutDC) return;
|
|
wxRect paperRect = GetPaperRectPixels();
|
|
wxCoord pw, ph;
|
|
GetPageSizePixels(&pw, &ph);
|
|
wxCoord w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
double scaleX = (double(paperRect.width) * w) / (double(pw) * imageSize.x);
|
|
double scaleY = (double(paperRect.height) * h) / (double(ph) * imageSize.y);
|
|
double actualScale = wxMin(scaleX, scaleY);
|
|
m_printoutDC->SetUserScale(actualScale, actualScale);
|
|
m_printoutDC->SetDeviceOrigin(0, 0);
|
|
wxRect logicalPaperRect = GetLogicalPaperRect();
|
|
SetLogicalOrigin(logicalPaperRect.x, logicalPaperRect.y);
|
|
}
|
|
|
|
void wxPrintout::FitThisSizeToPage(const wxSize& imageSize)
|
|
{
|
|
// Set the DC scale and origin so that the given image size fits within the
|
|
// printable area of the page and the origin is at the top left corner of
|
|
// the printable area.
|
|
if (!m_printoutDC) return;
|
|
int w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
double scaleX = double(w) / imageSize.x;
|
|
double scaleY = double(h) / imageSize.y;
|
|
double actualScale = wxMin(scaleX, scaleY);
|
|
m_printoutDC->SetUserScale(actualScale, actualScale);
|
|
m_printoutDC->SetDeviceOrigin(0, 0);
|
|
}
|
|
|
|
void wxPrintout::FitThisSizeToPageMargins(const wxSize& imageSize, const wxPageSetupDialogData& pageSetupData)
|
|
{
|
|
// Set the DC scale and origin so that the given image size fits within the
|
|
// page margins defined in the given wxPageSetupDialogData object and the
|
|
// origin is at the top left corner of the page margins.
|
|
if (!m_printoutDC) return;
|
|
wxRect paperRect = GetPaperRectPixels();
|
|
wxCoord pw, ph;
|
|
GetPageSizePixels(&pw, &ph);
|
|
wxPoint topLeft = pageSetupData.GetMarginTopLeft();
|
|
wxPoint bottomRight = pageSetupData.GetMarginBottomRight();
|
|
wxCoord mw, mh;
|
|
GetPageSizeMM(&mw, &mh);
|
|
float mmToDeviceX = float(pw) / mw;
|
|
float mmToDeviceY = float(ph) / mh;
|
|
wxRect pageMarginsRect(paperRect.x + wxRound(mmToDeviceX * topLeft.x),
|
|
paperRect.y + wxRound(mmToDeviceY * topLeft.y),
|
|
paperRect.width - wxRound(mmToDeviceX * (topLeft.x + bottomRight.x)),
|
|
paperRect.height - wxRound(mmToDeviceY * (topLeft.y + bottomRight.y)));
|
|
wxCoord w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
double scaleX = (double(pageMarginsRect.width) * w) / (double(pw) * imageSize.x);
|
|
double scaleY = (double(pageMarginsRect.height) * h) / (double(ph) * imageSize.y);
|
|
double actualScale = wxMin(scaleX, scaleY);
|
|
m_printoutDC->SetUserScale(actualScale, actualScale);
|
|
m_printoutDC->SetDeviceOrigin(0, 0);
|
|
wxRect logicalPageMarginsRect = GetLogicalPageMarginsRect(pageSetupData);
|
|
SetLogicalOrigin(logicalPageMarginsRect.x, logicalPageMarginsRect.y);
|
|
}
|
|
|
|
void wxPrintout::MapScreenSizeToPaper()
|
|
{
|
|
// Set the DC scale so that an image on the screen is the same size on the
|
|
// paper and the origin is at the top left of the paper. Note that with most
|
|
// printers, portions of the page will be cut off. Use this if you're
|
|
// managing your own page margins.
|
|
if (!m_printoutDC) return;
|
|
MapScreenSizeToPage();
|
|
wxRect logicalPaperRect = GetLogicalPaperRect();
|
|
SetLogicalOrigin(logicalPaperRect.x, logicalPaperRect.y);
|
|
}
|
|
|
|
void wxPrintout::MapScreenSizeToPage()
|
|
{
|
|
// Set the DC scale and origin so that an image on the screen is the same
|
|
// size on the paper and the origin is at the top left of the printable area.
|
|
if (!m_printoutDC) return;
|
|
int ppiScreenX, ppiScreenY;
|
|
GetPPIScreen(&ppiScreenX, &ppiScreenY);
|
|
int ppiPrinterX, ppiPrinterY;
|
|
GetPPIPrinter(&ppiPrinterX, &ppiPrinterY);
|
|
int w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
int pageSizePixelsX, pageSizePixelsY;
|
|
GetPageSizePixels(&pageSizePixelsX, &pageSizePixelsY);
|
|
double userScaleX = (double(ppiPrinterX) * w) / (double(ppiScreenX) * pageSizePixelsX);
|
|
double userScaleY = (double(ppiPrinterY) * h) / (double(ppiScreenY) * pageSizePixelsY);
|
|
m_printoutDC->SetUserScale(userScaleX, userScaleY);
|
|
m_printoutDC->SetDeviceOrigin(0, 0);
|
|
}
|
|
|
|
void wxPrintout::MapScreenSizeToPageMargins(const wxPageSetupDialogData& pageSetupData)
|
|
{
|
|
// Set the DC scale so that an image on the screen is the same size on the
|
|
// paper and the origin is at the top left of the page margins defined by
|
|
// the given wxPageSetupDialogData object.
|
|
if (!m_printoutDC) return;
|
|
MapScreenSizeToPage();
|
|
wxRect logicalPageMarginsRect = GetLogicalPageMarginsRect(pageSetupData);
|
|
SetLogicalOrigin(logicalPageMarginsRect.x, logicalPageMarginsRect.y);
|
|
}
|
|
|
|
void wxPrintout::MapScreenSizeToDevice()
|
|
{
|
|
// Set the DC scale so that a screen pixel is the same size as a device
|
|
// pixel and the origin is at the top left of the printable area.
|
|
if (!m_printoutDC) return;
|
|
int w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
int pageSizePixelsX, pageSizePixelsY;
|
|
GetPageSizePixels(&pageSizePixelsX, &pageSizePixelsY);
|
|
double userScaleX = double(w) / pageSizePixelsX;
|
|
double userScaleY = double(h) / pageSizePixelsY;
|
|
m_printoutDC->SetUserScale(userScaleX, userScaleY);
|
|
m_printoutDC->SetDeviceOrigin(0, 0);
|
|
}
|
|
|
|
wxRect wxPrintout::GetLogicalPaperRect() const
|
|
{
|
|
// Return the rectangle in logical units that corresponds to the paper
|
|
// rectangle.
|
|
wxRect paperRect = GetPaperRectPixels();
|
|
wxCoord pw, ph;
|
|
GetPageSizePixels(&pw, &ph);
|
|
wxCoord w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
if (w == pw && h == ph) {
|
|
// this DC matches the printed page, so no scaling
|
|
return wxRect(m_printoutDC->DeviceToLogicalX(paperRect.x),
|
|
m_printoutDC->DeviceToLogicalY(paperRect.y),
|
|
m_printoutDC->DeviceToLogicalXRel(paperRect.width),
|
|
m_printoutDC->DeviceToLogicalYRel(paperRect.height));
|
|
}
|
|
// This DC doesn't match the printed page, so we have to scale.
|
|
float scaleX = float(w) / pw;
|
|
float scaleY = float(h) / ph;
|
|
return wxRect(m_printoutDC->DeviceToLogicalX(wxRound(paperRect.x * scaleX)),
|
|
m_printoutDC->DeviceToLogicalY(wxRound(paperRect.y * scaleY)),
|
|
m_printoutDC->DeviceToLogicalXRel(wxRound(paperRect.width * scaleX)),
|
|
m_printoutDC->DeviceToLogicalYRel(wxRound(paperRect.height * scaleY)));
|
|
}
|
|
|
|
wxRect wxPrintout::GetLogicalPageRect() const
|
|
{
|
|
// Return the rectangle in logical units that corresponds to the printable
|
|
// area.
|
|
int w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
return wxRect(m_printoutDC->DeviceToLogicalX(0),
|
|
m_printoutDC->DeviceToLogicalY(0),
|
|
m_printoutDC->DeviceToLogicalXRel(w),
|
|
m_printoutDC->DeviceToLogicalYRel(h));
|
|
}
|
|
|
|
wxRect wxPrintout::GetLogicalPageMarginsRect(const wxPageSetupDialogData& pageSetupData) const
|
|
{
|
|
// Return the rectangle in logical units that corresponds to the region
|
|
// within the page margins as specified by the given wxPageSetupDialogData
|
|
// object.
|
|
|
|
// We get the paper size in device units and the margins in mm,
|
|
// so we need to calculate the conversion with this trick
|
|
wxCoord pw, ph;
|
|
GetPageSizePixels(&pw, &ph);
|
|
wxCoord mw, mh;
|
|
GetPageSizeMM(&mw, &mh);
|
|
float mmToDeviceX = float(pw) / mw;
|
|
float mmToDeviceY = float(ph) / mh;
|
|
|
|
// paper size in device units
|
|
wxRect paperRect = GetPaperRectPixels();
|
|
|
|
// margins in mm
|
|
wxPoint topLeft = pageSetupData.GetMarginTopLeft();
|
|
wxPoint bottomRight = pageSetupData.GetMarginBottomRight();
|
|
|
|
// calculate margins in device units
|
|
wxRect pageMarginsRect(
|
|
paperRect.x + wxRound(mmToDeviceX * topLeft.x),
|
|
paperRect.y + wxRound(mmToDeviceY * topLeft.y),
|
|
paperRect.width - wxRound(mmToDeviceX * (topLeft.x + bottomRight.x)),
|
|
paperRect.height - wxRound(mmToDeviceY * (topLeft.y + bottomRight.y)));
|
|
|
|
wxCoord w, h;
|
|
m_printoutDC->GetSize(&w, &h);
|
|
if (w == pw && h == ph)
|
|
{
|
|
// this DC matches the printed page, so no scaling
|
|
return wxRect(
|
|
m_printoutDC->DeviceToLogicalX(pageMarginsRect.x),
|
|
m_printoutDC->DeviceToLogicalY(pageMarginsRect.y),
|
|
m_printoutDC->DeviceToLogicalXRel(pageMarginsRect.width),
|
|
m_printoutDC->DeviceToLogicalYRel(pageMarginsRect.height));
|
|
}
|
|
|
|
// This DC doesn't match the printed page, so we have to scale.
|
|
float scaleX = float(w) / pw;
|
|
float scaleY = float(h) / ph;
|
|
return wxRect(m_printoutDC->DeviceToLogicalX(wxRound(pageMarginsRect.x * scaleX)),
|
|
m_printoutDC->DeviceToLogicalY(wxRound(pageMarginsRect.y * scaleY)),
|
|
m_printoutDC->DeviceToLogicalXRel(wxRound(pageMarginsRect.width * scaleX)),
|
|
m_printoutDC->DeviceToLogicalYRel(wxRound(pageMarginsRect.height * scaleY)));
|
|
}
|
|
|
|
void wxPrintout::SetLogicalOrigin(wxCoord x, wxCoord y)
|
|
{
|
|
// Set the device origin by specifying a point in logical coordinates.
|
|
m_printoutDC->SetDeviceOrigin(
|
|
m_printoutDC->LogicalToDeviceX(x),
|
|
m_printoutDC->LogicalToDeviceY(y) );
|
|
}
|
|
|
|
void wxPrintout::OffsetLogicalOrigin(wxCoord xoff, wxCoord yoff)
|
|
{
|
|
// Offset the device origin by a specified distance in device coordinates.
|
|
wxPoint dev_org = m_printoutDC->GetDeviceOrigin();
|
|
m_printoutDC->SetDeviceOrigin(
|
|
dev_org.x + m_printoutDC->LogicalToDeviceXRel(xoff),
|
|
dev_org.y + m_printoutDC->LogicalToDeviceYRel(yoff) );
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPreviewCanvas
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_CLASS(wxPreviewCanvas, wxWindow);
|
|
|
|
wxBEGIN_EVENT_TABLE(wxPreviewCanvas, wxScrolledWindow)
|
|
EVT_PAINT(wxPreviewCanvas::OnPaint)
|
|
EVT_CHAR(wxPreviewCanvas::OnChar)
|
|
EVT_IDLE(wxPreviewCanvas::OnIdle)
|
|
EVT_DPI_CHANGED(wxPreviewCanvas::OnDPIChanged)
|
|
EVT_SYS_COLOUR_CHANGED(wxPreviewCanvas::OnSysColourChanged)
|
|
#if wxUSE_MOUSEWHEEL
|
|
EVT_MOUSEWHEEL(wxPreviewCanvas::OnMouseWheel)
|
|
#endif
|
|
wxEND_EVENT_TABLE()
|
|
|
|
// VZ: the current code doesn't refresh properly without
|
|
// wxFULL_REPAINT_ON_RESIZE, this must be fixed as otherwise we have
|
|
// really horrible flicker when resizing the preview frame, but without
|
|
// this style it simply doesn't work correctly at all...
|
|
wxPreviewCanvas::wxPreviewCanvas(wxPrintPreviewBase *preview, wxWindow *parent,
|
|
const wxPoint& pos, const wxSize& size, long style, const wxString& name):
|
|
wxScrolledWindow(parent, wxID_ANY, pos, size, style | wxFULL_REPAINT_ON_RESIZE, name)
|
|
{
|
|
// As we rely on getting idle events, do this to ensure that we do receive
|
|
// them even when using wxIDLE_PROCESS_SPECIFIED global idle mode.
|
|
SetExtraStyle(wxWS_EX_PROCESS_IDLE);
|
|
|
|
m_printPreview = preview;
|
|
#ifdef __WXMAC__
|
|
// The app workspace colour is always white, but we should have
|
|
// a contrast with the page.
|
|
wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
|
|
#elif defined(__WXGTK__)
|
|
wxSystemColour colourIndex = wxSYS_COLOUR_BTNFACE;
|
|
#else
|
|
wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
|
|
#endif
|
|
SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
|
|
|
|
SetScrollbars(10, 10, 100, 100);
|
|
|
|
// Use some reasonable default size for this window, roughly proportional
|
|
// to the paper sheet.
|
|
SetInitialSize(FromDIP(wxSize(600, 750)));
|
|
}
|
|
|
|
wxPreviewCanvas::~wxPreviewCanvas()
|
|
{
|
|
}
|
|
|
|
void wxPreviewCanvas::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|
{
|
|
wxPaintDC dc(this);
|
|
PrepareDC( dc );
|
|
|
|
/*
|
|
#ifdef __WXGTK__
|
|
if (!GetUpdateRegion().IsEmpty())
|
|
dc.SetClippingRegion( GetUpdateRegion() );
|
|
#endif
|
|
*/
|
|
|
|
if (m_printPreview)
|
|
{
|
|
m_printPreview->PaintPage(this, dc);
|
|
}
|
|
}
|
|
|
|
void wxPreviewCanvas::OnIdle(wxIdleEvent& event)
|
|
{
|
|
event.Skip();
|
|
|
|
// prevent UpdatePageRendering() from being called recursively:
|
|
static bool s_inIdle = false;
|
|
if ( s_inIdle )
|
|
return;
|
|
s_inIdle = true;
|
|
|
|
if ( m_printPreview )
|
|
{
|
|
if ( m_printPreview->UpdatePageRendering() )
|
|
Refresh();
|
|
}
|
|
|
|
s_inIdle = false;
|
|
}
|
|
|
|
void wxPreviewCanvas::OnDPIChanged(wxDPIChangedEvent& event)
|
|
{
|
|
if ( m_printPreview )
|
|
{
|
|
m_printPreview->WXUpdateOnDPIChanged();
|
|
}
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void wxPreviewCanvas::OnSysColourChanged(wxSysColourChangedEvent& event)
|
|
{
|
|
#ifdef __WXMAC__
|
|
// The app workspace colour is always white, but we should have
|
|
// a contrast with the page.
|
|
wxSystemColour colourIndex = wxSYS_COLOUR_3DDKSHADOW;
|
|
#elif defined(__WXGTK__)
|
|
wxSystemColour colourIndex = wxSYS_COLOUR_BTNFACE;
|
|
#else
|
|
wxSystemColour colourIndex = wxSYS_COLOUR_APPWORKSPACE;
|
|
#endif
|
|
SetBackgroundColour(wxSystemSettings::GetColour(colourIndex));
|
|
Refresh();
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void wxPreviewCanvas::OnChar(wxKeyEvent &event)
|
|
{
|
|
wxPreviewControlBar* controlBar = ((wxPreviewFrame*) GetParent())->GetControlBar();
|
|
switch (event.GetKeyCode())
|
|
{
|
|
case WXK_RETURN:
|
|
controlBar->OnPrint();
|
|
return;
|
|
case (int)'+':
|
|
case WXK_NUMPAD_ADD:
|
|
case WXK_ADD:
|
|
controlBar->DoZoomIn();
|
|
return;
|
|
case (int)'-':
|
|
case WXK_NUMPAD_SUBTRACT:
|
|
case WXK_SUBTRACT:
|
|
controlBar->DoZoomOut();
|
|
return;
|
|
}
|
|
|
|
if (!event.ControlDown())
|
|
{
|
|
event.Skip();
|
|
return;
|
|
}
|
|
|
|
switch(event.GetKeyCode())
|
|
{
|
|
case WXK_PAGEDOWN:
|
|
controlBar->OnNext(); break;
|
|
case WXK_PAGEUP:
|
|
controlBar->OnPrevious(); break;
|
|
case WXK_HOME:
|
|
controlBar->OnFirst(); break;
|
|
case WXK_END:
|
|
controlBar->OnLast(); break;
|
|
default:
|
|
event.Skip();
|
|
}
|
|
}
|
|
|
|
#if wxUSE_MOUSEWHEEL
|
|
|
|
void wxPreviewCanvas::OnMouseWheel(wxMouseEvent& event)
|
|
{
|
|
wxPreviewControlBar *
|
|
controlBar = wxStaticCast(GetParent(), wxPreviewFrame)->GetControlBar();
|
|
|
|
if ( controlBar )
|
|
{
|
|
if ( event.ControlDown() && event.GetWheelRotation() != 0 )
|
|
{
|
|
int currentZoom = controlBar->GetZoomControl();
|
|
|
|
int delta;
|
|
if ( currentZoom < 100 )
|
|
delta = 5;
|
|
else if ( currentZoom <= 120 )
|
|
delta = 10;
|
|
else
|
|
delta = 50;
|
|
|
|
if ( event.GetWheelRotation() < 0 )
|
|
delta = -delta;
|
|
|
|
int newZoom = currentZoom + delta;
|
|
if ( newZoom < 10 )
|
|
newZoom = 10;
|
|
if ( newZoom > 200 )
|
|
newZoom = 200;
|
|
if ( newZoom != currentZoom )
|
|
{
|
|
controlBar->SetZoomControl(newZoom);
|
|
m_printPreview->SetZoom(newZoom);
|
|
Refresh();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
#endif // wxUSE_MOUSEWHEEL
|
|
|
|
namespace
|
|
{
|
|
|
|
// This is by the controls in the print preview as the maximal (and hence
|
|
// longest) page number we may have to display.
|
|
enum { MAX_PAGE_NUMBER = 99999 };
|
|
|
|
} // anonymous namespace
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxPrintPageMaxCtrl
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// A simple static control showing the maximal number of pages.
|
|
class wxPrintPageMaxCtrl : public wxStaticText
|
|
{
|
|
public:
|
|
wxPrintPageMaxCtrl(wxWindow *parent)
|
|
: wxStaticText(
|
|
parent,
|
|
wxID_ANY,
|
|
wxString(),
|
|
wxDefaultPosition,
|
|
wxSize
|
|
(
|
|
parent->GetTextExtent(MaxAsString(MAX_PAGE_NUMBER)).x,
|
|
wxDefaultCoord
|
|
),
|
|
wxST_NO_AUTORESIZE | wxALIGN_CENTRE
|
|
)
|
|
{
|
|
}
|
|
|
|
// Set the maximal page to display once we really know what it is.
|
|
void SetMaxPage(int maxPage)
|
|
{
|
|
SetLabel(MaxAsString(maxPage));
|
|
}
|
|
|
|
private:
|
|
static wxString MaxAsString(int maxPage)
|
|
{
|
|
return wxString::Format("/ %d", maxPage);
|
|
}
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxPrintPageMaxCtrl);
|
|
};
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// wxPrintPageTextCtrl
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// This text control contains the page number in the specified interval.
|
|
//
|
|
// Invalid pages are not accepted and the control contents is validated when it
|
|
// loses focus. Conversely, if the user changes the page to another valid one
|
|
// or presses Enter, OnGotoPage() method of the preview object will be called.
|
|
class wxPrintPageTextCtrl : public wxTextCtrl
|
|
{
|
|
public:
|
|
wxPrintPageTextCtrl(wxPreviewControlBar *preview)
|
|
: wxTextCtrl(preview,
|
|
wxID_PREVIEW_GOTO,
|
|
wxString(),
|
|
wxDefaultPosition,
|
|
// We use hardcoded maximal page number for the width
|
|
// instead of fitting it to the values we can show because
|
|
// the control looks uncomfortably narrow if the real page
|
|
// number is just one or two digits.
|
|
wxSize
|
|
(
|
|
preview->GetTextExtent(PageAsString(MAX_PAGE_NUMBER)).x,
|
|
wxDefaultCoord
|
|
),
|
|
wxTE_PROCESS_ENTER
|
|
#if wxUSE_VALIDATORS
|
|
, wxTextValidator(wxFILTER_DIGITS)
|
|
#endif // wxUSE_VALIDATORS
|
|
),
|
|
m_preview(preview)
|
|
{
|
|
m_minPage =
|
|
m_maxPage =
|
|
m_page = 1;
|
|
|
|
Bind(wxEVT_KILL_FOCUS, &wxPrintPageTextCtrl::OnKillFocus, this);
|
|
Bind(wxEVT_TEXT_ENTER, &wxPrintPageTextCtrl::OnTextEnter, this);
|
|
}
|
|
|
|
// Update the pages range, must be called after OnPreparePrinting() as
|
|
// these values are not known before.
|
|
void SetPageInfo(int minPage, int maxPage)
|
|
{
|
|
m_minPage = minPage;
|
|
m_maxPage = maxPage;
|
|
|
|
// Show the first page by default.
|
|
SetPageNumber(minPage);
|
|
}
|
|
|
|
// Helpers to conveniently set or get the current page number. Return value
|
|
// is 0 if the current controls contents is invalid.
|
|
void SetPageNumber(int page)
|
|
{
|
|
wxASSERT( IsValidPage(page) );
|
|
|
|
SetValue(PageAsString(page));
|
|
}
|
|
|
|
int GetPageNumber() const
|
|
{
|
|
long value;
|
|
if ( !GetValue().ToLong(&value) || !IsValidPage(value) )
|
|
return 0;
|
|
|
|
// Cast is safe because the value is less than (int) m_maxPage.
|
|
return static_cast<int>(value);
|
|
}
|
|
|
|
private:
|
|
static wxString PageAsString(int page)
|
|
{
|
|
return wxString::Format("%d", page);
|
|
}
|
|
|
|
bool IsValidPage(int page) const
|
|
{
|
|
return page >= m_minPage && page <= m_maxPage;
|
|
}
|
|
|
|
bool DoChangePage()
|
|
{
|
|
const int page = GetPageNumber();
|
|
|
|
if ( !page )
|
|
return false;
|
|
|
|
if ( page != m_page )
|
|
{
|
|
// We have a valid page, remember it.
|
|
m_page = page;
|
|
|
|
// And notify the owner about the change.
|
|
m_preview->OnGotoPage();
|
|
}
|
|
//else: Nothing really changed.
|
|
|
|
return true;
|
|
}
|
|
|
|
void OnKillFocus(wxFocusEvent& event)
|
|
{
|
|
if ( !DoChangePage() )
|
|
{
|
|
// The current contents is invalid so reset it back to the last
|
|
// known good page index.
|
|
SetPageNumber(m_page);
|
|
}
|
|
|
|
event.Skip();
|
|
}
|
|
|
|
void OnTextEnter(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
DoChangePage();
|
|
}
|
|
|
|
|
|
wxPreviewControlBar * const m_preview;
|
|
|
|
int m_minPage,
|
|
m_maxPage;
|
|
|
|
// This is the last valid page value that we had, we revert to it if an
|
|
// invalid page is entered.
|
|
int m_page;
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxPrintPageTextCtrl);
|
|
};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPreviewControlBar
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_CLASS(wxPreviewControlBar, wxWindow);
|
|
|
|
wxBEGIN_EVENT_TABLE(wxPreviewControlBar, wxPanel)
|
|
EVT_BUTTON(wxID_PREVIEW_CLOSE, wxPreviewControlBar::OnWindowClose)
|
|
EVT_BUTTON(wxID_PREVIEW_PRINT, wxPreviewControlBar::OnPrintButton)
|
|
EVT_BUTTON(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnPreviousButton)
|
|
EVT_BUTTON(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnNextButton)
|
|
EVT_BUTTON(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnFirstButton)
|
|
EVT_BUTTON(wxID_PREVIEW_LAST, wxPreviewControlBar::OnLastButton)
|
|
EVT_BUTTON(wxID_PREVIEW_ZOOM_IN, wxPreviewControlBar::OnZoomInButton)
|
|
EVT_BUTTON(wxID_PREVIEW_ZOOM_OUT, wxPreviewControlBar::OnZoomOutButton)
|
|
|
|
EVT_UPDATE_UI(wxID_PREVIEW_PREVIOUS, wxPreviewControlBar::OnUpdatePreviousButton)
|
|
EVT_UPDATE_UI(wxID_PREVIEW_NEXT, wxPreviewControlBar::OnUpdateNextButton)
|
|
EVT_UPDATE_UI(wxID_PREVIEW_FIRST, wxPreviewControlBar::OnUpdateFirstButton)
|
|
EVT_UPDATE_UI(wxID_PREVIEW_LAST, wxPreviewControlBar::OnUpdateLastButton)
|
|
EVT_UPDATE_UI(wxID_PREVIEW_ZOOM_IN, wxPreviewControlBar::OnUpdateZoomInButton)
|
|
EVT_UPDATE_UI(wxID_PREVIEW_ZOOM_OUT, wxPreviewControlBar::OnUpdateZoomOutButton)
|
|
|
|
EVT_CHOICE(wxID_PREVIEW_ZOOM, wxPreviewControlBar::OnZoomChoice)
|
|
EVT_PAINT(wxPreviewControlBar::OnPaint)
|
|
|
|
wxEND_EVENT_TABLE()
|
|
|
|
wxPreviewControlBar::wxPreviewControlBar(wxPrintPreviewBase *preview, long buttons,
|
|
wxWindow *parent, const wxPoint& pos, const wxSize& size,
|
|
long style, const wxString& name):
|
|
wxPanel(parent, wxID_ANY, pos, size, style, name)
|
|
{
|
|
m_printPreview = preview;
|
|
m_closeButton = nullptr;
|
|
m_zoomControl = nullptr;
|
|
m_currentPageText = nullptr;
|
|
m_maxPageText = nullptr;
|
|
m_buttonFlags = buttons;
|
|
}
|
|
|
|
wxPreviewControlBar::~wxPreviewControlBar()
|
|
{
|
|
}
|
|
|
|
void wxPreviewControlBar::OnPaint(wxPaintEvent& WXUNUSED(event))
|
|
{
|
|
wxPaintDC dc(this);
|
|
|
|
int w, h;
|
|
GetSize(&w, &h);
|
|
dc.SetPen(*wxBLACK_PEN);
|
|
dc.SetBrush(*wxTRANSPARENT_BRUSH);
|
|
dc.DrawLine( 0, h-1, w, h-1 );
|
|
}
|
|
|
|
void wxPreviewControlBar::OnWindowClose(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxPreviewFrame *frame = (wxPreviewFrame *)GetParent();
|
|
frame->Close(true);
|
|
}
|
|
|
|
void wxPreviewControlBar::OnPrint(void)
|
|
{
|
|
wxPrintPreviewBase *preview = GetPrintPreview();
|
|
preview->Print(true);
|
|
}
|
|
|
|
void wxPreviewControlBar::OnNext()
|
|
{
|
|
if ( IsNextEnabled() )
|
|
DoGotoPage(GetPrintPreview()->GetCurrentPage() + 1);
|
|
}
|
|
|
|
void wxPreviewControlBar::OnPrevious()
|
|
{
|
|
if ( IsPreviousEnabled() )
|
|
DoGotoPage(GetPrintPreview()->GetCurrentPage() - 1);
|
|
}
|
|
|
|
void wxPreviewControlBar::OnFirst()
|
|
{
|
|
if ( IsFirstEnabled() )
|
|
DoGotoPage(GetPrintPreview()->GetMinPage());
|
|
}
|
|
|
|
void wxPreviewControlBar::OnLast()
|
|
{
|
|
if ( IsLastEnabled() )
|
|
DoGotoPage(GetPrintPreview()->GetMaxPage());
|
|
}
|
|
|
|
bool wxPreviewControlBar::IsNextEnabled() const
|
|
{
|
|
wxPrintPreviewBase *preview = GetPrintPreview();
|
|
if ( !preview )
|
|
return false;
|
|
|
|
const int currentPage = preview->GetCurrentPage();
|
|
return currentPage < preview->GetMaxPage() &&
|
|
preview->GetPrintout()->HasPage(currentPage + 1);
|
|
}
|
|
|
|
bool wxPreviewControlBar::IsPreviousEnabled() const
|
|
{
|
|
wxPrintPreviewBase *preview = GetPrintPreview();
|
|
if ( !preview )
|
|
return false;
|
|
|
|
const int currentPage = preview->GetCurrentPage();
|
|
return currentPage > preview->GetMinPage() &&
|
|
preview->GetPrintout()->HasPage(currentPage - 1);
|
|
}
|
|
|
|
bool wxPreviewControlBar::IsFirstEnabled() const
|
|
{
|
|
wxPrintPreviewBase *preview = GetPrintPreview();
|
|
if (!preview)
|
|
return false;
|
|
|
|
return preview->GetPrintout()->HasPage(preview->GetMinPage());
|
|
}
|
|
|
|
bool wxPreviewControlBar::IsLastEnabled() const
|
|
{
|
|
wxPrintPreviewBase *preview = GetPrintPreview();
|
|
if (!preview)
|
|
return false;
|
|
|
|
return preview->GetPrintout()->HasPage(preview->GetMaxPage());
|
|
}
|
|
|
|
void wxPreviewControlBar::DoGotoPage(int page)
|
|
{
|
|
wxPrintPreviewBase *preview = GetPrintPreview();
|
|
wxCHECK_RET( preview, "Shouldn't be called if there is no preview." );
|
|
|
|
preview->SetCurrentPage(page);
|
|
|
|
if ( m_currentPageText )
|
|
m_currentPageText->SetPageNumber(page);
|
|
}
|
|
|
|
void wxPreviewControlBar::OnGotoPage()
|
|
{
|
|
wxPrintPreviewBase *preview = GetPrintPreview();
|
|
if (preview)
|
|
{
|
|
if (preview->GetMinPage() > 0)
|
|
{
|
|
long currentPage = m_currentPageText->GetPageNumber();
|
|
if ( currentPage )
|
|
{
|
|
if (preview->GetPrintout()->HasPage(currentPage))
|
|
{
|
|
preview->SetCurrentPage(currentPage);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxPreviewControlBar::DoZoom()
|
|
{
|
|
int zoom = GetZoomControl();
|
|
if (GetPrintPreview())
|
|
GetPrintPreview()->SetZoom(zoom);
|
|
}
|
|
|
|
bool wxPreviewControlBar::IsZoomInEnabled() const
|
|
{
|
|
if ( !m_zoomControl )
|
|
return false;
|
|
|
|
const unsigned sel = m_zoomControl->GetSelection();
|
|
return sel < m_zoomControl->GetCount() - 1;
|
|
}
|
|
|
|
bool wxPreviewControlBar::IsZoomOutEnabled() const
|
|
{
|
|
return m_zoomControl && m_zoomControl->GetSelection() > 0;
|
|
}
|
|
|
|
void wxPreviewControlBar::DoZoomIn()
|
|
{
|
|
if (IsZoomInEnabled())
|
|
{
|
|
m_zoomControl->SetSelection(m_zoomControl->GetSelection() + 1);
|
|
DoZoom();
|
|
}
|
|
}
|
|
|
|
void wxPreviewControlBar::DoZoomOut()
|
|
{
|
|
if (IsZoomOutEnabled())
|
|
{
|
|
m_zoomControl->SetSelection(m_zoomControl->GetSelection() - 1);
|
|
DoZoom();
|
|
}
|
|
}
|
|
|
|
namespace
|
|
{
|
|
|
|
// Helper class used by wxPreviewControlBar::CreateButtons() to add buttons
|
|
// sequentially to it in the simplest way possible.
|
|
class SizerWithButtons
|
|
{
|
|
public:
|
|
// Constructor creates the sizer that will hold the buttons and stores the
|
|
// parent that will be used for their creation.
|
|
SizerWithButtons(wxWindow *parent)
|
|
: m_sizer(new wxBoxSizer(wxHORIZONTAL)),
|
|
m_parent(parent)
|
|
{
|
|
m_hasContents =
|
|
m_needsSeparator = false;
|
|
}
|
|
|
|
// Destructor associates the sizer with the parent window.
|
|
~SizerWithButtons()
|
|
{
|
|
m_parent->SetSizer(m_sizer);
|
|
}
|
|
|
|
|
|
// Add an arbitrary window to the sizer.
|
|
void Add(wxWindow *win)
|
|
{
|
|
if ( m_needsSeparator )
|
|
{
|
|
m_needsSeparator = false;
|
|
|
|
m_sizer->AddSpacer(wxRound(2*wxSizerFlags::GetDefaultBorderFractional()));
|
|
}
|
|
|
|
m_hasContents = true;
|
|
|
|
m_sizer->Add(win,
|
|
wxSizerFlags().Border(wxLEFT | wxTOP | wxBOTTOM).Center());
|
|
}
|
|
|
|
// Add a button with the specified id, bitmap and tooltip.
|
|
void AddButton(wxWindowID btnId,
|
|
const wxArtID& artId,
|
|
const wxString& tooltip)
|
|
{
|
|
// We don't use (smaller) images inside a button with a text label but
|
|
// rather toolbar-like bitmap buttons hence use wxART_TOOLBAR and not
|
|
// wxART_BUTTON here.
|
|
wxBitmapBundle bb = wxArtProvider::GetBitmapBundle(artId, wxART_TOOLBAR);
|
|
wxBitmapButton * const btn = new wxBitmapButton(m_parent, btnId, bb);
|
|
btn->SetToolTip(tooltip);
|
|
|
|
Add(btn);
|
|
}
|
|
|
|
// Add a control at the right end of the window. This should be called last
|
|
// as everything else added after it will be added on the right side too.
|
|
void AddAtEnd(wxWindow *win)
|
|
{
|
|
// Ensure there is at least the same gap before the final button as
|
|
// between the other groups.
|
|
m_sizer->AddSpacer(wxRound(2*wxSizerFlags::GetDefaultBorderFractional()));
|
|
|
|
m_sizer->AddStretchSpacer();
|
|
m_sizer->Add(win,
|
|
wxSizerFlags().Border().Center());
|
|
}
|
|
|
|
// Indicates the end of a group of buttons, a separator will be added after
|
|
// it.
|
|
void EndOfGroup()
|
|
{
|
|
if ( m_hasContents )
|
|
{
|
|
m_needsSeparator = true;
|
|
m_hasContents = false;
|
|
}
|
|
}
|
|
|
|
private:
|
|
wxSizer * const m_sizer;
|
|
wxWindow * const m_parent;
|
|
|
|
// If true, we have some controls since the last group beginning. This is
|
|
// used to avoid inserting two consecutive separators if EndOfGroup() is
|
|
// called twice.
|
|
bool m_hasContents;
|
|
|
|
// If true, a separator should be inserted before adding the next button.
|
|
bool m_needsSeparator;
|
|
|
|
wxDECLARE_NO_COPY_CLASS(SizerWithButtons);
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
void wxPreviewControlBar::CreateButtons()
|
|
{
|
|
SizerWithButtons sizer(this);
|
|
|
|
// Print button group (a single button).
|
|
if (m_buttonFlags & wxPREVIEW_PRINT)
|
|
{
|
|
sizer.AddButton(wxID_PREVIEW_PRINT, wxART_PRINT, _("Print"));
|
|
sizer.EndOfGroup();
|
|
}
|
|
|
|
// Page selection buttons group.
|
|
if (m_buttonFlags & wxPREVIEW_FIRST)
|
|
{
|
|
sizer.AddButton(wxID_PREVIEW_FIRST, wxART_GOTO_FIRST, _("First page"));
|
|
}
|
|
|
|
if (m_buttonFlags & wxPREVIEW_PREVIOUS)
|
|
{
|
|
sizer.AddButton(wxID_PREVIEW_PREVIOUS, wxART_GO_BACK, _("Previous page"));
|
|
}
|
|
|
|
if (m_buttonFlags & wxPREVIEW_GOTO)
|
|
{
|
|
m_currentPageText = new wxPrintPageTextCtrl(this);
|
|
sizer.Add(m_currentPageText);
|
|
|
|
m_maxPageText = new wxPrintPageMaxCtrl(this);
|
|
sizer.Add(m_maxPageText);
|
|
}
|
|
|
|
if (m_buttonFlags & wxPREVIEW_NEXT)
|
|
{
|
|
sizer.AddButton(wxID_PREVIEW_NEXT, wxART_GO_FORWARD, _("Next page"));
|
|
}
|
|
|
|
if (m_buttonFlags & wxPREVIEW_LAST)
|
|
{
|
|
sizer.AddButton(wxID_PREVIEW_LAST, wxART_GOTO_LAST, _("Last page"));
|
|
}
|
|
|
|
sizer.EndOfGroup();
|
|
|
|
// Zoom controls group.
|
|
if (m_buttonFlags & wxPREVIEW_ZOOM)
|
|
{
|
|
sizer.AddButton(wxID_PREVIEW_ZOOM_OUT, wxART_MINUS, _("Zoom Out"));
|
|
|
|
wxString choices[] =
|
|
{
|
|
wxT("10%"), wxT("15%"), wxT("20%"), wxT("25%"), wxT("30%"), wxT("35%"), wxT("40%"), wxT("45%"), wxT("50%"), wxT("55%"),
|
|
wxT("60%"), wxT("65%"), wxT("70%"), wxT("75%"), wxT("80%"), wxT("85%"), wxT("90%"), wxT("95%"), wxT("100%"), wxT("110%"),
|
|
wxT("120%"), wxT("150%"), wxT("200%")
|
|
};
|
|
int n = WXSIZEOF(choices);
|
|
|
|
m_zoomControl = new wxChoice( this, wxID_PREVIEW_ZOOM, wxDefaultPosition, wxDefaultSize, n, choices, 0 );
|
|
sizer.Add(m_zoomControl);
|
|
SetZoomControl(m_printPreview->GetZoom());
|
|
|
|
sizer.AddButton(wxID_PREVIEW_ZOOM_IN, wxART_PLUS, _("Zoom In"));
|
|
|
|
sizer.EndOfGroup();
|
|
}
|
|
|
|
// Close button group (single button again).
|
|
m_closeButton = new wxButton(this, wxID_PREVIEW_CLOSE, _("&Close"));
|
|
sizer.AddAtEnd(m_closeButton);
|
|
}
|
|
|
|
void wxPreviewControlBar::SetPageInfo(int minPage, int maxPage)
|
|
{
|
|
if ( m_currentPageText )
|
|
m_currentPageText->SetPageInfo(minPage, maxPage);
|
|
|
|
if ( m_maxPageText )
|
|
m_maxPageText->SetMaxPage(maxPage);
|
|
}
|
|
|
|
void wxPreviewControlBar::SetZoomControl(int zoom)
|
|
{
|
|
if (m_zoomControl)
|
|
{
|
|
int n, count = m_zoomControl->GetCount();
|
|
long val;
|
|
for (n=0; n<count; n++)
|
|
{
|
|
if (m_zoomControl->GetString(n).BeforeFirst(wxT('%')).ToLong(&val) &&
|
|
(val >= long(zoom)))
|
|
{
|
|
m_zoomControl->SetSelection(n);
|
|
return;
|
|
}
|
|
}
|
|
|
|
m_zoomControl->SetSelection(count-1);
|
|
}
|
|
}
|
|
|
|
int wxPreviewControlBar::GetZoomControl()
|
|
{
|
|
if (m_zoomControl && !m_zoomControl->GetStringSelection().empty())
|
|
{
|
|
long val;
|
|
if (m_zoomControl->GetStringSelection().BeforeFirst(wxT('%')).ToLong(&val))
|
|
return int(val);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
* Preview frame
|
|
*/
|
|
|
|
wxIMPLEMENT_CLASS(wxPreviewFrame, wxFrame);
|
|
|
|
wxBEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame)
|
|
EVT_CHAR_HOOK(wxPreviewFrame::OnChar)
|
|
EVT_CLOSE(wxPreviewFrame::OnCloseWindow)
|
|
wxEND_EVENT_TABLE()
|
|
|
|
void wxPreviewFrame::OnChar(wxKeyEvent &event)
|
|
{
|
|
if ( event.GetKeyCode() == WXK_ESCAPE )
|
|
{
|
|
Close(true);
|
|
}
|
|
else
|
|
{
|
|
event.Skip();
|
|
}
|
|
}
|
|
|
|
wxPreviewFrame::wxPreviewFrame(wxPrintPreviewBase *preview, wxWindow *parent, const wxString& title,
|
|
const wxPoint& pos, const wxSize& size, long style, const wxString& name):
|
|
wxFrame(parent, wxID_ANY, title, pos, size, style, name),
|
|
m_initialSize(size)
|
|
{
|
|
m_printPreview = preview;
|
|
|
|
// Give the application icon
|
|
#ifdef __WXMSW__
|
|
wxFrame* topFrame = wxDynamicCast(wxTheApp->GetTopWindow(), wxFrame);
|
|
if (topFrame)
|
|
SetIcons(topFrame->GetIcons());
|
|
#endif
|
|
}
|
|
|
|
wxPreviewFrame::~wxPreviewFrame()
|
|
{
|
|
wxPrintout *printout = m_printPreview->GetPrintout();
|
|
if (printout)
|
|
{
|
|
delete printout;
|
|
m_printPreview->SetPrintout(nullptr);
|
|
m_printPreview->SetCanvas(nullptr);
|
|
m_printPreview->SetFrame(nullptr);
|
|
}
|
|
|
|
m_previewCanvas->SetPreview(nullptr);
|
|
delete m_printPreview;
|
|
}
|
|
|
|
void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
|
|
{
|
|
Destroy();
|
|
}
|
|
|
|
void wxPreviewFrame::InitializeWithModality(wxPreviewFrameModalityKind kind)
|
|
{
|
|
#if wxUSE_STATUSBAR
|
|
CreateStatusBar();
|
|
#endif
|
|
CreateCanvas();
|
|
CreateControlBar();
|
|
|
|
m_printPreview->SetCanvas(m_previewCanvas);
|
|
m_printPreview->SetFrame(this);
|
|
|
|
wxBoxSizer* const sizer = new wxBoxSizer( wxVERTICAL );
|
|
|
|
sizer->Add( m_controlBar, wxSizerFlags().Expand() );
|
|
sizer->Add( m_previewCanvas, wxSizerFlags(1).Expand() );
|
|
|
|
SetSizer( sizer );
|
|
|
|
// Respect the user-specified size, if any, but use the best appropriate
|
|
// size by default if none was explicitly given.
|
|
if ( !m_initialSize.IsFullySpecified() )
|
|
{
|
|
wxSize size = m_initialSize;
|
|
size.SetDefaults(sizer->ComputeFittingWindowSize(this));
|
|
SetSize(size);
|
|
}
|
|
|
|
// We don't want to restrict shrinking the window vertically as it might be
|
|
// too tall (see SetInitialSize() call in wxPreviewCanvas ctor), but we do
|
|
// want to make it at least as wide as the control bar, as otherwise the
|
|
// buttons wouldn't fit, and restricting it to at least its height
|
|
// vertically is also quite reasonable.
|
|
SetSizeHints(ClientToWindowSize(m_controlBar->GetBestSize()));
|
|
|
|
SetWindowModality(kind);
|
|
|
|
m_printPreview->AdjustScrollbars(m_previewCanvas);
|
|
m_previewCanvas->SetFocus();
|
|
m_controlBar->SetFocus();
|
|
}
|
|
|
|
void wxPreviewFrame::CreateCanvas()
|
|
{
|
|
m_previewCanvas = new wxPreviewCanvas(m_printPreview, this);
|
|
}
|
|
|
|
void wxPreviewFrame::CreateControlBar()
|
|
{
|
|
long buttons = wxPREVIEW_DEFAULT;
|
|
if (m_printPreview->GetPrintoutForPrinting())
|
|
buttons |= wxPREVIEW_PRINT;
|
|
|
|
m_controlBar = new wxPreviewControlBar(m_printPreview, buttons, this);
|
|
m_controlBar->CreateButtons();
|
|
}
|
|
|
|
/*
|
|
* Print preview
|
|
*/
|
|
|
|
wxIMPLEMENT_CLASS(wxPrintPreviewBase, wxObject);
|
|
|
|
wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
|
|
wxPrintout *printoutForPrinting,
|
|
wxPrintData *data)
|
|
{
|
|
if (data)
|
|
m_printDialogData = (*data);
|
|
|
|
Init(printout, printoutForPrinting);
|
|
}
|
|
|
|
wxPrintPreviewBase::wxPrintPreviewBase(wxPrintout *printout,
|
|
wxPrintout *printoutForPrinting,
|
|
wxPrintDialogData *data)
|
|
{
|
|
if (data)
|
|
m_printDialogData = (*data);
|
|
|
|
Init(printout, printoutForPrinting);
|
|
}
|
|
|
|
void wxPrintPreviewBase::Init(wxPrintout *printout,
|
|
wxPrintout *printoutForPrinting)
|
|
{
|
|
m_isOk = true;
|
|
m_previewPrintout = printout;
|
|
if (m_previewPrintout)
|
|
m_previewPrintout->SetPreview(static_cast<wxPrintPreview *>(this));
|
|
|
|
m_printPrintout = printoutForPrinting;
|
|
|
|
m_previewCanvas = nullptr;
|
|
m_previewFrame = nullptr;
|
|
m_previewBitmap = nullptr;
|
|
m_previewFailed = false;
|
|
m_currentPage = 1;
|
|
m_currentZoom = 70;
|
|
m_topMargin =
|
|
m_leftMargin = wxRound(2*wxSizerFlags::GetDefaultBorderFractional());
|
|
m_pageWidth = 0;
|
|
m_pageHeight = 0;
|
|
m_printingPrepared = false;
|
|
m_minPage = 1;
|
|
m_maxPage = 1;
|
|
}
|
|
|
|
wxPrintPreviewBase::~wxPrintPreviewBase()
|
|
{
|
|
delete m_previewPrintout;
|
|
delete m_previewBitmap;
|
|
delete m_printPrintout;
|
|
}
|
|
|
|
bool wxPrintPreviewBase::SetCurrentPage(int pageNum)
|
|
{
|
|
if (m_currentPage == pageNum)
|
|
return true;
|
|
|
|
m_currentPage = pageNum;
|
|
|
|
InvalidatePreviewBitmap();
|
|
|
|
if (m_previewCanvas)
|
|
{
|
|
AdjustScrollbars(m_previewCanvas);
|
|
|
|
m_previewCanvas->Refresh();
|
|
m_previewCanvas->SetFocus();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int wxPrintPreviewBase::GetCurrentPage() const
|
|
{ return m_currentPage; }
|
|
void wxPrintPreviewBase::SetPrintout(wxPrintout *printout)
|
|
{ m_previewPrintout = printout; }
|
|
wxPrintout *wxPrintPreviewBase::GetPrintout() const
|
|
{ return m_previewPrintout; }
|
|
wxPrintout *wxPrintPreviewBase::GetPrintoutForPrinting() const
|
|
{ return m_printPrintout; }
|
|
void wxPrintPreviewBase::SetFrame(wxFrame *frame)
|
|
{ m_previewFrame = frame; }
|
|
void wxPrintPreviewBase::SetCanvas(wxPreviewCanvas *canvas)
|
|
{ m_previewCanvas = canvas; }
|
|
wxFrame *wxPrintPreviewBase::GetFrame() const
|
|
{ return m_previewFrame; }
|
|
wxPreviewCanvas *wxPrintPreviewBase::GetCanvas() const
|
|
{ return m_previewCanvas; }
|
|
|
|
void wxPrintPreviewBase::CalcRects(wxPreviewCanvas *canvas, wxRect& pageRect, wxRect& paperRect)
|
|
{
|
|
// Calculate the rectangles for the printable area of the page and the
|
|
// entire paper as they appear on the canvas on-screen.
|
|
int canvasWidth, canvasHeight;
|
|
canvas->GetSize(&canvasWidth, &canvasHeight);
|
|
|
|
float zoomScale = m_currentZoom / 100.0f;
|
|
float screenPrintableWidth = zoomScale * canvas->FromDIP(m_pageWidth) * m_previewScaleX;
|
|
float screenPrintableHeight = zoomScale * canvas->FromDIP(m_pageHeight) * m_previewScaleY;
|
|
|
|
wxRect devicePaperRect = m_previewPrintout->GetPaperRectPixels();
|
|
wxCoord devicePrintableWidth, devicePrintableHeight;
|
|
m_previewPrintout->GetPageSizePixels(&devicePrintableWidth, &devicePrintableHeight);
|
|
float scaleX = screenPrintableWidth / devicePrintableWidth;
|
|
float scaleY = screenPrintableHeight / devicePrintableHeight;
|
|
paperRect.width = wxCoord(scaleX * devicePaperRect.width);
|
|
paperRect.height = wxCoord(scaleY * devicePaperRect.height);
|
|
|
|
paperRect.x = (canvasWidth - paperRect.width) / 2;
|
|
if (paperRect.x < m_leftMargin)
|
|
paperRect.x = m_leftMargin;
|
|
paperRect.y = (canvasHeight - paperRect.height) / 2;
|
|
if (paperRect.y < m_topMargin)
|
|
paperRect.y = m_topMargin;
|
|
|
|
pageRect.x = paperRect.x - wxCoord(scaleX * devicePaperRect.x);
|
|
pageRect.y = paperRect.y - wxCoord(scaleY * devicePaperRect.y);
|
|
pageRect.width = wxCoord(screenPrintableWidth);
|
|
pageRect.height = wxCoord(screenPrintableHeight);
|
|
}
|
|
|
|
|
|
void wxPrintPreviewBase::InvalidatePreviewBitmap()
|
|
{
|
|
wxDELETE(m_previewBitmap);
|
|
// if there was a problem with rendering the preview, try again now
|
|
// that it changed in some way (less memory may be needed, for example):
|
|
m_previewFailed = false;
|
|
}
|
|
|
|
bool wxPrintPreviewBase::UpdatePageRendering()
|
|
{
|
|
if ( m_previewBitmap )
|
|
return false;
|
|
|
|
if ( m_previewFailed )
|
|
return false;
|
|
|
|
if ( !RenderPage(m_currentPage) )
|
|
{
|
|
m_previewFailed = true; // don't waste time failing again
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool wxPrintPreviewBase::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
|
|
{
|
|
DrawBlankPage(canvas, dc);
|
|
|
|
if (!m_previewBitmap)
|
|
return false;
|
|
if (!canvas)
|
|
return false;
|
|
|
|
wxRect pageRect, paperRect;
|
|
CalcRects(canvas, pageRect, paperRect);
|
|
wxMemoryDC temp_dc;
|
|
temp_dc.SelectObject(*m_previewBitmap);
|
|
|
|
dc.Blit(pageRect.x, pageRect.y,
|
|
m_previewBitmap->GetWidth(), m_previewBitmap->GetHeight(), &temp_dc, 0, 0);
|
|
|
|
temp_dc.SelectObject(wxNullBitmap);
|
|
return true;
|
|
}
|
|
|
|
// Adjusts the scrollbars for the current scale
|
|
void wxPrintPreviewBase::AdjustScrollbars(wxPreviewCanvas *canvas)
|
|
{
|
|
if (!canvas)
|
|
return ;
|
|
|
|
wxRect pageRect, paperRect;
|
|
CalcRects(canvas, pageRect, paperRect);
|
|
int totalWidth = paperRect.width + 2 * m_leftMargin;
|
|
int totalHeight = paperRect.height + 2 * m_topMargin;
|
|
int scrollUnitsX = totalWidth / 10;
|
|
int scrollUnitsY = totalHeight / 10;
|
|
wxSize virtualSize = canvas->GetVirtualSize();
|
|
if (virtualSize.GetWidth() != totalWidth || virtualSize.GetHeight() != totalHeight)
|
|
canvas->SetScrollbars(10, 10, scrollUnitsX, scrollUnitsY, 0, 0, true);
|
|
}
|
|
|
|
bool wxPrintPreviewBase::RenderPageIntoDC(wxDC& dc, int pageNum)
|
|
{
|
|
m_previewPrintout->SetDC(&dc);
|
|
m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight);
|
|
|
|
// Need to delay OnPreparePrinting() until here, so we have enough
|
|
// information and a wxDC.
|
|
if (!m_printingPrepared)
|
|
{
|
|
m_printingPrepared = true;
|
|
|
|
m_previewPrintout->OnPreparePrinting();
|
|
|
|
wxPrintPageRanges ranges;
|
|
const auto all = m_previewPrintout->GetPagesInfo(ranges);
|
|
m_minPage = all.fromPage;
|
|
m_maxPage = all.toPage;
|
|
|
|
// Update the wxPreviewControlBar page range display.
|
|
if ( m_previewFrame )
|
|
{
|
|
wxPreviewControlBar * const
|
|
controlBar = ((wxPreviewFrame*)m_previewFrame)->GetControlBar();
|
|
if ( controlBar )
|
|
controlBar->SetPageInfo(m_minPage, m_maxPage);
|
|
}
|
|
}
|
|
|
|
m_previewPrintout->OnBeginPrinting();
|
|
|
|
if (!m_previewPrintout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage()))
|
|
{
|
|
wxMessageBox(_("Could not start document preview."), _("Print Preview Failure"), wxOK);
|
|
return false;
|
|
}
|
|
|
|
m_previewPrintout->OnPrintPage(pageNum);
|
|
m_previewPrintout->OnEndDocument();
|
|
m_previewPrintout->OnEndPrinting();
|
|
|
|
m_previewPrintout->SetDC(nullptr);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool wxPrintPreviewBase::RenderPageIntoBitmap(wxBitmap& bmp, int pageNum)
|
|
{
|
|
wxMemoryDC memoryDC;
|
|
memoryDC.SelectObject(bmp);
|
|
memoryDC.Clear();
|
|
|
|
return RenderPageIntoDC(memoryDC, pageNum);
|
|
}
|
|
|
|
bool wxPrintPreviewBase::RenderPage(int pageNum)
|
|
{
|
|
wxBusyCursor busy;
|
|
|
|
if (!m_previewCanvas)
|
|
{
|
|
wxFAIL_MSG(wxT("wxPrintPreviewBase::RenderPage: must use wxPrintPreviewBase::SetCanvas to let me know about the canvas!"));
|
|
return false;
|
|
}
|
|
|
|
wxRect pageRect, paperRect;
|
|
CalcRects(m_previewCanvas, pageRect, paperRect);
|
|
|
|
if (!m_previewBitmap)
|
|
{
|
|
m_previewBitmap = new wxBitmap();
|
|
m_previewBitmap->CreateWithLogicalSize( pageRect.width, pageRect.height,
|
|
m_previewCanvas->GetDPIScaleFactor() );
|
|
|
|
if (!m_previewBitmap || !m_previewBitmap->IsOk())
|
|
{
|
|
InvalidatePreviewBitmap();
|
|
wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ( !RenderPageIntoBitmap(*m_previewBitmap, pageNum) )
|
|
{
|
|
InvalidatePreviewBitmap();
|
|
wxMessageBox(_("Sorry, not enough memory to create a preview."), _("Print Preview Failure"), wxOK);
|
|
return false;
|
|
}
|
|
|
|
#if wxUSE_STATUSBAR
|
|
wxString status;
|
|
if (m_maxPage != 0)
|
|
status = wxString::Format(_("Page %d of %d"), pageNum, m_maxPage);
|
|
else
|
|
status = wxString::Format(_("Page %d"), pageNum);
|
|
|
|
if (m_previewFrame)
|
|
m_previewFrame->SetStatusText(status);
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool wxPrintPreviewBase::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
|
|
{
|
|
wxRect pageRect, paperRect;
|
|
|
|
CalcRects(canvas, pageRect, paperRect);
|
|
|
|
// Draw shadow, allowing for 1-pixel border AROUND the actual paper
|
|
wxCoord shadowOffset = dc.FromDIP(4);
|
|
|
|
dc.SetPen(*wxBLACK_PEN);
|
|
dc.SetBrush(*wxBLACK_BRUSH);
|
|
dc.DrawRectangle(paperRect.x + shadowOffset, paperRect.y + paperRect.height,
|
|
paperRect.width, shadowOffset);
|
|
|
|
dc.DrawRectangle(paperRect.x + paperRect.width, paperRect.y + shadowOffset,
|
|
shadowOffset, paperRect.height);
|
|
|
|
// Draw blank page allowing for 1-pixel border AROUND the actual paper
|
|
dc.SetPen(wxPen(*wxBLACK, dc.FromDIP(1), wxPENSTYLE_SOLID));
|
|
dc.SetBrush(*wxWHITE_BRUSH);
|
|
wxCoord borderOffset = wxRound(dc.GetPen().GetWidth() / 2.0);
|
|
dc.DrawRectangle(paperRect.x - borderOffset, paperRect.y - borderOffset,
|
|
paperRect.width + 2*borderOffset, paperRect.height + 2*borderOffset);
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxPrintPreviewBase::SetZoom(int percent)
|
|
{
|
|
if (m_currentZoom == percent)
|
|
return;
|
|
|
|
m_currentZoom = percent;
|
|
|
|
InvalidatePreviewBitmap();
|
|
|
|
if (m_previewCanvas)
|
|
{
|
|
AdjustScrollbars(m_previewCanvas);
|
|
m_previewCanvas->Scroll(0, 0);
|
|
m_previewCanvas->Refresh();
|
|
m_previewCanvas->SetFocus();
|
|
}
|
|
}
|
|
|
|
wxPrintDialogData& wxPrintPreviewBase::GetPrintDialogData()
|
|
{
|
|
return m_printDialogData;
|
|
}
|
|
|
|
int wxPrintPreviewBase::GetZoom() const
|
|
{ return m_currentZoom; }
|
|
int wxPrintPreviewBase::GetMaxPage() const
|
|
{ return m_maxPage; }
|
|
int wxPrintPreviewBase::GetMinPage() const
|
|
{ return m_minPage; }
|
|
bool wxPrintPreviewBase::IsOk() const
|
|
{ return m_isOk; }
|
|
void wxPrintPreviewBase::SetOk(bool ok)
|
|
{ m_isOk = ok; }
|
|
|
|
void wxPrintPreviewBase::WXUpdateOnDPIChanged()
|
|
{
|
|
InvalidatePreviewBitmap();
|
|
UpdatePageRendering();
|
|
|
|
if (m_previewCanvas)
|
|
{
|
|
AdjustScrollbars(m_previewCanvas);
|
|
|
|
m_previewCanvas->Refresh();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// wxPrintPreview
|
|
//----------------------------------------------------------------------------
|
|
|
|
wxIMPLEMENT_CLASS(wxPrintPreview, wxPrintPreviewBase);
|
|
|
|
wxPrintPreview::wxPrintPreview(wxPrintout *printout,
|
|
wxPrintout *printoutForPrinting,
|
|
wxPrintDialogData *data) :
|
|
wxPrintPreviewBase( printout, printoutForPrinting, data )
|
|
{
|
|
m_pimpl = wxPrintFactory::GetFactory()->
|
|
CreatePrintPreview( printout, printoutForPrinting, data );
|
|
}
|
|
|
|
wxPrintPreview::wxPrintPreview(wxPrintout *printout,
|
|
wxPrintout *printoutForPrinting,
|
|
wxPrintData *data ) :
|
|
wxPrintPreviewBase( printout, printoutForPrinting, data )
|
|
{
|
|
m_pimpl = wxPrintFactory::GetFactory()->
|
|
CreatePrintPreview( printout, printoutForPrinting, data );
|
|
}
|
|
|
|
wxPrintPreview::~wxPrintPreview()
|
|
{
|
|
delete m_pimpl;
|
|
|
|
// don't delete twice
|
|
m_printPrintout = nullptr;
|
|
m_previewPrintout = nullptr;
|
|
m_previewBitmap = nullptr;
|
|
}
|
|
|
|
bool wxPrintPreview::SetCurrentPage(int pageNum)
|
|
{
|
|
return m_pimpl->SetCurrentPage( pageNum );
|
|
}
|
|
|
|
int wxPrintPreview::GetCurrentPage() const
|
|
{
|
|
return m_pimpl->GetCurrentPage();
|
|
}
|
|
|
|
void wxPrintPreview::SetPrintout(wxPrintout *printout)
|
|
{
|
|
m_pimpl->SetPrintout( printout );
|
|
}
|
|
|
|
wxPrintout *wxPrintPreview::GetPrintout() const
|
|
{
|
|
return m_pimpl->GetPrintout();
|
|
}
|
|
|
|
wxPrintout *wxPrintPreview::GetPrintoutForPrinting() const
|
|
{
|
|
return m_pimpl->GetPrintoutForPrinting();
|
|
}
|
|
|
|
void wxPrintPreview::SetFrame(wxFrame *frame)
|
|
{
|
|
m_pimpl->SetFrame( frame );
|
|
}
|
|
|
|
void wxPrintPreview::SetCanvas(wxPreviewCanvas *canvas)
|
|
{
|
|
m_pimpl->SetCanvas( canvas );
|
|
}
|
|
|
|
wxFrame *wxPrintPreview::GetFrame() const
|
|
{
|
|
return m_pimpl->GetFrame();
|
|
}
|
|
|
|
wxPreviewCanvas *wxPrintPreview::GetCanvas() const
|
|
{
|
|
return m_pimpl->GetCanvas();
|
|
}
|
|
|
|
bool wxPrintPreview::PaintPage(wxPreviewCanvas *canvas, wxDC& dc)
|
|
{
|
|
return m_pimpl->PaintPage( canvas, dc );
|
|
}
|
|
|
|
bool wxPrintPreview::UpdatePageRendering()
|
|
{
|
|
return m_pimpl->UpdatePageRendering();
|
|
}
|
|
|
|
bool wxPrintPreview::DrawBlankPage(wxPreviewCanvas *canvas, wxDC& dc)
|
|
{
|
|
return m_pimpl->DrawBlankPage( canvas, dc );
|
|
}
|
|
|
|
void wxPrintPreview::AdjustScrollbars(wxPreviewCanvas *canvas)
|
|
{
|
|
m_pimpl->AdjustScrollbars( canvas );
|
|
}
|
|
|
|
bool wxPrintPreview::RenderPage(int pageNum)
|
|
{
|
|
return m_pimpl->RenderPage( pageNum );
|
|
}
|
|
|
|
void wxPrintPreview::SetZoom(int percent)
|
|
{
|
|
m_pimpl->SetZoom( percent );
|
|
}
|
|
|
|
int wxPrintPreview::GetZoom() const
|
|
{
|
|
return m_pimpl->GetZoom();
|
|
}
|
|
|
|
wxPrintDialogData& wxPrintPreview::GetPrintDialogData()
|
|
{
|
|
return m_pimpl->GetPrintDialogData();
|
|
}
|
|
|
|
int wxPrintPreview::GetMaxPage() const
|
|
{
|
|
return m_pimpl->GetMaxPage();
|
|
}
|
|
|
|
int wxPrintPreview::GetMinPage() const
|
|
{
|
|
return m_pimpl->GetMinPage();
|
|
}
|
|
|
|
bool wxPrintPreview::IsOk() const
|
|
{
|
|
return m_pimpl->IsOk();
|
|
}
|
|
|
|
void wxPrintPreview::SetOk(bool ok)
|
|
{
|
|
m_pimpl->SetOk( ok );
|
|
}
|
|
|
|
void wxPrintPreview::WXUpdateOnDPIChanged()
|
|
{
|
|
m_pimpl->WXUpdateOnDPIChanged();
|
|
}
|
|
|
|
bool wxPrintPreview::Print(bool interactive)
|
|
{
|
|
return m_pimpl->Print( interactive );
|
|
}
|
|
|
|
void wxPrintPreview::DetermineScaling()
|
|
{
|
|
m_pimpl->DetermineScaling();
|
|
}
|
|
|
|
#endif // wxUSE_PRINTING_ARCHITECTURE
|