1///////////////////////////////////////////////////////////////////////////// 2// Name: src/generic/printps.cpp 3// Purpose: Postscript print/preview framework 4// Author: Julian Smart 5// Modified by: 6// Created: 04/01/98 7// RCS-ID: $Id: printps.cpp 42522 2006-10-27 13:07:40Z JS $ 8// Copyright: (c) Julian Smart 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#ifdef __BORLANDC__ 16 #pragma hdrstop 17#endif 18 19// ============================================================================ 20// declarations 21// ============================================================================ 22 23// ---------------------------------------------------------------------------- 24// headers 25// ---------------------------------------------------------------------------- 26 27#if wxUSE_PRINTING_ARCHITECTURE && wxUSE_POSTSCRIPT && (!defined(__WXMSW__) || wxUSE_POSTSCRIPT_ARCHITECTURE_IN_MSW) 28 29#ifndef WX_PRECOMP 30 #include "wx/utils.h" 31 #include "wx/dc.h" 32 #include "wx/app.h" 33 #include "wx/msgdlg.h" 34 #include "wx/intl.h" 35 #include "wx/progdlg.h" 36 #include "wx/log.h" 37 #include "wx/dcprint.h" 38#endif 39 40#include "wx/generic/printps.h" 41#include "wx/printdlg.h" 42#include "wx/generic/prntdlgg.h" 43#include "wx/generic/progdlgg.h" 44#include "wx/paper.h" 45 46#include <stdlib.h> 47 48// ---------------------------------------------------------------------------- 49// wxWin macros 50// ---------------------------------------------------------------------------- 51 52 IMPLEMENT_DYNAMIC_CLASS(wxPostScriptPrinter, wxPrinterBase) 53 IMPLEMENT_CLASS(wxPostScriptPrintPreview, wxPrintPreviewBase) 54 55// ============================================================================ 56// implementation 57// ============================================================================ 58 59// ---------------------------------------------------------------------------- 60// Printer 61// ---------------------------------------------------------------------------- 62 63wxPostScriptPrinter::wxPostScriptPrinter(wxPrintDialogData *data) 64 : wxPrinterBase(data) 65{ 66} 67 68wxPostScriptPrinter::~wxPostScriptPrinter() 69{ 70} 71 72bool wxPostScriptPrinter::Print(wxWindow *parent, wxPrintout *printout, bool prompt) 73{ 74 sm_abortIt = false; 75 sm_abortWindow = (wxWindow *) NULL; 76 77 if (!printout) 78 { 79 sm_lastError = wxPRINTER_ERROR; 80 return false; 81 } 82 83 printout->SetIsPreview(false); 84 85 if (m_printDialogData.GetMinPage() < 1) 86 m_printDialogData.SetMinPage(1); 87 if (m_printDialogData.GetMaxPage() < 1) 88 m_printDialogData.SetMaxPage(9999); 89 90 // Create a suitable device context 91 wxDC *dc; 92 if (prompt) 93 { 94 dc = PrintDialog(parent); 95 if (!dc) 96 return false; 97 } 98 else 99 { 100 dc = new wxPostScriptDC(GetPrintDialogData().GetPrintData()); 101 } 102 103 // May have pressed cancel. 104 if (!dc || !dc->Ok()) 105 { 106 if (dc) delete dc; 107 sm_lastError = wxPRINTER_ERROR; 108 return false; 109 } 110 111 wxSize ScreenPixels = wxGetDisplaySize(); 112 wxSize ScreenMM = wxGetDisplaySizeMM(); 113 114 printout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()), 115 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) ); 116 printout->SetPPIPrinter( wxPostScriptDC::GetResolution(), 117 wxPostScriptDC::GetResolution() ); 118 119 // Set printout parameters 120 printout->SetDC(dc); 121 122 int w, h; 123 dc->GetSize(&w, &h); 124 printout->SetPageSizePixels((int)w, (int)h); 125 printout->SetPaperRectPixels(wxRect(0, 0, w, h)); 126 int mw, mh; 127 dc->GetSizeMM(&mw, &mh); 128 printout->SetPageSizeMM((int)mw, (int)mh); 129 130 // Create an abort window 131 wxBeginBusyCursor(); 132 133 printout->OnPreparePrinting(); 134 135 // Get some parameters from the printout, if defined 136 int fromPage, toPage; 137 int minPage, maxPage; 138 printout->GetPageInfo(&minPage, &maxPage, &fromPage, &toPage); 139 140 if (maxPage == 0) 141 { 142 sm_lastError = wxPRINTER_ERROR; 143 wxEndBusyCursor(); 144 return false; 145 } 146 147 // Only set min and max, because from and to have been 148 // set by the user 149 m_printDialogData.SetMinPage(minPage); 150 m_printDialogData.SetMaxPage(maxPage); 151 152 if (m_printDialogData.GetFromPage() < minPage) 153 m_printDialogData.SetFromPage( minPage ); 154 if (m_printDialogData.GetToPage() > maxPage) 155 m_printDialogData.SetToPage( maxPage ); 156 157 int 158 pagesPerCopy = m_printDialogData.GetToPage()-m_printDialogData.GetFromPage()+1, 159 totalPages = pagesPerCopy * m_printDialogData.GetNoCopies(), 160 printedPages = 0; 161 // Open the progress bar dialog 162 wxProgressDialog *progressDialog = new wxProgressDialog ( 163 printout->GetTitle(), 164 _("Printing..."), 165 totalPages, 166 parent, 167 wxPD_CAN_ABORT|wxPD_AUTO_HIDE|wxPD_APP_MODAL); 168 169 printout->OnBeginPrinting(); 170 171 sm_lastError = wxPRINTER_NO_ERROR; 172 173 bool keepGoing = true; 174 175 int copyCount; 176 for (copyCount = 1; copyCount <= m_printDialogData.GetNoCopies(); copyCount ++) 177 { 178 if (!printout->OnBeginDocument(m_printDialogData.GetFromPage(), m_printDialogData.GetToPage())) 179 { 180 wxEndBusyCursor(); 181 wxLogError(_("Could not start printing.")); 182 sm_lastError = wxPRINTER_ERROR; 183 break; 184 } 185 if (sm_abortIt) 186 { 187 sm_lastError = wxPRINTER_CANCELLED; 188 break; 189 } 190 191 int pn; 192 for (pn = m_printDialogData.GetFromPage(); keepGoing && (pn <= m_printDialogData.GetToPage()) && printout->HasPage(pn); 193 pn++) 194 { 195 if (sm_abortIt) 196 { 197 keepGoing = false; 198 sm_lastError = wxPRINTER_CANCELLED; 199 break; 200 } 201 else 202 { 203 wxString msg; 204 msg.Printf(_("Printing page %d..."), printedPages+1); 205 if(progressDialog->Update(printedPages++, msg)) 206 { 207 dc->StartPage(); 208 printout->OnPrintPage(pn); 209 dc->EndPage(); 210 } 211 else 212 { 213 sm_abortIt = true; 214 sm_lastError = wxPRINTER_CANCELLED; 215 keepGoing = false; 216 } 217 } 218 wxYield(); 219 } 220 printout->OnEndDocument(); 221 } 222 223 printout->OnEndPrinting(); 224 delete progressDialog; 225 226 wxEndBusyCursor(); 227 228 delete dc; 229 230 return (sm_lastError == wxPRINTER_NO_ERROR); 231} 232 233wxDC* wxPostScriptPrinter::PrintDialog(wxWindow *parent) 234{ 235 wxDC* dc = (wxDC*) NULL; 236 237 wxGenericPrintDialog dialog( parent, &m_printDialogData ); 238 if (dialog.ShowModal() == wxID_OK) 239 { 240 dc = dialog.GetPrintDC(); 241 m_printDialogData = dialog.GetPrintDialogData(); 242 243 if (dc == NULL) 244 sm_lastError = wxPRINTER_ERROR; 245 else 246 sm_lastError = wxPRINTER_NO_ERROR; 247 } 248 else 249 sm_lastError = wxPRINTER_CANCELLED; 250 251 return dc; 252} 253 254bool wxPostScriptPrinter::Setup(wxWindow *WXUNUSED(parent)) 255{ 256#if 0 257 wxGenericPrintDialog* dialog = new wxGenericPrintDialog(parent, & m_printDialogData); 258 dialog->GetPrintDialogData().SetSetupDialog(true); 259 260 int ret = dialog->ShowModal(); 261 262 if (ret == wxID_OK) 263 { 264 m_printDialogData = dialog->GetPrintDialogData(); 265 } 266 267 dialog->Destroy(); 268 269 return (ret == wxID_OK); 270#endif 271 272 return false; 273} 274 275// ---------------------------------------------------------------------------- 276// Print preview 277// ---------------------------------------------------------------------------- 278 279void wxPostScriptPrintPreview::Init(wxPrintout * WXUNUSED(printout), 280 wxPrintout * WXUNUSED(printoutForPrinting)) 281{ 282 // Have to call it here since base constructor can't call it 283 DetermineScaling(); 284} 285 286wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout, 287 wxPrintout *printoutForPrinting, 288 wxPrintDialogData *data) 289 : wxPrintPreviewBase(printout, printoutForPrinting, data) 290{ 291 Init(printout, printoutForPrinting); 292} 293 294wxPostScriptPrintPreview::wxPostScriptPrintPreview(wxPrintout *printout, 295 wxPrintout *printoutForPrinting, 296 wxPrintData *data) 297 : wxPrintPreviewBase(printout, printoutForPrinting, data) 298{ 299 Init(printout, printoutForPrinting); 300} 301 302wxPostScriptPrintPreview::~wxPostScriptPrintPreview() 303{ 304} 305 306bool wxPostScriptPrintPreview::Print(bool interactive) 307{ 308 if (!m_printPrintout) 309 return false; 310 311 // Assume that on Unix, the preview may use the PostScript 312 // (generic) version, but printing using the native system is required. 313 // TODO: make a generic print preview class from which wxPostScriptPrintPreview 314 // is derived. 315#ifdef __UNIX__ 316 wxPrinter printer(& m_printDialogData); 317#else 318 wxPostScriptPrinter printer(& m_printDialogData); 319#endif 320 return printer.Print(m_previewFrame, m_printPrintout, interactive); 321} 322 323void wxPostScriptPrintPreview::DetermineScaling() 324{ 325 wxPaperSize paperType = m_printDialogData.GetPrintData().GetPaperId(); 326 if (paperType == wxPAPER_NONE) 327 paperType = wxPAPER_NONE; 328 329 wxPrintPaperType *paper = wxThePrintPaperDatabase->FindPaperType(paperType); 330 if (!paper) 331 paper = wxThePrintPaperDatabase->FindPaperType(wxPAPER_A4); 332 333 if (paper) 334 { 335 wxSize ScreenPixels = wxGetDisplaySize(); 336 wxSize ScreenMM = wxGetDisplaySizeMM(); 337 338 m_previewPrintout->SetPPIScreen( (int) ((ScreenPixels.GetWidth() * 25.4) / ScreenMM.GetWidth()), 339 (int) ((ScreenPixels.GetHeight() * 25.4) / ScreenMM.GetHeight()) ); 340 m_previewPrintout->SetPPIPrinter(wxPostScriptDC::GetResolution(), wxPostScriptDC::GetResolution()); 341 342 wxSize sizeDevUnits(paper->GetSizeDeviceUnits()); 343 sizeDevUnits.x = (wxCoord)((float)sizeDevUnits.x * wxPostScriptDC::GetResolution() / 72.0); 344 sizeDevUnits.y = (wxCoord)((float)sizeDevUnits.y * wxPostScriptDC::GetResolution() / 72.0); 345 wxSize sizeTenthsMM(paper->GetSize()); 346 wxSize sizeMM(sizeTenthsMM.x / 10, sizeTenthsMM.y / 10); 347 348 // If in landscape mode, we need to swap the width and height. 349 if ( m_printDialogData.GetPrintData().GetOrientation() == wxLANDSCAPE ) 350 { 351 m_pageWidth = sizeDevUnits.y; 352 m_pageHeight = sizeDevUnits.x; 353 m_previewPrintout->SetPageSizeMM(sizeMM.y, sizeMM.x); 354 } 355 else 356 { 357 m_pageWidth = sizeDevUnits.x; 358 m_pageHeight = sizeDevUnits.y; 359 m_previewPrintout->SetPageSizeMM(sizeMM.x, sizeMM.y); 360 } 361 m_previewPrintout->SetPageSizePixels(m_pageWidth, m_pageHeight); 362 m_previewPrintout->SetPaperRectPixels(wxRect(0, 0, m_pageWidth, m_pageHeight)); 363 364 // At 100%, the page should look about page-size on the screen. 365 m_previewScaleX = (float)0.8 * 72.0 / (float)wxPostScriptDC::GetResolution(); 366 m_previewScaleY = m_previewScaleX; 367 } 368} 369 370#endif 371