20#include "kexisimpleprintingengine.h"
22#include <core/keximainwindow.h>
23#include <kexiutils/utils.h>
25#include <tdeapplication.h>
26#include <kiconloader.h>
28#include <tdefontdialog.h>
35#include <tqcheckbox.h>
36#include <tqwhatsthis.h>
37#include <tqpaintdevicemetrics.h>
40#include <kexiutils/tristate.h>
41#include <kexidb/connection.h>
42#include <kexidb/tableschema.h>
43#include <kexidb/cursor.h>
44#include <kexidb/utils.h>
45#include <kexidb/queryschema.h>
47KexiSimplePrintingSettings::KexiSimplePrintingSettings()
49 pageLayout = KoPageLayout::standardLayout();
50 addPageNumbers = true;
51 addDateAndTime = true;
52 addTableBorders = false;
53 pageTitleFont = kapp->font();
54 pageTitleFont.setPointSizeFloat( ( double)TQFontInfo(pageTitleFont).pointSize()*1.5 );
55 pageTitleFont.setBold( true);
58KexiSimplePrintingSettings::~KexiSimplePrintingSettings()
64 KexiSimplePrintingSettings settings;
66 TDEConfig *config = kapp->config();
67 config->setGroup( "Simple Printing");
68 if (config->hasKey( "pageTitleFont"))
69 settings.pageTitleFont = config->readFontEntry( "pageTitleFont");
71 if (config->hasKey( "pageFormat"))
72 settings.pageLayout.format = KoPageFormat::formatFromString(
73 config->readEntry( "pageFormat" ) );
74 if (config->readEntry( "pageOrientation", "portrait").lower()== "landscape")
75 settings.pageLayout.orientation = PG_LANDSCAPE;
77 settings.pageLayout.orientation = PG_PORTRAIT;
78 if (config->hasKey( "pageWidth"))
79 settings.pageLayout.ptWidth = config->readDoubleNumEntry( "pageWidth");
80 if (config->hasKey( "pageHeight"))
81 settings.pageLayout.ptHeight = config->readDoubleNumEntry( "pageHeight");
82 if (config->hasKey( "pageLeftMargin"))
83 settings.pageLayout.ptLeft = config->readDoubleNumEntry( "pageLeftMargin");
84 if (config->hasKey( "pageRightMargin"))
85 settings.pageLayout.ptRight = config->readDoubleNumEntry( "pageRightMargin");
86 if (config->hasKey( "pageTopMargin"))
87 settings.pageLayout.ptTop = config->readDoubleNumEntry( "pageTopMargin");
88 if (config->hasKey( "pageBottomMargin"))
89 settings.pageLayout.ptBottom = config->readDoubleNumEntry( "pageBottomMargin");
90 settings.addPageNumbers = config->readBoolEntry( "addPageNumbersToPage", true);
91 settings.addDateAndTime = config->readBoolEntry( "addDateAndTimePage", true);
92 settings.addTableBorders = config->readBoolEntry( "addTableBorders", false);
96void KexiSimplePrintingSettings::save()
98 TDEConfig *config = kapp->config();
99 config->setGroup( "Simple Printing");
100 config->writeEntry( "pageTitleFont", pageTitleFont );
101 config->writeEntry( "pageFormat", KoPageFormat::formatString( pageLayout.format ) );
102 config->writeEntry( "pageOrientation",
103 pageLayout.orientation == PG_PORTRAIT ? "portrait" : "landscape");
104 config->writeEntry( "pageWidth", pageLayout.ptWidth);
105 config->writeEntry( "pageHeight", pageLayout.ptHeight);
106 config->writeEntry( "pageLeftMargin", pageLayout.ptLeft);
107 config->writeEntry( "pageRightMargin", pageLayout.ptRight);
108 config->writeEntry( "pageTopMargin", pageLayout.ptTop);
109 config->writeEntry( "pageBottomMargin", pageLayout.ptBottom);
110 config->writeEntry( "addPageNumbersToPage", addPageNumbers);
111 config->writeEntry( "addDateAndTimePage", addDateAndTime);
112 config->writeEntry( "addTableBorders", addTableBorders);
118KexiSimplePrintingEngine::KexiSimplePrintingEngine(
120 : TQObject(parent, "KexiSimplePrintingEngine")
121 , m_settings(&settings)
126 m_visibleFieldsCount = 0;
127 m_dataOffsets.setAutoDelete( true);
131KexiSimplePrintingEngine::~KexiSimplePrintingEngine()
139 errorMessage = TQString();
141 m_headerText = titleText;
145 if (tableOrQuery. table())
148 query = tableOrQuery. query();
150 errorMessage = i18n( "Could not load data from table or query.");
159 bool ok = !m_cursor-> error();
163 m_data->preloadAllRows();
165 m_visibleFieldsCount = m_cursor->query()->fieldsExpanded().count();
170 m_eof = !ok || m_data->count() == 0;
176bool KexiSimplePrintingEngine::done()
188 m_fieldsExpanded.clear();
189 m_visibleFieldsCount = 0;
193void KexiSimplePrintingEngine::clear()
197 m_dataOffsets.clear();
198 m_dataOffsets.append( new uint(0));
205 if (pageNumber < ( int)m_dataOffsets.count()) {
206 offset = *m_dataOffsets.at(pageNumber);
211 const bool printing = painter.device()->devType() == TQInternal::Printer;
212 m_SCALE = printing ? 1 : 20;
215 m_pdm = TQPaintDeviceMetrics( painter.device() );
217 if ( dynamic_cast<TQWidget* >(painter.device())) {
218 w = dynamic_cast<TQWidget* >(painter.device())->width() * m_SCALE;
219 h = dynamic_cast<TQWidget* >(painter.device())->height() * m_SCALE;
221 else if ( dynamic_cast<TQPixmap* >(painter.device())) {
222 w = dynamic_cast<TQPixmap* >(painter.device())->width() * m_SCALE;
223 h = dynamic_cast<TQPixmap* >(painter.device())->height() * m_SCALE;
227 h = m_pdm.heightMM();
233 double widthMM = KoPageFormat::width(
234 m_settings->pageLayout.format, m_settings->pageLayout.orientation);
235 double heightMM = KoPageFormat::height(
236 m_settings->pageLayout.format, m_settings->pageLayout.orientation);
238 m_dpiY = m_pdm.logicalDpiY();
239 m_dpiX = m_pdm.logicalDpiX();
248 double pdWidthMM = m_pdm.widthMM();
249 double pdHeightMM = m_pdm.heightMM();
254 m_leftMargin = POINT_TO_INCH(m_settings->pageLayout.ptLeft)*m_dpiX * (double)m_SCALE;
255 m_rightMargin = POINT_TO_INCH(m_settings->pageLayout.ptRight)*m_dpiX * (double)m_SCALE;
256 m_topMargin = POINT_TO_INCH(m_settings->pageLayout.ptTop)*m_dpiY * (double)m_SCALE;
257 m_bottomMargin = POINT_TO_INCH(m_settings->pageLayout.ptBottom)*m_dpiY * (double)m_SCALE;
259 m_fx = widthMM / (pdWidthMM);
260 m_fy = heightMM / (pdHeightMM);
264 m_pageWidth = uint( m_fx* double(m_pdm.width()) * m_SCALE - m_leftMargin - m_rightMargin );
265 m_pageHeight = uint( m_fy* double(m_pdm.height()) * m_SCALE - m_topMargin - m_bottomMargin );
266 m_headerFont = m_settings->pageTitleFont;
268 int pixelSize = int( POINT_TO_INCH(( double)TQFontInfo(m_headerFont).pointSize())*m_dpiX ) * m_SCALE;
269 m_headerFont.setPixelSize(pixelSize);
273 m_mainFont = kapp->font();
275 int pixelSize = int( POINT_TO_INCH(m_mainFont.pointSizeFloat())*m_dpiX )
277 m_mainFont.setPixelSize(pixelSize);
279 painter.setFont(m_mainFont);
281 m_dateTimeText = TDEGlobal::locale()->formatDateTime(TQDateTime::currentDateTime(),
283 m_dateTimeWidth = painter.fontMetrics().width(m_dateTimeText+ " ");
284 m_mainLineSpacing = painter.fontMetrics().lineSpacing();
285 m_footerHeight = m_mainLineSpacing * 2;
286 painter.setFont(m_headerFont);
287 m_headerTextRect = painter.fontMetrics().boundingRect(
288 ( int)m_leftMargin, ( int)m_topMargin,
289 m_pageWidth - m_dateTimeWidth,
290 m_pageHeight, TQt::AlignAuto|TQt::WordBreak, m_headerText);
291 m_headerTextRect.setRight(m_headerTextRect.right()+10);
292 m_headerTextRect.setWidth(
293 TQMIN( int(m_pageWidth - m_dateTimeWidth), m_headerTextRect.width()));
296 m_maxFieldNameWidth = 0;
298 painter.setFont(m_mainFont);
299 for (uint i=0; i < m_visibleFieldsCount; i++) {
301 painter.fontMetrics().width(m_fieldsExpanded[i]->captionOrAliasOrName()+ ":");
304 if (m_maxFieldNameWidth < newW)
305 m_maxFieldNameWidth = newW;
307 m_maxFieldNameWidth += painter.fontMetrics().width( "ww");
312 painter.setWindow(0, 0, int(w*m_fx), int(h*m_fy));
316 painter.setFont(m_headerFont);
318 painter.drawText(m_headerTextRect, TQt::AlignAuto|TQt::WordBreak, m_headerText);
320 painter.setFont(m_mainFont);
322 painter.drawText(( int)m_leftMargin + m_pageWidth - m_dateTimeWidth,
323 ( int)m_topMargin, m_dateTimeWidth,
324 m_headerTextRect.height(), TQt::AlignRight, m_dateTimeText);
326 TQString pageNumString;
328 pageNumString = i18n( "Page (number) of (total)", "Page %1 of %2")
329 .arg(pageNumber+1).arg(m_pagesCount);
331 pageNumString = i18n( "Page %1").arg(pageNumber+1);
332 painter.drawText(( int)m_leftMargin,
333 ( int)m_topMargin + m_pageHeight - m_mainLineSpacing,
334 m_pageWidth, m_mainLineSpacing,
335 TQt::AlignRight | TQt::AlignBottom, pageNumString);
336 painter.drawLine(( int)m_leftMargin,
337 ( int)m_topMargin + m_pageHeight - m_mainLineSpacing*3/2,
338 ( int)m_leftMargin + m_pageWidth,
339 ( int)m_topMargin + m_pageHeight - m_mainLineSpacing*3/2);
341 y = (double)m_topMargin + ( double)m_headerTextRect.height() + double(m_mainLineSpacing)/2;
342 if (!m_settings->addTableBorders) {
345 painter.drawLine(( int)m_leftMargin, ( int)y, ( int)m_leftMargin + m_pageWidth-1, ( int)y);
346 y += (double)m_mainLineSpacing;
354 const uint rows = m_data->count();
355 const int cellMargin = m_settings->addTableBorders ?
356 painter.fontMetrics().width( "i") : 0;
357 uint paintedRows = 0;
358 for (;offset < rows; ++offset) {
359 item = m_data->at(offset);
363 paintRecord(painter, item, cellMargin, newY, paintedRows, false, printing);
365 if (newY > (m_topMargin + m_pageHeight - m_mainLineSpacing*2 + m_mainLineSpacing) && paintedRows > 0) {
378 paintRecord(painter, item, cellMargin, y, paintedRows, paint, printing);
384 if ( int(m_dataOffsets.count()-1)==pageNumber) {
385 m_dataOffsets.append( new uint(offset));
387 m_eof = offset == rows;
391 int cellMargin, double &y, uint paintedRows, bool paint, bool printing)
393 if (paintedRows>0 && !m_settings->addTableBorders) {
395 painter.setPen(TQt::darkGray);
397 int(m_leftMargin), int( y-( double)m_mainLineSpacing ),
398 int(m_leftMargin)+m_pageWidth-1, int(y-( double)m_mainLineSpacing));
399 painter.setPen(TQt::black);
403 for (uint i=0; i<m_visibleFieldsCount; i++) {
407 ( int)m_leftMargin+cellMargin, ( int)y, m_maxFieldNameWidth-cellMargin*2, m_mainLineSpacing,
408 TQt::AlignTop, m_fieldsExpanded[i]->captionOrAliasOrName()
409 + (m_settings->addTableBorders ? "" : ":"));
416 if (-1 != indexForVisibleLookupValue && indexForVisibleLookupValue < ( int)item->count())
417 ci = m_fieldsExpanded[ indexForVisibleLookupValue ];
419 ci = m_fieldsExpanded[ i ];
420 indexForVisibleLookupValue = i;
423 TQVariant v(item->at( indexForVisibleLookupValue ));
425 TQRect rect( ( int)m_leftMargin + m_maxFieldNameWidth + cellMargin, ( int)y,
426 m_pageWidth - m_maxFieldNameWidth - cellMargin*2, m_pageHeight - ( int)y);
428 if (v.isNull() || !v.isValid()) {
432 else if (ftype==KexiDB::Field::DateTime) {
433 TQDateTime dt(v.toDateTime());
435 text = TDEGlobal::locale()->formatDateTime(dt);
438 else if (ftype==KexiDB::Field::Date) {
439 TQDate date(v.toDate());
441 text = TDEGlobal::locale()->formatDate(date, true);
444 else if (ftype==KexiDB::Field::Time) {
445 TQTime time(v.toTime());
447 text = TDEGlobal::locale()->formatTime(time);
451 text = TDEGlobal::locale()->formatNumber(v.toDouble());
454 ? i18n( "Boolean Yes (true)", "Yes") : i18n( "Boolean No (false)", "No");
456 const TQByteArray ba( v.toByteArray() );
459#define MAX_PIXMAP_HEIGHT (m_mainLineSpacing * 5)
460 double pixmapHeight = MAX_PIXMAP_HEIGHT;
461 double pixmapWidth = double(MAX_PIXMAP_HEIGHT) * pixmap.width() / (double)pixmap.height();
462 if (pixmapWidth > ( double)rect.width()) {
463 pixmapHeight = pixmapHeight * (double)rect.width() / pixmapWidth;
464 pixmapWidth = rect.width();
466 rect.setHeight( int( pixmapHeight + m_mainLineSpacing / 2 ) );
467 if (paint && !pixmap.isNull()) {
470 TQRect(rect.x(), rect.y()+m_mainLineSpacing/4,
471 int(pixmapWidth), int(pixmapHeight)), pixmap );
477 TQRect(painter.window().topLeft(),
478 painter.window().size() / ( int)m_SCALE ) );
480 int(rect.x() / m_SCALE),
481 int( (rect.y()+m_mainLineSpacing/4) / m_SCALE),
482 pixmap.convertToImage().smoothScale(
483 int(pixmapWidth / m_SCALE), int(pixmapHeight / m_SCALE),
484 TQImage::ScaleMin ));
494 rect = TQRect( painter.fontMetrics().boundingRect(
495 rect.x(), rect.y(), rect.width(), rect.height(),
496 TQt::AlignAuto|TQt::WordBreak, text) );
497 if (!text.isEmpty() && paint) {
503 rect.x(), rect.y(), m_pageWidth - m_maxFieldNameWidth - cellMargin*2,
504 int(m_topMargin + m_pageHeight - ( int)y),
505 TQt::AlignTop|TQt::WordBreak, text);
507 if (m_settings->addTableBorders) {
509 painter.setPen(TQt::darkGray);
511 ( int)m_leftMargin, rect.top(), ( int)m_leftMargin+m_pageWidth-1, rect.top());
513 ( int)m_leftMargin, rect.top(), ( int)m_leftMargin, rect.bottom());
515 ( int)m_leftMargin+m_pageWidth-1, rect.top(),
516 ( int)m_leftMargin+m_pageWidth-1, rect.bottom());
518 ( int)m_leftMargin+m_maxFieldNameWidth, rect.top(),
519 ( int)m_leftMargin+m_maxFieldNameWidth, rect.bottom());
520 painter.setPen(TQt::black);
523 y += (double)rect.height();
525 if (m_settings->addTableBorders) {
527 painter.setPen(TQt::darkGray);
529 ( int)m_leftMargin, ( int)y, ( int)m_leftMargin+m_pageWidth-1, ( int)y);
530 painter.setPen(TQt::black);
534 y += double(m_mainLineSpacing)*3.0/2.0;
541 if (m_eof || !m_data) {
547 for(;!m_eof; ++pageNumber) {
550 m_pagesCount = pageNumber;
553void KexiSimplePrintingEngine::setTitleText( const TQString& titleText)
555 m_headerText = titleText;
558#include "kexisimpleprintingengine.moc"
Provides database connection, allowing queries and data modification.
bool deleteCursor(Cursor *cursor)
Cursor * executeQuery(const TQString &statement, uint cursor_options=0)
Connection * connection() const
bool isFPNumericType() const
Helper class that assigns additional information for the column in a query.
int indexForVisibleLookupValue() const
KexiDB::QuerySchema provides information about database query.
@ WithInternalFields Like Default but internal fields (for lookup) are appended.
QueryColumnInfo::Vector fieldsExpanded(FieldsExpandedOptions options=Default)
QuerySchema * query() const
TableSchema * table() const
void paintPage(int pageNumber, TQPainter &painter, bool paint=true)
void paintRecord(TQPainter &painter, KexiTableItem *item, int cellMargin, double &y, uint paintedRows, bool paint, bool printing)
bool m_paintInitialized used by paintPage()
bool init(KexiDB::Connection &conn, KexiDB::TableOrQuerySchema &tableOrQuery, const TQString &titleText, TQString &errorMessage)
void calculatePagesCount(TQPainter &painter)
Settings data for simple printing engine.
static KexiSimplePrintingSettings load()
TQValueVector< TQVariant > RowData structure for storing single record with type information
|