Перейти к содержимому

Класс wxHtmlPrint — производный от wxHtmlEasyPrinting

    В этой статье я опишу еще один переопределенный класс для своих нужд. Думаю, что не только для моих нужд. Началось все с того, что мне пришлось выводить нокоторые свои данные на печать в табличном представлении. Но перед этим, как сами понимаете, не лишним будет и предварительный просмотр.

    Для реализации этой простой задачи мне приглянулся класс wxHtmlEasyPrinting, которому дастаточно передать строку, содержащую html-код. Вот небольшой пример его использования.

    Example1.cpp

    #include <wx/html/htmprint.h>
    /*... */
    wxHtmlEasyPrinting* prn = new wxHtmlEasyPrinting(wxT("Довідник користувачів"));
    prn->GetPrintData()->SetOrientation(wxLANDSCAPE);
    prn->GetPageSetupData()->SetMarginTopLeft(wxPoint(10,10));
    prn->GetPageSetupData()->SetMarginBottomRight(wxPoint(5,5));
    prn->SetFooter(sFooter);
    prn->PreviewText(sText);
    /*... */

    Для пояснения: sFooter — это строка, содержащая html-код нижнего колонтитула; sText — строка, содержащая html-код содержания документа, выводимого на печать.

    Выглядит все это довольно неплохо:

    Но мне, как всегда нашлось что-то, что не понравилось. Первое, что мне захотелось улучшить, — это кнопки навигации. Второе, — мне (вернее пользователю) нужно было все написать «рідною мовою». Чтобы долго не рассказывать, посмотрите на рисунок ниже, и ощутите разницу.

    Теперь, как это мне удалось. Для начала, посмотрите на заголовочный файл.

    wxHtmlPrint.h

    #pragma once
    #include <wx/html/htmprint.h>
    #include <wx/choice.h>
    #include <wx/numdlg.h>
    #include <wx/bmpbuttn.h>
    #include <wx/sizer.h>

    class wxPreviewCtrlBar : public wxPreviewControlBar {
    wxBitmapButton* m_bPrint;
    wxBitmapButton* m_bRewind;
    wxBitmapButton* m_bPreview;
    wxBitmapButton* m_bNext;
    wxBitmapButton* m_bLast;
    public:
    wxPreviewCtrlBar(wxPrintPreviewBase* preview,
    long buttons,
    wxWindow* parent,
    const wxPoint& pos = wxDefaultPosition,
    const wxSize& size = wxDefaultSize,
    long style = wxTAB_TRAVERSAL,
    const wxString& name = wxT("panel"));
    void CreateButtons();
    void OnGoto();
    };

    class wxPreviewCtrl : public wxPreviewFrame {
    wxPreviewCtrlBar* m_ctrlBar;
    public:
    wxPreviewCtrl(wxPrintPreviewBase* preview,
    wxWindow* parent,
    const wxString& title = wxT("Print Preview"),
    const wxPoint& pos = wxDefaultPosition,
    const wxSize& size = wxDefaultSize,
    long style = wxDEFAULT_FRAME_STYLE,
    const wxString& name = wxT("frame"));
    inline wxPreviewControlBar* GetControlBar() const {return (wxPreviewControlBar*)m_ctrlBar;}
    void Initialize();
    void CreateControlBar();
    };

    class wxHtmlPrint : public wxHtmlEasyPrinting {
    wxString m_sTitle;
    wxWindow* m_wParent;
    protected:
    bool DoPreview(wxHtmlPrintout* printout1, wxHtmlPrintout* printout2);
    public:
    wxHtmlPrint::wxHtmlPrint(const wxString& name, wxWindow* parentWindow = NULL);
    };

    Как видите, переопределить пришлось не один класс. а целых три. Теперь, по-порядку. Класс wxPreviewCtrlBar, наследуемый от wxPreviewControlBar нужен больше всего, так как именно в этом классе переопределены кнопки и их названия. Подробнее, вместо wxButton для навигации используются wxBitmapButton, а для кнопки «Close» написано «Закрити». (Интерфейс программы был написан на украинском языке. Кому необходимо, — перепишите по-русски сами) Для реализации этой задачи и нужно было переписать функцию CreateButtons(). Функция OnGoto() переписана для того, чтобы в функцию wxGetNumberFromUser передать строки на украинском языке, а не на английском.

    Класс wxPreviewCtrl, наследуемый от wxPreviewFrame, имеет член экземпляра wxPreviewCtrlBar* m_ctrlBar. Его предок использовал предка этого члена. Потому пришлось переписать функции, в которых использовался wxPreviewControlBar, почти полностью, изменив лишь использование wxPreviewControlBar* на wxPreviewCtrlBar*.

    В классе wxHtmlPrint, наследнике wxHtmlEasyPrinting, надо было переопределить только функцию DoPreview. Но, так как члены предка wxWindow* m_ParentWindow и wxString m_Name — закрытые, то пришлось ввести их альтернативы: wxWindow* m_wParent и wxString m_sTitle.

    wxHtmlPrint.cpp

    #include "wxHtmlPrint.h"

    /// XPM
    static char * btn_rew_xpm[] = {
    "16 16 2 1",
    " c None",
    ". c #000000",
    " ",
    " .. . ",
    " .. .. ",
    " .. ... ",
    " .. .... ",
    " .. ..... ",
    " .. ...... ",
    " .. ....... ",
    " .. ....... ",
    " .. ...... ",
    " .. ..... ",
    " .. .... ",
    " .. ... ",
    " .. .. ",
    " .. . ",
    " "};

    static char * btn_prev_xpm[] = {
    "16 16 2 1",
    " c None",
    ". c #000000",
    " ",
    " . . ",
    " .. .. ",
    " ... ... ",
    " .... .... ",
    " ..... ..... ",
    " ...... ...... ",
    " .............. ",
    " .............. ",
    " ...... ...... ",
    " ..... ..... ",
    " .... .... ",
    " ... ... ",
    " .. .. ",
    " . . ",
    " "};

    static char * btn_next_xpm[] = {
    "16 16 2 1",
    " c None",
    ". c #000000",
    " ",
    " . . ",
    " .. .. ",
    " ... ... ",
    " .... .... ",
    " ..... ..... ",
    " ...... ...... ",
    " .............. ",
    " .............. ",
    " ...... ...... ",
    " ..... ..... ",
    " .... .... ",
    " ... ... ",
    " .. .. ",
    " . . ",
    " "};

    static char * btn_last_xpm[] = {
    "16 16 2 1",
    " c None",
    ". c #000000",
    " ",
    " . .. ",
    " .. .. ",
    " ... .. ",
    " .... .. ",
    " ..... .. ",
    " ...... .. ",
    " ....... .. ",
    " ....... .. ",
    " ...... .. ",
    " ..... .. ",
    " .... .. ",
    " ... .. ",
    " .. .. ",
    " . .. ",
    " "};

    static char *print_xpm[] = {
    /* columns rows colors chars-per-pixel */
    "16 15 39 1",
    "< c #E3E4E6",
    "+ c #C3C3C4",
    "i c #FFFFFF",
    ": c #74879B",
    "# c #5A89A6",
    "a c #F1F4F7",
    "r c #5A809C",
    "@ c #BDCCD9",
    "e c #7A92A4",
    "% c #3F6F93",
    "t c #9FA2A6",
    "3 c #939495",
    "w c #5F666D",
    "9 c #65839E",
    "5 c #4A7291",
    "$ c #4B7F9E",
    " c None",
    "O c #DFE0E2",
    "o c #F3F3F3",
    "; c #84A5BB",
    "& c #467291",
    ". c #7897AD",
    "* c #407598",
    "4 c #CFCFD0",
    "7 c #6F90A6",
    "y c #6A89A2",
    "0 c #AAADB2",
    "1 c #D2D3D4",
    "u c #4F7592",
    ", c #BCBDBE",
    "p c #57778E",
    "q c #979BA0",
    "2 c #ABABAC",
    "- c #E7E7E7",
    "= c #D6DEE6",
    "> c #9FA0A0",
    "8 c #829EB5",
    "X c #8FB0C3",
    "6 c #5D7C93",
    /* pixels */
    " .XXXXXXXX ",
    " .oooooooX ",
    " .OOOOOOOX ",
    " .+++++++X ",
    "@##$%&&&&&%*##@ ",
    "$=-;:>,<123$-=$ ",
    ".44.5678.96$44. ",
    "7,,,,,,,,,,,,,7 ",
    "900qwwwwwwwe009 ",
    "rtt9ryyyyyyuttr ",
    "6qq6iiiiiii%qq6 ",
    "633paiiiiii%336 ",
    "XXX*iiiiiii%XXX ",
    " 6iiiiiii% ",
    " $XXXXXXX# "
    };

    /// wxPreviewCtrlBar
    wxPreviewCtrlBar::wxPreviewCtrlBar(wxPrintPreviewBase* preview,
    long buttons,
    wxWindow* parent,
    const wxPoint& pos,
    const wxSize& size,
    long style,
    const wxString& name) :
    wxPreviewControlBar(preview, buttons, parent, pos, size, style, name)
    {
    m_bPrint = (wxBitmapButton*)NULL;
    m_bRewind = (wxBitmapButton*)NULL;
    m_bPreview = (wxBitmapButton*)NULL;
    m_bNext = (wxBitmapButton*)NULL;
    m_bLast = (wxBitmapButton*)NULL;
    }

    void wxPreviewCtrlBar::CreateButtons()
    {
    SetSize(0, 0, 400, 40);

    wxBoxSizer *item0 = new wxBoxSizer( wxHORIZONTAL );

    m_closeButton = new wxButton(this, wxID_PREVIEW_CLOSE, wxT("Закрити"),
    wxDefaultPosition, wxDefaultSize, 0);
    item0->Add(m_closeButton, 0, wxALIGN_CENTRE | wxALL, 5);

    if (m_buttonFlags & wxPREVIEW_PRINT) {
    m_bPrint = new wxBitmapButton(this, wxID_PREVIEW_PRINT, wxBitmap(print_xpm),
    wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
    item0->Add(m_bPrint, 0, wxALIGN_CENTRE|wxALL, 5);
    }

    // Exact-fit buttons are too tiny on wxUniversal
    int navButtonStyle;
    wxSize navButtonSize;
    #ifdef __WXUNIVERSAL__
    navButtonStyle = 0;
    navButtonSize = wxSize(40, m_closeButton->GetSize().y);
    #else
    navButtonStyle = wxBU_EXACTFIT;
    navButtonSize = wxDefaultSize;
    #endif

    if (m_buttonFlags & wxPREVIEW_FIRST) {
    m_bRewind = new wxBitmapButton(this, wxID_PREVIEW_FIRST, wxBitmap(btn_rew_xpm),
    wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
    item0->Add(m_bRewind, 0, wxALIGN_CENTRE | wxALL, 5);
    }
    if (m_buttonFlags & wxPREVIEW_PREVIOUS) {
    m_bPreview = new wxBitmapButton(this, wxID_PREVIEW_PREVIOUS, wxBitmap(btn_prev_xpm),
    wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
    item0->Add(m_bPreview, 0, wxALIGN_CENTRE |wxRIGHT | wxTOP | wxBOTTOM, 5);
    }
    if (m_buttonFlags & wxPREVIEW_NEXT) {
    m_bNext = new wxBitmapButton(this, wxID_PREVIEW_NEXT, wxBitmap(btn_next_xpm),
    wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
    item0->Add(m_bNext, 0, wxALIGN_CENTRE | wxRIGHT | wxTOP | wxBOTTOM, 5);
    }
    if (m_buttonFlags & wxPREVIEW_LAST) {
    m_bLast = new wxBitmapButton(this, wxID_PREVIEW_LAST, wxBitmap(btn_last_xpm),
    wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW);
    item0->Add(m_bLast, 0, wxALIGN_CENTRE | wxRIGHT | wxTOP | wxBOTTOM, 5);
    }

    if (m_buttonFlags & wxPREVIEW_GOTO) {
    m_gotoPageButton = new wxButton(this, wxID_PREVIEW_GOTO, wxT("Сторінка..."),
    wxDefaultPosition, wxDefaultSize, 0);
    item0->Add(m_gotoPageButton, 0, wxALIGN_CENTRE | wxALL, 5);
    }

    if (m_buttonFlags & wxPREVIEW_ZOOM) {
    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,
    wxSize(70,wxDefaultCoord), n, choices, 0);
    item0->Add(m_zoomControl, 0, wxALIGN_CENTRE | wxALL, 5);
    SetZoomControl(m_printPreview->GetZoom());
    }
    SetSizer(item0);
    item0->Fit(this);
    }


    void wxPreviewCtrlBar::OnGoto()
    {
    wxPrintPreviewBase *preview = GetPrintPreview();
    long nPage=0;
    if (preview) {
    if (preview->GetMinPage() > 0) {
    nPage=wxGetNumberFromUser(
    wxString::Format("Введіть номер сторінки між %d та %d:",
    preview->GetMinPage(),preview->GetMaxPage()),
    wxString::Format("%d",preview->GetCurrentPage()),
    wxT("Перейти на сторінку"),
    preview->GetCurrentPage());
    if (preview->GetPrintout()->HasPage(nPage)) {
    preview->SetCurrentPage(nPage);
    }
    }
    }
    }

    /// wxPreviewCtrl
    wxPreviewCtrl::wxPreviewCtrl(wxPrintPreviewBase* preview,
    wxWindow* parent,
    const wxString& title,
    const wxPoint& pos,
    const wxSize& size,
    long style,
    const wxString& name) :
    wxPreviewFrame(preview, parent, title, pos, size, style, name)
    {
    m_ctrlBar = NULL;
    }

    void wxPreviewCtrl::Initialize()
    {
    #if wxUSE_STATUSBAR
    CreateStatusBar();
    #endif
    CreateCanvas();
    CreateControlBar();

    m_printPreview->SetCanvas(m_previewCanvas);
    m_printPreview->SetFrame(this);

    wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );

    item0->Add(m_ctrlBar, 0, wxGROW | wxALIGN_CENTER_VERTICAL, 5);
    item0->Add(m_previewCanvas, 1, wxGROW | wxALIGN_CENTER_VERTICAL, 5);

    SetAutoLayout( true );
    SetSizer( item0 );

    m_windowDisabler = new wxWindowDisabler(this);

    Layout();

    m_printPreview->AdjustScrollbars(m_previewCanvas);
    m_previewCanvas->SetFocus();
    m_ctrlBar->SetFocus();
    }

    void wxPreviewCtrl::CreateControlBar()
    {
    long buttons = wxPREVIEW_DEFAULT;
    if (m_printPreview->GetPrintoutForPrinting())
    buttons |= wxPREVIEW_PRINT;

    m_ctrlBar = new wxPreviewCtrlBar(m_printPreview, buttons, this, wxPoint(0,0), wxSize(400,40));
    m_ctrlBar->CreateButtons();
    }

    /// wxHtmlPrint
    wxHtmlPrint::wxHtmlPrint(const wxString& name, wxWindow* parentWindow) :
    wxHtmlEasyPrinting(name, parentWindow),
    m_sTitle(name),
    m_wParent(parentWindow)
    {
    }

    bool wxHtmlPrint::DoPreview(wxHtmlPrintout* printout1, wxHtmlPrintout* printout2)
    {
    wxPrintDialogData printDialogData(*GetPrintData());
    wxPrintPreview *preview = new wxPrintPreview(printout1, printout2, &printDialogData);
    if (!preview->Ok())
    {
    delete preview;
    return false;
    }

    wxPreviewCtrl* frame = new wxPreviewCtrl(preview, m_wParent,
    m_sTitle + wxT(" (Попередній перегляд)"),
    wxPoint(100, 100), wxSize(650, 500));

    frame->Centre(wxBOTH);
    frame->Initialize();
    frame->Show(true);
    return true;
    }

    Теперь, для красивого предварительного просмотра, Вы можете использовать wxHtmlPrint. Использование аналогично его предку — wxHtmlEasyPrinting.

    Example2.cpp

    #include <wxHtmlPrint.h>
    /* ... */
    wxHtmlPrint* prn = new wxHtmlPrint(wxT("Довідник користувачів"));
    prn->GetPrintData()->SetOrientation(wxLANDSCAPE);
    prn->GetPageSetupData()->SetMarginTopLeft(wxPoint(10,10));
    prn->GetPageSetupData()->SetMarginBottomRight(wxPoint(5,5));
    prn->SetFooter(sFooter);
    /// Предварительный просмотр
    prn->PreviewText(sText);
    /// Печать без предварительного просмотра
    prn->PrintText(sText);
    /* ... */

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *