// This file is part of fityk program. Copyright (C) Marcin Wojdyr // Licence: GNU General Public License version 2 // $Id: print.cpp 264 2007-03-01 10:10:54Z wojdyr $ /// In this file: /// printing related utilities #include #ifdef __BORLANDC__ #pragma hdrstop #endif #ifndef WX_PRECOMP #include #endif #include #include #include //TODO #include #include #include "print.h" #include "cmn.h" #include "pane.h" #include "plot.h" #include "mplot.h" #include "aplot.h" using namespace std; //====================================================================== // PageSetupDialog //====================================================================== BEGIN_EVENT_TABLE(PageSetupDialog, wxDialog) EVT_BUTTON(wxID_OK, PageSetupDialog::OnOk) END_EVENT_TABLE() PageSetupDialog::PageSetupDialog(wxWindow *parent, PrintManager *print_mgr) : wxDialog(parent, -1, wxT("Page Setup"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER), pm(print_mgr) { wxBoxSizer *top_sizer = new wxBoxSizer(wxVERTICAL); //paper size wxStaticBoxSizer *sizerp = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Paper Size")); wxArrayString paper_sizes; int paper_sel = 0; for (size_t i = 0; i < wxThePrintPaperDatabase->GetCount(); ++i) { wxPrintPaperType *papertype = wxThePrintPaperDatabase->Item(i); paper_sizes.Add(papertype->GetName()); if (pm->get_print_data().GetPaperId() == papertype->GetId()) paper_sel = i; } papers = new wxComboBox(this, -1, _("Paper Size"), wxDefaultPosition, wxDefaultSize, paper_sizes, wxCB_READONLY); papers->SetSelection(paper_sel); sizerp->Add(papers, 1, wxALL|wxEXPAND, 5); top_sizer->Add(sizerp, 0, wxALL|wxEXPAND, 5); //orientation wxString orient_choices[] = { wxT("Portrait"), wxT("Landscape") }; orientation = new wxRadioBox(this, -1, wxT("Orientation"), wxDefaultPosition, wxDefaultSize, 2, orient_choices, 2, wxRA_SPECIFY_COLS); top_sizer->Add(orientation, 0, wxALL|wxEXPAND, 5); /* TODO what about margins? wxStaticBox *margbox = new wxStaticBox(this, -1, wxT("Margins (millimetres)")); wxStaticBoxSizer *hsizer = new wxStaticBoxSizer(margbox, wxHORIZONTAL); hsizer->Add(new wxStaticText(this, -1, wxT(" Left")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); left_margin = new SpinCtrl(this, -1, 0, -100, 500); hsizer->Add(left_margin, 0, wxALL, 5); hsizer->Add(new wxStaticText(this, -1, wxT(" Right")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); right_margin = new SpinCtrl(this, -1, 0, -100, 500); hsizer->Add(right_margin, 0, wxALL, 5); hsizer->Add(new wxStaticText(this, -1, wxT(" Top")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); top_margin = new SpinCtrl(this, -1, 0, -100, 500); hsizer->Add(top_margin, 0, wxALL, 5); hsizer->Add(new wxStaticText(this, -1, wxT(" Bottom")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); bottom_margin = new SpinCtrl(this, -1, 0, -100, 500); hsizer->Add(bottom_margin, 0, wxALL, 5); top_sizer->Add(hsizer, 0, wxALL|wxEXPAND, 5); */ wxBoxSizer *h2sizer = new wxBoxSizer(wxHORIZONTAL); h2sizer->Add(new wxStaticText(this, -1, wxT("Scale to")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); scale = new SpinCtrl(this, -1, 100, 1, 150); h2sizer->Add(scale, 0, wxTOP|wxBOTTOM, 5); h2sizer->Add(new wxStaticText(this, -1, wxT("% of page")), 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); top_sizer->Add(h2sizer); keep_ratio = new wxCheckBox(this, -1, wxT("keep width to height ratio")); top_sizer->Add(keep_ratio, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5); wxString color_choices[] = { wxT("black lines on white background"), wxT("colors from plots on white background") }; colors = new wxRadioBox(this, -1, wxT("Colors"), wxDefaultPosition, wxDefaultSize, 2, color_choices, 1, wxRA_SPECIFY_COLS); top_sizer->Add(colors, 0, wxALL|wxEXPAND, 5); wxStaticBoxSizer *boxsizer = new wxStaticBoxSizer(wxVERTICAL, this, wxT("Optional elements")); for (int i = 0; i < 2; ++i) { plot_aux[i] = new wxCheckBox(this, -1, wxString::Format(wxT("auxiliary plot %i"), i)); boxsizer->Add(plot_aux[i], 0, wxALL, 5); } plot_borders = new wxCheckBox(this, -1, wxT("borders around plots")); boxsizer->Add(plot_borders, 0, wxALL, 5); top_sizer->Add(boxsizer, 0, wxALL|wxEXPAND, 5); top_sizer->Add (new wxStaticLine(this, -1), 0, wxEXPAND|wxLEFT|wxRIGHT, 5); top_sizer->Add(CreateButtonSizer(wxOK|wxCANCEL), 0, wxALL|wxALIGN_CENTER, 5); SetSizerAndFit(top_sizer); orientation->SetSelection(pm->landscape ? 1 : 0); colors->SetSelection(pm->colors ? 1 : 0); keep_ratio->SetValue(pm->keep_ratio); scale->SetValue(pm->scale); for (int i = 0; i < 2; ++i) { if (pm->plot_pane->aux_visible(i)) { plot_aux[i]->SetValue(pm->plot_aux[i]); } else { plot_aux[i]->SetValue(false); plot_aux[i]->Enable(false); } } plot_borders->SetValue(pm->plot_borders); /* left_margin->SetValue(pm->get_page_data().GetMarginTopLeft().x); right_margin->SetValue(pm->get_page_data().GetMarginBottomRight().x); top_margin->SetValue(pm->get_page_data().GetMarginTopLeft().y); bottom_margin->SetValue(pm->get_page_data().GetMarginBottomRight().y); */ } void PageSetupDialog::OnOk(wxCommandEvent&) { if (papers->GetSelection() != -1) { wxPrintPaperType *ppt = wxThePrintPaperDatabase->Item(papers->GetSelection()); if (ppt) { pm->get_page_data().SetPaperSize(wxSize(ppt->GetWidth()/10, ppt->GetHeight()/10)); pm->get_print_data().SetPaperId(ppt->GetId()); } } pm->landscape = (orientation->GetSelection() == 1); pm->colors = colors->GetSelection() == 1; pm->keep_ratio = keep_ratio->GetValue(); pm->scale = scale->GetValue(); for (int i = 0; i < 2; ++i) pm->plot_aux[i] = plot_aux[i]->GetValue(); pm->plot_borders = plot_borders->GetValue(); /* pm->get_page_data().GetMarginTopLeft().x = left_margin->GetValue(); pm->get_page_data().GetMarginBottomRight().x = right_margin->GetValue(); pm->get_page_data().GetMarginTopLeft().y = top_margin->GetValue(); pm->get_page_data().GetMarginBottomRight().y = bottom_margin->GetValue(); */ close_it(this, wxID_OK); } //=============================================================== // Printing utilities //=============================================================== void do_print_plots(wxDC *dc, PrintManager const* pm) { // Set the scale and origin const int space = 10; //vertical space between plots const int marginX = 50, marginY = 50; //page margins //width is the same for all plots int width = pm->plot_pane->GetClientSize().GetWidth(); vector vp; vp.push_back(pm->plot_pane->get_plot()); for (int i = 0; i < 2; ++i) if (pm->plot_pane->aux_visible(i) && pm->plot_aux[i]) vp.push_back(pm->plot_pane->get_aux_plot(i)); int height = -space; //height = sum of all heights + (N-1)*space for (vector::const_iterator i = vp.begin(); i != vp.end(); ++i) height += (*i)->GetClientSize().GetHeight() + space; int w, h; dc->GetSize(&w, &h); fp scaleX = w / (width + 2.*marginX) * pm->scale/100.; fp scaleY = h / (height + 2.*marginY) * pm->scale/100.; if (pm->keep_ratio) { if (scaleX > scaleY) scaleX = scaleY; else scaleY = scaleX; } dc->SetUserScale (scaleX, scaleY); const int posX = iround((w - width * scaleX) / 2.); int posY = iround((h - height * scaleY) / 2.); //drawing all visible plots, every at different posY for (vector::const_iterator i = vp.begin(); i != vp.end(); ++i) { dc->SetDeviceOrigin (posX, posY); if (pm->plot_borders && i != vp.begin()) { int Y = -space/2; dc->DrawLine(0, Y, width, Y); } int plot_height = (*i)->GetClientSize().GetHeight(); dc->SetClippingRegion(0, 0, width, plot_height); (*i)->draw(*dc, !pm->colors); dc->DestroyClippingRegion(); posY += iround((plot_height+space) * scaleY); } } //=============================================================== FPrintout::FPrintout(PrintManager const* print_manager) : wxPrintout(wxT("fityk")), pm(print_manager) {} bool FPrintout::OnPrintPage(int page) { if (page != 1) return false; wxDC *dc = GetDC(); if (!dc) return false; do_print_plots(dc, pm); return true; } //=============================================================== class FPreviewFrame : public wxPreviewFrame { public: FPreviewFrame(wxPrintPreview* preview, wxWindow* parent) : wxPreviewFrame (preview, parent, wxT("Print Preview"), wxDefaultPosition, wxSize(600, 550)) {} void CreateControlBar() { m_controlBar = new wxPreviewControlBar(m_printPreview, wxPREVIEW_PRINT|wxPREVIEW_ZOOM, this); m_controlBar->CreateButtons(); m_controlBar->SetZoomControl(110); } }; //=============================================================== PrintManager::PrintManager(PlotPane* pane) : plot_pane(pane), print_data(0), page_setup_data(0) { read_settings(wxConfig::Get()); } PrintManager::~PrintManager() { save_settings(wxConfig::Get()); if (print_data) delete print_data; if (page_setup_data) delete page_setup_data; } void PrintManager::save_settings(wxConfigBase *cf) const { cf->Write(wxT("/print/colors"), colors); cf->Write(wxT("/print/scale"), scale); cf->Write(wxT("/print/keepRatio"), keep_ratio); cf->Write(wxT("/print/plotBorders"), plot_borders); for (int i = 0; i < 2; ++i) cf->Write(wxString::Format(wxT("/print/plotAux%i"), i), plot_aux[i]); cf->Write(wxT("/print/landscape"), landscape); } void PrintManager::read_settings(wxConfigBase *cf) { colors = cfg_read_bool(cf, wxT("/print/colors"), false); scale = cf->Read(wxT("/print/scale"), 100); keep_ratio = cfg_read_bool(cf, wxT("/print/keepRatio"), false); plot_borders = cfg_read_bool(cf, wxT("/print/plotBorders"), true); for (int i = 0; i < 2; ++i) plot_aux[i] = cfg_read_bool(cf, wxString::Format(wxT("/print/plotAux%i"), i), true); landscape = cfg_read_bool(cf, wxT("/print/landscape"), true); } wxPrintData& PrintManager::get_print_data() { if (!print_data) { print_data = new wxPrintData; print_data->SetOrientation(landscape ? wxLANDSCAPE : wxPORTRAIT); } return *print_data; } wxPageSetupDialogData& PrintManager::get_page_data() { if (!page_setup_data) page_setup_data = new wxPageSetupDialogData; return *page_setup_data; } void PrintManager::printPreview() { // Pass two printout objects: for preview, and possible printing. wxPrintDialogData print_dialog_data(get_print_data()); wxPrintPreview *preview = new wxPrintPreview (new FPrintout(this), new FPrintout(this), &print_dialog_data); if (!preview->Ok()) { delete preview; wxMessageBox(wxT("There was a problem previewing.\n") wxT("Perhaps your current printer is not set correctly?"), wxT("Previewing"), wxOK); return; } FPreviewFrame *preview_frame = new FPreviewFrame (preview, 0); preview_frame->Centre(wxBOTH); preview_frame->Initialize(); preview_frame->Show(true); } void PrintManager::pageSetup() { PageSetupDialog dlg(0, this); dlg.ShowModal(); /* * Old standard wxWidgets "page setup" dlg worked in this way: if (!page_setup_data) page_setup_data = new wxPageSetupDialogData(get_print_data()); else (*page_setup_data) = get_print_data(); wxPageSetupDialog page_setup_dialog(this, page_setup_data); page_setup_dialog.ShowModal(); get_print_data()=page_setup_dialog.GetPageSetupData().GetPrintData(); (*page_setup_data) = page_setup_dialog.GetPageSetupData(); */ } void PrintManager::print() { wxPrintDialogData print_dialog_data(get_print_data()); print_dialog_data.SetFromPage(1); print_dialog_data.SetToPage(1); print_dialog_data.EnablePageNumbers(false); print_dialog_data.EnableSelection(false); wxPrinter printer (&print_dialog_data); FPrintout printout(this); bool r = printer.Print(0, &printout, true); if (r) { get_print_data() = printer.GetPrintDialogData().GetPrintData(); landscape = (get_print_data().GetOrientation() == wxLANDSCAPE); } else if (wxPrinter::GetLastError() == wxPRINTER_ERROR) wxMessageBox(wxT("There was a problem printing.\nPerhaps your current ") wxT("printer is not set correctly?"), wxT("Printing"), wxOK); } void PrintManager::print_to_psfile() { wxFileDialog dialog(0, wxT("PostScript file"), wxT(""), wxT(""), wxT("*.ps"), wxFD_SAVE | wxFD_OVERWRITE_PROMPT); if (dialog.ShowModal() != wxID_OK) return; get_print_data().SetPrintMode(wxPRINT_MODE_FILE); get_print_data().SetFilename(dialog.GetPath()); wxPrintDialogData print_dialog_data(get_print_data()); print_dialog_data.SetFromPage(1); print_dialog_data.SetToPage(1); wxPostScriptPrinter printer (&print_dialog_data); FPrintout printout(this); bool r = printer.Print(0, &printout, false); if (!r) wxMessageBox(wxT("Can't save plots as a file:\n") + dialog.GetPath(), wxT("Exporting to PostScript"), wxOK|wxICON_ERROR); }