kexi

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