kexi

kexisimpleprintingpagesetup.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
00003 
00004    This program is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this program; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "kexisimpleprintingpagesetup.h"
00021 #include "kexisimpleprintingpagesetupbase.h"
00022 #include "kexisimpleprintpreviewwindow.h"
00023 
00024 #include <core/keximainwindow.h>
00025 #include <kexiutils/utils.h>
00026 #include <kexi_version.h>
00027 
00028 #include <kapplication.h>
00029 #include <kiconloader.h>
00030 #include <klocale.h>
00031 #include <kfontdialog.h>
00032 #include <kurllabel.h>
00033 #include <kdebug.h>
00034 #include <klineedit.h>
00035 #include <kprinter.h>
00036 #include <kpushbutton.h>
00037 #include <kdeversion.h>
00038 
00039 #include <qlabel.h>
00040 #include <qtimer.h>
00041 #include <qlayout.h>
00042 #include <qpainter.h>
00043 #include <qcheckbox.h>
00044 #include <qwhatsthis.h>
00045 #include <qtooltip.h>
00046 
00047 #include <kexiutils/tristate.h>
00048 
00049 KexiSimplePrintingCommand::KexiSimplePrintingCommand(
00050     KexiMainWindow* mainWin, int objectId, QObject* parent)
00051  : QObject(parent, "KexiSimplePrintCommand")
00052  , m_previewEngine(0)
00053  , m_mainWin(mainWin)
00054  , m_objectId(objectId)
00055  , m_previewWindow(0)
00056  , m_printPreviewNeedsReloading(false)
00057 {
00058     connect(this, SIGNAL(showPageSetupRequested(KexiPart::Item*)), 
00059         m_mainWin, SLOT(showPageSetupForItem(KexiPart::Item*)));
00060 }
00061 
00062 KexiSimplePrintingCommand::~KexiSimplePrintingCommand()
00063 {
00064     delete m_previewWindow;
00065     delete m_previewEngine;
00066 //  delete m_settings;
00067 }
00068 
00069 
00070 bool KexiSimplePrintingCommand::print(const KexiSimplePrintingSettings& settings, 
00071     const QString& aTitleText)
00072 {
00073     m_settings = settings;
00074     return print(aTitleText);
00075 }
00076 
00077 bool KexiSimplePrintingCommand::print(const QString& aTitleText)
00078 {
00079     KexiDB::Connection *conn = m_mainWin->project()->dbConnection();
00080     KexiDB::TableOrQuerySchema tableOrQuery(conn, m_objectId);
00081     if (!tableOrQuery.table() && !tableOrQuery.query()) {
00083         return false;
00084     }
00085     QString titleText(aTitleText.stripWhiteSpace());
00086     if (titleText.isEmpty())
00087         titleText = tableOrQuery.captionOrName();
00088 
00089     KexiSimplePrintingEngine engine(m_settings, this);
00090     QString errorMessage;
00091     if (!engine.init(*conn, tableOrQuery, titleText, errorMessage)) {
00092         if (!errorMessage.isEmpty())
00093             KMessageBox::sorry(m_mainWin, errorMessage, i18n("Printing"));
00094         return false;
00095     }
00096 
00097     //setup printing
00098 #ifdef Q_WS_WIN
00099     QPrinter printer(QPrinter::HighResolution);
00100     printer.setOrientation( m_settings.pageLayout.orientation == PG_PORTRAIT 
00101         ? QPrinter::Portrait : QPrinter::Landscape );
00102     printer.setPageSize( 
00103         (QPrinter::PageSize)KoPageFormat::printerPageSize( m_settings.pageLayout.format ) );
00104 
00105     // "chicken-egg" problem: 
00106     // we cannot use real from/to values in setMinMax() and setFromTo() 
00107     // because page count is known after obtaining print settings
00108     printer.setFromTo(1,1);
00109 #else
00110     KPrinter printer;
00111     printer.setOrientation( m_settings.pageLayout.orientation == PG_PORTRAIT 
00112         ? KPrinter::Portrait : KPrinter::Landscape );
00113     printer.setPageSize( 
00114         (KPrinter::PageSize)KoPageFormat::printerPageSize( m_settings.pageLayout.format ) );
00115 #endif
00116 
00117     printer.setFullPage(true);
00118     QString docName( titleText );
00119     printer.setDocName( docName );
00120     printer.setCreator(KEXI_APP_NAME);
00121     if ( !printer.setup( m_mainWin ) ) {
00122         return true;
00123     }
00124 
00125     // now we have final settings
00126 
00128     QPainter painter;
00129 
00130     if (!painter.begin(&printer)) {
00132         return false;
00133     }
00134     engine.calculatePagesCount(painter);
00135 
00136     uint loops, loopsPerPage;
00137     QValueList<int> pagesToPrint;
00138     int fromPage = 0;
00139 #ifdef Q_WS_WIN
00140     int toPage = 0;
00141     if (QPrinter::PageRange == printer.printRange()) {
00142         fromPage = printer.fromPage();
00143         toPage = printer.toPage();
00144     }
00145     if (fromPage==0 || toPage==0) {
00146         fromPage = 0;
00147         toPage = (int)engine.pagesCount()-1;
00148     }
00149     else {
00150         fromPage--;
00151         if (toPage > (int)engine.pagesCount())
00152             toPage = (int)engine.pagesCount();
00153         toPage--;
00154     }
00155     // win32 only supports one range, build the list
00156     for (int i = fromPage; i<=toPage; i++) {
00157         pagesToPrint.append(i);
00158     }
00159     // on win32 the OS does perform buffering (only when collation is off, each copy needs to be repeated)
00160     loops = 1;
00161     loopsPerPage = printer.collateCopies() ? 1 : printer.numCopies();
00162 #else
00163     // on !win32 print QPrinter::numCopies() times (the OS does not perform buffering)
00164     pagesToPrint = printer.pageList();
00165     kdDebug() << pagesToPrint << endl;
00166     if (pagesToPrint.isEmpty()) {
00167         fromPage = 0;
00168         for (int i = 0; i<(int)engine.pagesCount(); i++) {
00169             pagesToPrint.append(i);
00170         }
00171     }
00172     else
00173         fromPage = pagesToPrint.first();
00174     if (printer.collate()==KPrinter::Collate) {
00175         //collation: p1, p2,..pn; p1, p2,..pn; ......; p1, p2,..pn
00176         loops = printer.numCopies();
00177         loopsPerPage = 1;
00178     }
00179     else {
00180         //no collation: p1, p1, ..., p1; p2, p2, ..., p2; ......; pn, pn,..pn
00181         loops = 1; 
00182         loopsPerPage = printer.numCopies();
00183     }
00185 #endif
00186     // now, total number of printed pages is printer.numCopies()*printer.pageList().count()
00187 
00188     kdDebug() << "printing..." << endl;
00189     bool firstPage = true;
00190     for (uint copy = 0;copy < loops; copy++) {
00191         kdDebug() << "copy " << (copy+1) << " of " << loops << endl;
00192         uint pageNumber = fromPage;
00193         QValueList<int>::ConstIterator pagesIt = pagesToPrint.constBegin();
00194         for(;(int)pageNumber == fromPage || !engine.eof(); ++pageNumber) {
00195             kdDebug() << "printing..." << endl;
00196             if (pagesIt == pagesToPrint.constEnd()) //no more pages to print
00197                 break;
00198             if ((int)pageNumber < *pagesIt) { //skip pages without printing (needed for computation)
00199                 engine.paintPage(pageNumber, painter, false);
00200                 continue;
00201             }
00202             if (*pagesIt < (int)pageNumber) { //sanity
00203                 ++pagesIt;
00204                 continue;
00205             }
00206             for (uint onePageCounter = 0; onePageCounter < loopsPerPage; onePageCounter++) {
00207                 if (!firstPage)
00208                     printer.newPage();
00209                 else
00210                     firstPage = false;
00211                 kdDebug() << "page #" << pageNumber << endl;
00212                 engine.paintPage(pageNumber, painter);
00213             }
00214             ++pagesIt;
00215         }
00216     }
00217     kdDebug() << "end of printing." << endl;
00218 
00219     // stop painting, this will automatically send the print data to the printer
00220     if (!painter.end())
00221         return false;
00222 
00223     if (!engine.done())
00224         return false;
00225 
00226     return true;
00227 }
00228 
00229 bool KexiSimplePrintingCommand::showPrintPreview(const KexiSimplePrintingSettings& settings, 
00230     const QString& aTitleText, bool reload)
00231 {
00232     m_settings = settings;
00233     if (!m_previewEngine)
00234         m_previewEngine = new KexiSimplePrintingEngine(m_settings, this);
00235 
00236     if (reload)
00237         m_printPreviewNeedsReloading = true;
00238 
00239     bool backToPage0 = true;
00240     QString titleText(aTitleText.stripWhiteSpace());
00241     KexiDB::Connection *conn = m_mainWin->project()->dbConnection();
00242     KexiDB::TableOrQuerySchema tableOrQuery(conn, m_objectId);
00243     if (!tableOrQuery.table() && !tableOrQuery.query()) {
00245         return false;
00246     }
00247     if (titleText.isEmpty())
00248         titleText = tableOrQuery.captionOrName();
00249     if (!m_previewWindow || m_printPreviewNeedsReloading) {
00250         QString errorMessage;
00251         if (!m_previewEngine->init(
00252             *conn, tableOrQuery, titleText, errorMessage)) {
00253             if (!errorMessage.isEmpty())
00254                 KMessageBox::sorry(m_mainWin, errorMessage, i18n("Print Preview")); 
00255             return false;
00256         }
00257     }
00258     if (!m_previewWindow) {
00259         backToPage0 = false;
00260         m_previewWindow = new KexiSimplePrintPreviewWindow(
00261             *m_previewEngine, tableOrQuery.captionOrName(), 0, 
00262             Qt::WStyle_Customize|Qt::WStyle_NormalBorder|Qt::WStyle_Title|
00263             Qt::WStyle_SysMenu|Qt::WStyle_MinMax|Qt::WStyle_ContextHelp);
00264         connect(m_previewWindow, SIGNAL(printRequested()), this, SLOT(print()));
00265         connect(m_previewWindow, SIGNAL(pageSetupRequested()), this, SLOT(slotShowPageSetupRequested()));
00266         m_previewWindow->show();
00267         KDialog::centerOnScreen(m_previewWindow);
00268         m_printPreviewNeedsReloading = false;
00269     }
00270 
00271     if (m_printPreviewNeedsReloading) {//dirty
00272         m_previewEngine->clear();
00274         m_previewEngine->setTitleText( titleText );
00275         m_previewWindow->setFullWidth();
00276         m_previewWindow->updatePagesCount();
00277         m_printPreviewNeedsReloading = false;
00278     }
00279     if (backToPage0)
00280         m_previewWindow->goToPage(0);
00281     m_previewWindow->show();
00282     m_previewWindow->raise();
00283 //  m_previewWindow->setPagesCount(INT_MAX); //will be properly set on demand
00284     return true;
00285 }
00286 
00287 void KexiSimplePrintingCommand::slotShowPageSetupRequested()
00288 {
00289     m_mainWin->raise();
00290     emit showPageSetupRequested( m_mainWin->project()->item( m_objectId ) );
00291 }
00292 
00293 /*void KexiSimplePrintingCommand::setPrintPreviewNeedsReloading()
00294 {
00295     m_printPreviewNeedsReloading = true;
00296 }*/
00297 
00298 //----------------------------------------------------------
00299 
00300 KexiSimplePrintingPageSetup::KexiSimplePrintingPageSetup( KexiMainWindow *mainWin, QWidget *parent, 
00301     QMap<QString,QString>* args )
00302     : KexiViewBase( mainWin, parent, "KexiSimplePrintingPageSetup" )
00303     , m_settings( KexiSimplePrintingSettings::load() )
00304 //  , m_command(0)
00305 {
00306     // object to print
00307     bool ok = args;
00308     int objectId;
00309     if (ok)
00310         objectId = (*args)["identifier"].toInt();
00311     ok = objectId<=0;
00312     m_item = mainWin->project()->item( objectId );
00313     ok = m_item;
00314 
00315     bool printPreview = false;
00316     bool print = false;
00317     bool pageSetup = false;
00318     if (ok) {
00319         printPreview = (*args)["action"]=="printPreview";
00320         print = (*args)["action"]=="print";
00321         pageSetup = (*args)["action"]=="pageSetup";
00322         ok = printPreview || print || pageSetup;
00323     }
00324 
00325     // settings
00327     m_unit = KLocale::Metric == KGlobal::locale()->measureSystem() ? KoUnit::U_CM : KoUnit::U_INCH;
00328 
00329     // GUI
00330     QVBoxLayout *lyr = new QVBoxLayout(this);
00331     m_contents = new KexiSimplePrintingPageSetupBase(this, "KexiSimplePrintingPageSetupBase");
00332     lyr->addWidget(m_contents);
00333 
00334     setViewWidget(m_contents, true);
00335 //  setFocusPolicy(WheelFocus);
00336     m_contents->setFocusProxy(m_contents->headerTitleLineEdit);
00337 
00338     m_contents->printButton->setIconSet( KStdGuiItem::print().iconSet(KIcon::Small) );
00339     m_contents->printButton->setText( KStdGuiItem::print().text() );
00340     connect(m_contents->printButton, SIGNAL(clicked()), this, SLOT(print()));
00341 
00342     m_contents->printPreviewButton->setIconSet( SmallIconSet("filequickprint") );
00343     m_contents->printPreviewButton->setText( i18n("Print Previe&w...") );
00344     connect(m_contents->printPreviewButton, SIGNAL(clicked()), this, SLOT(printPreview()));
00345 
00346     m_contents->iconLabel->setFixedWidth(32+6);
00347     m_contents->iconLabel->setPixmap( DesktopIcon("document", 32) );
00348     QWhatsThis::add(m_contents->headerTitleFontButton, i18n("Changes font for title text."));
00349     connect(m_contents->headerTitleFontButton, SIGNAL(clicked()), 
00350         this, SLOT(slotChangeTitleFont()));
00351 
00352     if (m_item) {
00353         m_origCaptionLabelText = m_contents->captionLabel->text();
00354         m_contents->headerTitleLineEdit->setText( m_item->captionOrName() );
00355         if (m_item->mimeType()=="kexi/query") {
00356             m_contents->openDataLink->setText( i18n("Open This Query") );
00357             m_origCaptionLabelText = i18n("<h2>Page setup for printing \"%1\" query data</h2>");
00358         }
00359         m_contents->captionLabel->setText( m_origCaptionLabelText.arg(m_item->name()) );
00360     }
00361     connect(m_contents->headerTitleLineEdit,SIGNAL(textChanged(const QString&)), 
00362         this, SLOT(slotTitleTextChanged(const QString&)));
00363     m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
00364 
00365     QWhatsThis::add(m_contents->openDataLink, 
00366         i18n("Shows data for table or query associated with this page setup."));
00367     QToolTip::add(m_contents->openDataLink, 
00368         i18n("Shows data for table or query associated with this page setup."));
00369     connect(m_contents->openDataLink, SIGNAL(leftClickedURL()), this, SLOT(slotOpenData())); 
00370 
00371     QWhatsThis::add(m_contents->saveSetupLink, i18n("Saves settings for this setup as default."));
00372     connect(m_contents->saveSetupLink, SIGNAL(leftClickedURL()), this, SLOT(slotSaveSetup()));
00373 #if !KDE_IS_VERSION(3,5,1) && !defined(Q_WS_WIN)
00374     //a fix for problems with focusable KUrlLabel on KDElibs<=3.5.0
00375     m_contents->openDataLink->setFocusPolicy(NoFocus);
00376     m_contents->saveSetupLink->setFocusPolicy(NoFocus);
00377 #endif
00378 
00379     QWhatsThis::add(m_contents->addDateTimeCheckbox, i18n("Adds date and time to the header."));
00380     QWhatsThis::add(m_contents->addPageNumbersCheckbox, i18n("Adds page numbers to the footer."));
00381     QWhatsThis::add(m_contents->addTableBordersCheckbox, i18n("Adds table borders."));
00382     
00383 #ifdef KEXI_NO_UNFINISHED 
00384     m_contents->addDateTimeCheckbox->hide();
00385     m_contents->addPageNumbersCheckbox->hide();
00386 #endif
00387 
00388     updatePageLayoutAndUnitInfo();
00389     QWhatsThis::add(m_contents->changePageSizeAndMarginsButton, 
00390         i18n("Changes page size and margins."));
00391     connect(m_contents->changePageSizeAndMarginsButton, SIGNAL(clicked()), 
00392         this, SLOT(slotChangePageSizeAndMargins()));
00393 
00394     connect(m_contents->addPageNumbersCheckbox, SIGNAL(toggled(bool)), 
00395         this, SLOT(slotAddPageNumbersCheckboxToggled(bool)));
00396     connect(m_contents->addDateTimeCheckbox, SIGNAL(toggled(bool)), 
00397         this, SLOT(slotAddDateTimeCheckboxToggled(bool)));
00398     connect(m_contents->addTableBordersCheckbox, SIGNAL(toggled(bool)), 
00399         this, SLOT(slotAddTableBordersCheckboxToggled(bool)));
00400 
00401     if (!ok) {
00402         // no data!
00403         setEnabled(false);
00404     }
00405 
00406     m_contents->addPageNumbersCheckbox->setChecked( m_settings.addPageNumbers );
00407     m_contents->addDateTimeCheckbox->setChecked( m_settings.addDateAndTime );
00408     m_contents->addTableBordersCheckbox->setChecked( m_settings.addTableBorders );
00409     setDirty(false);
00410 
00411 //  m_engine = new KexiSimplePrintingEngine(m_settings, this);
00412 
00413     //clear it back to false after widgets initialization
00414     m_printPreviewNeedsReloading = false;
00415 
00416 /*  if (printPreview)
00417         QTimer::singleShot(50, this, SLOT(printPreview()));
00418     else if (print)
00419         QTimer::singleShot(50, this, SLOT(print()));*/
00420     connect(this, SIGNAL(printItemRequested(KexiPart::Item*,const KexiSimplePrintingSettings&,
00421         const QString&)),
00422         m_mainWin, SLOT(printItem(KexiPart::Item*,const KexiSimplePrintingSettings&,
00423         const QString&)));
00424     connect(this, SIGNAL(printPreviewForItemRequested(KexiPart::Item*, 
00425         const KexiSimplePrintingSettings&,const QString&,bool)),
00426         m_mainWin, SLOT(printPreviewForItem(KexiPart::Item*, 
00427         const KexiSimplePrintingSettings&,const QString&,bool)));
00428 }
00429 
00430 KexiSimplePrintingPageSetup::~KexiSimplePrintingPageSetup()
00431 {
00432 }
00433 
00434 void KexiSimplePrintingPageSetup::slotSaveSetup()
00435 {
00436     m_settings.save();
00437     setDirty(false);
00438 }
00439 
00440 void KexiSimplePrintingPageSetup::updatePageLayoutAndUnitInfo()
00441 {
00442     QString s;
00443     if (m_settings.pageLayout.format == PG_CUSTOM) {
00444         s += QString(" (%1 %2 x %3 %4)")
00445             .arg(m_settings.pageLayout.ptWidth).arg(KoUnit::unitName(m_unit))
00446             .arg(m_settings.pageLayout.ptHeight).arg(KoUnit::unitName(m_unit));
00447     }
00448     else
00449         s += KoPageFormat::name(m_settings.pageLayout.format);
00450     s += QString(", ")
00451      + (m_settings.pageLayout.orientation == PG_PORTRAIT ? i18n("Portrait") : i18n("Landscape"))
00452      + ", " + i18n("margins:")
00453      + " " + KoUnit::toUserStringValue(m_settings.pageLayout.ptLeft, m_unit)
00454      + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptRight, m_unit)
00455      + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptTop, m_unit)
00456      + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptBottom, m_unit)
00457      + " " + KoUnit::unitName(m_unit);
00458     m_contents->pageSizeAndMarginsLabel->setText( s );
00459 }
00460 
00461 /*void KexiSimplePrintingPageSetup::setupPrintingCommand()
00462 {
00463     if (!m_command) {
00464         m_command = new KexiSimplePrintingCommand(
00465             m_mainWin, m_item->identifier(), m_settings, false/!owned/, this);
00466     }
00467 }*/
00468 
00469 void KexiSimplePrintingPageSetup::print()
00470 {
00471 //  setupPrintingCommand();
00472 //  m_command->print(m_contents->headerTitleLineEdit->text());
00473     emit printItemRequested(m_item, m_settings, m_contents->headerTitleLineEdit->text());
00474 }
00475 
00476 void KexiSimplePrintingPageSetup::printPreview()
00477 {
00478 //  setupPrintingCommand();
00479 //  m_command->showPrintPreview(m_contents->headerTitleLineEdit->text());
00480     emit printPreviewForItemRequested(m_item, m_settings, 
00481         m_contents->headerTitleLineEdit->text(), m_printPreviewNeedsReloading);
00482     m_printPreviewNeedsReloading = false;
00483 }
00484 
00485 void KexiSimplePrintingPageSetup::slotOpenData()
00486 {
00487     bool openingCancelled;
00488     m_mainWin->openObject(m_item, Kexi::DataViewMode, openingCancelled);
00489 }
00490 
00491 void KexiSimplePrintingPageSetup::slotTitleTextChanged(const QString&)
00492 {
00493     if (m_contents->headerTitleLineEdit->isModified()) {
00494         m_printPreviewNeedsReloading = true;
00495 //      if (m_command)
00496 //          m_command->setPrintPreviewNeedsReloading();
00497     }
00498         
00499     m_contents->headerTitleLineEdit->clearModified();
00500 }
00501 
00502 void KexiSimplePrintingPageSetup::slotChangeTitleFont()
00503 {
00504     if (QDialog::Accepted != KFontDialog::getFont(m_settings.pageTitleFont, false, this))
00505         return;
00506     m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
00507     setDirty(true);
00508 }
00509 
00510 void KexiSimplePrintingPageSetup::slotChangePageSizeAndMargins()
00511 {
00512     KoHeadFoot headfoot; //dummy
00513 
00514     if (int(QDialog::Accepted) != KoPageLayoutDia::pageLayout( 
00515         m_settings.pageLayout, headfoot, FORMAT_AND_BORDERS | DISABLE_UNIT, m_unit, this ))
00516         return;
00517 
00518     //update
00519     updatePageLayoutAndUnitInfo();
00520     setDirty(true);
00521 }
00522 
00523 void KexiSimplePrintingPageSetup::setDirty(bool set)
00524 {
00525     m_contents->saveSetupLink->setEnabled(set);
00526 //  if (m_command)
00527 //      m_command->setPrintPreviewNeedsReloading();
00528     if (set)
00529         m_printPreviewNeedsReloading = true;
00530 }
00531 
00532 void KexiSimplePrintingPageSetup::slotAddPageNumbersCheckboxToggled(bool set)
00533 {
00534     m_settings.addPageNumbers = set;
00535     setDirty(true);
00536 }
00537 
00538 void KexiSimplePrintingPageSetup::slotAddDateTimeCheckboxToggled(bool set)
00539 {
00540     m_settings.addDateAndTime = set;
00541     setDirty(true);
00542 }
00543 
00544 void KexiSimplePrintingPageSetup::slotAddTableBordersCheckboxToggled(bool set)
00545 {
00546     m_settings.addTableBorders = set;
00547     setDirty(true);
00548 }
00549 
00550 #include "kexisimpleprintingpagesetup.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys