From 4209475ced5240eb3ce516767e7c9a0a74d12bc7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 26 Mar 2009 13:37:37 +0000 Subject: [PATCH] detect horizontal overflow in wxHtmlPrintout and warn the user about it git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59862 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/changes.txt | 2 ++ include/wx/html/htmprint.h | 17 ++++++++- interface/wx/html/htmprint.h | 49 ++++++++++++++++++++++--- src/html/htmprint.cpp | 70 ++++++++++++++++++++++++++++++------ 4 files changed, 122 insertions(+), 16 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 4c7b5806b4..bfaf60aa6f 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -514,6 +514,8 @@ All (GUI): - Add support for wxSP_WRAP in the generic version of wxSpinCtrlDouble. - Add alignment flags support to wxSpinCtrl[Double] (Andrew Radke). - Added wxGetSelectedChoices() replacing wxGetMultipleChoices() (Kolya Kosenko). +- Check whether document fits into page horizontally in wxHtmlPrintout, see the + new CheckFit() method for more information. wxGTK: diff --git a/include/wx/html/htmprint.h b/include/wx/html/htmprint.h index aaa359e64a..cf0a18fb12 100644 --- a/include/wx/html/htmprint.h +++ b/include/wx/html/htmprint.h @@ -80,9 +80,12 @@ public: int Render(int x, int y, wxArrayInt& known_pagebreaks, int from = 0, int dont_render = false, int to = INT_MAX); + // returns total width of the html document + int GetTotalWidth() const; + // returns total height of the html document // (compare Render's return value with this) - int GetTotalHeight(); + int GetTotalHeight() const; private: wxDC *m_DC; @@ -169,6 +172,18 @@ public: static void CleanUpStatics(); private: + // this function is called by the base class OnPreparePrinting() + // implementation and by default checks whether the document fits into + // pageArea horizontally and warns the user if it does not, giving him + // the possibility to cancel printing in this case + // + // you may override it to either suppress this check if truncation of the + // HTML being printed is acceptable or, on the contrary, add more checks to + // it, e.g. for the fit in the vertical direction if the document should + // always appear on a single page + // + // return true if printing should go ahead or false to cancel it + virtual bool CheckFit(const wxSize& pageArea, const wxSize& docArea) const; void RenderPage(wxDC *dc, int page); // renders one page into dc diff --git a/interface/wx/html/htmprint.h b/interface/wx/html/htmprint.h index c0a31b6898..a7dd53b286 100644 --- a/interface/wx/html/htmprint.h +++ b/interface/wx/html/htmprint.h @@ -25,12 +25,28 @@ public: wxHtmlDCRenderer(); /** - Returns the height of the HTML text. This is important if area height - (see wxHtmlDCRenderer::SetSize) is smaller that total height and thus - the page cannot fit into it. In that case you're supposed to call - Render() as long as its return value is smaller than GetTotalHeight()'s. + Returns the width of the HTML text in pixels. + + This can be compared with the width parameter of SetSize() to check if + the document being printed fits into the page boundary. + + @see GetTotalHeight() + + @since 2.9.0 + */ + int GetTotalWidth() const; + + /** + Returns the height of the HTML text in pixels. + + This is important if area height (see wxHtmlDCRenderer::SetSize) is + smaller that total height and thus the page cannot fit into it. In that + case you're supposed to call Render() as long as its return value is + smaller than GetTotalHeight()'s. + + @see GetTotalWidth() */ - int GetTotalHeight(); + int GetTotalHeight() const; /** Renders HTML text to the DC. @@ -245,6 +261,29 @@ public: Sets the parent window for dialogs. */ void SetParentWindow(wxWindow* window); + +private: + /** + Check whether the document fits into the page area. + + This function is called by the base class OnPreparePrinting() + implementation and by default checks whether the document fits into + @a pageArea horizontally and warns the user if it does not, giving him + the possibility to cancel printing in this case (presumably in order to + change some layout options and retry it again). + + You may override it to either suppress this check if truncation of the + HTML being printed is acceptable or, on the contrary, add more checks to + it, e.g. for the fit in the vertical direction if the document should + always appear on a single page. + + @return + @true if wxHtmlPrintout should continue or @false to cancel + printing. + + @since 2.9.0 + */ + virtual bool CheckFit(const wxSize& pageArea, const wxSize& docArea) const; }; diff --git a/src/html/htmprint.cpp b/src/html/htmprint.cpp index f4c978dbf3..e674237f88 100644 --- a/src/html/htmprint.cpp +++ b/src/html/htmprint.cpp @@ -150,11 +150,14 @@ int wxHtmlDCRenderer::Render(int x, int y, else return GetTotalHeight(); } +int wxHtmlDCRenderer::GetTotalWidth() const +{ + return m_Cells ? m_Cells->GetWidth() : 0; +} -int wxHtmlDCRenderer::GetTotalHeight() +int wxHtmlDCRenderer::GetTotalHeight() const { - if (m_Cells) return m_Cells->GetHeight(); - else return 0; + return m_Cells ? m_Cells->GetHeight() : 0; } @@ -197,6 +200,40 @@ void wxHtmlPrintout::AddFilter(wxHtmlFilter *filter) m_Filters.Append(filter); } +bool +wxHtmlPrintout::CheckFit(const wxSize& pageArea, const wxSize& docArea) const +{ + if ( docArea.x > pageArea.x ) + { + wxMessageDialog + dlg + ( + NULL, + wxString::Format + ( + _("The document \"%s\" doesn't fit on the page " + "horizontally and will be truncated if printed.\n" + "\n" + "Would you like to proceed with printing it nevertheless?"), + GetTitle() + ), + _("Printing"), + wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION + ); + dlg.SetExtendedMessage + ( + _("If possible, try changing the layout parameters to " + "make the printout more narrow") + ); + dlg.SetYesNoLabels(_("&Print"), _("&Cancel")); + + if ( dlg.ShowModal() != wxYES ) + return false; + } + + return true; +} + void wxHtmlPrintout::OnPreparePrinting() { int pageWidth, pageHeight, mm_w, mm_h, scr_w, scr_h, dc_w, dc_h; @@ -248,14 +285,27 @@ void wxHtmlPrintout::OnPreparePrinting() /* prepare main renderer: */ m_Renderer->SetDC(GetDC(), (double)ppiPrinterY / (double)ppiScreenY); - m_Renderer->SetSize((int) (ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)), - (int) (ppmm_v * (mm_h - m_MarginTop - m_MarginBottom) - - m_FooterHeight - m_HeaderHeight - - ((m_HeaderHeight == 0) ? 0 : m_MarginSpace * ppmm_v) - - ((m_FooterHeight == 0) ? 0 : m_MarginSpace * ppmm_v) - )); + + const int printAreaW = int(ppmm_h * (mm_w - m_MarginLeft - m_MarginRight)); + int printAreaH = int(ppmm_v * (mm_h - m_MarginTop - m_MarginBottom)); + if ( m_HeaderHeight ) + printAreaH -= m_HeaderHeight + m_MarginSpace * ppmm_v; + if ( m_FooterHeight ) + printAreaH -= m_FooterHeight + m_MarginSpace * ppmm_v; + + m_Renderer->SetSize(printAreaW, printAreaH); m_Renderer->SetHtmlText(m_Document, m_BasePath, m_BasePathIsDir); - CountPages(); + + if ( CheckFit(wxSize(printAreaW, printAreaH), + wxSize(m_Renderer->GetTotalWidth(), + m_Renderer->GetTotalHeight())) ) + { + // do paginate the document + CountPages(); + } + //else: if we don't call CountPages() m_PageBreaks remains empty and our + // GetPageInfo() will return 0 as max page and so nothing will be + // printed } bool wxHtmlPrintout::OnBeginDocument(int startPage, int endPage) -- 2.45.2