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(pageSetupForItem(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) {
00250         backToPage0 = false;
00251         QString errorMessage;
00252         if (!m_previewEngine->init(
00253             *conn, tableOrQuery, titleText, errorMessage)) {
00254             if (!errorMessage.isEmpty())
00255                 KMessageBox::sorry(m_mainWin, errorMessage, i18n("Print Preview")); 
00256             return false;
00257         }
00258         m_previewWindow = new KexiSimplePrintPreviewWindow(
00259             *m_previewEngine, tableOrQuery.captionOrName(), 0, 
00260             Qt::WStyle_Customize|Qt::WStyle_NormalBorder|Qt::WStyle_Title|
00261             Qt::WStyle_SysMenu|Qt::WStyle_MinMax|Qt::WStyle_ContextHelp);
00262         connect(m_previewWindow, SIGNAL(printRequested()), this, SLOT(print()));
00263         connect(m_previewWindow, SIGNAL(pageSetupRequested()), this, SLOT(slotShowPageSetupRequested()));
00264         m_previewWindow->show();
00265         KDialog::centerOnScreen(m_previewWindow);
00266         m_printPreviewNeedsReloading = false;
00267     }
00268 
00269     if (m_printPreviewNeedsReloading) {//dirty
00270         m_previewEngine->clear();
00272         m_previewEngine->setTitleText( titleText );
00273         m_previewWindow->setFullWidth();
00274         m_previewWindow->updatePagesCount();
00275         m_printPreviewNeedsReloading = false;
00276     }
00277     if (backToPage0)
00278         m_previewWindow->goToPage(0);
00279     m_previewWindow->show();
00280     m_previewWindow->raise();
00281 //  m_previewWindow->setPagesCount(INT_MAX); //will be properly set on demand
00282     return true;
00283 }
00284 
00285 void KexiSimplePrintingCommand::slotShowPageSetupRequested()
00286 {
00287     m_mainWin->raise();
00288     emit showPageSetupRequested( m_mainWin->project()->item( m_objectId ) );
00289 }
00290 
00291 /*void KexiSimplePrintingCommand::setPrintPreviewNeedsReloading()
00292 {
00293     m_printPreviewNeedsReloading = true;
00294 }*/
00295 
00296 //----------------------------------------------------------
00297 
00298 KexiSimplePrintingPageSetup::KexiSimplePrintingPageSetup( KexiMainWindow *mainWin, QWidget *parent, 
00299     QMap<QString,QString>* args )
00300     : KexiViewBase( mainWin, parent, "KexiSimplePrintingPageSetup" )
00301     , m_settings( KexiSimplePrintingSettings::load() )
00302 //  , m_command(0)
00303 {
00304     // object to print
00305     bool ok = args;
00306     int objectId;
00307     if (ok)
00308         objectId = (*args)["identifier"].toInt();
00309     ok = objectId<=0;
00310     m_item = mainWin->project()->item( objectId );
00311     ok = m_item;
00312 
00313     bool printPreview = false;
00314     bool print = false;
00315     bool pageSetup = false;
00316     if (ok) {
00317         printPreview = (*args)["action"]=="printPreview";
00318         print = (*args)["action"]=="print";
00319         pageSetup = (*args)["action"]=="pageSetup";
00320         ok = printPreview || print || pageSetup;
00321     }
00322 
00323     // settings
00325     m_unit = KLocale::Metric == KGlobal::locale()->measureSystem() ? KoUnit::U_CM : KoUnit::U_INCH;
00326 
00327     // GUI
00328     QVBoxLayout *lyr = new QVBoxLayout(this);
00329     m_contents = new KexiSimplePrintingPageSetupBase(this, "KexiSimplePrintingPageSetupBase");
00330     lyr->addWidget(m_contents);
00331 
00332     setViewWidget(m_contents, true);
00333 //  setFocusPolicy(WheelFocus);
00334     m_contents->setFocusProxy(m_contents->headerTitleLineEdit);
00335 
00336     m_contents->printButton->setIconSet( KStdGuiItem::print().iconSet(KIcon::Small) );
00337     m_contents->printButton->setText( KStdGuiItem::print().text() );
00338     connect(m_contents->printButton, SIGNAL(clicked()), this, SLOT(print()));
00339 
00340     m_contents->printPreviewButton->setIconSet( SmallIconSet("filequickprint") );
00341     m_contents->printPreviewButton->setText( i18n("Print Previe&w...") );
00342     connect(m_contents->printPreviewButton, SIGNAL(clicked()), this, SLOT(printPreview()));
00343 
00344     m_contents->iconLabel->setFixedWidth(32+6);
00345     m_contents->iconLabel->setPixmap( DesktopIcon("document", 32) );
00346     QWhatsThis::add(m_contents->headerTitleFontButton, i18n("Changes font for title text."));
00347     connect(m_contents->headerTitleFontButton, SIGNAL(clicked()), 
00348         this, SLOT(slotChangeTitleFont()));
00349 
00350     if (m_item) {
00351         m_origCaptionLabelText = m_contents->captionLabel->text();
00352         m_contents->headerTitleLineEdit->setText( m_item->captionOrName() );
00353         if (m_item->mimeType()=="kexi/query") {
00354             m_contents->openDataLink->setText( i18n("Open This Query") );
00355             m_origCaptionLabelText = i18n("<h2>Page setup for printing \"%1\" query data</h2>");
00356         }
00357         m_contents->captionLabel->setText( m_origCaptionLabelText.arg(m_item->name()) );
00358     }
00359     connect(m_contents->headerTitleLineEdit,SIGNAL(textChanged(const QString&)), 
00360         this, SLOT(slotTitleTextChanged(const QString&)));
00361     m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
00362 
00363     QWhatsThis::add(m_contents->openDataLink, 
00364         i18n("Shows data for table or query associated with this page setup."));
00365     QToolTip::add(m_contents->openDataLink, 
00366         i18n("Shows data for table or query associated with this page setup."));
00367     connect(m_contents->openDataLink, SIGNAL(leftClickedURL()), this, SLOT(slotOpenData())); 
00368 
00369     QWhatsThis::add(m_contents->saveSetupLink, i18n("Saves settings for this setup as default."));
00370     connect(m_contents->saveSetupLink, SIGNAL(leftClickedURL()), this, SLOT(slotSaveSetup()));
00371 #if !KDE_IS_VERSION(3,5,1) && !defined(Q_WS_WIN)
00372     //a fix for problems with focusable KUrlLabel on KDElibs<=3.5.0
00373     m_contents->openDataLink->setFocusPolicy(NoFocus);
00374     m_contents->saveSetupLink->setFocusPolicy(NoFocus);
00375 #endif
00376 
00377     QWhatsThis::add(m_contents->addDateTimeCheckbox, i18n("Adds date and time to the header."));
00378     QWhatsThis::add(m_contents->addPageNumbersCheckbox, i18n("Adds page numbers to the footer."));
00379     QWhatsThis::add(m_contents->addTableBordersCheckbox, i18n("Adds table borders."));
00380     
00381 #ifdef KEXI_NO_UNFINISHED 
00382     m_contents->addDateTimeCheckbox->hide();
00383     m_contents->addPageNumbersCheckbox->hide();
00384 #endif
00385 
00386     updatePageLayoutAndUnitInfo();
00387     QWhatsThis::add(m_contents->changePageSizeAndMarginsButton, 
00388         i18n("Changes page size and margins."));
00389     connect(m_contents->changePageSizeAndMarginsButton, SIGNAL(clicked()), 
00390         this, SLOT(slotChangePageSizeAndMargins()));
00391 
00392     connect(m_contents->addPageNumbersCheckbox, SIGNAL(toggled(bool)), 
00393         this, SLOT(slotAddPageNumbersCheckboxToggled(bool)));
00394     connect(m_contents->addDateTimeCheckbox, SIGNAL(toggled(bool)), 
00395         this, SLOT(slotAddDateTimeCheckboxToggled(bool)));
00396     connect(m_contents->addTableBordersCheckbox, SIGNAL(toggled(bool)), 
00397         this, SLOT(slotAddTableBordersCheckboxToggled(bool)));
00398 
00399     if (!ok) {
00400         // no data!
00401         setEnabled(false);
00402     }
00403 
00404     m_contents->addPageNumbersCheckbox->setChecked( m_settings.addPageNumbers );
00405     m_contents->addDateTimeCheckbox->setChecked( m_settings.addDateAndTime );
00406     m_contents->addTableBordersCheckbox->setChecked( m_settings.addTableBorders );
00407     setDirty(false);
00408 
00409 //  m_engine = new KexiSimplePrintingEngine(m_settings, this);
00410 
00411     //clear it back to false after widgets initialization
00412     m_printPreviewNeedsReloading = false;
00413 
00414 /*  if (printPreview)
00415         QTimer::singleShot(50, this, SLOT(printPreview()));
00416     else if (print)
00417         QTimer::singleShot(50, this, SLOT(print()));*/
00418     connect(this, SIGNAL(printItemRequested(KexiPart::Item*,const KexiSimplePrintingSettings&,
00419         const QString&)),
00420         m_mainWin, SLOT(printItem(KexiPart::Item*,const KexiSimplePrintingSettings&,
00421         const QString&)));
00422     connect(this, SIGNAL(printPreviewForItemRequested(KexiPart::Item*, 
00423         const KexiSimplePrintingSettings&,const QString&,bool)),
00424         m_mainWin, SLOT(printPreviewForItem(KexiPart::Item*, 
00425         const KexiSimplePrintingSettings&,const QString&,bool)));
00426 }
00427 
00428 KexiSimplePrintingPageSetup::~KexiSimplePrintingPageSetup()
00429 {
00430 }
00431 
00432 void KexiSimplePrintingPageSetup::slotSaveSetup()
00433 {
00434     m_settings.save();
00435     setDirty(false);
00436 }
00437 
00438 void KexiSimplePrintingPageSetup::updatePageLayoutAndUnitInfo()
00439 {
00440     QString s;
00441     if (m_settings.pageLayout.format == PG_CUSTOM) {
00442         s += QString(" (%1 %2 x %3 %4)")
00443             .arg(m_settings.pageLayout.ptWidth).arg(KoUnit::unitName(m_unit))
00444             .arg(m_settings.pageLayout.ptHeight).arg(KoUnit::unitName(m_unit));
00445     }
00446     else
00447         s += KoPageFormat::name(m_settings.pageLayout.format);
00448     s += QString(", ")
00449      + (m_settings.pageLayout.orientation == PG_PORTRAIT ? i18n("Portrait") : i18n("Landscape"))
00450      + ", " + i18n("margins:")
00451      + " " + KoUnit::toUserStringValue(m_settings.pageLayout.ptLeft, m_unit)
00452      + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptRight, m_unit)
00453      + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptTop, m_unit)
00454      + "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptBottom, m_unit)
00455      + " " + KoUnit::unitName(m_unit);
00456     m_contents->pageSizeAndMarginsLabel->setText( s );
00457 }
00458 
00459 /*void KexiSimplePrintingPageSetup::setupPrintingCommand()
00460 {
00461     if (!m_command) {
00462         m_command = new KexiSimplePrintingCommand(
00463             m_mainWin, m_item->identifier(), m_settings, false/!owned/, this);
00464     }
00465 }*/
00466 
00467 void KexiSimplePrintingPageSetup::print()
00468 {
00469 //  setupPrintingCommand();
00470 //  m_command->print(m_contents->headerTitleLineEdit->text());
00471     emit printItemRequested(m_item, m_settings, m_contents->headerTitleLineEdit->text());
00472 }
00473 
00474 void KexiSimplePrintingPageSetup::printPreview()
00475 {
00476 //  setupPrintingCommand();
00477 //  m_command->showPrintPreview(m_contents->headerTitleLineEdit->text());
00478     emit printPreviewForItemRequested(m_item, m_settings, 
00479         m_contents->headerTitleLineEdit->text(), m_printPreviewNeedsReloading);
00480     m_printPreviewNeedsReloading = false;
00481 }
00482 
00483 void KexiSimplePrintingPageSetup::slotOpenData()
00484 {
00485     bool openingCancelled;
00486     m_mainWin->openObject(m_item, Kexi::DataViewMode, openingCancelled);
00487 }
00488 
00489 void KexiSimplePrintingPageSetup::slotTitleTextChanged(const QString&)
00490 {
00491     if (m_contents->headerTitleLineEdit->isModified()) {
00492         m_printPreviewNeedsReloading = true;
00493 //      if (m_command)
00494 //          m_command->setPrintPreviewNeedsReloading();
00495     }
00496         
00497     m_contents->headerTitleLineEdit->clearModified();
00498 }
00499 
00500 void KexiSimplePrintingPageSetup::slotChangeTitleFont()
00501 {
00502     if (QDialog::Accepted != KFontDialog::getFont(m_settings.pageTitleFont, false, this))
00503         return;
00504     m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
00505     setDirty(true);
00506 }
00507 
00508 void KexiSimplePrintingPageSetup::slotChangePageSizeAndMargins()
00509 {
00510     KoHeadFoot headfoot; //dummy
00511 
00512     if (int(QDialog::Accepted) != KoPageLayoutDia::pageLayout( 
00513         m_settings.pageLayout, headfoot, FORMAT_AND_BORDERS | DISABLE_UNIT, m_unit, this ))
00514         return;
00515 
00516     //update
00517     updatePageLayoutAndUnitInfo();
00518     setDirty(true);
00519 }
00520 
00521 void KexiSimplePrintingPageSetup::setDirty(bool set)
00522 {
00523     m_contents->saveSetupLink->setEnabled(set);
00524 //  if (m_command)
00525 //      m_command->setPrintPreviewNeedsReloading();
00526     if (set)
00527         m_printPreviewNeedsReloading = true;
00528 }
00529 
00530 void KexiSimplePrintingPageSetup::slotAddPageNumbersCheckboxToggled(bool set)
00531 {
00532     m_settings.addPageNumbers = set;
00533     setDirty(true);
00534 }
00535 
00536 void KexiSimplePrintingPageSetup::slotAddDateTimeCheckboxToggled(bool set)
00537 {
00538     m_settings.addDateAndTime = set;
00539     setDirty(true);
00540 }
00541 
00542 void KexiSimplePrintingPageSetup::slotAddTableBordersCheckboxToggled(bool set)
00543 {
00544     m_settings.addTableBorders = set;
00545     setDirty(true);
00546 }
00547 
00548 #include "kexisimpleprintingpagesetup.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys