kexisimpleprintingpagesetup.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this program; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "kexisimpleprintingpagesetup.h"
21#include "kexisimpleprintingpagesetupbase.h"
22#include "kexisimpleprintpreviewwindow.h"
23
24#include <core/keximainwindow.h>
25#include <kexiutils/utils.h>
26#include <kexi_version.h>
27
28#include <tdeapplication.h>
29#include <kiconloader.h>
30#include <tdelocale.h>
31#include <tdefontdialog.h>
32#include <kurllabel.h>
33#include <kdebug.h>
34#include <klineedit.h>
35#include <kprinter.h>
36#include <kpushbutton.h>
37#include <tdeversion.h>
38
39#include <tqlabel.h>
40#include <tqtimer.h>
41#include <tqlayout.h>
42#include <tqpainter.h>
43#include <tqcheckbox.h>
44#include <tqwhatsthis.h>
45#include <tqtooltip.h>
46
47#include <kexiutils/tristate.h>
48
49KexiSimplePrintingCommand::KexiSimplePrintingCommand(
50 KexiMainWindow* mainWin, int objectId, TQObject* parent)
51 : TQObject(parent, "KexiSimplePrintCommand")
52 , m_previewEngine(0)
53 , m_mainWin(mainWin)
54 , m_objectId(objectId)
55 , m_previewWindow(0)
56 , m_printPreviewNeedsReloading(false)
57{
58 connect(this, TQ_SIGNAL(showPageSetupRequested(KexiPart::Item*)),
59 m_mainWin, TQ_SLOT(showPageSetupForItem(KexiPart::Item*)));
60}
61
62KexiSimplePrintingCommand::~KexiSimplePrintingCommand()
63{
64 delete m_previewWindow;
65 delete m_previewEngine;
66// delete m_settings;
67}
68
69
70bool KexiSimplePrintingCommand::print(const KexiSimplePrintingSettings& settings,
71 const TQString& aTitleText)
72{
73 m_settings = settings;
74 return print(aTitleText);
75}
76
77bool KexiSimplePrintingCommand::print(const TQString& aTitleText)
78{
79 KexiDB::Connection *conn = m_mainWin->project()->dbConnection();
80 KexiDB::TableOrQuerySchema tableOrQuery(conn, m_objectId);
81 if (!tableOrQuery.table() && !tableOrQuery.query()) {
83 return false;
84 }
85 TQString titleText(aTitleText.stripWhiteSpace());
86 if (titleText.isEmpty())
87 titleText = tableOrQuery.captionOrName();
88
89 KexiSimplePrintingEngine engine(m_settings, this);
90 TQString errorMessage;
91 if (!engine.init(*conn, tableOrQuery, titleText, errorMessage)) {
92 if (!errorMessage.isEmpty())
93 KMessageBox::sorry(m_mainWin, errorMessage, i18n("Printing"));
94 return false;
95 }
96
97 //setup printing
98#ifdef TQ_WS_WIN
99 TQPrinter printer(TQPrinter::HighResolution);
100 printer.setOrientation( m_settings.pageLayout.orientation == PG_PORTRAIT
101 ? TQPrinter::Portrait : TQPrinter::Landscape );
102 printer.setPageSize(
103 (TQPrinter::PageSize)KoPageFormat::printerPageSize( m_settings.pageLayout.format ) );
104
105 // "chicken-egg" problem:
106 // we cannot use real from/to values in setMinMax() and setFromTo()
107 // because page count is known after obtaining print settings
108 printer.setFromTo(1,1);
109#else
110 KPrinter printer;
111 printer.setOrientation( m_settings.pageLayout.orientation == PG_PORTRAIT
112 ? KPrinter::Portrait : KPrinter::Landscape );
113 printer.setPageSize(
114 (KPrinter::PageSize)KoPageFormat::printerPageSize( m_settings.pageLayout.format ) );
115#endif
116
117 printer.setFullPage(true);
118 TQString docName( titleText );
119 printer.setDocName( docName );
120 printer.setCreator(KEXI_APP_NAME);
121 if ( !printer.setup( m_mainWin ) ) {
122 return true;
123 }
124
125 // now we have final settings
126
128 TQPainter painter;
129
130 if (!painter.begin(&printer)) {
132 return false;
133 }
134 engine.calculatePagesCount(painter);
135
136 uint loops, loopsPerPage;
137 TQValueList<int> pagesToPrint;
138 int fromPage = 0;
139#ifdef TQ_WS_WIN
140 int toPage = 0;
141 if (TQPrinter::PageRange == printer.printRange()) {
142 fromPage = printer.fromPage();
143 toPage = printer.toPage();
144 }
145 if (fromPage==0 || toPage==0) {
146 fromPage = 0;
147 toPage = (int)engine.pagesCount()-1;
148 }
149 else {
150 fromPage--;
151 if (toPage > (int)engine.pagesCount())
152 toPage = (int)engine.pagesCount();
153 toPage--;
154 }
155 // win32 only supports one range, build the list
156 for (int i = fromPage; i<=toPage; i++) {
157 pagesToPrint.append(i);
158 }
159 // on win32 the OS does perform buffering (only when collation is off, each copy needs to be repeated)
160 loops = 1;
161 loopsPerPage = printer.collateCopies() ? 1 : printer.numCopies();
162#else
163 // on !win32 print TQPrinter::numCopies() times (the OS does not perform buffering)
164 pagesToPrint = printer.pageList();
165 kdDebug() << pagesToPrint << endl;
166 if (pagesToPrint.isEmpty()) {
167 fromPage = 0;
168 for (int i = 0; i<(int)engine.pagesCount(); i++) {
169 pagesToPrint.append(i);
170 }
171 }
172 else
173 fromPage = pagesToPrint.first();
174 if (printer.collate()==KPrinter::Collate) {
175 //collation: p1, p2,..pn; p1, p2,..pn; ......; p1, p2,..pn
176 loops = printer.numCopies();
177 loopsPerPage = 1;
178 }
179 else {
180 //no collation: p1, p1, ..., p1; p2, p2, ..., p2; ......; pn, pn,..pn
181 loops = 1;
182 loopsPerPage = printer.numCopies();
183 }
185#endif
186 // now, total number of printed pages is printer.numCopies()*printer.pageList().count()
187
188 kdDebug() << "printing..." << endl;
189 bool firstPage = true;
190 for (uint copy = 0;copy < loops; copy++) {
191 kdDebug() << "copy " << (copy+1) << " of " << loops << endl;
192 uint pageNumber = fromPage;
193 TQValueList<int>::ConstIterator pagesIt = pagesToPrint.constBegin();
194 for(;(int)pageNumber == fromPage || !engine.eof(); ++pageNumber) {
195 kdDebug() << "printing..." << endl;
196 if (pagesIt == pagesToPrint.constEnd()) //no more pages to print
197 break;
198 if ((int)pageNumber < *pagesIt) { //skip pages without printing (needed for computation)
199 engine.paintPage(pageNumber, painter, false);
200 continue;
201 }
202 if (*pagesIt < (int)pageNumber) { //sanity
203 ++pagesIt;
204 continue;
205 }
206 for (uint onePageCounter = 0; onePageCounter < loopsPerPage; onePageCounter++) {
207 if (!firstPage)
208 printer.newPage();
209 else
210 firstPage = false;
211 kdDebug() << "page #" << pageNumber << endl;
212 engine.paintPage(pageNumber, painter);
213 }
214 ++pagesIt;
215 }
216 }
217 kdDebug() << "end of printing." << endl;
218
219 // stop painting, this will automatically send the print data to the printer
220 if (!painter.end())
221 return false;
222
223 if (!engine.done())
224 return false;
225
226 return true;
227}
228
230 const TQString& aTitleText, bool reload)
231{
232 m_settings = settings;
233 if (!m_previewEngine)
234 m_previewEngine = new KexiSimplePrintingEngine(m_settings, this);
235
236 if (reload)
237 m_printPreviewNeedsReloading = true;
238
239 bool backToPage0 = true;
240 TQString titleText(aTitleText.stripWhiteSpace());
241 KexiDB::Connection *conn = m_mainWin->project()->dbConnection();
242 KexiDB::TableOrQuerySchema tableOrQuery(conn, m_objectId);
243 if (!tableOrQuery.table() && !tableOrQuery.query()) {
245 return false;
246 }
247 if (titleText.isEmpty())
248 titleText = tableOrQuery.captionOrName();
249 if (!m_previewWindow || m_printPreviewNeedsReloading) {
250 TQString errorMessage;
251 if (!m_previewEngine->init(
252 *conn, tableOrQuery, titleText, errorMessage)) {
253 if (!errorMessage.isEmpty())
254 KMessageBox::sorry(m_mainWin, errorMessage, i18n("Print Preview"));
255 return false;
256 }
257 }
258 if (!m_previewWindow) {
259 backToPage0 = false;
260 m_previewWindow = new KexiSimplePrintPreviewWindow(
261 *m_previewEngine, tableOrQuery.captionOrName(), 0,
262 TQt::WStyle_Customize|TQt::WStyle_NormalBorder|TQt::WStyle_Title|
263 TQt::WStyle_SysMenu|TQt::WStyle_MinMax|TQt::WStyle_ContextHelp);
264 connect(m_previewWindow, TQ_SIGNAL(printRequested()), this, TQ_SLOT(print()));
265 connect(m_previewWindow, TQ_SIGNAL(pageSetupRequested()), this, TQ_SLOT(slotShowPageSetupRequested()));
266 m_previewWindow->show();
267 KDialog::centerOnScreen(m_previewWindow);
268 m_printPreviewNeedsReloading = false;
269 }
270
271 if (m_printPreviewNeedsReloading) {//dirty
272 m_previewEngine->clear();
274 m_previewEngine->setTitleText( titleText );
275 m_previewWindow->setFullWidth();
276 m_previewWindow->updatePagesCount();
277 m_printPreviewNeedsReloading = false;
278 }
279 if (backToPage0)
280 m_previewWindow->goToPage(0);
281 m_previewWindow->show();
282 m_previewWindow->raise();
283// m_previewWindow->setPagesCount(INT_MAX); //will be properly set on demand
284 return true;
285}
286
287void KexiSimplePrintingCommand::slotShowPageSetupRequested()
288{
289 m_mainWin->raise();
290 emit showPageSetupRequested( m_mainWin->project()->item( m_objectId ) );
291}
292
293/*void KexiSimplePrintingCommand::setPrintPreviewNeedsReloading()
294{
295 m_printPreviewNeedsReloading = true;
296}*/
297
298//----------------------------------------------------------
299
301 TQMap<TQString,TQString>* args )
302 : KexiViewBase( mainWin, parent, "KexiSimplePrintingPageSetup" )
303 , m_settings( KexiSimplePrintingSettings::load() )
304// , m_command(0)
305{
306 // object to print
307 bool ok = args;
308 int objectId;
309 if (ok)
310 objectId = (*args)["identifier"].toInt();
311 ok = objectId<=0;
312 m_item = mainWin->project()->item( objectId );
313 ok = m_item;
314
315 bool printPreview = false;
316 bool print = false;
317 bool pageSetup = false;
318 if (ok) {
319 printPreview = (*args)["action"]=="printPreview";
320 print = (*args)["action"]=="print";
321 pageSetup = (*args)["action"]=="pageSetup";
322 ok = printPreview || print || pageSetup;
323 }
324
325 // settings
327 m_unit = TDELocale::Metric == TDEGlobal::locale()->measureSystem() ? KoUnit::U_CM : KoUnit::U_INCH;
328
329 // GUI
330 TQVBoxLayout *lyr = new TQVBoxLayout(this);
331 m_contents = new KexiSimplePrintingPageSetupBase(this, "KexiSimplePrintingPageSetupBase");
332 lyr->addWidget(m_contents);
333
334 setViewWidget(m_contents, true);
335// setFocusPolicy(WheelFocus);
336 m_contents->setFocusProxy(m_contents->headerTitleLineEdit);
337
338 m_contents->printButton->setIconSet( KStdGuiItem::print().iconSet(TDEIcon::Small) );
339 m_contents->printButton->setText( KStdGuiItem::print().text() );
340 connect(m_contents->printButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(print()));
341
342 m_contents->printPreviewButton->setIconSet( SmallIconSet("document-print-preview") );
343 m_contents->printPreviewButton->setText( i18n("Print Previe&w...") );
344 connect(m_contents->printPreviewButton, TQ_SIGNAL(clicked()), this, TQ_SLOT(printPreview()));
345
346 m_contents->iconLabel->setFixedWidth(32+6);
347 m_contents->iconLabel->setPixmap( DesktopIcon("text-x-generic", 32) );
348 TQWhatsThis::add(m_contents->headerTitleFontButton, i18n("Changes font for title text."));
349 connect(m_contents->headerTitleFontButton, TQ_SIGNAL(clicked()),
350 this, TQ_SLOT(slotChangeTitleFont()));
351
352 if (m_item) {
353 m_origCaptionLabelText = m_contents->captionLabel->text();
354 m_contents->headerTitleLineEdit->setText( m_item->captionOrName() );
355 if (m_item->mimeType()=="kexi/query") {
356 m_contents->openDataLink->setText( i18n("Open This Query") );
357 m_origCaptionLabelText = i18n("<h2>Page setup for printing \"%1\" query data</h2>");
358 }
359 m_contents->captionLabel->setText( m_origCaptionLabelText.arg(m_item->name()) );
360 }
361 connect(m_contents->headerTitleLineEdit,TQ_SIGNAL(textChanged(const TQString&)),
362 this, TQ_SLOT(slotTitleTextChanged(const TQString&)));
363 m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
364
365 TQWhatsThis::add(m_contents->openDataLink,
366 i18n("Shows data for table or query associated with this page setup."));
367 TQToolTip::add(m_contents->openDataLink,
368 i18n("Shows data for table or query associated with this page setup."));
369 connect(m_contents->openDataLink, TQ_SIGNAL(leftClickedURL()), this, TQ_SLOT(slotOpenData()));
370
371 TQWhatsThis::add(m_contents->saveSetupLink, i18n("Saves settings for this setup as default."));
372 connect(m_contents->saveSetupLink, TQ_SIGNAL(leftClickedURL()), this, TQ_SLOT(slotSaveSetup()));
373#if !KDE_IS_VERSION(3,5,1) && !defined(TQ_WS_WIN)
374 //a fix for problems with focusable KUrlLabel on KDElibs<=3.5.0
375 m_contents->openDataLink->setFocusPolicy(NoFocus);
376 m_contents->saveSetupLink->setFocusPolicy(NoFocus);
377#endif
378
379 TQWhatsThis::add(m_contents->addDateTimeCheckbox, i18n("Adds date and time to the header."));
380 TQWhatsThis::add(m_contents->addPageNumbersCheckbox, i18n("Adds page numbers to the footer."));
381 TQWhatsThis::add(m_contents->addTableBordersCheckbox, i18n("Adds table borders."));
382
383#ifdef KEXI_NO_UNFINISHED
384 m_contents->addDateTimeCheckbox->hide();
385 m_contents->addPageNumbersCheckbox->hide();
386#endif
387
388 updatePageLayoutAndUnitInfo();
389 TQWhatsThis::add(m_contents->changePageSizeAndMarginsButton,
390 i18n("Changes page size and margins."));
391 connect(m_contents->changePageSizeAndMarginsButton, TQ_SIGNAL(clicked()),
392 this, TQ_SLOT(slotChangePageSizeAndMargins()));
393
394 connect(m_contents->addPageNumbersCheckbox, TQ_SIGNAL(toggled(bool)),
395 this, TQ_SLOT(slotAddPageNumbersCheckboxToggled(bool)));
396 connect(m_contents->addDateTimeCheckbox, TQ_SIGNAL(toggled(bool)),
397 this, TQ_SLOT(slotAddDateTimeCheckboxToggled(bool)));
398 connect(m_contents->addTableBordersCheckbox, TQ_SIGNAL(toggled(bool)),
399 this, TQ_SLOT(slotAddTableBordersCheckboxToggled(bool)));
400
401 if (!ok) {
402 // no data!
403 setEnabled(false);
404 }
405
406 m_contents->addPageNumbersCheckbox->setChecked( m_settings.addPageNumbers );
407 m_contents->addDateTimeCheckbox->setChecked( m_settings.addDateAndTime );
408 m_contents->addTableBordersCheckbox->setChecked( m_settings.addTableBorders );
409 setDirty(false);
410
411// m_engine = new KexiSimplePrintingEngine(m_settings, this);
412
413 //clear it back to false after widgets initialization
414 m_printPreviewNeedsReloading = false;
415
416/* if (printPreview)
417 TQTimer::singleShot(50, this, TQ_SLOT(printPreview()));
418 else if (print)
419 TQTimer::singleShot(50, this, TQ_SLOT(print()));*/
420 connect(this, TQ_SIGNAL(printItemRequested(KexiPart::Item*,const KexiSimplePrintingSettings&,
421 const TQString&)),
422 m_mainWin, TQ_SLOT(printItem(KexiPart::Item*,const KexiSimplePrintingSettings&,
423 const TQString&)));
424 connect(this, TQ_SIGNAL(printPreviewForItemRequested(KexiPart::Item*,
425 const KexiSimplePrintingSettings&,const TQString&,bool)),
426 m_mainWin, TQ_SLOT(printPreviewForItem(KexiPart::Item*,
427 const KexiSimplePrintingSettings&,const TQString&,bool)));
428}
429
430KexiSimplePrintingPageSetup::~KexiSimplePrintingPageSetup()
431{
432}
433
434void KexiSimplePrintingPageSetup::slotSaveSetup()
435{
436 m_settings.save();
437 setDirty(false);
438}
439
440void KexiSimplePrintingPageSetup::updatePageLayoutAndUnitInfo()
441{
442 TQString s;
443 if (m_settings.pageLayout.format == PG_CUSTOM) {
444 s += TQString(" (%1 %2 x %3 %4)")
445 .arg(m_settings.pageLayout.ptWidth).arg(KoUnit::unitName(m_unit))
446 .arg(m_settings.pageLayout.ptHeight).arg(KoUnit::unitName(m_unit));
447 }
448 else
449 s += KoPageFormat::name(m_settings.pageLayout.format);
450 s += TQString(", ")
451 + (m_settings.pageLayout.orientation == PG_PORTRAIT ? i18n("Portrait") : i18n("Landscape"))
452 + ", " + i18n("margins:")
453 + " " + KoUnit::toUserStringValue(m_settings.pageLayout.ptLeft, m_unit)
454 + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptRight, m_unit)
455 + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptTop, m_unit)
456 + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptBottom, m_unit)
457 + " " + KoUnit::unitName(m_unit);
458 m_contents->pageSizeAndMarginsLabel->setText( s );
459}
460
461/*void KexiSimplePrintingPageSetup::setupPrintingCommand()
462{
463 if (!m_command) {
464 m_command = new KexiSimplePrintingCommand(
465 m_mainWin, m_item->identifier(), m_settings, false/!owned/, this);
466 }
467}*/
468
469void KexiSimplePrintingPageSetup::print()
470{
471// setupPrintingCommand();
472// m_command->print(m_contents->headerTitleLineEdit->text());
473 emit printItemRequested(m_item, m_settings, m_contents->headerTitleLineEdit->text());
474}
475
476void KexiSimplePrintingPageSetup::printPreview()
477{
478// setupPrintingCommand();
479// m_command->showPrintPreview(m_contents->headerTitleLineEdit->text());
480 emit printPreviewForItemRequested(m_item, m_settings,
481 m_contents->headerTitleLineEdit->text(), m_printPreviewNeedsReloading);
482 m_printPreviewNeedsReloading = false;
483}
484
485void KexiSimplePrintingPageSetup::slotOpenData()
486{
487 bool openingCancelled;
488 m_mainWin->openObject(m_item, Kexi::DataViewMode, openingCancelled);
489}
490
491void KexiSimplePrintingPageSetup::slotTitleTextChanged(const TQString&)
492{
493 if (m_contents->headerTitleLineEdit->isModified()) {
494 m_printPreviewNeedsReloading = true;
495// if (m_command)
496// m_command->setPrintPreviewNeedsReloading();
497 }
498
499 m_contents->headerTitleLineEdit->clearModified();
500}
501
502void KexiSimplePrintingPageSetup::slotChangeTitleFont()
503{
504 if (TQDialog::Accepted != TDEFontDialog::getFont(m_settings.pageTitleFont, false, this))
505 return;
506 m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
507 setDirty(true);
508}
509
510void KexiSimplePrintingPageSetup::slotChangePageSizeAndMargins()
511{
512 KoHeadFoot headfoot; //dummy
513
514 if (int(TQDialog::Accepted) != KoPageLayoutDia::pageLayout(
515 m_settings.pageLayout, headfoot, FORMAT_AND_BORDERS | DISABLE_UNIT, m_unit, this ))
516 return;
517
518 //update
519 updatePageLayoutAndUnitInfo();
520 setDirty(true);
521}
522
524{
525 m_contents->saveSetupLink->setEnabled(set);
526// if (m_command)
527// m_command->setPrintPreviewNeedsReloading();
528 if (set)
529 m_printPreviewNeedsReloading = true;
530}
531
532void KexiSimplePrintingPageSetup::slotAddPageNumbersCheckboxToggled(bool set)
533{
534 m_settings.addPageNumbers = set;
535 setDirty(true);
536}
537
538void KexiSimplePrintingPageSetup::slotAddDateTimeCheckboxToggled(bool set)
539{
540 m_settings.addDateAndTime = set;
541 setDirty(true);
542}
543
544void KexiSimplePrintingPageSetup::slotAddTableBordersCheckboxToggled(bool set)
545{
546 m_settings.addTableBorders = set;
547 setDirty(true);
548}
549
550#include "kexisimpleprintingpagesetup.moc"
Provides database connection, allowing queries and data modification.
Definition connection.h:62
QuerySchema * query() const
TableSchema * table() const
TQString captionOrName() const
Kexi's main window interface This interface is implemented by KexiMainWindowImpl class.
virtual KexiProject * project()=0
Project data of currently opened project or NULL if no project here yet.
virtual KexiDialogBase * openObject(KexiPart::Item *item, int viewMode, bool &openingCancelled, TQMap< TQString, TQString > *staticObjectArgs=0, TQString *errorMessage=0)=0
Opens object pointed by item in a view viewMode.
Information about a single object that can be instantiated using Kexi Part.
TQString captionOrName() const
KexiPart::Item * item(KexiPart::Info *i, const TQString &name)
KexiDB::Connection * dbConnection() const
A window for displaying print preview for simple printing.
bool showPrintPreview(const KexiSimplePrintingSettings &settings, const TQString &aTitleText=TQString(), bool reload=false)
void showPageSetupRequested(KexiPart::Item *item)
connected to Kexi Main Window
An engine painting data on pages using TQPainter. The engine allows for random access to any page.
void paintPage(int pageNumber, TQPainter &painter, bool paint=true)
bool init(KexiDB::Connection &conn, KexiDB::TableOrQuerySchema &tableOrQuery, const TQString &titleText, TQString &errorMessage)
void calculatePagesCount(TQPainter &painter)
Calculates pafe count that can be later obtained using pagesCount().
KexiSimplePrintingPageSetup(KexiMainWindow *mainWin, TQWidget *parent, TQMap< TQString, TQString > *args)
Settings data for simple printing engine.
Base class for single view embeddable of in KexiDialogBase.
KexiMainWindow * mainWin() const