diff --git a/include/wx/cmndata.h b/include/wx/cmndata.h index db647824d7..101345409d 100644 --- a/include/wx/cmndata.h +++ b/include/wx/cmndata.h @@ -21,6 +21,8 @@ #include "wx/stream.h" #endif +#include + class WXDLLIMPEXP_FWD_CORE wxPrintNativeDataBase; /* @@ -101,8 +103,9 @@ public: wxPrintData& operator=(const wxPrintData& data); - char* GetPrivData() const { return m_privData; } - int GetPrivDataLen() const { return m_privDataLen; } + char* GetPrivData() { return m_privData.empty() ? nullptr : &m_privData[0]; } + const char* GetPrivData() const { return m_privData.empty() ? nullptr : &m_privData[0]; } + int GetPrivDataLen() const { return static_cast(m_privData.size()); } void SetPrivData( char *privData, int len ); @@ -110,31 +113,33 @@ public: void ConvertToNative(); void ConvertFromNative(); // Holds the native print data - wxPrintNativeDataBase *GetNativeData() const { return m_nativeData; } + wxPrintNativeDataBase *GetNativeData() const { return m_nativeData.get(); } private: - wxPrintBin m_bin; - int m_media; - wxPrintMode m_printMode; + wxPrintBin m_bin = wxPRINTBIN_DEFAULT; + int m_media = wxPRINTMEDIA_DEFAULT; + wxPrintMode m_printMode = wxPRINT_MODE_PRINTER; - int m_printNoCopies; - wxPrintOrientation m_printOrientation; - bool m_printOrientationReversed; - bool m_printCollate; + int m_printNoCopies = 1; + wxPrintOrientation m_printOrientation = wxPORTRAIT; + bool m_printOrientationReversed = false; + bool m_printCollate = false; wxString m_printerName; - bool m_colour; - wxDuplexMode m_duplexMode; - wxPrintQuality m_printQuality; - wxPaperSize m_paperId; - wxSize m_paperSize; + bool m_colour = true; + wxDuplexMode m_duplexMode = wxDUPLEX_SIMPLEX; + wxPrintQuality m_printQuality = wxPRINT_QUALITY_HIGH; + + // we intentionally don't initialize paper id and size at all, like this + // the default system settings will be used for them + wxPaperSize m_paperId = wxPAPER_NONE; + wxSize m_paperSize = wxDefaultSize; wxString m_filename; - char* m_privData; - int m_privDataLen; + std::vector m_privData; - wxPrintNativeDataBase *m_nativeData; + wxObjectDataPtr m_nativeData; private: wxDECLARE_DYNAMIC_CLASS(wxPrintData); @@ -151,7 +156,7 @@ class WXDLLIMPEXP_CORE wxPrintDialogData: public wxObject { public: wxPrintDialogData(); - wxPrintDialogData(const wxPrintDialogData& dialogData); + wxPrintDialogData(const wxPrintDialogData& dialogData) = default; wxPrintDialogData(const wxPrintData& printData); virtual ~wxPrintDialogData(); @@ -162,6 +167,7 @@ public: int GetNoCopies() const { return m_printNoCopies; } bool GetAllPages() const { return m_printAllPages; } bool GetSelection() const { return m_printSelection; } + bool GetCurrentPage() const { return m_printCurrentPage; } bool GetCollate() const { return m_printCollate; } bool GetPrintToFile() const { return m_printToFile; } @@ -172,16 +178,19 @@ public: void SetNoCopies(int v) { m_printNoCopies = v; } void SetAllPages(bool flag) { m_printAllPages = flag; } void SetSelection(bool flag) { m_printSelection = flag; } + void SetCurrentPage(bool flag) { m_printCurrentPage = flag; } void SetCollate(bool flag) { m_printCollate = flag; } void SetPrintToFile(bool flag) { m_printToFile = flag; } void EnablePrintToFile(bool flag) { m_printEnablePrintToFile = flag; } void EnableSelection(bool flag) { m_printEnableSelection = flag; } + void EnableCurrentPage(bool flag) { m_printEnableCurrentPage = flag; } void EnablePageNumbers(bool flag) { m_printEnablePageNumbers = flag; } void EnableHelp(bool flag) { m_printEnableHelp = flag; } bool GetEnablePrintToFile() const { return m_printEnablePrintToFile; } bool GetEnableSelection() const { return m_printEnableSelection; } + bool GetEnableCurrentPage() const { return m_printEnableCurrentPage; } bool GetEnablePageNumbers() const { return m_printEnablePageNumbers; } bool GetEnableHelp() const { return m_printEnableHelp; } @@ -192,23 +201,25 @@ public: wxPrintData& GetPrintData() { return m_printData; } void SetPrintData(const wxPrintData& printData) { m_printData = printData; } - void operator=(const wxPrintDialogData& data); + wxPrintDialogData& operator=(const wxPrintDialogData& data) = default; void operator=(const wxPrintData& data); // Sets internal m_printData member private: - int m_printFromPage; - int m_printToPage; - int m_printMinPage; - int m_printMaxPage; - int m_printNoCopies; - bool m_printAllPages; - bool m_printCollate; - bool m_printToFile; - bool m_printSelection; - bool m_printEnableSelection; - bool m_printEnablePageNumbers; - bool m_printEnableHelp; - bool m_printEnablePrintToFile; + int m_printFromPage = 0; + int m_printToPage = 0; + int m_printMinPage = 0; + int m_printMaxPage = 0; + int m_printNoCopies = 1; + bool m_printAllPages = false; + bool m_printCollate = false; + bool m_printToFile = false; + bool m_printSelection = false; + bool m_printCurrentPage = false; + bool m_printEnableSelection = false; + bool m_printEnableCurrentPage = false; + bool m_printEnablePageNumbers = true; + bool m_printEnableHelp = false; + bool m_printEnablePrintToFile = true; wxPrintData m_printData; private: @@ -226,9 +237,8 @@ class WXDLLIMPEXP_CORE wxPageSetupDialogData: public wxObject { public: wxPageSetupDialogData(); - wxPageSetupDialogData(const wxPageSetupDialogData& dialogData); + wxPageSetupDialogData(const wxPageSetupDialogData& dialogData) = default; wxPageSetupDialogData(const wxPrintData& printData); - virtual ~wxPageSetupDialogData(); wxSize GetPaperSize() const { return m_paperSize; } wxPaperSize GetPaperId() const { return m_printData.GetPaperId(); } @@ -278,7 +288,7 @@ public: // Use paper id in wxPrintData to set this object's paper size void CalculatePaperSizeFromId(); - wxPageSetupDialogData& operator=(const wxPageSetupDialogData& data); + wxPageSetupDialogData& operator=(const wxPageSetupDialogData& data) = default; wxPageSetupDialogData& operator=(const wxPrintData& data); wxPrintData& GetPrintData() { return m_printData; } @@ -291,13 +301,13 @@ private: wxPoint m_minMarginBottomRight; wxPoint m_marginTopLeft; wxPoint m_marginBottomRight; - bool m_defaultMinMargins; - bool m_enableMargins; - bool m_enableOrientation; - bool m_enablePaper; - bool m_enablePrinter; - bool m_getDefaultInfo; // Equiv. to PSD_RETURNDEFAULT - bool m_enableHelp; + bool m_defaultMinMargins = false; + bool m_enableMargins = true; + bool m_enableOrientation = true; + bool m_enablePaper = true; + bool m_enablePrinter = true; + bool m_getDefaultInfo = false; // Equiv. to PSD_RETURNDEFAULT + bool m_enableHelp = false; wxPrintData m_printData; private: diff --git a/include/wx/prntbase.h b/include/wx/prntbase.h index db7d726e1a..8796ffdf5e 100644 --- a/include/wx/prntbase.h +++ b/include/wx/prntbase.h @@ -159,8 +159,8 @@ public: class WXDLLIMPEXP_CORE wxPrintNativeDataBase: public wxObject { public: - wxPrintNativeDataBase(); - virtual ~wxPrintNativeDataBase() {} + wxPrintNativeDataBase() = default; + virtual ~wxPrintNativeDataBase(); virtual bool TransferTo( wxPrintData &data ) = 0; virtual bool TransferFrom( const wxPrintData &data ) = 0; @@ -172,7 +172,14 @@ public: virtual bool Ok() const { return IsOk(); } virtual bool IsOk() const = 0; - int m_ref; + // Internal implementation details, do not use. + + // For historical reasons, this class doesn't use wxRefCounter, but provides + // the same methods, so that it could still be used with wxObjectDataPtr. + void IncRef() { m_ref++; } + void DecRef() { if ( !--m_ref) delete this; } + + int m_ref = 1; private: wxDECLARE_CLASS(wxPrintNativeDataBase); @@ -278,6 +285,7 @@ public: virtual bool HasPage(int page); virtual bool OnPrintPage(int page) = 0; virtual void GetPageInfo(int *minPage, int *maxPage, int *pageFrom, int *pageTo); + virtual bool IsPageSelected(int page); virtual wxString GetTitle() const { return m_printoutTitle; } diff --git a/interface/wx/cmndata.h b/interface/wx/cmndata.h index 3375f8dcfe..c06fba3f84 100644 --- a/interface/wx/cmndata.h +++ b/interface/wx/cmndata.h @@ -489,6 +489,18 @@ public: */ void EnableSelection(bool flag); + /** + Allows or disallows selecting printing the "Current Page" in the + dialog. + + This currently only has an effect under MSW, where the native dialog + enables the "Current Page" radio button if this function is called to + allow the user to print the current page only. + + @since 3.3.0 + */ + void EnableCurrentPage(bool flag); + /** Returns @true if the user requested that all pages be printed. */ @@ -535,6 +547,18 @@ public: */ bool GetSelection() const; + /** + Returns @true if the user requested that the current page be printed. + + Note that the "current page" is defined by the application. + + It only makes sense to call this function if EnableCurrentPage() had been + called before, otherwise it always returns @false. + + @since 3.3.0 + */ + bool GetCurrentPage() const; + /** Returns the @e "print to" page number, as entered by the user. */ @@ -590,6 +614,19 @@ public: */ void SetSelection(bool flag); + /** + Selects the "Current Page" radio button when the dialog is initially + shown. + + This function can only be called when EnableCurrentPage() is used as + well. + + @see GetCurrentPage() + + @since 3.3.0 + */ + void SetCurrentPage(bool flag); + /** @deprecated This function has been deprecated since version 2.5.4. diff --git a/interface/wx/print.h b/interface/wx/print.h index 416fccc9c6..d2c56bec04 100644 --- a/interface/wx/print.h +++ b/interface/wx/print.h @@ -705,6 +705,14 @@ public: and maximum page values that the user can select, and the required page range to be printed. + If the user chose to print only selected pages in the MSW printing + dialog, then @a pageFrom and @a pageTo are used to limit the page range + and IsPageSelected() is called later to query whether the page is + selected and so should be printed. + + If the user chose to print the current page, then @a pageFrom and + @a pageTo should be both set to the current page number. + By default this returns (1, 32000) for the page minimum and maximum values, and (1, 1) for the required page range. @@ -773,6 +781,20 @@ public: */ virtual bool HasPage(int pageNum); + /** + Should be overridden to return @true if this page is selected, or @false + if not. + + This function is called for all the pages in the valid range when the + user chooses "Selection" in the "Page Range" area of the printing + dialog under MSW. It is not currently called under the other platforms. + + The default implementation always returns @false. + + @since 3.3.0 + */ + virtual bool IsPageSelected(int pageNum); + /** Returns @true if the printout is currently being used for previewing. diff --git a/samples/printing/printing.cpp b/samples/printing/printing.cpp index 8222104288..7c4d7254db 100644 --- a/samples/printing/printing.cpp +++ b/samples/printing/printing.cpp @@ -291,25 +291,18 @@ MyFrame::MyFrame(const wxString& title) // Make a menubar wxMenu *file_menu = new wxMenu; - file_menu->Append(wxID_PRINT, "&Print...", "Print"); - file_menu->Append(WXPRINT_PAGE_SETUP, "Page Set&up...", "Page setup"); + file_menu->Append(wxID_PRINT, "&Print...\tCtrl+P", "Show \"Print\" dialog"); + file_menu->Append(WXPRINT_PAGE_SETUP, "Page &Setup...\tCtrl+S", "Page setup"); #ifdef __WXMAC__ file_menu->Append(WXPRINT_PAGE_MARGINS, "Page Margins...", "Page margins"); #endif - file_menu->Append(wxID_PREVIEW, "Print Pre&view", "Preview"); + file_menu->Append(wxID_PREVIEW, "Pre&view\tCtrl+V", "Show print preview"); wxMenu * const menuModalKind = new wxMenu; menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_APP, "&App modal"); menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_WIN, "&Window modal"); menuModalKind->AppendRadioItem(WXPRINT_FRAME_MODAL_NON, "&Not modal"); file_menu->AppendSubMenu(menuModalKind, "Preview frame &modal kind"); -#if wxUSE_ACCEL - // Accelerators - wxAcceleratorEntry entries[1]; - entries[0].Set(wxACCEL_CTRL, (int) 'V', wxID_PREVIEW); - wxAcceleratorTable accel(1, entries); - SetAcceleratorTable(accel); -#endif #if wxUSE_POSTSCRIPT file_menu->AppendSeparator(); @@ -356,9 +349,23 @@ void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event)) { wxPrintDialogData printDialogData(* g_printData); + printDialogData.EnableSelection(true); + printDialogData.EnablePageNumbers(true); + printDialogData.EnableCurrentPage(true); + printDialogData.SetMinPage(1); + printDialogData.SetMaxPage(2); + printDialogData.SetFromPage(1); + printDialogData.SetToPage(2); + printDialogData.SetAllPages(true); wxPrinter printer(&printDialogData); - MyPrintout printout(this, "My printout"); + + // wxPrinter copies printDialogData internally, so we have to pass this + // instance in order to evaluate users inputs. + MyPrintout printout(this, &printer.GetPrintDialogData(), "My printout"); + + SetStatusText(""); // clear previous "cancelled" message, if any + if (!printer.Print(this, &printout, true /*prompt*/)) { if (wxPrinter::GetLastError() == wxPRINTER_ERROR) @@ -367,7 +374,7 @@ void MyFrame::OnPrint(wxCommandEvent& WXUNUSED(event)) } else { - wxLogMessage("You canceled printing"); + wxLogStatus("You canceled printing"); } } else @@ -381,7 +388,7 @@ void MyFrame::OnPrintPreview(wxCommandEvent& WXUNUSED(event)) // Pass two printout objects: for preview, and possible printing. wxPrintDialogData printDialogData(* g_printData); wxPrintPreview *preview = - new wxPrintPreview(new MyPrintout(this), new MyPrintout(this), &printDialogData); + new wxPrintPreview(new MyPrintout(this, &printDialogData), new MyPrintout(this, &printDialogData), &printDialogData); if (!preview->IsOk()) { delete preview; @@ -412,7 +419,7 @@ void MyFrame::OnPrintPS(wxCommandEvent& WXUNUSED(event)) wxPrintDialogData printDialogData(* g_printData); wxPostScriptPrinter printer(&printDialogData); - MyPrintout printout(this, "My printout"); + MyPrintout printout(this, &printer.GetPrintDialogData(), "My printout"); printer.Print(this, &printout, true/*prompt*/); (*g_printData) = printer.GetPrintDialogData().GetPrintData(); @@ -422,7 +429,7 @@ void MyFrame::OnPrintPreviewPS(wxCommandEvent& WXUNUSED(event)) { // Pass two printout objects: for preview, and possible printing. wxPrintDialogData printDialogData(* g_printData); - wxPrintPreview *preview = new wxPrintPreview(new MyPrintout(this), new MyPrintout(this), &printDialogData); + wxPrintPreview *preview = new wxPrintPreview(new MyPrintout(this, &printDialogData), new MyPrintout(this, &printDialogData), &printDialogData); wxPreviewFrame *frame = new wxPreviewFrame(preview, this, "Demo Print Preview"); frame->Initialize(); frame->Centre(wxBOTH); @@ -541,6 +548,23 @@ void MyPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int * *maxPage = 2; *selPageFrom = 1; *selPageTo = 2; + + // check if the user just wants to print the current page and if so, + // we say, that page 1 is the current page in this example. + if (m_printDlgData->GetCurrentPage()) + { + *selPageFrom = 1; + *selPageTo = 1; + } + else if (m_printDlgData->GetSelection()) + { + // if the user wants to print the selection, we could set the range via + // selPageFrom and selPageTo, but if the pages are not consecutive, we + // set selPageFrom and selPageTo to the maximum range and we use + // IsPageSelected() to tell the printing system which page is selected. + + // in our example below, only page 2 is selected. + } } bool MyPrintout::HasPage(int pageNum) @@ -548,6 +572,12 @@ bool MyPrintout::HasPage(int pageNum) return (pageNum == 1 || pageNum == 2); } +bool MyPrintout::IsPageSelected(int pageNum) +{ + // to demonstrate selection, we just simulate selection of page 2 + return pageNum == 2; +} + void MyPrintout::DrawPageOne() { // You might use THIS code if you were scaling graphics of known size to fit diff --git a/samples/printing/printing.h b/samples/printing/printing.h index fb60bca57b..5e76330332 100644 --- a/samples/printing/printing.h +++ b/samples/printing/printing.h @@ -86,13 +86,20 @@ private: class MyPrintout: public wxPrintout { public: - MyPrintout(MyFrame* frame, const wxString &title = "My printout") - : wxPrintout(title) { m_frame=frame; } + MyPrintout(MyFrame* frame, + wxPrintDialogData* printDlgData, + const wxString& title = "My printout") + : wxPrintout(title) + { + m_frame = frame; + m_printDlgData = printDlgData; + } virtual bool OnPrintPage(int page) override; virtual bool HasPage(int page) override; virtual bool OnBeginDocument(int startPage, int endPage) override; virtual void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) override; + virtual bool IsPageSelected(int pageNum) override; void DrawPageOne(); void DrawPageTwo(); @@ -102,6 +109,7 @@ public: private: MyFrame *m_frame; + wxPrintDialogData* m_printDlgData; }; diff --git a/src/common/cmndata.cpp b/src/common/cmndata.cpp index 6306facf92..535740c78d 100644 --- a/src/common/cmndata.cpp +++ b/src/common/cmndata.cpp @@ -54,58 +54,26 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxPageSetupDialogData, wxObject); // ---------------------------------------------------------------------------- wxPrintData::wxPrintData() - : m_paperSize(wxDefaultSize) { - m_bin = wxPRINTBIN_DEFAULT; - m_media = wxPRINTMEDIA_DEFAULT; - m_printMode = wxPRINT_MODE_PRINTER; - m_printOrientation = wxPORTRAIT; - m_printOrientationReversed = false; - m_printNoCopies = 1; - m_printCollate = false; - - // New, 24/3/99 - m_colour = true; - m_duplexMode = wxDUPLEX_SIMPLEX; - m_printQuality = wxPRINT_QUALITY_HIGH; - - // we intentionally don't initialize paper id and size at all, like this - // the default system settings will be used for them - m_paperId = wxPAPER_NONE; - - m_privData = nullptr; - m_privDataLen = 0; - m_nativeData = wxPrintFactory::GetFactory()->CreatePrintNativeData(); } -wxPrintData::wxPrintData(const wxPrintData& printData) - : wxObject() -{ - m_nativeData = nullptr; - m_privData = nullptr; - (*this) = printData; -} +wxPrintData::wxPrintData(const wxPrintData&) = default; void wxPrintData::SetPrivData( char *privData, int len ) { - wxDELETEA(m_privData); - m_privDataLen = len; - if (m_privDataLen > 0) + if (len > 0) { - m_privData = new char[m_privDataLen]; - memcpy( m_privData, privData, m_privDataLen ); + m_privData.resize(len); + memcpy( &m_privData[0], privData, len ); + } + else + { + m_privData.clear(); } } -wxPrintData::~wxPrintData() -{ - m_nativeData->m_ref--; - if (m_nativeData->m_ref == 0) - delete m_nativeData; - - delete[] m_privData; -} +wxPrintData::~wxPrintData() = default; void wxPrintData::ConvertToNative() { @@ -117,47 +85,7 @@ void wxPrintData::ConvertFromNative() m_nativeData->TransferTo( *this ) ; } -wxPrintData& wxPrintData::operator=(const wxPrintData& data) -{ - if ( &data == this ) - return *this; - - m_printNoCopies = data.m_printNoCopies; - m_printCollate = data.m_printCollate; - m_printOrientation = data.m_printOrientation; - m_printOrientationReversed = data.m_printOrientationReversed; - m_printerName = data.m_printerName; - m_colour = data.m_colour; - m_duplexMode = data.m_duplexMode; - m_printQuality = data.m_printQuality; - m_paperId = data.m_paperId; - m_paperSize = data.m_paperSize; - m_bin = data.m_bin; - m_media = data.m_media; - m_printMode = data.m_printMode; - m_filename = data.m_filename; - - // UnRef old m_nativeData - if (m_nativeData) - { - m_nativeData->m_ref--; - if (m_nativeData->m_ref == 0) - delete m_nativeData; - } - // Set Ref new one - m_nativeData = data.GetNativeData(); - m_nativeData->m_ref++; - - wxDELETEA(m_privData); - m_privDataLen = data.GetPrivDataLen(); - if (m_privDataLen > 0) - { - m_privData = new char[m_privDataLen]; - memcpy( m_privData, data.GetPrivData(), m_privDataLen ); - } - - return *this; -} +wxPrintData& wxPrintData::operator=(const wxPrintData&) = default; // Is this data OK for showing the print dialog? bool wxPrintData::IsOk() const @@ -173,28 +101,9 @@ bool wxPrintData::IsOk() const wxPrintDialogData::wxPrintDialogData() { - m_printFromPage = 0; - m_printToPage = 0; - m_printMinPage = 0; - m_printMaxPage = 0; - m_printNoCopies = 1; - m_printAllPages = false; - m_printCollate = false; - m_printToFile = false; - m_printSelection = false; - m_printEnableSelection = false; - m_printEnablePageNumbers = true; - wxPrintFactory* factory = wxPrintFactory::GetFactory(); - m_printEnablePrintToFile = ! factory->HasOwnPrintToFile(); - - m_printEnableHelp = false; -} - -wxPrintDialogData::wxPrintDialogData(const wxPrintDialogData& dialogData) - : wxObject() -{ - (*this) = dialogData; + if ( factory->HasOwnPrintToFile() ) + m_printEnablePrintToFile = false; } wxPrintDialogData::wxPrintDialogData(const wxPrintData& printData) @@ -204,44 +113,16 @@ wxPrintDialogData::wxPrintDialogData(const wxPrintData& printData) m_printToPage = 0; m_printMinPage = 1; m_printMaxPage = 9999; - m_printNoCopies = 1; // On Mac the Print dialog always defaults to "All Pages" #ifdef __WXMAC__ m_printAllPages = true; -#else - m_printAllPages = false; #endif - m_printCollate = false; - m_printToFile = false; - m_printSelection = false; - m_printEnableSelection = false; - m_printEnablePageNumbers = true; - m_printEnablePrintToFile = true; - m_printEnableHelp = false; } wxPrintDialogData::~wxPrintDialogData() { } -void wxPrintDialogData::operator=(const wxPrintDialogData& data) -{ - m_printFromPage = data.m_printFromPage; - m_printToPage = data.m_printToPage; - m_printMinPage = data.m_printMinPage; - m_printMaxPage = data.m_printMaxPage; - m_printNoCopies = data.m_printNoCopies; - m_printAllPages = data.m_printAllPages; - m_printCollate = data.m_printCollate; - m_printToFile = data.m_printToFile; - m_printSelection = data.m_printSelection; - m_printEnableSelection = data.m_printEnableSelection; - m_printEnablePageNumbers = data.m_printEnablePageNumbers; - m_printEnableHelp = data.m_printEnableHelp; - m_printEnablePrintToFile = data.m_printEnablePrintToFile; - m_printData = data.m_printData; -} - void wxPrintDialogData::operator=(const wxPrintData& data) { m_printData = data; @@ -254,69 +135,16 @@ void wxPrintDialogData::operator=(const wxPrintData& data) wxPageSetupDialogData::wxPageSetupDialogData() { CalculatePaperSizeFromId(); - - m_minMarginTopLeft = - m_minMarginBottomRight = - m_marginTopLeft = - m_marginBottomRight = wxPoint(0,0); - - // Flags - m_defaultMinMargins = false; - m_enableMargins = true; - m_enableOrientation = true; - m_enablePaper = true; - m_enablePrinter = true; - m_enableHelp = false; - m_getDefaultInfo = false; -} - -wxPageSetupDialogData::wxPageSetupDialogData(const wxPageSetupDialogData& dialogData) - : wxObject() -{ - (*this) = dialogData; } wxPageSetupDialogData::wxPageSetupDialogData(const wxPrintData& printData) : m_printData(printData) { - // Flags - m_defaultMinMargins = false; - m_enableMargins = true; - m_enableOrientation = true; - m_enablePaper = true; - m_enablePrinter = true; - m_enableHelp = false; - m_getDefaultInfo = false; - // The wxPrintData paper size overrides these values, unless the size cannot // be found. CalculatePaperSizeFromId(); } -wxPageSetupDialogData::~wxPageSetupDialogData() -{ -} - -wxPageSetupDialogData& wxPageSetupDialogData::operator=(const wxPageSetupDialogData& data) -{ - m_paperSize = data.m_paperSize; - m_minMarginTopLeft = data.m_minMarginTopLeft; - m_minMarginBottomRight = data.m_minMarginBottomRight; - m_marginTopLeft = data.m_marginTopLeft; - m_marginBottomRight = data.m_marginBottomRight; - m_defaultMinMargins = data.m_defaultMinMargins; - m_enableMargins = data.m_enableMargins; - m_enableOrientation = data.m_enableOrientation; - m_enablePaper = data.m_enablePaper; - m_enablePrinter = data.m_enablePrinter; - m_getDefaultInfo = data.m_getDefaultInfo; - m_enableHelp = data.m_enableHelp; - - m_printData = data.m_printData; - - return *this; -} - wxPageSetupDialogData& wxPageSetupDialogData::operator=(const wxPrintData& data) { m_printData = data; diff --git a/src/common/prntbase.cpp b/src/common/prntbase.cpp index 3c9f8345c4..d76e788529 100644 --- a/src/common/prntbase.cpp +++ b/src/common/prntbase.cpp @@ -288,10 +288,7 @@ wxPrintNativeDataBase *wxNativePrintFactory::CreatePrintNativeData() wxIMPLEMENT_ABSTRACT_CLASS(wxPrintNativeDataBase, wxObject); -wxPrintNativeDataBase::wxPrintNativeDataBase() -{ - m_ref = 1; -} +wxPrintNativeDataBase::~wxPrintNativeDataBase() = default; //---------------------------------------------------------------------------- // wxPrintFactoryModule @@ -635,6 +632,11 @@ void wxPrintout::GetPageInfo(int *minPage, int *maxPage, int *fromPage, int *toP *toPage = 1; } +bool wxPrintout::IsPageSelected(int WXUNUSED(page)) +{ + return false; +} + bool wxPrintout::SetUp(wxDC& dc) { wxCHECK_MSG( dc.IsOk(), false, "should have a valid DC to set up" ); diff --git a/src/msw/printdlg.cpp b/src/msw/printdlg.cpp index 4513568cc7..6325c4dc87 100644 --- a/src/msw/printdlg.cpp +++ b/src/msw/printdlg.cpp @@ -793,9 +793,14 @@ bool wxWindowsPrintDialog::Create(wxWindow *p, wxPrintDialogData* data) wxWindowsPrintDialog::~wxWindowsPrintDialog() { - PRINTDLG *pd = (PRINTDLG *) m_printDlg; + PRINTDLGEX* pd = (PRINTDLGEX*) m_printDlg; + if (pd && pd->hDevMode) GlobalFree(pd->hDevMode); + + if (pd && pd->lpPageRanges) + delete pd->lpPageRanges; + if ( pd ) delete pd; @@ -814,11 +819,11 @@ int wxWindowsPrintDialog::ShowModal() ConvertToNative( m_printDialogData ); - PRINTDLG *pd = (PRINTDLG*) m_printDlg; - + PRINTDLGEX* pd = (PRINTDLGEX*) m_printDlg; pd->hwndOwner = hWndParent; - bool ret = (PrintDlg( pd ) != 0); + HRESULT dlgRes = PrintDlgEx(pd); + bool ret = (dlgRes == S_OK && pd->dwResultAction == PD_RESULT_PRINT); pd->hwndOwner = 0; @@ -852,14 +857,14 @@ bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data ) (wxWindowsPrintNativeData *) data.GetPrintData().GetNativeData(); data.GetPrintData().ConvertToNative(); - PRINTDLG *pd = (PRINTDLG*) m_printDlg; + PRINTDLGEX* pd = (PRINTDLGEX*) m_printDlg; // Shouldn't have been defined anywhere if (pd) return false; - pd = new PRINTDLG; - memset( pd, 0, sizeof(PRINTDLG) ); + pd = new PRINTDLGEX; + memset(pd, 0, sizeof(PRINTDLGEX)); m_printDlg = (void*) pd; pd->hDevMode = static_cast(native_data->GetDevMode()); @@ -871,31 +876,35 @@ bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data ) pd->hDevNames = static_cast(native_data->GetDevNames()); native_data->SetDevNames(nullptr); + pd->nStartPage = START_PAGE_GENERAL; + pd->nMinPage = (DWORD)data.GetMinPage(); + pd->nMaxPage = (DWORD)data.GetMaxPage(); + pd->nCopies = (DWORD)data.GetNoCopies(); - pd->hDC = nullptr; - pd->nFromPage = (WORD)data.GetFromPage(); - pd->nToPage = (WORD)data.GetToPage(); - pd->nMinPage = (WORD)data.GetMinPage(); - pd->nMaxPage = (WORD)data.GetMaxPage(); - pd->nCopies = (WORD)data.GetNoCopies(); + // Required only if PD_NOPAGENUMS flag is not set. + // Currently only one page range is supported. + if ( data.GetEnablePageNumbers() ) + { + pd->nPageRanges = 1; + pd->nMaxPageRanges = 1; + pd->lpPageRanges = new PRINTPAGERANGE[1]; + pd->lpPageRanges[0].nFromPage = (DWORD)data.GetFromPage(); + pd->lpPageRanges[0].nToPage = (DWORD)data.GetToPage(); + + // PrintDlgEx returns E_INVALIDARG if nFromPage is greater than nToPage + if (pd->lpPageRanges[0].nToPage < pd->lpPageRanges[0].nFromPage) + pd->lpPageRanges[0].nToPage = pd->lpPageRanges[0].nFromPage; + } pd->Flags = PD_RETURNDC; - pd->lStructSize = sizeof( PRINTDLG ); - - pd->hwndOwner = nullptr; - pd->hInstance = nullptr; - pd->lCustData = 0; - pd->lpfnPrintHook = nullptr; - pd->lpfnSetupHook = nullptr; - pd->lpPrintTemplateName = nullptr; - pd->lpSetupTemplateName = nullptr; - pd->hPrintTemplate = nullptr; - pd->hSetupTemplate = nullptr; + pd->lStructSize = sizeof(PRINTDLGEX); if ( data.GetAllPages() ) pd->Flags |= PD_ALLPAGES; if ( data.GetSelection() ) pd->Flags |= PD_SELECTION; + if ( data.GetCurrentPage() ) + pd->Flags |= PD_CURRENTPAGE; if ( data.GetCollate() ) pd->Flags |= PD_COLLATE; if ( data.GetPrintToFile() ) @@ -904,9 +913,11 @@ bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data ) pd->Flags |= PD_DISABLEPRINTTOFILE; if ( !data.GetEnableSelection() ) pd->Flags |= PD_NOSELECTION; + if ( !data.GetEnableCurrentPage() ) + pd->Flags |= PD_NOCURRENTPAGE; if ( !data.GetEnablePageNumbers() ) pd->Flags |= PD_NOPAGENUMS; - else if ( (!data.GetAllPages()) && (!data.GetSelection()) && (data.GetFromPage() != 0) && (data.GetToPage() != 0)) + else if ( (!data.GetAllPages()) && (!data.GetSelection()) && (!data.GetCurrentPage()) && (data.GetFromPage() != 0) && (data.GetToPage() != 0)) pd->Flags |= PD_PAGENUMS; if ( data.GetEnableHelp() ) pd->Flags |= PD_SHOWHELP; @@ -916,7 +927,7 @@ bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data ) bool wxWindowsPrintDialog::ConvertFromNative( wxPrintDialogData &data ) { - PRINTDLG *pd = (PRINTDLG*) m_printDlg; + PRINTDLGEX* pd = (PRINTDLGEX*) m_printDlg; if ( pd == nullptr ) return false; @@ -949,18 +960,24 @@ bool wxWindowsPrintDialog::ConvertFromNative( wxPrintDialogData &data ) // into wxWidgets form. native_data->TransferTo( data.GetPrintData() ); - data.SetFromPage( pd->nFromPage ); - data.SetToPage( pd->nToPage ); + if ( pd->lpPageRanges ) + { + data.SetFromPage(pd->lpPageRanges[0].nFromPage); + data.SetToPage(pd->lpPageRanges[0].nToPage); + } + data.SetMinPage( pd->nMinPage ); data.SetMaxPage( pd->nMaxPage ); data.SetNoCopies( pd->nCopies ); - data.SetAllPages( (((pd->Flags & PD_PAGENUMS) != PD_PAGENUMS) && ((pd->Flags & PD_SELECTION) != PD_SELECTION)) ); + data.SetAllPages( ((pd->Flags & (PD_PAGENUMS | PD_SELECTION | PD_CURRENTPAGE)) == 0) ); data.SetSelection( ((pd->Flags & PD_SELECTION) == PD_SELECTION) ); + data.SetCurrentPage(((pd->Flags & PD_CURRENTPAGE) == PD_CURRENTPAGE)); data.SetCollate( ((pd->Flags & PD_COLLATE) == PD_COLLATE) ); data.SetPrintToFile( ((pd->Flags & PD_PRINTTOFILE) == PD_PRINTTOFILE) ); data.EnablePrintToFile( ((pd->Flags & PD_DISABLEPRINTTOFILE) != PD_DISABLEPRINTTOFILE) ); data.EnableSelection( ((pd->Flags & PD_NOSELECTION) != PD_NOSELECTION) ); + data.EnableCurrentPage(((pd->Flags & PD_NOCURRENTPAGE) != PD_NOCURRENTPAGE)); data.EnablePageNumbers( ((pd->Flags & PD_NOPAGENUMS) != PD_NOPAGENUMS) ); data.EnableHelp( ((pd->Flags & PD_SHOWHELP) == PD_SHOWHELP) ); diff --git a/src/msw/printwin.cpp b/src/msw/printwin.cpp index b3e529bcd5..b671bb1007 100644 --- a/src/msw/printwin.cpp +++ b/src/msw/printwin.cpp @@ -164,7 +164,12 @@ bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt int minPageNum = minPage, maxPageNum = maxPage; - if ( !(m_printDialogData.GetAllPages() || m_printDialogData.GetSelection()) ) + if ( m_printDialogData.GetCurrentPage() || m_printDialogData.GetSelection() ) + { + minPageNum = fromPage; + maxPageNum = toPage; + } + else if ( !m_printDialogData.GetAllPages() ) { minPageNum = m_printDialogData.GetFromPage(); maxPageNum = m_printDialogData.GetToPage(); @@ -198,6 +203,10 @@ bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt pn <= maxPageNum && printout->HasPage(pn); pn++ ) { + // allow non-consecutive selected pages + if ( m_printDialogData.GetSelection() && !printout->IsPageSelected(pn) ) + continue; + win->SetProgress(pn - minPageNum + 1, maxPageNum - minPageNum + 1, copyCount, maxCopyCount);