You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/kexi/main/printing/kexisimpleprintingpagesetup...

551 lines
18 KiB

/* This file is part of the KDE project
Copyright (C) 2005 Jaroslaw Staniek <js@iidea.pl>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this program; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "kexisimpleprintingpagesetup.h"
#include "kexisimpleprintingpagesetupbase.h"
#include "kexisimpleprintpreviewwindow.h"
#include <core/keximainwindow.h>
#include <kexiutils/utils.h>
#include <kexi_version.h>
#include <tdeapplication.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdefontdialog.h>
#include <kurllabel.h>
#include <kdebug.h>
#include <klineedit.h>
#include <kprinter.h>
#include <kpushbutton.h>
#include <tdeversion.h>
#include <tqlabel.h>
#include <tqtimer.h>
#include <tqlayout.h>
#include <tqpainter.h>
#include <tqcheckbox.h>
#include <tqwhatsthis.h>
#include <tqtooltip.h>
#include <kexiutils/tristate.h>
KexiSimplePrintingCommand::KexiSimplePrintingCommand(
KexiMainWindow* mainWin, int objectId, TQObject* parent)
: TQObject(parent, "KexiSimplePrintCommand")
, m_previewEngine(0)
, m_mainWin(mainWin)
, m_objectId(objectId)
, m_previewWindow(0)
, m_printPreviewNeedsReloading(false)
{
connect(this, TQT_SIGNAL(showPageSetupRequested(KexiPart::Item*)),
m_mainWin, TQT_SLOT(showPageSetupForItem(KexiPart::Item*)));
}
KexiSimplePrintingCommand::~KexiSimplePrintingCommand()
{
delete m_previewWindow;
delete m_previewEngine;
// delete m_settings;
}
bool KexiSimplePrintingCommand::print(const KexiSimplePrintingSettings& settings,
const TQString& aTitleText)
{
m_settings = settings;
return print(aTitleText);
}
bool KexiSimplePrintingCommand::print(const TQString& aTitleText)
{
KexiDB::Connection *conn = m_mainWin->project()->dbConnection();
KexiDB::TableOrQuerySchema tableOrQuery(conn, m_objectId);
if (!tableOrQuery.table() && !tableOrQuery.query()) {
//! @todo item not found
return false;
}
TQString titleText(aTitleText.stripWhiteSpace());
if (titleText.isEmpty())
titleText = tableOrQuery.captionOrName();
KexiSimplePrintingEngine engine(m_settings, this);
TQString errorMessage;
if (!engine.init(*conn, tableOrQuery, titleText, errorMessage)) {
if (!errorMessage.isEmpty())
KMessageBox::sorry(m_mainWin, errorMessage, i18n("Printing"));
return false;
}
//setup printing
#ifdef TQ_WS_WIN
TQPrinter printer(TQPrinter::HighResolution);
printer.setOrientation( m_settings.pageLayout.orientation == PG_PORTRAIT
? TQPrinter::Portrait : TQPrinter::Landscape );
printer.setPageSize(
(TQPrinter::PageSize)KoPageFormat::printerPageSize( m_settings.pageLayout.format ) );
// "chicken-egg" problem:
// we cannot use real from/to values in setMinMax() and setFromTo()
// because page count is known after obtaining print settings
printer.setFromTo(1,1);
#else
KPrinter printer;
printer.setOrientation( m_settings.pageLayout.orientation == PG_PORTRAIT
? KPrinter::Portrait : KPrinter::Landscape );
printer.setPageSize(
(KPrinter::PageSize)KoPageFormat::printerPageSize( m_settings.pageLayout.format ) );
#endif
printer.setFullPage(true);
TQString docName( titleText );
printer.setDocName( docName );
printer.setCreator(KEXI_APP_NAME);
if ( !printer.setup( m_mainWin ) ) {
return true;
}
// now we have final settings
//! @todo get printer.pageOrder() (for reversed order requires improved engine)
TQPainter painter;
if (!painter.begin(&printer)) {
//! @todo msg
return false;
}
engine.calculatePagesCount(painter);
uint loops, loopsPerPage;
TQValueList<int> pagesToPrint;
int fromPage = 0;
#ifdef TQ_WS_WIN
int toPage = 0;
if (TQPrinter::PageRange == printer.printRange()) {
fromPage = printer.fromPage();
toPage = printer.toPage();
}
if (fromPage==0 || toPage==0) {
fromPage = 0;
toPage = (int)engine.pagesCount()-1;
}
else {
fromPage--;
if (toPage > (int)engine.pagesCount())
toPage = (int)engine.pagesCount();
toPage--;
}
// win32 only supports one range, build the list
for (int i = fromPage; i<=toPage; i++) {
pagesToPrint.append(i);
}
// on win32 the OS does perform buffering (only when collation is off, each copy needs to be repeated)
loops = 1;
loopsPerPage = printer.collateCopies() ? 1 : printer.numCopies();
#else
// on !win32 print TQPrinter::numCopies() times (the OS does not perform buffering)
pagesToPrint = printer.pageList();
kdDebug() << pagesToPrint << endl;
if (pagesToPrint.isEmpty()) {
fromPage = 0;
for (int i = 0; i<(int)engine.pagesCount(); i++) {
pagesToPrint.append(i);
}
}
else
fromPage = pagesToPrint.first();
if (printer.collate()==KPrinter::Collate) {
//collation: p1, p2,..pn; p1, p2,..pn; ......; p1, p2,..pn
loops = printer.numCopies();
loopsPerPage = 1;
}
else {
//no collation: p1, p1, ..., p1; p2, p2, ..., p2; ......; pn, pn,..pn
loops = 1;
loopsPerPage = printer.numCopies();
}
//! @todo also look at printer.pageSet() option : all/odd/even pages
#endif
// now, total number of printed pages is printer.numCopies()*printer.pageList().count()
kdDebug() << "printing..." << endl;
bool firstPage = true;
for (uint copy = 0;copy < loops; copy++) {
kdDebug() << "copy " << (copy+1) << " of " << loops << endl;
uint pageNumber = fromPage;
TQValueList<int>::ConstIterator pagesIt = pagesToPrint.constBegin();
for(;(int)pageNumber == fromPage || !engine.eof(); ++pageNumber) {
kdDebug() << "printing..." << endl;
if (pagesIt == pagesToPrint.constEnd()) //no more pages to print
break;
if ((int)pageNumber < *pagesIt) { //skip pages without printing (needed for computation)
engine.paintPage(pageNumber, painter, false);
continue;
}
if (*pagesIt < (int)pageNumber) { //sanity
++pagesIt;
continue;
}
for (uint onePageCounter = 0; onePageCounter < loopsPerPage; onePageCounter++) {
if (!firstPage)
printer.newPage();
else
firstPage = false;
kdDebug() << "page #" << pageNumber << endl;
engine.paintPage(pageNumber, painter);
}
++pagesIt;
}
}
kdDebug() << "end of printing." << endl;
// stop painting, this will automatically send the print data to the printer
if (!painter.end())
return false;
if (!engine.done())
return false;
return true;
}
bool KexiSimplePrintingCommand::showPrintPreview(const KexiSimplePrintingSettings& settings,
const TQString& aTitleText, bool reload)
{
m_settings = settings;
if (!m_previewEngine)
m_previewEngine = new KexiSimplePrintingEngine(m_settings, this);
if (reload)
m_printPreviewNeedsReloading = true;
bool backToPage0 = true;
TQString titleText(aTitleText.stripWhiteSpace());
KexiDB::Connection *conn = m_mainWin->project()->dbConnection();
KexiDB::TableOrQuerySchema tableOrQuery(conn, m_objectId);
if (!tableOrQuery.table() && !tableOrQuery.query()) {
//! @todo item not found
return false;
}
if (titleText.isEmpty())
titleText = tableOrQuery.captionOrName();
if (!m_previewWindow || m_printPreviewNeedsReloading) {
TQString errorMessage;
if (!m_previewEngine->init(
*conn, tableOrQuery, titleText, errorMessage)) {
if (!errorMessage.isEmpty())
KMessageBox::sorry(m_mainWin, errorMessage, i18n("Print Preview"));
return false;
}
}
if (!m_previewWindow) {
backToPage0 = false;
m_previewWindow = new KexiSimplePrintPreviewWindow(
*m_previewEngine, tableOrQuery.captionOrName(), 0,
TQt::WStyle_Customize|TQt::WStyle_NormalBorder|TQt::WStyle_Title|
TQt::WStyle_SysMenu|TQt::WStyle_MinMax|TQt::WStyle_ContextHelp);
connect(m_previewWindow, TQT_SIGNAL(printRequested()), this, TQT_SLOT(print()));
connect(m_previewWindow, TQT_SIGNAL(pageSetupRequested()), this, TQT_SLOT(slotShowPageSetupRequested()));
m_previewWindow->show();
KDialog::centerOnScreen(m_previewWindow);
m_printPreviewNeedsReloading = false;
}
if (m_printPreviewNeedsReloading) {//dirty
m_previewEngine->clear();
//! @todo progress bar...
m_previewEngine->setTitleText( titleText );
m_previewWindow->setFullWidth();
m_previewWindow->updatePagesCount();
m_printPreviewNeedsReloading = false;
}
if (backToPage0)
m_previewWindow->goToPage(0);
m_previewWindow->show();
m_previewWindow->raise();
// m_previewWindow->setPagesCount(INT_MAX); //will be properly set on demand
return true;
}
void KexiSimplePrintingCommand::slotShowPageSetupRequested()
{
m_mainWin->raise();
emit showPageSetupRequested( m_mainWin->project()->item( m_objectId ) );
}
/*void KexiSimplePrintingCommand::setPrintPreviewNeedsReloading()
{
m_printPreviewNeedsReloading = true;
}*/
//----------------------------------------------------------
KexiSimplePrintingPageSetup::KexiSimplePrintingPageSetup( KexiMainWindow *mainWin, TQWidget *parent,
TQMap<TQString,TQString>* args )
: KexiViewBase( mainWin, parent, "KexiSimplePrintingPageSetup" )
, m_settings( KexiSimplePrintingSettings::load() )
// , m_command(0)
{
// object to print
bool ok = args;
int objectId;
if (ok)
objectId = (*args)["identifier"].toInt();
ok = objectId<=0;
m_item = mainWin->project()->item( objectId );
ok = m_item;
bool printPreview = false;
bool print = false;
bool pageSetup = false;
if (ok) {
printPreview = (*args)["action"]=="printPreview";
print = (*args)["action"]=="print";
pageSetup = (*args)["action"]=="pageSetup";
ok = printPreview || print || pageSetup;
}
// settings
//! @todo default?
m_unit = TDELocale::Metric == TDEGlobal::locale()->measureSystem() ? KoUnit::U_CM : KoUnit::U_INCH;
// GUI
TQVBoxLayout *lyr = new TQVBoxLayout(this);
m_contents = new KexiSimplePrintingPageSetupBase(this, "KexiSimplePrintingPageSetupBase");
lyr->addWidget(m_contents);
setViewWidget(m_contents, true);
// setFocusPolicy(WheelFocus);
m_contents->setFocusProxy(m_contents->headerTitleLineEdit);
m_contents->printButton->setIconSet( KStdGuiItem::print().iconSet(TDEIcon::Small) );
m_contents->printButton->setText( KStdGuiItem::print().text() );
connect(m_contents->printButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(print()));
m_contents->printPreviewButton->setIconSet( SmallIconSet("document-print-preview") );
m_contents->printPreviewButton->setText( i18n("Print Previe&w...") );
connect(m_contents->printPreviewButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(printPreview()));
m_contents->iconLabel->setFixedWidth(32+6);
m_contents->iconLabel->setPixmap( DesktopIcon("document", 32) );
TQWhatsThis::add(m_contents->headerTitleFontButton, i18n("Changes font for title text."));
connect(m_contents->headerTitleFontButton, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotChangeTitleFont()));
if (m_item) {
m_origCaptionLabelText = m_contents->captionLabel->text();
m_contents->headerTitleLineEdit->setText( m_item->captionOrName() );
if (m_item->mimeType()=="kexi/query") {
m_contents->openDataLink->setText( i18n("Open This Query") );
m_origCaptionLabelText = i18n("<h2>Page setup for printing \"%1\" query data</h2>");
}
m_contents->captionLabel->setText( m_origCaptionLabelText.arg(m_item->name()) );
}
connect(m_contents->headerTitleLineEdit,TQT_SIGNAL(textChanged(const TQString&)),
this, TQT_SLOT(slotTitleTextChanged(const TQString&)));
m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
TQWhatsThis::add(m_contents->openDataLink,
i18n("Shows data for table or query associated with this page setup."));
TQToolTip::add(m_contents->openDataLink,
i18n("Shows data for table or query associated with this page setup."));
connect(m_contents->openDataLink, TQT_SIGNAL(leftClickedURL()), this, TQT_SLOT(slotOpenData()));
TQWhatsThis::add(m_contents->saveSetupLink, i18n("Saves settings for this setup as default."));
connect(m_contents->saveSetupLink, TQT_SIGNAL(leftClickedURL()), this, TQT_SLOT(slotSaveSetup()));
#if !KDE_IS_VERSION(3,5,1) && !defined(TQ_WS_WIN)
//a fix for problems with focusable KUrlLabel on KDElibs<=3.5.0
m_contents->openDataLink->setFocusPolicy(NoFocus);
m_contents->saveSetupLink->setFocusPolicy(NoFocus);
#endif
TQWhatsThis::add(m_contents->addDateTimeCheckbox, i18n("Adds date and time to the header."));
TQWhatsThis::add(m_contents->addPageNumbersCheckbox, i18n("Adds page numbers to the footer."));
TQWhatsThis::add(m_contents->addTableBordersCheckbox, i18n("Adds table borders."));
#ifdef KEXI_NO_UNFINISHED
m_contents->addDateTimeCheckbox->hide();
m_contents->addPageNumbersCheckbox->hide();
#endif
updatePageLayoutAndUnitInfo();
TQWhatsThis::add(m_contents->changePageSizeAndMarginsButton,
i18n("Changes page size and margins."));
connect(m_contents->changePageSizeAndMarginsButton, TQT_SIGNAL(clicked()),
this, TQT_SLOT(slotChangePageSizeAndMargins()));
connect(m_contents->addPageNumbersCheckbox, TQT_SIGNAL(toggled(bool)),
this, TQT_SLOT(slotAddPageNumbersCheckboxToggled(bool)));
connect(m_contents->addDateTimeCheckbox, TQT_SIGNAL(toggled(bool)),
this, TQT_SLOT(slotAddDateTimeCheckboxToggled(bool)));
connect(m_contents->addTableBordersCheckbox, TQT_SIGNAL(toggled(bool)),
this, TQT_SLOT(slotAddTableBordersCheckboxToggled(bool)));
if (!ok) {
// no data!
setEnabled(false);
}
m_contents->addPageNumbersCheckbox->setChecked( m_settings.addPageNumbers );
m_contents->addDateTimeCheckbox->setChecked( m_settings.addDateAndTime );
m_contents->addTableBordersCheckbox->setChecked( m_settings.addTableBorders );
setDirty(false);
// m_engine = new KexiSimplePrintingEngine(m_settings, this);
//clear it back to false after widgets initialization
m_printPreviewNeedsReloading = false;
/* if (printPreview)
TQTimer::singleShot(50, this, TQT_SLOT(printPreview()));
else if (print)
TQTimer::singleShot(50, this, TQT_SLOT(print()));*/
connect(this, TQT_SIGNAL(printItemRequested(KexiPart::Item*,const KexiSimplePrintingSettings&,
const TQString&)),
m_mainWin, TQT_SLOT(printItem(KexiPart::Item*,const KexiSimplePrintingSettings&,
const TQString&)));
connect(this, TQT_SIGNAL(printPreviewForItemRequested(KexiPart::Item*,
const KexiSimplePrintingSettings&,const TQString&,bool)),
m_mainWin, TQT_SLOT(printPreviewForItem(KexiPart::Item*,
const KexiSimplePrintingSettings&,const TQString&,bool)));
}
KexiSimplePrintingPageSetup::~KexiSimplePrintingPageSetup()
{
}
void KexiSimplePrintingPageSetup::slotSaveSetup()
{
m_settings.save();
setDirty(false);
}
void KexiSimplePrintingPageSetup::updatePageLayoutAndUnitInfo()
{
TQString s;
if (m_settings.pageLayout.format == PG_CUSTOM) {
s += TQString(" (%1 %2 x %3 %4)")
.arg(m_settings.pageLayout.ptWidth).arg(KoUnit::unitName(m_unit))
.arg(m_settings.pageLayout.ptHeight).arg(KoUnit::unitName(m_unit));
}
else
s += KoPageFormat::name(m_settings.pageLayout.format);
s += TQString(", ")
+ (m_settings.pageLayout.orientation == PG_PORTRAIT ? i18n("Portrait") : i18n("Landscape"))
+ ", " + i18n("margins:")
+ " " + KoUnit::toUserStringValue(m_settings.pageLayout.ptLeft, m_unit)
+ "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptRight, m_unit)
+ "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptTop, m_unit)
+ "/" + KoUnit::toUserStringValue(m_settings.pageLayout.ptBottom, m_unit)
+ " " + KoUnit::unitName(m_unit);
m_contents->pageSizeAndMarginsLabel->setText( s );
}
/*void KexiSimplePrintingPageSetup::setupPrintingCommand()
{
if (!m_command) {
m_command = new KexiSimplePrintingCommand(
m_mainWin, m_item->identifier(), m_settings, false/!owned/, this);
}
}*/
void KexiSimplePrintingPageSetup::print()
{
// setupPrintingCommand();
// m_command->print(m_contents->headerTitleLineEdit->text());
emit printItemRequested(m_item, m_settings, m_contents->headerTitleLineEdit->text());
}
void KexiSimplePrintingPageSetup::printPreview()
{
// setupPrintingCommand();
// m_command->showPrintPreview(m_contents->headerTitleLineEdit->text());
emit printPreviewForItemRequested(m_item, m_settings,
m_contents->headerTitleLineEdit->text(), m_printPreviewNeedsReloading);
m_printPreviewNeedsReloading = false;
}
void KexiSimplePrintingPageSetup::slotOpenData()
{
bool openingCancelled;
m_mainWin->openObject(m_item, Kexi::DataViewMode, openingCancelled);
}
void KexiSimplePrintingPageSetup::slotTitleTextChanged(const TQString&)
{
if (m_contents->headerTitleLineEdit->isModified()) {
m_printPreviewNeedsReloading = true;
// if (m_command)
// m_command->setPrintPreviewNeedsReloading();
}
m_contents->headerTitleLineEdit->clearModified();
}
void KexiSimplePrintingPageSetup::slotChangeTitleFont()
{
if (TQDialog::Accepted != TDEFontDialog::getFont(m_settings.pageTitleFont, false, this))
return;
m_contents->headerTitleLineEdit->setFont( m_settings.pageTitleFont );
setDirty(true);
}
void KexiSimplePrintingPageSetup::slotChangePageSizeAndMargins()
{
KoHeadFoot headfoot; //dummy
if (int(TQDialog::Accepted) != KoPageLayoutDia::pageLayout(
m_settings.pageLayout, headfoot, FORMAT_AND_BORDERS | DISABLE_UNIT, m_unit, this ))
return;
//update
updatePageLayoutAndUnitInfo();
setDirty(true);
}
void KexiSimplePrintingPageSetup::setDirty(bool set)
{
m_contents->saveSetupLink->setEnabled(set);
// if (m_command)
// m_command->setPrintPreviewNeedsReloading();
if (set)
m_printPreviewNeedsReloading = true;
}
void KexiSimplePrintingPageSetup::slotAddPageNumbersCheckboxToggled(bool set)
{
m_settings.addPageNumbers = set;
setDirty(true);
}
void KexiSimplePrintingPageSetup::slotAddDateTimeCheckboxToggled(bool set)
{
m_settings.addDateAndTime = set;
setDirty(true);
}
void KexiSimplePrintingPageSetup::slotAddTableBordersCheckboxToggled(bool set)
{
m_settings.addTableBorders = set;
setDirty(true);
}
#include "kexisimpleprintingpagesetup.moc"