Add support for printing only the current page

Add wxPrintDialogData::EnableCurrentPage() and implement support for it
under MSW, where it enables selecting the "Current page" radio button in
the pages selection area of the native dialog.

Update the sample to show the new function.
This commit is contained in:
Stefan Ziegler 2023-03-10 20:38:10 +01:00 committed by Vadim Zeitlin
parent 8d71d304b9
commit d75956d3e6
7 changed files with 108 additions and 31 deletions

View file

@ -162,6 +162,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 +173,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; }
@ -205,7 +209,9 @@ private:
bool m_printCollate;
bool m_printToFile;
bool m_printSelection;
bool m_printCurrentPage;
bool m_printEnableSelection;
bool m_printEnableCurrentPage;
bool m_printEnablePageNumbers;
bool m_printEnableHelp;
bool m_printEnablePrintToFile;

View file

@ -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.

View file

@ -710,6 +710,9 @@ public:
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.

View file

@ -351,6 +351,7 @@ 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);
@ -548,7 +549,14 @@ void MyPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *
*selPageFrom = 1;
*selPageTo = 2;
if (m_printDlgData->GetSelection())
// 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

View file

@ -182,7 +182,9 @@ wxPrintDialogData::wxPrintDialogData()
m_printCollate = false;
m_printToFile = false;
m_printSelection = false;
m_printCurrentPage = false;
m_printEnableSelection = false;
m_printEnableCurrentPage = false;
m_printEnablePageNumbers = true;
wxPrintFactory* factory = wxPrintFactory::GetFactory();
@ -214,7 +216,9 @@ wxPrintDialogData::wxPrintDialogData(const wxPrintData& printData)
m_printCollate = false;
m_printToFile = false;
m_printSelection = false;
m_printCurrentPage = false;
m_printEnableSelection = false;
m_printEnableCurrentPage = false;
m_printEnablePageNumbers = true;
m_printEnablePrintToFile = true;
m_printEnableHelp = false;
@ -235,7 +239,9 @@ void wxPrintDialogData::operator=(const wxPrintDialogData& data)
m_printCollate = data.m_printCollate;
m_printToFile = data.m_printToFile;
m_printSelection = data.m_printSelection;
m_printCurrentPage = data.m_printCurrentPage;
m_printEnableSelection = data.m_printEnableSelection;
m_printEnableCurrentPage = data.m_printEnableCurrentPage;
m_printEnablePageNumbers = data.m_printEnablePageNumbers;
m_printEnableHelp = data.m_printEnableHelp;
m_printEnablePrintToFile = data.m_printEnablePrintToFile;

View file

@ -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<HGLOBAL>(native_data->GetDevMode());
@ -871,31 +876,35 @@ bool wxWindowsPrintDialog::ConvertToNative( wxPrintDialogData &data )
pd->hDevNames = static_cast<HGLOBAL>(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) );

View file

@ -164,7 +164,7 @@ bool wxWindowsPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt
int minPageNum = minPage, maxPageNum = maxPage;
if ( m_printDialogData.GetSelection() )
if ( m_printDialogData.GetCurrentPage() || m_printDialogData.GetSelection() )
{
minPageNum = fromPage;
maxPageNum = toPage;