diff options
Diffstat (limited to 'kugar/lib')
29 files changed, 5047 insertions, 0 deletions
diff --git a/kugar/lib/Makefile.am b/kugar/lib/Makefile.am new file mode 100644 index 00000000..e6c2af0f --- /dev/null +++ b/kugar/lib/Makefile.am @@ -0,0 +1,19 @@ +INCLUDES = $(KOFFICE_INCLUDES) $(all_includes) + +METASOURCES = AUTO + +libkugarlib_la_LIBADD = $(LIB_QT) $(LIB_KDEPRINT) + +libkugarlib_la_LDFLAGS = $(all_libraries) -version-info 1:2 -no-undefined + +# libkugar.la is already reserved for the kdeinit module for kugar (on some platforms), +# so we have to call the lib differently, e.g. libkugarlib +lib_LTLIBRARIES = libkugarlib.la + +libkugarlib_la_SOURCES = mcalcobject.cpp mfieldobject.cpp mlabelobject.cpp \ + mlineobject.cpp mpagecollection.cpp mpagedisplay.cpp mreportdetail.cpp \ + mreportengine.cpp mreportobject.cpp mreportsection.cpp mreportviewer.cpp \ + mspecialobject.cpp mutil.cpp inputmask.cpp + +include_HEADERS = +noinst_HEADERS = inputmask.h diff --git a/kugar/lib/inputmask.cpp b/kugar/lib/inputmask.cpp new file mode 100644 index 00000000..75a72f61 --- /dev/null +++ b/kugar/lib/inputmask.cpp @@ -0,0 +1,359 @@ +/*************************************************************************** +* Copyright (C) 2005 by Adam Treat * +* treat@kde.org * +* * +* Copyright (C) 2000 Trolltech AS. All rights reserved. * +* info@trolltech.com * +* * +* 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. * +* * +***************************************************************************/ + +#include "inputmask.h" + +namespace Kugar +{ + +InputMask::InputMask( QObject *parent, const char *name ) + : QObject( parent, name ), + m_text( QString::null ), + m_maxLength( 32767 ), + m_blank( ' ' ), + m_mask( QString::null ), + m_maskData( 0L ) +{} + +InputMask::~InputMask() +{ + delete [] m_maskData; +} + +QString InputMask::mask() const +{ + return ( m_maskData ? m_mask + ';' + m_blank : QString::null ); +} + +void InputMask::setMask( const QString &mask ) +{ + parseInputMask( mask ); +} + +QString InputMask::formatText( const QString &txt ) +{ + return maskString( 0, txt, true ); +} + +void InputMask::parseInputMask( const QString &maskFields ) +{ + if ( maskFields.isEmpty() || maskFields.section( ';', 0, 0 ).isEmpty() ) + { + if ( m_maskData ) + { + delete [] m_maskData; + m_maskData = 0; + m_maxLength = 32767; + } + return ; + } + + m_mask = maskFields.section( ';', 0, 0 ); + m_blank = maskFields.section( ';', 1, 1 ).at( 0 ); + if ( m_blank.isNull() ) + m_blank = ' '; + + // calculate m_maxLength / m_maskData length + m_maxLength = 0; + QChar c = 0; + uint i; + for ( i = 0; i < m_mask.length(); i++ ) + { + c = m_mask.at( i ); + if ( i > 0 && m_mask.at( i - 1 ) == '\\' ) + { + m_maxLength++; + continue; + } + if ( c != '\\' && c != '!' && + c != '<' && c != '>' && + c != '{' && c != '}' && + c != '[' && c != ']' ) + m_maxLength++; + } + + delete [] m_maskData; + m_maskData = new MaskInputData[ m_maxLength ]; + + MaskInputData::Casemode m = MaskInputData::NoCaseMode; + c = 0; + bool s; + bool escape = FALSE; + int index = 0; + for ( i = 0; i < m_mask.length(); i++ ) + { + c = m_mask.at( i ); + if ( escape ) + { + s = TRUE; + m_maskData[ index ].maskChar = c; + m_maskData[ index ].separator = s; + m_maskData[ index ].caseMode = m; + index++; + escape = FALSE; + } + else if ( c == '<' || c == '>' || c == '!' ) + { + switch ( c ) + { + case '<': + m = MaskInputData::Lower; + break; + case '>': + m = MaskInputData::Upper; + break; + case '!': + m = MaskInputData::NoCaseMode; + break; + } + } + else if ( c != '{' && c != '}' && c != '[' && c != ']' ) + { + switch ( c ) + { + case 'A': + case 'a': + case 'N': + case 'n': + case 'X': + case 'x': + case '9': + case '0': + case 'D': + case 'd': + case '#': + s = FALSE; + break; + case '\\': + escape = TRUE; + default: + s = TRUE; + break; + } + + if ( !escape ) + { + m_maskData[ index ].maskChar = c; + m_maskData[ index ].separator = s; + m_maskData[ index ].caseMode = m; + index++; + } + } + } +} + +bool InputMask::isValidInput( QChar key, QChar mask ) const +{ + switch ( mask ) + { + case 'A': + if ( key.isLetter() && key != m_blank ) + return TRUE; + break; + case 'a': + if ( key.isLetter() || key == m_blank ) + return TRUE; + break; + case 'N': + if ( key.isLetterOrNumber() && key != m_blank ) + return TRUE; + break; + case 'n': + if ( key.isLetterOrNumber() || key == m_blank ) + return TRUE; + break; + case 'X': + if ( key.isPrint() && key != m_blank ) + return TRUE; + break; + case 'x': + if ( key.isPrint() || key == m_blank ) + return TRUE; + break; + case '9': + if ( key.isNumber() && key != m_blank ) + return TRUE; + break; + case '0': + if ( key.isNumber() || key == m_blank ) + return TRUE; + break; + case 'D': + if ( key.isNumber() && key.digitValue() > 0 && key != m_blank ) + return TRUE; + break; + case 'd': + if ( ( key.isNumber() && key.digitValue() > 0 ) || key == m_blank ) + return TRUE; + break; + case '#': + if ( key.isNumber() || key == '+' || key == '-' || key == m_blank ) + return TRUE; + break; + default: + break; + } + return FALSE; +} + +QString InputMask::maskString( uint pos, const QString &str, bool clear ) const +{ + if ( pos >= ( uint ) m_maxLength ) + return QString::fromLatin1( "" ); + + QString fill; + fill = clear ? clearString( 0, m_maxLength ) : m_text; + + uint strIndex = 0; + QString s = QString::fromLatin1( "" ); + int i = pos; + while ( i < m_maxLength ) + { + if ( strIndex < str.length() ) + { + if ( m_maskData[ i ].separator ) + { + s += m_maskData[ i ].maskChar; + if ( str[ ( int ) strIndex ] == m_maskData[ i ].maskChar ) + strIndex++; + ++i; + } + else + { + if ( isValidInput( str[ ( int ) strIndex ], m_maskData[ i ].maskChar ) ) + { + switch ( m_maskData[ i ].caseMode ) + { + case MaskInputData::Upper: + s += str[ ( int ) strIndex ].upper(); + break; + case MaskInputData::Lower: + s += str[ ( int ) strIndex ].lower(); + break; + default: + s += str[ ( int ) strIndex ]; + } + ++i; + } + else + { + // search for separator first + int n = findInMask( i, TRUE, TRUE, str[ ( int ) strIndex ] ); + if ( n != -1 ) + { + if ( str.length() != 1 || i == 0 || ( i > 0 && ( !m_maskData[ i - 1 ].separator || m_maskData[ i - 1 ].maskChar != str[ ( int ) strIndex ] ) ) ) + { + s += fill.mid( i, n - i + 1 ); + i = n + 1; // update i to find + 1 + } + } + else + { + // search for valid m_blank if not + n = findInMask( i, TRUE, FALSE, str[ ( int ) strIndex ] ); + if ( n != -1 ) + { + s += fill.mid( i, n - i ); + switch ( m_maskData[ n ].caseMode ) + { + case MaskInputData::Upper: + s += str[ ( int ) strIndex ].upper(); + break; + case MaskInputData::Lower: + s += str[ ( int ) strIndex ].lower(); + break; + default: + s += str[ ( int ) strIndex ]; + } + i = n + 1; // updates i to find + 1 + } + } + } + strIndex++; + } + } + else + break; + } + + return s; +} + +QString InputMask::clearString( uint pos, uint len ) const +{ + if ( pos >= ( uint ) m_maxLength ) + return QString::null; + + QString s; + int end = QMIN( ( uint ) m_maxLength, pos + len ); + for ( int i = pos; i < end; i++ ) + if ( m_maskData[ i ].separator ) + s += m_maskData[ i ].maskChar; + else + s += m_blank; + + return s; +} + +QString InputMask::stripString( const QString &str ) const +{ + if ( !m_maskData ) + return str; + + QString s; + int end = QMIN( m_maxLength, ( int ) str.length() ); + for ( int i = 0; i < end; i++ ) + if ( m_maskData[ i ].separator ) + s += m_maskData[ i ].maskChar; + else + if ( str[ i ] != m_blank ) + s += str[ i ]; + + return s; +} + +int InputMask::findInMask( int pos, bool forward, bool findSeparator, QChar searchChar ) const +{ + if ( pos >= m_maxLength || pos < 0 ) + return -1; + + int end = forward ? m_maxLength : -1; + int step = forward ? 1 : -1; + int i = pos; + + while ( i != end ) + { + if ( findSeparator ) + { + if ( m_maskData[ i ].separator && m_maskData[ i ].maskChar == searchChar ) + return i; + } + else + { + if ( !m_maskData[ i ].separator ) + { + if ( searchChar.isNull() ) + return i; + else if ( isValidInput( searchChar, m_maskData[ i ].maskChar ) ) + return i; + } + } + i += step; + } + return -1; +} + +} + +#include "inputmask.moc" diff --git a/kugar/lib/inputmask.h b/kugar/lib/inputmask.h new file mode 100644 index 00000000..2668ba0c --- /dev/null +++ b/kugar/lib/inputmask.h @@ -0,0 +1,61 @@ +/*************************************************************************** +* Copyright (C) 2005 by Adam Treat * +* treat@kde.org * +* * +* Copyright (C) 2000 Trolltech AS. All rights reserved. * +* info@trolltech.com * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef INPUTMASK_H +#define INPUTMASK_H + +#include <qobject.h> + +namespace Kugar +{ + +class InputMask : public QObject +{ + Q_OBJECT +public: + InputMask( QObject *parent = 0, const char *name = 0 ); + + ~InputMask(); + + QString mask() const; + void setMask( const QString &mask ); + + QString formatText( const QString &txt ); + +private: + void parseInputMask( const QString &maskFields ); + bool isValidInput( QChar key, QChar mask ) const; + QString maskString( uint pos, const QString &str, bool clear = FALSE ) const; + QString clearString( uint pos, uint len ) const; + QString stripString( const QString &str ) const; + int findInMask( int pos, bool forward, bool findSeparator, QChar searchChar = QChar() ) const; + +private: + QString m_text; + int m_maxLength; + QChar m_blank; + QString m_mask; + struct MaskInputData + { + enum Casemode { NoCaseMode, Upper, Lower }; + QChar maskChar; // either the separator char or the inputmask + bool separator; + Casemode caseMode; + }; + MaskInputData *m_maskData; +}; + +} + +#endif diff --git a/kugar/lib/mcalcobject.cpp b/kugar/lib/mcalcobject.cpp new file mode 100644 index 00000000..fbb7345f --- /dev/null +++ b/kugar/lib/mcalcobject.cpp @@ -0,0 +1,66 @@ +/*************************************************************************** + mcalcobject.cpp - Kugar report calculation field object + ------------------- + begin : Thu Sep 2 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#include "mcalcobject.h" + +namespace Kugar +{ + +/** Constructor */ +MCalcObject::MCalcObject() : MFieldObject() +{ + // Set the default calculation type + calcType = MCalcObject::Count; +} + +/** Copy constructor */ +MCalcObject::MCalcObject( const MCalcObject& mCalcObject ) : MFieldObject( ( MFieldObject & ) mCalcObject ) +{ + copy( &mCalcObject ); +} + +/** Assignment operator */ +MCalcObject MCalcObject::operator=( const MCalcObject& mCalcObject ) +{ + if ( &mCalcObject == this ) + return * this; + + // Copy the derived class's data + copy( &mCalcObject ); + + // Copy the base class's data + ( ( MFieldObject & ) * this ) = mCalcObject; + + return *this; +} + +/** Destructor */ +MCalcObject::~MCalcObject() +{} + +/** Sets the field's calculation type */ +void MCalcObject::setCalculationType( int type ) +{ + calcType = type; +} + +/** Returns the field's calculation type */ +int MCalcObject::getCalculationType() +{ + return calcType; +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MCalcObject::copy( const MCalcObject* mCalcObject ) +{ + // Copy the fields's calculation type + calcType = mCalcObject->calcType; +} + +} diff --git a/kugar/lib/mcalcobject.h b/kugar/lib/mcalcobject.h new file mode 100644 index 00000000..dfedb48c --- /dev/null +++ b/kugar/lib/mcalcobject.h @@ -0,0 +1,56 @@ +/*************************************************************************** + mcalcobject.h - Kugar report calculation field object + ------------------- + begin : Thu Sep 2 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MCALCOBJECT_H +#define MCALCOBJECT_H + +#include "mfieldobject.h" + +/**Kugar report calculation field object + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MCalcObject : public MFieldObject +{ + +public: + /** Calculation type constants */ + enum CalculationType { Count = 0, Sum, Average, Variance, StandardDeviation}; + + /** Constructor */ + MCalcObject(); + /** Copy constructor */ + MCalcObject( const MCalcObject& mCalcObject ); + /** Assignment operator */ + MCalcObject operator=( const MCalcObject& mCalcObject ); + /** Destructor */ + ~MCalcObject(); + + /** Sets the field's calculation type */ + void setCalculationType( int type ); + /** Returns the field's calculation type */ + int getCalculationType(); + +private: + /** Calculation type */ + int calcType; + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MCalcObject* mCalcObject ); + +}; + +} + +#endif diff --git a/kugar/lib/mfieldobject.cpp b/kugar/lib/mfieldobject.cpp new file mode 100644 index 00000000..c2d60203 --- /dev/null +++ b/kugar/lib/mfieldobject.cpp @@ -0,0 +1,261 @@ +/*************************************************************************** + mfieldobject.cpp - Kugar report field object + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#include "mfieldobject.h" +#include "mutil.h" + +#include "inputmask.h" + +namespace Kugar +{ + +/** Constructor */ +MFieldObject::MFieldObject() : MLabelObject() +{ + // Set the defaults + fieldName = ""; + dataType = MFieldObject::String; + format = MUtil::MDY_SLASH; + precision = 0; + currency = 36; + negativeValueColor.setRgb( 255, 0, 0 ); + comma = 0; + m_inputMask = new InputMask(); +} + +/** Copy constructor */ +MFieldObject::MFieldObject( const MFieldObject& mFieldObject ) : MLabelObject( ( MLabelObject & ) mFieldObject ) +{ + copy( &mFieldObject ); +} + +/** Assignment operator */ +MFieldObject MFieldObject::operator=( const MFieldObject& mFieldObject ) +{ + if ( &mFieldObject == this ) + return * this; + + // Copy the derived class's data + copy( &mFieldObject ); + + // Copy the base class's data + ( ( MLabelObject & ) * this ) = mFieldObject; + + return *this; +} + +/** Destructor */ +MFieldObject::~MFieldObject() +{} + +/** Returns the bound data field name */ +QString MFieldObject::getFieldName() +{ + return fieldName; +} + +/** Sets the bound data field */ +void MFieldObject::setFieldName( const QString field ) +{ + fieldName = field; +} + +/** Sets the field's data string */ +void MFieldObject::setText( const QString txt ) +{ + int ret; + QDate d; + int pos; + QString month, day, year; + QRegExp regexp( "[0-9][0-9](-|//)[0-9][0-9](-|//)[0-9][0-9][0-9][0-9]" ); + + // Check for empty string + if ( txt.isEmpty() && dataType == MFieldObject::Date ) + { + text = QString::null; + return ; + } + + // Set the data + switch ( dataType ) + { + case MFieldObject::String: + text = txt; + if ( !getInputMask().isEmpty() ) + text = m_inputMask->formatText( txt ); + break; + case MFieldObject::Integer: + text.setNum( txt.toDouble(), 'f', 0 ); + if ( comma ) + formatCommas(); + formatNegValue(); + break; + case MFieldObject::Float: + text.setNum( txt.toDouble(), 'f', precision ); + if ( comma ) + formatCommas(); + formatNegValue(); + break; + case MFieldObject::Date: + // Check if we can read the date and if so, reformat it ... + + pos = regexp.search( txt.mid( 0 ) ); + ret = regexp.matchedLength(); + //ret = regexp.match(txt); + + if ( ret != 1 ) + { + year = txt.right( 4 ); + month = txt.left( 2 ); + day = txt.mid( 3, 2 ); + + d.setYMD( year.toInt(), month.toInt(), day.toInt() ); + // d = QDate::fromString(txt, Qt::LocalDate); + text = MUtil::formatDate( d, format ); + } + else + text = txt; + break; + case MFieldObject::Currency: + int prec = precision < 2 ? precision : 2; + bool ok; + text.setNum( txt.toDouble( &ok ), 'f', prec ); + if( !ok ) + text = QString::null; + else + { + if ( comma ) + formatCommas(); + formatNegValue(); + text = QString( currency + text ); + } + break; + } +} + +QString MFieldObject::getInputMask() const +{ + return m_inputMask->mask(); +} + +void MFieldObject::setInputMask( const QString &inputMask ) +{ + m_inputMask->setMask( inputMask ); +} + +/** Sets the field's data type */ +void MFieldObject::setDataType( int t ) +{ + dataType = t; + if ( dataType == MFieldObject::Integer || + dataType == MFieldObject::Float || + dataType == MFieldObject::Currency ) + saveColor = foregroundColor; +} + +/** Sets the field's date formatting */ +void MFieldObject::setDateFormat( int f ) +{ + format = f; +} + +/** Sets the field's precision */ +void MFieldObject::setPrecision( int p ) +{ + precision = p; +} + +/** Sets the field's currency symbol */ +void MFieldObject::setCurrency( const QChar c ) +{ + if ( c.isNull() ) + currency = 36; + else + currency = c; +} + +/** Sets the object's negative value color - default is red*/ +void MFieldObject::setNegValueColor( int r, int g, int b ) +{ + negativeValueColor.setRgb( r, g, b ); +} + +/** Sets if object should delimit numeric values with commas */ +void MFieldObject::setCommaSeparator( int c ) +{ + comma = c; +} + +/** Formats a string representation of a negative number using the negative value color */ +void MFieldObject::formatNegValue() +{ + if ( text.toDouble() < 0 ) + foregroundColor = negativeValueColor; + else + foregroundColor = saveColor; +} + +/** Formats the string representation of a number with comma separators */ +void MFieldObject::formatCommas() +{ + // text = text.replace(".", ","); + QString tmp; + int i, j; + int offset; + + // If a neg value + if ( text.toDouble() < 0 ) + offset = 1; + else + offset = 0; + + // Look for decimal point + int pos = text.findRev( "." ); + + // If a decimal was not found, start at end of string + if ( pos == -1 ) + pos = text.length(); + else + tmp = text.mid( pos, text.length() ); + + // Move through the string and insert the commas + for ( i = pos - 1, j = 0; i >= offset; i-- ) + { + tmp = text.mid( i, 1 ) + tmp; + j++; + if ( ( j == 3 ) && ( i - 1 >= offset ) ) + { + tmp = tr( "," ) + tmp; + j = 0; + } + } + + // If neg value, add back the sign + if ( offset ) + tmp = "-" + tmp; + + // Set the new string to the field + text = tmp; +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MFieldObject::copy( const MFieldObject* mFieldObject ) +{ + // Copy the fields's data type and format + fieldName = mFieldObject->fieldName; + dataType = mFieldObject->dataType; + format = mFieldObject->format; + precision = mFieldObject->precision; + currency = mFieldObject->currency; + negativeValueColor = mFieldObject->negativeValueColor; + saveColor = mFieldObject->saveColor; + comma = mFieldObject->comma; +} + +} diff --git a/kugar/lib/mfieldobject.h b/kugar/lib/mfieldobject.h new file mode 100644 index 00000000..8832414f --- /dev/null +++ b/kugar/lib/mfieldobject.h @@ -0,0 +1,102 @@ +/*************************************************************************** + mfieldobject.h - Kugar report field object + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MFIELDOBJECT_H +#define MFIELDOBJECT_H + +#include <qregexp.h> + +#include "mlabelobject.h" + +/**Kugar report field object + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class InputMask; + +class MFieldObject : public MLabelObject +{ + +public: + /** Data type constants */ + enum DataType { String = 0, Integer, Float, Date, Currency}; + + /** Constructor */ + MFieldObject(); + /** Copy constructor */ + MFieldObject( const MFieldObject& mFieldObject ); + /** Assignment operator */ + MFieldObject operator=( const MFieldObject& mFieldObject ); + /** Destructor */ + virtual ~MFieldObject(); + +protected: + /** Field name */ + QString fieldName; + /** Field data type */ + int dataType; + /** Field date format */ + int format; + /** Field precision */ + int precision; + /** Field currency symbol */ + QChar currency; + /** Field's negative value color */ + QColor negativeValueColor; + /** Field's original color */ + QColor saveColor; + /** Field's comma flag */ + int comma; + /** Input mask */ + QString inputMask; + +public: + /** Returns the bound data field name */ + QString getFieldName(); + /** Sets the bound data field */ + void setFieldName( const QString field ); + /** Sets the field's data string - default is an empty string*/ + void setText( const QString txt ); + /** Sets the field's data type */ + void setDataType( int t ); + /** Sets the field's date formatting */ + void setDateFormat( int f ); + /** Sets the field's precision */ + void setPrecision( int p ); + /** Sets the field's currency symbol */ + void setCurrency( const QChar c ); + /** Sets the object's negative value color - default is red*/ + void setNegValueColor( int r, int g, int b ); + /** Sets if object should delimit numeric values with commas */ + void setCommaSeparator( int c ); + + QString getInputMask() const; + void setInputMask( const QString &inputMask ); + +private: + /** Formats a string representation of a negative number using the negative value color */ + void formatNegValue(); + /** Formats a string representation of number with comma seperators */ + void formatCommas(); + void parseInputMask(); + + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MFieldObject* mFieldObject ); + + InputMask *m_inputMask; + +}; + +} + +#endif diff --git a/kugar/lib/mlabelobject.cpp b/kugar/lib/mlabelobject.cpp new file mode 100644 index 00000000..bc01c22d --- /dev/null +++ b/kugar/lib/mlabelobject.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + mlabelobject.cpp - Kugar report label object + ------------------- + begin : Wed Aug 11 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +//#include <kglobalsettings.h> +#include <qfont.h> + +#include "mlabelobject.h" + +namespace Kugar +{ + +/** Constructor */ +MLabelObject::MLabelObject() : MReportObject(), xMargin( 0 ), yMargin( 0 ) +{ + // Set the default label text + text = ""; + + // Set the default font + QFont defaultFont; + fontFamily = defaultFont.family(); + fontSize = 10; + fontWeight = MLabelObject::Normal; + fontItalic = false; + + // Set the default alignment + hAlignment = MLabelObject::Left; + vAlignment = MLabelObject::Top; + wordWrap = false; +} + +/** Copy constructor */ +MLabelObject::MLabelObject( const MLabelObject& mLabelObject ) : + MReportObject( ( MReportObject & ) mLabelObject ), xMargin( 0 ), yMargin( 0 ) +{ + copy( &mLabelObject ); +} + +/** Assignment operator */ +MLabelObject MLabelObject::operator=( const MLabelObject& mLabelObject ) +{ + if ( &mLabelObject == this ) + return * this; + + // Copy the derived class's data + copy( &mLabelObject ); + + // Copy the base class's data + ( ( MReportObject & ) * this ) = mLabelObject; + + return *this; +} + +/** Destructor */ +MLabelObject::~MLabelObject() +{} + +/** Sets the label's text string */ +void MLabelObject::setText( const QString txt ) +{ + text = txt; +} + +/** Sets the label's text font */ +void MLabelObject::setFont( const QString family, int size, int weight, bool italic ) +{ + fontFamily = family; + fontSize = size; + fontWeight = weight; + fontItalic = italic; +} + +/** Sets the label's horizontal alignment */ +void MLabelObject::setHorizontalAlignment( int a ) +{ + hAlignment = a; +} + +/** Sets the label's vertical alignment */ +void MLabelObject::setVerticalAlignment( int a ) +{ + vAlignment = a; +} + +/** Sets the label's word wrap flag */ +void MLabelObject::setWordWrap( bool state ) +{ + wordWrap = state; +} + +/** Draws the label using the specificed painter & x/y-offsets */ +void MLabelObject::draw( QPainter* p, int xoffset, int yoffset ) +{ + QFont font( fontFamily, fontSize, fontWeight, fontItalic ); + QPen textPen( foregroundColor, 0, QPen::NoPen ); + + int tf; + + // Set the offsets + int xcalc = xpos + xoffset; + int ycalc = ypos + yoffset; + + // Draw the base + drawBase( p, xoffset, yoffset ); + + // Set the font + p->setFont( font ); + QFontMetrics fm = p->fontMetrics(); + + // Set the text alignment flags + + // Horizontal + switch ( hAlignment ) + { + case MLabelObject::Left: + tf = QPainter::AlignLeft; + break; + case MLabelObject::Center: + tf = QPainter::AlignHCenter; + break; + case MLabelObject::Right: + tf = QPainter::AlignRight; + } + + // Vertical + switch ( vAlignment ) + { + case MLabelObject::Top: + tf = tf | QPainter::AlignTop; + break; + case MLabelObject::Bottom: + tf = tf | QPainter::AlignBottom; + break; + case MLabelObject::Middle: + tf = tf | QPainter::AlignVCenter; + } + + // Word wrap + if ( wordWrap ) + tf = tf | QPainter::WordBreak; + + // Draw the text + p->setPen( textPen ); + p->drawText( xcalc + xMargin, ycalc + yMargin, + width - xMargin, height - yMargin, + tf, text ); +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MLabelObject::copy( const MLabelObject* mLabelObject ) +{ + // Copy the label's text + text = mLabelObject->text; + + // Copy the label's font data + fontFamily = mLabelObject->fontFamily; + fontSize = mLabelObject->fontSize; + fontWeight = mLabelObject->fontWeight; + fontItalic = mLabelObject->fontItalic; + + // Copy the label's alignment data + vAlignment = mLabelObject->vAlignment; + hAlignment = mLabelObject->hAlignment; + wordWrap = mLabelObject->wordWrap; +} + +} diff --git a/kugar/lib/mlabelobject.h b/kugar/lib/mlabelobject.h new file mode 100644 index 00000000..7f4a5164 --- /dev/null +++ b/kugar/lib/mlabelobject.h @@ -0,0 +1,92 @@ +/*************************************************************************** + mlabelobject.h - Kugar report label object + ------------------- + begin : Wed Aug 11 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MLABELOBJECT_H +#define MLABELOBJECT_H + +#include <qstring.h> +#include <qfontmetrics.h> + +#include "mreportobject.h" + +/**Kugar report label object + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MLabelObject : public MReportObject +{ + +public: + /** Font weight constants */ + enum FontWeight { Light = 25, Normal = 50, DemiBold = 63, Bold = 75, Black = 87 }; + /** Horizontal alignment constants */ + enum HAlignment { Left = 0, Center, Right }; + /** Vertial alignment constants */ + enum VAlignment { Top = 0, Middle, Bottom }; + + /** Constructor */ + MLabelObject(); + /** Copy constructor */ + MLabelObject( const MLabelObject& mLabelObject ); + /** Assignment operator */ + MLabelObject operator=( const MLabelObject& mLabelObject ); + /** Destructor */ + virtual ~MLabelObject(); + +protected: + /** Label text */ + QString text; + /** Label text font family */ + QString fontFamily; + /** Label text font size in points */ + int fontSize; + /** Label text font weight */ + int fontWeight; + /** Label text font italic flag */ + bool fontItalic; + /** Lable text horizontal alignment */ + int hAlignment; + /** Label text vertical alignment */ + int vAlignment; + /** Label text word wrap flag */ + bool wordWrap; + +private: + /** Label text horizontal margin spacing */ + const int xMargin; + /** Label text vertical margin spacing */ + const int yMargin; + +public: + /** Sets the label's text string - default is an empty string*/ + virtual void setText( const QString txt ); + /** Sets the label's text font - default is Times,10,Normal,false */ + void setFont( const QString family, int size, int weight, bool italic ); + /** Sets the label's horizontal alignment -default is Left */ + void setHorizontalAlignment( int a ); + /** Sets the label's vertical alignment - default is Top */ + void setVerticalAlignment( int a ); + /** Sets the label's word wrap flag - default is false */ + void setWordWrap( bool state ); + /** Draws the label using the specificed painter & x/y-offsets */ + void draw( QPainter* p, int xoffset, int yoffset ); + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MLabelObject* mLabelObject ); + +}; + +} + +#endif diff --git a/kugar/lib/mlineobject.cpp b/kugar/lib/mlineobject.cpp new file mode 100644 index 00000000..dba41078 --- /dev/null +++ b/kugar/lib/mlineobject.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + mlineobject.cpp - Kugar report line object + ------------------- + begin : Wed Feb 23 2000 + copyright : (C) 2000 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#include "mlineobject.h" + +namespace Kugar +{ + +/** Constructor */ +MLineObject::MLineObject() : QObject() +{ + // Set the object's default geometry + xpos1 = 0; + ypos1 = 0; + xpos2 = 0; + ypos2 = 0; + + // Set the object's default attributes + penWidth = 1; + penColor.setRgb( 0, 0, 0 ); + penStyle = MLineObject::SolidLine; +} + +/** Copy constructor */ +MLineObject::MLineObject( const MLineObject& mLineObject ) /*: QObject((QObject &) mLineObject)*/ +{ + copy( &mLineObject ); +} + +/** Assignment operator */ +MLineObject MLineObject::operator=( const MLineObject& mLineObject ) +{ + if ( &mLineObject == this ) + return * this; + + // Copy the derived class's data + copy( &mLineObject ); + + // Copy the base class's data + //((QObject &) *this) = mLineObject; + + return *this; +} + +/** Destructor */ +MLineObject::~MLineObject() +{} + +/** Sets the start and end points for the line */ +void MLineObject::setLine( int xStart, int yStart, int xEnd, int yEnd ) +{ + xpos1 = xStart; + ypos1 = yStart; + xpos2 = xEnd; + ypos2 = yEnd; +} + +/** Sets the object's color */ +void MLineObject::setColor( int r, int g, int b ) +{ + penColor.setRgb( r, g, b ); +} + +/** Sets the object's style */ +void MLineObject::setStyle( int style ) +{ + penStyle = style; +} + +/** Sets the object's width */ +void MLineObject::setWidth( int width ) +{ + penWidth = width; +} + +/** Draws the object to the specified painter & x/y offsets */ +void MLineObject::draw( QPainter* p, int xoffset, int yoffset ) +{ + drawBase( p, xoffset, yoffset ); +} + +/** Draws the base object to the specified painter & x/y offsets */ +void MLineObject::drawBase( QPainter* p, int xoffset, int yoffset ) +{ + QPen linePen( penColor, penWidth, ( QPen::PenStyle ) penStyle ); + + // Set the offsets + int xcalc1 = xpos1 + xoffset; + int ycalc1 = ypos1 + yoffset; + int xcalc2 = xpos2 + xoffset; + int ycalc2 = ypos2 + yoffset; + + // Draw the line + p->setPen( linePen ); + p->drawLine( xcalc1, ycalc1, xcalc2, ycalc2 ); +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MLineObject::copy( const MLineObject* mLineObject ) +{ + // Copy the object's geometry + xpos1 = mLineObject->xpos1; + ypos1 = mLineObject->ypos1; + xpos2 = mLineObject->xpos2; + ypos2 = mLineObject->ypos2; + + // copy the object's attributes + penWidth = mLineObject->penWidth; + penColor = mLineObject->penColor; + penStyle = mLineObject->penStyle; +} + +} diff --git a/kugar/lib/mlineobject.h b/kugar/lib/mlineobject.h new file mode 100644 index 00000000..f3260ddd --- /dev/null +++ b/kugar/lib/mlineobject.h @@ -0,0 +1,83 @@ +/*************************************************************************** + mlineobject.h - Kugar report line object + ------------------- + begin : Wed Feb 23 2000 + copyright : (C) 2000 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MLINEOBJECT_H +#define MLINEOBJECT_H + +#include <qobject.h> +#include <qpainter.h> +#include <qpaintdevice.h> +#include <qcolor.h> + +/**Kugar report line object + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MLineObject : public QObject +{ + +public: + /** Line style constants */ + enum Style { NoPen = 0, SolidLine, DashLine, + DotLine, DashDotLine, DashDotDotLine }; + + /** Constructor */ + MLineObject(); + /** Copy constructor */ + MLineObject( const MLineObject& mLineObject ); + /** Assignment operator */ + MLineObject operator=( const MLineObject& mLineObject ); + /** Destructor */ + virtual ~MLineObject(); + +protected: + /** Object's x start position */ + int xpos1; + /** Object's y start postition */ + int ypos1; + /** Object's x end position */ + int xpos2; + /** Object's y end position */ + int ypos2; + + /** Object's width */ + int penWidth; + /** Object's color */ + QColor penColor; + /** Object's style */ + int penStyle; + +public: + /** Sets the start and end points for the line */ + void setLine( int xStart, int yStart, int xEnd, int yEnd ); + /** Sets the object's width */ + void setWidth( int width ); + /** Sets the object's style */ + void setStyle( int style ); + /** Sets the object's color */ + void setColor( int r, int g, int b ); + /** Draws the object to the specified painter & x/y offsets */ + virtual void draw( QPainter* p, int xoffset, int yoffset ); + +protected: + /** Draws the object to the specified painter & x/y offsets */ + void drawBase( QPainter* p, int xoffset, int yoffset ); + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MLineObject* mLineObject ); +}; + +} + +#endif diff --git a/kugar/lib/mpagecollection.cpp b/kugar/lib/mpagecollection.cpp new file mode 100644 index 00000000..3359f4b4 --- /dev/null +++ b/kugar/lib/mpagecollection.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + mpagecollection.cpp - Kugar report page collection + ------------------- + begin : Fri Aug 20 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#include "mpagecollection.h" +#include "mreportengine.h" + +#include <kdebug.h> + +namespace Kugar +{ + +/** Constructor */ +MPageCollection::MPageCollection( QObject *parent ) : QObject( parent ) +{ + // Set page list to AutoDelete + pages.setAutoDelete( true ); + + // Set the metrics + size = MReportEngine::Letter; + orientation = MReportEngine::Portrait; + dimensions.setWidth( 0 ); + dimensions.setHeight( 0 ); + m_ref = 1; +} + +/** Copy constructor */ +MPageCollection::MPageCollection( const MPageCollection& mPageCollection ) /*: QObject((QObject &) mPageCollection)*/ +{ + copy( &mPageCollection ); +} + +/** Assignment operator */ +MPageCollection MPageCollection::operator=( const MPageCollection& mPageCollection ) +{ + if ( &mPageCollection == this ) + return * this; + + // Copy the derived class's data + copy( &mPageCollection ); + + // Copy the base class's data + //((QObject &) *this) = mPageCollection; + + return *this; +} + +/** Destructor */ +MPageCollection::~MPageCollection() +{ + pages.clear(); + kdDebug(31000) << k_funcinfo << endl; +} + +/** Clears the page collection */ +void MPageCollection::clear() +{ + pages.clear(); +} + +/** Appends a new page to the page collection */ +void MPageCollection::appendPage() +{ + pages.append( new QPicture() ); +} + +/** Gets the current page in the page collection, + * the current page may be null + */ +QPicture* MPageCollection::getCurrentPage() +{ + return pages.current(); +} + +/** Gets the first page in the page collection, + * returns NULL if the list is empty + */ +QPicture* MPageCollection::getFirstPage() +{ + return pages.first(); +} + +/** Gets the next page in the page collection, + * returns NULL if the end of the list has been reached + */ +QPicture* MPageCollection::getNextPage() +{ + return pages.next(); +} + +/** Get the previous page in the page collection, + * returns NULL if the beginning of the list has been reached + */ +QPicture* MPageCollection::getPreviousPage() +{ + return pages.prev(); +} + +/** Gets the last page in the page collection, + * returns NULL if the list is empty + */ +QPicture* MPageCollection::getLastPage() +{ + return pages.last(); +} + +/** Get the index of the current page */ +int MPageCollection::getCurrentIndex() +{ + return pages.at(); +} + +/** Set the current page to page at idx */ +void MPageCollection::setCurrentPage( int idx ) +{ + pages.at( idx ); +} + +/** Sets the page size */ +void MPageCollection::setPageSize( int s ) +{ + size = s; +} + +/** Sets the page orientation */ +void MPageCollection::setPageOrientation( int o ) +{ + orientation = o; +} + +/** Sets the page dimensions */ +void MPageCollection::setPageDimensions( QSize dim ) +{ + dimensions = dim; +} + +/** Returns the page size */ +int MPageCollection::pageSize() +{ + return size; +} + +/** Returns the page orientation */ +int MPageCollection::pageOrientation() +{ + return orientation; +} + +/** Returns the page dimensions */ +QSize MPageCollection::pageDimensions() +{ + return dimensions; +} + +/** Returns the number of pages in the page collection */ +int MPageCollection::pageCount() +{ + return pages.count(); +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MPageCollection::copy( const MPageCollection* mPageCollection ) +{ + // Copy the page collection + pages = mPageCollection->pages; + + // Copy the page metrics + dimensions = mPageCollection->dimensions; + size = mPageCollection->size; + orientation = mPageCollection->orientation; + m_ref = 1; +} + +void MPageCollection::addRef() +{ + m_ref++; +} +void MPageCollection::removeRef() +{ + m_ref--; + if ( !m_ref ) + deleteLater(); +} + +} diff --git a/kugar/lib/mpagecollection.h b/kugar/lib/mpagecollection.h new file mode 100644 index 00000000..8b1c84aa --- /dev/null +++ b/kugar/lib/mpagecollection.h @@ -0,0 +1,108 @@ +/*************************************************************************** + mpagecollection.h - Kugar report page collection + ------------------- + begin : Fri Aug 20 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MPAGECOLLECTION_H +#define MPAGECOLLECTION_H + +#include <qobject.h> +#include <qptrlist.h> +#include <qpicture.h> +#include <qsize.h> + +/**Kugar report page collection + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MPageCollection : public QObject +{ + +public: + /** Constructor */ + MPageCollection( QObject *parent ); + /** Copy constructor */ + MPageCollection( const MPageCollection& mPageCollection ); + /** Assignment operator */ + MPageCollection operator=( const MPageCollection& mPageCollection ); + /** Destructor */ + virtual ~MPageCollection(); + +private: + /** The report page list */ + QPtrList<QPicture> pages; + /** Page dimensions */ + QSize dimensions; + /** Page size */ + int size; + /** Page orientation */ + int orientation; + +public: + /** Clears the page collection */ + void clear(); + + /** Appends a new page to the page collection */ + void appendPage(); + + /** Gets the current page in the page collection, + * the current page may be null + */ + QPicture* getCurrentPage(); + /** Gets the first page in the page collection, + * returns NULL if the list is empty + */ + QPicture* getFirstPage(); + /** Get the previous page in the page collection, + * returns NULL if the beginning of the list has been reached + */ + QPicture* getPreviousPage(); + /** Gets the next page in the page collection, + * returns NULL if the end of the list has been reached + */ + QPicture* getNextPage(); + /** Gets the last page in the page collection, + * returns NULL if the list empty + */ + QPicture* getLastPage(); + + /** Get the index of the current page */ + int getCurrentIndex(); + /** Set the current page to page at idx */ + void setCurrentPage( int idx ); + + /** Sets the page size */ + void setPageSize( int s ); + /** Sets the page orientation */ + void setPageOrientation( int o ); + /** Sets the page dimensions */ + void setPageDimensions( QSize dim ); + /** Returns the page size */ + int pageSize(); + /** Returns the page orientation */ + int pageOrientation(); + /** Returns the page dimensions */ + QSize pageDimensions(); + /** Returns the number of pages in the page collection */ + int pageCount(); + + void addRef(); + void removeRef(); + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MPageCollection* mPageCollection ); + int m_ref; +}; + +} + +#endif diff --git a/kugar/lib/mpagedisplay.cpp b/kugar/lib/mpagedisplay.cpp new file mode 100644 index 00000000..c3a5d587 --- /dev/null +++ b/kugar/lib/mpagedisplay.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + mpagedisplay.cpp - Kugar page display widget + ------------------- + begin : Sun Aug 15 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#include "mpagedisplay.h" + +namespace Kugar +{ + +/** Constructor */ +MPageDisplay::MPageDisplay( QWidget *parent, const char *name ) : QWidget( parent, name ) +{ + buffer.resize( 1, 1 ); +} + +/** Destructor */ +MPageDisplay::~MPageDisplay() +{} + +/** Sets the report page image */ +void MPageDisplay::setPage( QPicture* image ) +{ + buffer.fill( white ); + QPainter p( &buffer ); + image->play( &p ); +} + +/** Display object's paint event */ +void MPageDisplay::paintEvent( QPaintEvent* event ) +{ + bitBlt( this, 0, 0, &buffer ); +} + +/** Sets the page display dimensions */ +void MPageDisplay::setPageDimensions( QSize size ) +{ + buffer.resize( size ); + resize( size ); +} + + +// Return the preferred size of the display. + +QSize MPageDisplay::sizeHint() const +{ + return buffer.size(); +} + + +// Return the size policy. + +QSizePolicy MPageDisplay::sizePolicy() const +{ + return QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ); +} + +} + +#include "mpagedisplay.moc" diff --git a/kugar/lib/mpagedisplay.h b/kugar/lib/mpagedisplay.h new file mode 100644 index 00000000..ffaa4921 --- /dev/null +++ b/kugar/lib/mpagedisplay.h @@ -0,0 +1,55 @@ +/*************************************************************************** + mpagedisplay.h - Kugar page display widget + ------------------- + begin : Sun Aug 15 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MPAGEDISPLAY_H +#define MPAGEDISPLAY_H + +#include <qwidget.h> +#include <qpainter.h> +#include <qpixmap.h> +#include <qpicture.h> +#include <qsize.h> + +/**Kugar page display widget + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MPageDisplay : public QWidget +{ + Q_OBJECT +public: + /** Constructor */ + MPageDisplay( QWidget *parent = 0, const char *name = 0 ); + /** Destructor */ + virtual ~MPageDisplay(); + +private: + /** Page Widget's image buffer */ + QPixmap buffer; + +public: + /** Sets the page image */ + void setPage( QPicture* image ); + /** Sets the page display dimensions */ + void setPageDimensions( QSize size ); + + QSize sizeHint() const; + QSizePolicy sizePolicy() const; + +protected: + /** Page widget's's paint event */ + void paintEvent( QPaintEvent* event ); + +}; + +} + +#endif diff --git a/kugar/lib/mreportdetail.cpp b/kugar/lib/mreportdetail.cpp new file mode 100644 index 00000000..6fa4bc53 --- /dev/null +++ b/kugar/lib/mreportdetail.cpp @@ -0,0 +1,123 @@ +/*************************************************************************** + mreportdetail.cpp - Kugar report detail section + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#include "mreportdetail.h" + +namespace Kugar +{ + +/** Constructor */ +MReportDetail::MReportDetail() : MReportSection() +{ + // Set the label list to AutoDelete + fields.setAutoDelete( true ); +} + +/** Copy constructor */ +MReportDetail::MReportDetail( const MReportDetail& mReportDetail ) : MReportSection( ( MReportSection & ) mReportDetail ) +{ + copy( &mReportDetail ); +} + +/** Assignment operator */ +MReportDetail MReportDetail::operator=( const MReportDetail& mReportDetail ) +{ + if ( &mReportDetail == this ) + return * this; + + // Copy the derived class's data + copy( &mReportDetail ); + + // Copy the base class's data + ( ( MReportSection & ) * this ) = mReportDetail; + + return *this; +} + +/** Destructor */ +MReportDetail::~MReportDetail() +{ + clear(); +} + +/** Frees all resources allocated by the report section */ +void MReportDetail::clear() +{ + // Free the base resources + clearBase(); + + // Clear the field collection + fields.clear(); +} + +void MReportDetail::setRepeat( bool b ) +{ + repeat = b; +} + +bool MReportDetail::getRepeat() const +{ + return repeat; +} + +/** Draws the detail section to the selected painter & x/y-offsets */ +void MReportDetail::draw( QPainter* p, int xoffset, int yoffset ) +{ + MFieldObject * field; + + // Set the offsets + int xcalc = xoffset; + int ycalc = yoffset; + + // Draw the base objects + drawObjects( p, xoffset, yoffset ); + + // Draw the field collection + for ( field = fields.first(); field != 0; field = fields.next() ) + { + field->draw( p, xcalc, ycalc ); + } +} + +/** Adds a new field object to the section's field collection */ +void MReportDetail::addField( MFieldObject* field ) +{ + fields.append( field ); +} + +/** Sets the data for the field at the specified index */ +void MReportDetail::setFieldData( int idx, QString data ) +{ + MFieldObject * field = fields.at( idx ); + + field->setText( data ); +} + +/** Returns the number of fields in the detail section */ +int MReportDetail::getFieldCount() +{ + return fields.count(); +} + +/** Returns the name of the bound field for field object at the given index */ +QString MReportDetail::getFieldName( int idx ) +{ + MFieldObject * field = fields.at( idx ); + + return field->getFieldName(); +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MReportDetail::copy( const MReportDetail* mReportDetail ) +{ + // Copy the field list + fields = mReportDetail->fields; +} + +} diff --git a/kugar/lib/mreportdetail.h b/kugar/lib/mreportdetail.h new file mode 100644 index 00000000..ee2e9222 --- /dev/null +++ b/kugar/lib/mreportdetail.h @@ -0,0 +1,89 @@ +/*************************************************************************** + mreportdetail.h - Kugar report detail section + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MREPORTDETAIL_H +#define MREPORTDETAIL_H + +#include "mfieldobject.h" +#include "mreportsection.h" + +/**Kugar report detail section + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MReportDetail : public MReportSection +{ + +public: + /** Constructor */ + MReportDetail(); + /** Copy constructor */ + MReportDetail( const MReportDetail& mReportDetail ); + /** Assignment operator */ + MReportDetail operator=( const MReportDetail& mReportDetail ); + /** Destructor */ + virtual ~MReportDetail(); + +protected: + /** Sections's repeat on new pages */ + bool repeat; + /** Section's field collection */ + QPtrList<MFieldObject> fields; + +public: + /** Sets whether to repeat the detail on new pages */ + void setRepeat( bool b ); + /** Sets whether to repeat the detail on new pages */ + bool getRepeat() const; + /** Draws the detail section to the specified painter & x/y-offsets */ + void draw( QPainter* p, int xoffset, int yoffset ); + /** Adds a new field object to the section's field collection */ + void addField( MFieldObject* field ); + /** Sets the data for the field at the specified index */ + void setFieldData( int idx, QString data ); + /** Returns the number of fields in the detail section */ + int getFieldCount(); + /** Returns the name of the bound field for field object at the given index */ + QString getFieldName( int idx ); + /** Frees all resources allocated by the report section */ + void clear(); + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MReportDetail* mReportDetail ); + +}; + +} + +#endif + + + + + + + + + + + + + + + + + + + + diff --git a/kugar/lib/mreportengine.cpp b/kugar/lib/mreportengine.cpp new file mode 100644 index 00000000..fd4a2ce2 --- /dev/null +++ b/kugar/lib/mreportengine.cpp @@ -0,0 +1,1081 @@ +/*************************************************************************** + mreportengine.cpp - Kugar report engine + ------------------- + begin : Sun Aug 15 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#include <qfile.h> +#include <qprinter.h> + +#include "mreportengine.h" +#include "mutil.h" + +#include <kdebug.h> + +#include <math.h> + +namespace Kugar +{ + +/** Constructor */ +MReportEngine::MReportEngine() : QObject() +{ + // Set page params + m_pageCollection = 0; + m_needRegeneration = true; + m_refCount = 1; + pageSize = MReportEngine::Letter; + pageOrientation = MReportEngine::Portrait; + topMargin = 0; + bottomMargin = 0; + leftMargin = 0; + rightMargin = 0; + heightOfDetails = 0; + widthDelta = 1; + heightDelta = 1; + + // Set cancel flag + cancelRender = false; + + // Set the grand total list to AutoDelete + grandTotal.setAutoDelete( true ); + // Set the details lists to AutoDelete + dHeaders.setAutoDelete( true ); + details.setAutoDelete( true ); + dFooters.setAutoDelete( true ); + + rHeader.setPrintFrequency( MReportSection::FirstPage ); + pHeader.setPrintFrequency( MReportSection::EveryPage ); + pFooter.setPrintFrequency( MReportSection::EveryPage ); + rFooter.setPrintFrequency( MReportSection::LastPage ); + + // Set the default page metrics + QSize ps = getPageMetrics( pageSize, pageOrientation ); + pageWidth = ps.width(); + pageHeight = ps.height(); +} + +/** Copy constructor */ +MReportEngine::MReportEngine( const MReportEngine& mReportEngine ) /*: QObject((QObject &) mReportEngine)*/ +{ + copy( &mReportEngine ); +} + +/** Assignment operator */ +MReportEngine MReportEngine::operator=( const MReportEngine& mReportEngine ) +{ + if ( &mReportEngine == this ) + return * this; + + // Copy the derived class's data + copy( &mReportEngine ); + + // Copy the base class's data + //((QObject &) *this) = mReportEngine; + + return *this; +} + +/** Destructor */ +MReportEngine::~MReportEngine() +{ + // Clear the grand total data + grandTotal.clear(); + kdDebug( 31000 ) << k_funcinfo << endl; +} + +void MReportEngine::addRef() +{ + m_refCount++; +} + +void MReportEngine::removeRef() +{ + m_refCount--; + if ( !m_refCount ) + deleteLater(); +} + +/** Clears report formatting */ +void MReportEngine::clearFormatting() +{ + rHeader.clear(); + pHeader.clear(); + dHeaders.clear(); + details.clear(); + dFooters.clear(); + pFooter.clear(); + rFooter.clear(); +} + + +//Set the report data from an existing QDomDocument +bool MReportEngine::setReportData( const QDomDocument &data ) +{ + rd = data.cloneNode( true ).toDocument(); + initData(); + + return true; +} + + +// Set the report's data from an inline string. Return true if it was valid +// data. + +bool MReportEngine::setReportData( const QString &data ) +{ + + if ( !rd.setContent( data ) ) + { + kdDebug() << "Unable to parse report data" << endl; + return false; + } + initData(); + + return true; +} + + +// Set the report's data from an i/o device. Return true if it was valid data. + +bool MReportEngine::setReportData( QIODevice *dev ) +{ + if ( !rd.setContent( dev ) ) + { + kdDebug() << "Unable to parse report data" << endl; + return false; + } + initData(); + + return true; +} + + +// Initialise after reading a report's data. + +void MReportEngine::initData() +{ + m_needRegeneration = true; + // Get the record set (we assume there is only one). + + for ( QDomNode n = rd.firstChild(); !n.isNull(); n = n.nextSibling() ) + if ( n.nodeName() == "KugarData" ) + { + // Get the records. + + records = n.childNodes(); + + // See if there is a prefered template given. + + QDomNamedNodeMap attr = n.attributes(); + QDomNode tempattr = attr.namedItem( "Template" ); + QString tempname = tempattr.nodeValue(); + + if ( !tempname.isNull() ) + emit preferedTemplate( tempname ); + + break; + } +} + + +// Set the report's template from an inline string. Return true if it was a +// valid template. + +bool MReportEngine::setReportTemplate( const QString &tpl ) +{ + clearFormatting(); + + if ( !rt.setContent( tpl ) ) + { + kdDebug() << "Unable to parse report template" << endl; + return false; + } + + initTemplate(); + + return true; +} + + +// Set the report's template from an i/o device. Return true if it was a valid +// template. + +bool MReportEngine::setReportTemplate( QIODevice *dev ) +{ + clearFormatting(); + + if ( !rt.setContent( dev ) ) + { + kdDebug() << "Unable to parse report template" << endl; + return false; + } + + initTemplate(); + + return true; +} + + +/** Cancels rendering of a report */ +void MReportEngine::slotCancelRendering() +{ + cancelRender = true; +} + +/** Finds the detail header object, which is apropriate for the given level */ +MReportSection *MReportEngine::findDetailHeader( int level ) +{ + MReportSection * sec; + for ( sec = dHeaders.first(); sec; sec = dHeaders.next() ) + { + if ( sec->getLevel() == level ) + return sec; + } + return NULL; +} + +/** Finds the detail object, which is apropriate for the given level */ +MReportDetail *MReportEngine::findDetail( int level ) +{ + MReportDetail * sec; + for ( sec = details.first(); sec; sec = details.next() ) + { + if ( sec->getLevel() == level ) + return sec; + } + return NULL; +} + +/** Finds the detail footer object, which is apropriate for the given level */ +MReportSection *MReportEngine::findDetailFooter( int level ) +{ + MReportSection * sec; + for ( sec = dFooters.first(); sec; sec = dFooters.next() ) + { + if ( sec->getLevel() == level ) + return sec; + } + return NULL; +} + +/** Renders the report as a page collection - the caller + * is responsible for de-allocating the returned + * collection + */ +MPageCollection* MReportEngine::renderReport() +{ + if ( !m_needRegeneration ) + return m_pageCollection; + if ( m_pageCollection ) + { + m_pageCollection->deleteLater(); + m_pageCollection = 0; + } + + unsigned int j; + unsigned int i; + + // Set cancel flag + cancelRender = false; + + // Create the page collection + MPageCollection* pages = new MPageCollection( this ); + + // Initialize the basic page data + currHeight = pageHeight - ( topMargin + bottomMargin + pFooter.getHeight() ); + currPage = 0; + currDate = QDate::currentDate(); + + // Initialise global report variables + unsigned int rowCount = records.length(); + for ( j = 0; j < rowCount; j++ ) + { + QDomNode record = records.item( j ); + if ( ( record.nodeType() == QDomNode::ElementNode ) + && ( record.nodeName() == "Var" ) ) + { + // Process the variable ... + QDomNamedNodeMap fields = record.attributes(); + for ( int k = 0; k < fields.count(); ++k ) + { + rHeader.setFieldData( fields.item( k ).nodeName(), fields.item( k ).nodeValue() ); + rFooter.setFieldData( fields.item( k ).nodeName(), fields.item( k ).nodeValue() ); + pHeader.setFieldData( fields.item( k ).nodeName(), fields.item( k ).nodeValue() ); + pFooter.setFieldData( fields.item( k ).nodeName(), fields.item( k ).nodeValue() ); + } + } + } + + // Initialize the grand total array + grandTotal.clear(); + for ( int i = 0; i < rFooter.getCalcFieldCount(); i++ ) + grandTotal.append( new QMemArray<double> ); + + // Create the first page + startPage( pages ); + + // Draw the detail section by looping through all the records + int chkRow = 0; + int curDetailLevel = 0; + int prevDetailLevel = -1; + int curDetailHeader = -1; + int curDetailFooter = -1; + + for ( j = 0; j < rowCount; j++ ) + { + QString detailValue; + QDomNode record = records.item( j ); + + if ( ( record.nodeType() == QDomNode::ElementNode ) + && ( record.nodeName() == "Row" ) ) + { + // Update status event + if ( ( chkRow = ( j / 2 ) % 20 ) == 0 ) + emit signalRenderStatus( j / 2 ); + + // Check for cancel action + if ( cancelRender ) + { + p.end(); + delete pages; + return 0; + } + + // Process the record ... + QDomNamedNodeMap fields = record.attributes(); + + // Find the detail object to process with rendering + detailValue = fields.namedItem( "level" ).nodeValue(); + curDetailLevel = detailValue.toInt(); + + // Reset the header/footer detail levels? + curDetailHeader = curDetailLevel > curDetailHeader ? -1 : curDetailHeader; + curDetailFooter = curDetailLevel > curDetailFooter ? -1 : curDetailFooter; + + // Draw detail footer if appropriate + if ( curDetailLevel <= prevDetailLevel ) + { + // Draw footer for previous detail levels + // from prevDetailLevel up to curDetailLevel + // Draw footer for current detail level + for ( int i = prevDetailLevel; i >= curDetailLevel; i-- ) + { + MReportSection *footer = findDetailFooter( i ); + if ( footer ) + { + footer->setPageNumber( currPage ); + footer->setReportDate( currDate ); + footer->setCalcFieldData( &grandTotal ); + if ( ( currY + footer->getHeight() ) > currHeight ) + { + newPage( pages ); + } + footer->draw( &p, leftMargin, currY ); + currY += footer->getHeight(); + } + } + } + + MReportDetail *detail = findDetail( detailValue.toInt() ); + detail->setPageNumber( currPage ); + detail->setReportDate( currDate ); + + int headerHeight = 0; + MReportSection * header = findDetailHeader( curDetailLevel ); + if ( header && curDetailHeader != curDetailLevel ) + headerHeight = header->getHeight(); + + bool repeating = ( currY + detail->getHeight() + headerHeight ) > currHeight || + ( detail->getRepeat() && currY + heightOfDetails > currHeight ); + if ( repeating ) + { + newPage( pages ); + + MReportDetail *sec; + for ( sec = details.first(); sec; sec = details.next() ) + { + if ( sec->getLevel() != curDetailLevel && sec->getRepeat() ) + { + sec->draw( &p, leftMargin, currY ); + currY += sec->getHeight(); + } + } + } + + // Draw detail header for level curDetailLevel + // if it hasn't already been drawn + if ( curDetailHeader != curDetailLevel || repeating ) + { + MReportSection * header = findDetailHeader( curDetailLevel ); + if ( header ) + { + header->setPageNumber( currPage ); + header->setReportDate( currDate ); + if ( ( currY + header->getHeight() ) > currHeight ) + { + newPage( pages ); + } + header->draw( &p, leftMargin, currY ); + currY += header->getHeight(); + curDetailHeader = curDetailLevel; + } + } + + unsigned int fieldCount = detail->getFieldCount(); + for ( i = 0; i < fieldCount; i++ ) + { + // Get the field value + detailValue = fields.namedItem( detail->getFieldName( i ) ).nodeValue(); + // Set the field + detail->setFieldData( i, detailValue ); + // Set the grand total data + int calcIdx = rFooter.getCalcFieldIndex( detail->getFieldName( i ) ); + if ( calcIdx != -1 ) + { + int vsize = grandTotal.at( calcIdx ) ->size(); + grandTotal.at( calcIdx ) ->resize( vsize + 1 ); + grandTotal.at( calcIdx ) ->at( vsize ) = detailValue.toDouble(); + } + } + + detail->draw( &p, leftMargin, currY ); + currY += detail->getHeight(); + prevDetailLevel = curDetailLevel; + } + } + + // Draw detail footers that were not drawn before + // for details from curDetailLevel up to prevDetailLevel + for ( int i = prevDetailLevel; i >= 0; i-- ) + { + MReportSection *footer = findDetailFooter( i ); + if ( footer ) + { + footer->setPageNumber( currPage ); + footer->setReportDate( currDate ); + footer->setCalcFieldData( &grandTotal ); + if ( ( currY + footer->getHeight() ) > currHeight ) + { + newPage( pages ); + } + + footer->draw( &p, leftMargin, currY ); + currY += footer->getHeight(); + } + } + + // Finish the last page of the report + endPage( pages ); + + // Destroy the page painter + p.end(); + + // Set the page collection attributes + pages->setPageDimensions( QSize( pageWidth, pageHeight ) ); + pages->setPageSize( pageSize ); + pages->setPageOrientation( pageOrientation ); + + // Send final status + emit signalRenderStatus( rowCount / 2 ); + m_needRegeneration = false; + m_pageCollection = pages; + return pages; +} + +/** Starts a new page of the report */ +void MReportEngine::startPage( MPageCollection* pages ) +{ + // Set the current y pos + currY = topMargin; + + // Create a new page + pages->appendPage(); + // Increment the page count + currPage++; + + // Set the page painter to the current page + p.begin( pages->getCurrentPage() ); + + // Draw the report header + drawReportHeader( pages ); + // Draw the page header + drawPageHeader( pages ); +} + +/** Finishes the current page of the report */ +void MReportEngine::endPage( MPageCollection* pages ) +{ + // Draw the report footer + drawReportFooter( pages ); + // Draw the page footer + drawPageFooter( pages ); +} + +/** Finishes the current page and adds a new page */ +void MReportEngine::newPage( MPageCollection* pages ) +{ + // Draw the page footer + drawPageFooter( pages ); + + // Stop the painter + p.end(); + + // Start a new page + startPage( pages ); +} + +/** Draws the report header object to the current page */ +void MReportEngine::drawReportHeader( MPageCollection* pages ) +{ + if ( rHeader.getHeight() == 0 ) + return ; + + if ( ( rHeader.printFrequency() == MReportSection::FirstPage && currPage == 1 ) + || ( rHeader.printFrequency() == MReportSection::EveryPage ) ) + { + + rHeader.setPageNumber( currPage ); + rHeader.setReportDate( currDate ); + rHeader.draw( &p, leftMargin, currY ); + currY += rHeader.getHeight(); + } +} + +/** Draws the page header to the current page */ +void MReportEngine::drawPageHeader( MPageCollection* pages ) +{ + if ( pHeader.getHeight() == 0 ) + return ; + + if ( ( currY + pHeader.getHeight() ) > currHeight ) + newPage( pages ); + + if ( ( pHeader.printFrequency() == MReportSection::FirstPage && currPage == 1 ) + || ( pHeader.printFrequency() == MReportSection::EveryPage ) ) + { + + pHeader.setPageNumber( currPage ); + pHeader.setReportDate( currDate ); + pHeader.draw( &p, leftMargin, currY ); + currY += pHeader.getHeight(); + } +} + +/** Draws the page footer to the current page */ +void MReportEngine::drawPageFooter( MPageCollection* pages ) +{ + if ( pFooter.getHeight() == 0 ) + return ; + + if ( ( pFooter.printFrequency() == MReportSection::FirstPage && currPage == 1 ) + || ( pFooter.printFrequency() == MReportSection::EveryPage ) ) + { + + pFooter.setPageNumber( currPage ); + pFooter.setReportDate( currDate ); + pFooter.draw( &p, leftMargin, ( pageHeight - bottomMargin ) - pFooter.getHeight() ); + currY += pFooter.getHeight(); + } +} + +/** Draws the report footer to the current page */ +void MReportEngine::drawReportFooter( MPageCollection* pages ) +{ + if ( rFooter.getHeight() == 0 ) + return ; + + if ( ( currY + rFooter.getHeight() ) > currHeight ) + newPage( pages ); + + if ( ( rFooter.printFrequency() == MReportSection::EveryPage ) + || ( rFooter.printFrequency() == MReportSection::LastPage ) ) + { + + rFooter.setCalcFieldData( &grandTotal ); + + rFooter.setPageNumber( currPage ); + rFooter.setReportDate( currDate ); + rFooter.draw( &p, leftMargin, currY ); + currY += rFooter.getHeight(); + } +} + +/** Gets the metrics for the selected page size & orientation */ +QSize MReportEngine::getPageMetrics( int size, int orientation ) +{ + + QPrinter * printer; + QSize ps; + + // Set the page size + printer = new QPrinter(); + printer->setFullPage( true ); + printer->setPageSize( ( QPrinter::PageSize ) size ); + printer->setOrientation( ( QPrinter::Orientation ) orientation ); + + // Get the page metrics + QPaintDeviceMetrics pdm( printer ); + + // Display the first page of the report + ps.setWidth( pdm.width() ); + ps.setHeight( pdm.height() ); + + delete printer; + + return ps; +} + + +/** +This recalculates report dimensions to 96 dpi, standard on Windows +platform. + +FIXME: TODO: get the proper screen resolution and not hardcode 96dpi +FIXME: TODO: make this function work on X11 too +*/ +void MReportEngine::recalcDimensions() +{ + QDomNode report; + QDomNode child; + for ( report = rt.firstChild(); !report.isNull(); report = report.nextSibling() ) + if ( report.nodeName() == "KugarTemplate" ) + break; + + QDomNamedNodeMap rattributes = report.attributes(); + recalcAttribute( "BottomMargin", rattributes ); + recalcAttribute( "TopMargin", rattributes ); + recalcAttribute( "LeftMargin", rattributes ); + recalcAttribute( "RightMargin", rattributes ); + + QDomNodeList children = report.childNodes(); + int childCount = children.length(); + + for ( int j = 0; j < childCount; j++ ) + { + child = children.item( j ); + QDomNamedNodeMap attributes = child.attributes(); + + QDomNodeList children2 = child.childNodes(); + int childCount2 = children2.length(); + recalcAttribute( "Height", attributes ); + + for ( int k = 0; k < childCount2; k++ ) + { + QDomNode child2 = children2.item( k ); + QDomNamedNodeMap attributes = child2.attributes(); + recalcAttribute( "X", attributes ); + recalcAttribute( "Y", attributes ); + recalcAttribute( "Width", attributes ); + recalcAttribute( "Height", attributes ); + recalcAttribute( "X1", attributes ); + recalcAttribute( "X2", attributes ); + recalcAttribute( "Y1", attributes ); + recalcAttribute( "Y2", attributes ); + } + } + +} + +void MReportEngine::recalcAttribute( const QString& name, QDomNamedNodeMap attributes ) +{ + if ( !attributes.namedItem( name ).isNull() ) + { + attributes.namedItem( name ).setNodeValue( QString( "%1" ).arg( attributes.namedItem( name ).nodeValue().toInt() * 93 / 81 ) ); + } +} + +/** Walks the document tree, setting the report layout */ +void MReportEngine::initTemplate() +{ + heightOfDetails = 0; + +#ifdef Q_WS_WIN + + recalcDimensions(); +#endif + + QDomNode report; + QDomNode child; + + m_needRegeneration = true; + // Get the report - assume there is only one. + + for ( report = rt.firstChild(); !report.isNull(); report = report.nextSibling() ) + if ( report.nodeName() == "KugarTemplate" ) + break; + + setReportAttributes( &report ); + + // Get all the child report elements + QDomNodeList children = report.childNodes(); + int childCount = children.length(); + + for ( int j = 0; j < childCount; j++ ) + { + child = children.item( j ); + + if ( child.nodeType() == QDomNode::ElementNode ) + { + // Report Header + if ( child.nodeName() == "ReportHeader" ) + setSectionAttributes( &rHeader, &child ); + else if ( child.nodeName() == "PageHeader" ) + setSectionAttributes( &pHeader, &child ); + else if ( child.nodeName() == "DetailHeader" ) + { + MReportSection * dHeader = new MReportSection; + dHeaders.append( dHeader ); + setDetMiscAttributes( dHeader, &child ); + } + else if ( child.nodeName() == "Detail" ) + setDetailAttributes( &child ); + else if ( child.nodeName() == "DetailFooter" ) + { + MReportSection * dFooter = new MReportSection; + setDetMiscAttributes( dFooter, &child ); + dFooters.append( dFooter ); + } + else if ( child.nodeName() == "PageFooter" ) + setSectionAttributes( &pFooter, &child ); + else if ( child.nodeName() == "ReportFooter" ) + setSectionAttributes( &rFooter, &child ); + } + } +} + +/** Sets the main layout attributes for the report */ +void MReportEngine::setReportAttributes( QDomNode* report ) +{ + // Get the attributes for the report + QDomNamedNodeMap attributes = report->attributes(); + + pageSize = attributes.namedItem( "PageSize" ).nodeValue().toInt(); + pageOrientation = attributes.namedItem( "PageOrientation" ).nodeValue().toInt(); + int templateWidth = attributes.namedItem( "PageWidth" ).nodeValue().toInt(); + int templateheight = attributes.namedItem( "PageHeight" ).nodeValue().toInt(); + + QSize ps = getPageMetrics( pageSize, pageOrientation ); + pageWidth = ps.width(); + pageHeight = ps.height(); + + widthDelta = ( float ) pageWidth / templateWidth; + heightDelta = ( float ) pageHeight / templateheight; + + kdDebug( 30001 ) << "pagewidth: " << pageWidth + << " pageheight: " << pageHeight << "\n" + << "templateWidth: " << templateWidth + << " templateheight: " << templateheight << "\n" + << "widthDelta: " << widthDelta + << " heightDelta: " << heightDelta + << endl; + + topMargin = scaleDeltaHeight( attributes.namedItem( "TopMargin" ).nodeValue().toInt() ); + bottomMargin = scaleDeltaHeight( attributes.namedItem( "BottomMargin" ).nodeValue().toInt() ); + leftMargin = scaleDeltaWidth( attributes.namedItem( "LeftMargin" ).nodeValue().toInt() ); + rightMargin = scaleDeltaWidth( attributes.namedItem( "RightMargin" ).nodeValue().toInt() ); +} + +int MReportEngine::scaleDeltaWidth( int width ) const +{ + float f = width * widthDelta; + return f > 1 ? int( f + 0.5) : ceil( f ); +} + +int MReportEngine::scaleDeltaHeight( int height ) const +{ + float f = height * heightDelta; + return f > 1 ? int( f + 0.5 ) : ceil( f ); +} + +/** Sets the layout attributes for the given report section */ +void MReportEngine::setSectionAttributes( MReportSection* section, QDomNode* report ) +{ + // Get the attributes for the section + QDomNamedNodeMap attributes = report->attributes(); + + // Get the section attributes + section->setHeight( scaleDeltaHeight( attributes.namedItem( "Height" ).nodeValue().toInt() ) ); + section->setPrintFrequency( attributes.namedItem( "PrintFrequency" ).nodeValue().toInt() ); + + // Process the sections labels + QDomNodeList children = report->childNodes(); + int childCount = children.length(); + + // For each label, extract the attr list and add the new label + // to the sections's label collection + for ( int j = 0; j < childCount; j++ ) + { + QDomNode child = children.item( j ); + if ( child.nodeType() == QDomNode::ElementNode ) + { + if ( child.nodeName() == "Line" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MLineObject* line = new MLineObject(); + setLineAttributes( line, &attributes ); + section->addLine( line ); + } + else if ( child.nodeName() == "Label" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MLabelObject* label = new MLabelObject(); + setLabelAttributes( label, &attributes ); + section->addLabel( label ); + } + else if ( child.nodeName() == "Special" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MSpecialObject* field = new MSpecialObject(); + setSpecialAttributes( field, &attributes ); + section->addSpecialField( field ); + } + else if ( child.nodeName() == "CalculatedField" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MCalcObject* field = new MCalcObject(); + setCalculatedFieldAttributes( field, &attributes ); + section->addCalculatedField( field ); + } + else if ( child.nodeName() == "Field" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MFieldObject* field = new MFieldObject(); + setFieldAttributes( field, &attributes ); + section->addField( field ); + } + } + } +} + +/** Sets the layout attributes for the detail headers and footers */ +void MReportEngine::setDetMiscAttributes( MReportSection* section, QDomNode* report ) +{ + // Get the attributes for the section + QDomNamedNodeMap attributes = report->attributes(); + + // Get the section attributes + section->setLevel( attributes.namedItem( "Level" ).nodeValue().toInt() ); + + // Set other section attributes + setSectionAttributes( section, report ); +} + + +/** Sets the layout attributes for the detail section */ +void MReportEngine::setDetailAttributes( QDomNode* report ) +{ + // Get the attributes for the detail section + QDomNamedNodeMap attributes = report->attributes(); + + // Get the report detail attributes + MReportDetail *detail = new MReportDetail; + int height = scaleDeltaHeight( attributes.namedItem( "Height" ).nodeValue().toInt() ); + heightOfDetails += height; + detail->setHeight( height ); + detail->setLevel( attributes.namedItem( "Level" ).nodeValue().toInt() ); + detail->setRepeat( attributes.namedItem( "Repeat" ).nodeValue() == "true" ); + + // Process the report detail labels + QDomNodeList children = report->childNodes(); + int childCount = children.length(); + + for ( int j = 0; j < childCount; j++ ) + { + QDomNode child = children.item( j ); + if ( child.nodeType() == QDomNode::ElementNode ) + { + if ( child.nodeName() == "Line" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MLineObject* line = new MLineObject(); + setLineAttributes( line, &attributes ); + detail->addLine( line ); + } + else if ( child.nodeName() == "Label" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MLabelObject* label = new MLabelObject(); + setLabelAttributes( label, &attributes ); + detail->addLabel( label ); + } + else if ( child.nodeName() == "Special" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MSpecialObject* field = new MSpecialObject(); + setSpecialAttributes( field, &attributes ); + detail->addSpecialField( field ); + } + else if ( child.nodeName() == "Field" ) + { + QDomNamedNodeMap attributes = child.attributes(); + MFieldObject* field = new MFieldObject(); + setFieldAttributes( field, &attributes ); + detail->addField( field ); + } + } + } + // Append a newly created detail to the list + details.append( detail ); +} + +/** Sets a line's layout attributes */ +void MReportEngine::setLineAttributes( MLineObject* line, QDomNamedNodeMap* attr ) +{ + line->setLine( scaleDeltaWidth( attr->namedItem( "X1" ).nodeValue().toInt() ), + scaleDeltaHeight( attr->namedItem( "Y1" ).nodeValue().toInt() ), + scaleDeltaWidth( attr->namedItem( "X2" ).nodeValue().toInt() ), + scaleDeltaHeight( attr->namedItem( "Y2" ).nodeValue().toInt() ) ); + + QString tmp = attr->namedItem( "Color" ).nodeValue(); + + line->setColor( tmp.left( tmp.find( "," ) ).toInt(), + tmp.mid( tmp.find( "," ) + 1, ( tmp.findRev( "," ) - tmp.find( "," ) ) - 1 ).toInt(), + tmp.right( tmp.length() - tmp.findRev( "," ) - 1 ).toInt() ); + + line->setWidth( attr->namedItem( "Width" ).nodeValue().toInt() ); + line->setStyle( attr->namedItem( "Style" ).nodeValue().toInt() ); +} + +/** Sets a label's layout attributes */ +void MReportEngine::setLabelAttributes( MLabelObject* label, QDomNamedNodeMap* attr ) +{ + QString tmp; + + label->setText( attr->namedItem( "Text" ).nodeValue() ); + label->setGeometry( scaleDeltaWidth( attr->namedItem( "X" ).nodeValue().toInt() ), + scaleDeltaHeight( attr->namedItem( "Y" ).nodeValue().toInt() ), + scaleDeltaWidth( attr->namedItem( "Width" ).nodeValue().toInt() ), + scaleDeltaHeight( attr->namedItem( "Height" ).nodeValue().toInt() ) ); + + tmp = attr->namedItem( "BackgroundColor" ).nodeValue(); + label->setBackgroundColor( tmp.left( tmp.find( "," ) ).toInt(), + tmp.mid( tmp.find( "," ) + 1, ( tmp.findRev( "," ) - tmp.find( "," ) ) - 1 ).toInt(), + tmp.right( tmp.length() - tmp.findRev( "," ) - 1 ).toInt() ); + + tmp = attr->namedItem( "ForegroundColor" ).nodeValue(); + label->setForegroundColor( tmp.left( tmp.find( "," ) ).toInt(), + tmp.mid( tmp.find( "," ) + 1, ( tmp.findRev( "," ) - tmp.find( "," ) ) - 1 ).toInt(), + tmp.right( tmp.length() - tmp.findRev( "," ) - 1 ).toInt() ); + + tmp = attr->namedItem( "BorderColor" ).nodeValue(); + label->setBorderColor( tmp.left( tmp.find( "," ) ).toInt(), + tmp.mid( tmp.find( "," ) + 1, ( tmp.findRev( "," ) - tmp.find( "," ) ) - 1 ).toInt(), + tmp.right( tmp.length() - tmp.findRev( "," ) - 1 ).toInt() ); + + label->setBorderWidth( attr->namedItem( "BorderWidth" ).nodeValue().toInt() ); + label->setBorderStyle( attr->namedItem( "BorderStyle" ).nodeValue().toInt() ); + if ( !attr->namedItem( "DrawBottom" ).isNull() ) + label->setDrawBottom( attr->namedItem( "DrawBottom" ).nodeValue() == "true" ); + if ( !attr->namedItem( "DrawTop" ).isNull() ) + label->setDrawTop( attr->namedItem( "DrawTop" ).nodeValue() == "true" ); + if ( !attr->namedItem( "DrawLeft" ).isNull() ) + label->setDrawLeft( attr->namedItem( "DrawLeft" ).nodeValue() == "true" ); + if ( !attr->namedItem( "DrawRight" ).isNull() ) + label->setDrawRight( attr->namedItem( "DrawRight" ).nodeValue() == "true" ); + label->setFont( attr->namedItem( "FontFamily" ).nodeValue(), + attr->namedItem( "FontSize" ).nodeValue().toInt(), + attr->namedItem( "FontWeight" ).nodeValue().toInt(), + ( attr->namedItem( "FontItalic" ).nodeValue().toInt() == 0 ? false : true ) ); + label->setHorizontalAlignment( attr->namedItem( "HAlignment" ).nodeValue().toInt() ); + label->setVerticalAlignment( attr->namedItem( "VAlignment" ).nodeValue().toInt() ); + label->setWordWrap( attr->namedItem( "WordWrap" ).nodeValue().toInt() == 0 ? false : true ); +} + +/** Sets a special field's layout attributes */ +void MReportEngine::setSpecialAttributes( MSpecialObject* field, QDomNamedNodeMap* attr ) +{ + field->setType( attr->namedItem( "Type" ).nodeValue().toInt() ); + field->setDateFormat( attr->namedItem( "DateFormat" ).nodeValue().toInt() ); + + setLabelAttributes( ( MLabelObject * ) field, attr ); +} + +/** Sets a field's layout attributes */ +void MReportEngine::setFieldAttributes( MFieldObject* field, QDomNamedNodeMap* attr ) +{ + field->setFieldName( attr->namedItem( "Field" ).nodeValue() ); + field->setDataType( attr->namedItem( "DataType" ).nodeValue().toInt() ); + field->setDateFormat( attr->namedItem( "DateFormat" ).nodeValue().toInt() ); + field->setPrecision( attr->namedItem( "Precision" ).nodeValue().toInt() ); + field->setCurrency( attr->namedItem( "Currency" ).nodeValue().toInt() ); + field->setCommaSeparator( attr->namedItem( "CommaSeparator" ).nodeValue().toInt() ); + field->setInputMask( attr->namedItem( "InputMask" ).nodeValue() ); + + QString tmp = attr->namedItem( "NegValueColor" ).nodeValue(); + + field->setNegValueColor( tmp.left( tmp.find( "," ) ).toInt(), + tmp.mid( tmp.find( "," ) + 1, ( tmp.findRev( "," ) - tmp.find( "," ) ) - 1 ).toInt(), + tmp.right( tmp.length() - tmp.findRev( "," ) - 1 ).toInt() ); + + setLabelAttributes( ( MLabelObject * ) field, attr ); +} + +/** Sets a calculated field's layout attributes */ +void MReportEngine::setCalculatedFieldAttributes( MCalcObject* field, QDomNamedNodeMap* attr ) +{ + field->setCalculationType( attr->namedItem( "CalculationType" ).nodeValue().toInt() ); + setFieldAttributes( ( MFieldObject * ) field, attr ); +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MReportEngine::copy( const MReportEngine* mReportEngine ) +{ + // Copy document data + m_refCount = 1; + rd = mReportEngine->rd; + rt = mReportEngine->rt; + + // Copy page metrics + pageSize = mReportEngine->pageSize; + pageOrientation = mReportEngine->pageOrientation; + topMargin = mReportEngine->topMargin; + bottomMargin = mReportEngine->bottomMargin; + leftMargin = mReportEngine->leftMargin; + rightMargin = mReportEngine->rightMargin; + pageWidth = mReportEngine->pageWidth; + pageHeight = mReportEngine->pageHeight; + heightOfDetails = mReportEngine->heightOfDetails; + + // Copy the report header + rHeader = mReportEngine->rHeader; + // Copy the page header + pHeader = mReportEngine->pHeader; + // Copy the detail sections + MReportDetail *detail; + QPtrList<MReportDetail> temp = mReportEngine->details; + temp.setAutoDelete( false ); + for ( detail = temp.first(); detail; detail = temp.next() ) + { + MReportDetail * new_detail = new MReportDetail; + *new_detail = *detail; + details.append( new_detail ); + } + // Copy the page footer + pFooter = mReportEngine->pFooter; + // Copy the report footer + rFooter = mReportEngine->rFooter; + + // Copy the rendering state + currY = mReportEngine->currY; + currHeight = mReportEngine->currHeight; + currPage = mReportEngine->currPage; + currDate = mReportEngine->currDate; + cancelRender = mReportEngine->cancelRender; + + // Copy grand totals list + grandTotal = mReportEngine->grandTotal; + m_pageCollection = mReportEngine->m_pageCollection; + m_needRegeneration = mReportEngine->m_needRegeneration; + if ( m_pageCollection ) + m_pageCollection->addRef(); +} + +} + +#include "mreportengine.moc" diff --git a/kugar/lib/mreportengine.h b/kugar/lib/mreportengine.h new file mode 100644 index 00000000..c8280c1d --- /dev/null +++ b/kugar/lib/mreportengine.h @@ -0,0 +1,210 @@ +/*************************************************************************** + mreportengine.h - Kugar report engine + ------------------- + begin : Sun Aug 15 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#ifndef MREPORTENGINE_H +#define MREPORTENGINE_H + +#include <qobject.h> +#include <qpicture.h> +#include <qpaintdevicemetrics.h> +#include <qsize.h> +#include <qmemarray.h> +#include <qdom.h> +#include <qguardedptr.h> + +#include "mlineobject.h" +#include "mlabelobject.h" +#include "mspecialobject.h" +#include "mfieldobject.h" +#include "mreportsection.h" +#include "mreportdetail.h" +#include "mpagecollection.h" + +/**Kugar report engine + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MReportEngine : public QObject +{ + Q_OBJECT + +public: + enum PageOrientation { Portrait, Landscape }; + + enum PageSize { + A4, B5, Letter, Legal, Executive, + A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1, + B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E, + DLE, Folio, Ledger, Tabloid, NPageSize + }; + + MReportEngine(); + MReportEngine( const MReportEngine& mReportEngine ); + MReportEngine operator=( const MReportEngine& mReportEngine ); + virtual ~MReportEngine(); + + bool setReportData( const QString & ); + bool setReportData( QIODevice * ); + bool setReportData( const QDomDocument& ); + bool setReportTemplate( const QString & ); + bool setReportTemplate( QIODevice * ); + int getRenderSteps() + { + return records.length() / 2; + } + MPageCollection* renderReport(); + + void addRef(); + void removeRef(); +public slots: + void slotCancelRendering(); + +signals: + void signalRenderStatus( int ); + void preferedTemplate( const QString & ); + +protected: + void recalcDimensions(); + void recalcAttribute( const QString& name, QDomNamedNodeMap attributes ); + +private: + + MPageCollection *m_pageCollection; + bool m_needRegeneration; + /** Report data document */ + QDomDocument rd; + /** Report template document */ + QDomDocument rt; + + /** Report painter */ + QPainter p; + + /** Report page size */ + int pageSize; + /** Report page orientation */ + int pageOrientation; + /** Report top margin */ + int topMargin; + /** Report top margin */ + int bottomMargin; + /** Report top margin */ + int leftMargin; + /** Report top margin */ + int rightMargin; + + /** Report page width */ + int pageWidth; + /** Report page height */ + int pageHeight; + + float widthDelta; + float heightDelta; + + /** Report header */ + MReportSection rHeader; + /** Page header */ + MReportSection pHeader; + /** Detail headers */ + QPtrList<MReportSection> dHeaders; + /** Detail sections */ + QPtrList<MReportDetail> details; + /** Detail footers */ + QPtrList<MReportSection> dFooters; + /** Page footer */ + MReportSection pFooter; + /** Report footer */ + MReportSection rFooter; + + /** Stores the combined heights of the detail levels */ + int heightOfDetails; + + /** Current y position on page */ + int currY; + /** Current height of page excluding margins */ + int currHeight; + /** Current page number */ + int currPage; + /** Current report date */ + QDate currDate; + + /** Grand total array */ + QPtrList<QMemArray<double> > grandTotal; + + /** Cancel rendering flag */ + bool cancelRender; + int m_refCount; +private: + // The set of records being rendered. + QDomNodeList records; + /** Clears report formatting */ + void clearFormatting(); + /** Starts a new page of the report */ + void startPage( MPageCollection* pages ); + /** Finishes the current page of the report */ + void endPage( MPageCollection* pages ); + /** Finishes the current page and adds a new page */ + void newPage( MPageCollection* pages ); + /** Draws the report header object to the current page */ + void drawReportHeader( MPageCollection* pages ); + /** Draws the page header to the current page */ + void drawPageHeader( MPageCollection* pages ); + /** Draws the page footer to the current page */ + void drawPageFooter( MPageCollection* pages ); + /** Draws the report footer to the current page */ + void drawReportFooter( MPageCollection* pages ); + + /** Gets the metrics for the selected page size */ + QSize getPageMetrics( int size, int orientation ); + + void initData(); + void initTemplate(); + + /** Sets the main layout attributes for the report */ + void setReportAttributes( QDomNode* report ); + + int scaleDeltaWidth( int width ) const; + int scaleDeltaHeight( int width ) const; + + /** Sets the layout attributes for the given report section */ + void setSectionAttributes( MReportSection* section, QDomNode* report ); + /** Sets the layout attributes for the detail headers and footers */ + void setDetMiscAttributes( MReportSection* section, QDomNode* report ); + /** Sets the layout attributes for the detail section */ + void setDetailAttributes( QDomNode* report ); + /** Sets a line's layout attributes */ + void setLineAttributes( MLineObject* line, QDomNamedNodeMap* attr ); + /** Sets a label's layout attributes */ + void setLabelAttributes( MLabelObject* label, QDomNamedNodeMap* attr ); + /** Sets a special field's layout attributes */ + void setSpecialAttributes( MSpecialObject* field, QDomNamedNodeMap* attr ); + /** Sets a field's layout attributes */ + void setFieldAttributes( MFieldObject* field, QDomNamedNodeMap* attr ); + /** Sets a calculated field's layout attributes */ + void setCalculatedFieldAttributes( MCalcObject* field, QDomNamedNodeMap* attr ); + + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MReportEngine* mReportEngine ); + + /** Finds the detail header object, which is apropriate for the given level */ + MReportSection *findDetailHeader( int level ); + /** Finds the detail object, which is apropriate for the given level */ + MReportDetail *findDetail( int level ); + /** Finds the detail footer object, which is apropriate for the given level */ + MReportSection *findDetailFooter( int level ); +}; + +} + +#endif diff --git a/kugar/lib/mreportobject.cpp b/kugar/lib/mreportobject.cpp new file mode 100644 index 00000000..d7e065f5 --- /dev/null +++ b/kugar/lib/mreportobject.cpp @@ -0,0 +1,225 @@ +/*************************************************************************** + mreportobject.cpp - Kugar report object baseclass + ------------------- + begin : Wed Aug 11 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2004 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#include "mreportobject.h" + +namespace Kugar +{ + +/** Constructor */ +MReportObject::MReportObject() : QObject() +{ + // Set the object's default geometry + xpos = 0; + ypos = 0; + width = 40; + height = 23; + + // Set the object's default colors + backgroundColor.setRgb( 255, 255, 255 ); + foregroundColor.setRgb( 0, 0, 0 ); + + // Set the object's default border attributes + borderColor.setRgb( 0, 0, 0 ); + borderWidth = 1; + borderStyle = MReportObject::SolidLine; + + drawLeft = true; + drawRight = true; + drawTop = true; + drawBottom = true; +} + +/** Copy constructor */ +MReportObject::MReportObject( const MReportObject& mReportObject ) /*: QObject((QObject &) mReportObject)*/ +{ + copy( &mReportObject ); +} + +/** Assignment operator */ +MReportObject MReportObject::operator=( const MReportObject& mReportObject ) +{ + if ( &mReportObject == this ) + return * this; + + // Copy the derived class's data + copy( &mReportObject ); + + // Copy the base class's data + //((QObject &) *this) = mReportObject; + + return *this; +} + +/** Destructor */ +MReportObject::~MReportObject() +{} + +/** Draws the object to the specified painter & x/y offsets */ +void MReportObject::draw( QPainter* p, int xoffset, int yoffset ) +{ + drawBase( p, xoffset, yoffset ); +} + +/** Draws the base object to the specified painter & x/y offsets */ +void MReportObject::drawBase( QPainter* p, int xoffset, int yoffset ) +{ + QBrush bgBrush( backgroundColor ); + QPen borderPen( borderColor, borderWidth, ( QPen::PenStyle ) borderStyle ); + + // Set the offsets + int xcalc = xpos + xoffset; + int ycalc = ypos + yoffset; + + // Set background in specified color + p->setBrush( bgBrush ); + p->setPen( Qt::NoPen ); + p->drawRect( xcalc, ycalc, width, height ); + + // Set border + if ( borderStyle != 0 ) + { + p->setPen( borderPen ); + if ( drawLeft ) + p->drawLine( xcalc, ycalc, xcalc, ycalc + height ); + if ( drawRight ) + p->drawLine( xcalc + width, ycalc, xcalc + width, ycalc + height ); + if ( drawTop ) + p->drawLine( xcalc, ycalc, xcalc + width, ycalc ); + if ( drawBottom ) + p->drawLine( xcalc, ycalc + height, xcalc + width, ycalc + height ); + // p->drawRect(xcalc, ycalc, width, height); + } + else + { + p->setPen( QPen( QColor( 255, 255, 255 ), 1, QPen::SolidLine ) ); + p->drawRect( xcalc, ycalc, width, height ); + } +} + +/** Set the object's position and size */ +void MReportObject::setGeometry( int x, int y, int w, int h ) +{ + xpos = x; + ypos = y; + width = w; + height = h; +} + +/** Set the object's position */ +void MReportObject::move( int x, int y ) +{ + xpos = x; + ypos = y; +} + +/** Gets the object's x position */ +int MReportObject::getX() +{ + return xpos; +} + +/** Gets the object's y position */ +int MReportObject::getY() +{ + return ypos; +} + +/** Sets the object's background color */ +void MReportObject::setBackgroundColor( int r, int g, int b ) +{ + backgroundColor.setRgb( r, g, b ); +} + +/** Sets the object's foreground color */ +void MReportObject::setForegroundColor( int r, int g, int b ) +{ + foregroundColor.setRgb( r, g, b ); +} + +/** Sets the object's border color */ +void MReportObject::setBorderColor( int r, int g, int b ) +{ + borderColor.setRgb( r, g, b ); +} + +/** Sets the object's border width */ +void MReportObject::setBorderWidth( int width ) +{ + borderWidth = width; +} + +/** Sets the object's border style */ +void MReportObject::setBorderStyle( int style ) +{ + borderStyle = style; +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MReportObject::copy( const MReportObject* mReportObject ) +{ + // Copy the object's geometry + xpos = mReportObject->xpos; + ypos = mReportObject->ypos; + width = mReportObject->width; + height = mReportObject->height; + + // Copy the colors + backgroundColor = mReportObject->backgroundColor; + foregroundColor = mReportObject->foregroundColor; + + // Copy the border attributes + borderColor = mReportObject->borderColor; + borderWidth = mReportObject->borderWidth; + borderStyle = mReportObject->borderStyle; +} + +bool MReportObject::getDrawLeft( ) +{ + return drawLeft; +} + +bool MReportObject::getDrawRight( ) +{ + return drawRight; +} + +bool MReportObject::getDrawTop( ) +{ + return drawTop; +} + +bool MReportObject::getDrawBottom( ) +{ + return drawBottom; +} + +void MReportObject::setDrawLeft( bool d ) +{ + drawLeft = d; +} + +void MReportObject::setDrawRight( bool d ) +{ + drawRight = d; +} + +void MReportObject::setDrawTop( bool d ) +{ + drawTop = d; +} + +void MReportObject::setDrawBottom( bool d ) +{ + drawBottom = d; +} + +} diff --git a/kugar/lib/mreportobject.h b/kugar/lib/mreportobject.h new file mode 100644 index 00000000..ce28cf75 --- /dev/null +++ b/kugar/lib/mreportobject.h @@ -0,0 +1,127 @@ +/*************************************************************************** + mreportobject.h - Kugar report object baseclass + ------------------- + begin : Wed Aug 11 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2004 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#ifndef MREPORTOBJECT_H +#define MREPORTOBJECT_H + +#include <qobject.h> +#include <qpainter.h> +#include <qpaintdevice.h> +#include <qcolor.h> + +/**Kugar report object baseclass + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MReportObject : public QObject +{ + +public: + /** Border style constants */ + enum BorderStyle { NoPen = 0, SolidLine, DashLine, + DotLine, DashDotLine, DashDotDotLine }; + + /** Constructor */ + MReportObject(); + /** Copy constructor */ + MReportObject( const MReportObject& mReportObject ); + /** Assignment operator */ + MReportObject operator=( const MReportObject& mReportObject ); + /** Destructor */ + virtual ~MReportObject(); + +protected: + /** Object's x position */ + int xpos; + /** Object's y postition */ + int ypos; + /** Object's width */ + int width; + /** Object's height */ + int height; + + /** Object's background color */ + QColor backgroundColor; + /** Object's foreground color */ + QColor foregroundColor; + + /** Object's border color */ + QColor borderColor; + /** Object's border width */ + int borderWidth; + /** Object's border style */ + int borderStyle; + /** Draw left border */ + bool drawLeft; + /** Draw right border */ + bool drawRight; + /** Draw top border */ + bool drawTop; + /** Draw bottom border */ + bool drawBottom; + +public: + /** Draws the object to the specified painter & x/y offsets */ + virtual void draw( QPainter* p, int xoffset, int yoffset ); + /** Sets the object's position and size */ + void setGeometry( int x, int y, int w, int h ); + /** Sets the object's position */ + void move( int x, int y ); + /** Gets the object's x position */ + int getX(); + /** Gets the object's y position */ + int getY(); + /** Sets the object's background color - default is white*/ + void setBackgroundColor( int r, int g, int b ); + /** Sets the object's foreground color - default is black*/ + void setForegroundColor( int r, int g, int b ); + /** Sets the object's border color - default is black*/ + void setBorderColor( int r, int g, int b ); + /** Sets the object's border width - default is 1*/ + void setBorderWidth( int width ); + /** Sets the object's border style - default is SolidLine*/ + void setBorderStyle( int style ); + + /** Gets the draw left border flag */ + bool getDrawLeft(); + /** Gets the draw right border flag */ + bool getDrawRight(); + /** Gets the draw top border flag */ + bool getDrawTop(); + /** Gets the draw bottom border flag */ + bool getDrawBottom(); + + /** Sets the draw left border flag */ + void setDrawLeft( bool d ); + /** Sets the draw right border flag */ + void setDrawRight( bool d ); + /** Sets the draw top border flag */ + void setDrawTop( bool d ); + /** Sets the draw bottom border flag */ + void setDrawBottom( bool d ); + +protected: + /** Draws the base object to the specified painter & x/y offsets */ + void drawBase( QPainter* p, int xoffset, int yoffset ); + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MReportObject* mReportObject ); + +}; + +} + +#endif diff --git a/kugar/lib/mreportsection.cpp b/kugar/lib/mreportsection.cpp new file mode 100644 index 00000000..9712407a --- /dev/null +++ b/kugar/lib/mreportsection.cpp @@ -0,0 +1,326 @@ +/*************************************************************************** + mreportsection.cpp - Kugar report section + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#include "mreportsection.h" +#include "mutil.h" + +namespace Kugar +{ + +/** Constructor */ +MReportSection::MReportSection() +{ + // Set geometry + height = 50; + + // Set print frequency + frequency = MReportSection::EveryPage; + + // Set special field data + reportDate = QDate::currentDate(); + pageNumber = 0; + + // Set the line list to AutoDelete + lines.setAutoDelete( true ); + // Set the label list to AutoDelete + labels.setAutoDelete( true ); + // Set the field list to AutoDelete + fields.setAutoDelete( true ); + // Set the special field list to AutoDelete + specialFields.setAutoDelete( true ); +} + +/** Copy constructor */ +MReportSection::MReportSection( const MReportSection& mReportSection ) /*: QObject((QObject &) mReportSection)*/ +{ + copy( &mReportSection ); +} + +/** Assignment operator */ +MReportSection MReportSection::operator=( const MReportSection& mReportSection ) +{ + if ( &mReportSection == this ) + return * this; + + // Copy the derived class's data + copy( &mReportSection ); + + // Copy the base class's data + //((QObject &) *this) = mReportSection; + + return *this; +} + +/** Destructor */ +MReportSection::~MReportSection() +{ + clear(); +} + +/** Frees all resources allocated by the report section */ +void MReportSection::clear() +{ + clearBase(); +} + +/** Frees base resources allocated by the report section */ +void MReportSection::clearBase() +{ + // Clear the line collection + lines.clear(); + // Clear the label collection + labels.clear(); + // Clear the field collection + fields.clear(); + // Clear the special field collection + specialFields.clear(); + // Clear the calculated field collection + calculatedFields.clear(); +} + +/** Adds a new line object to the section's line collection */ +void MReportSection::addLine( MLineObject* line ) +{ + lines.append( line ); +} + +/** Adds a new label object to the section's label collection */ +void MReportSection::addLabel( MLabelObject* label ) +{ + labels.append( label ); +} + +/** Adds a new field object to the section's label collection */ +void MReportSection::addField( MFieldObject * field ) +{ + fields.append( field ); +} + +/** Adds a new special field object to the section's special field collection */ +void MReportSection::addSpecialField( MSpecialObject* special ) +{ + specialFields.append( special ); +} + +/** Adds a new calculated field object to the section's calculated field collection */ +void MReportSection::addCalculatedField( MCalcObject* calc ) +{ + calculatedFields.append( calc ); +} + +/** Gets the height of the section */ +int MReportSection::getHeight() +{ + return height; +} + +/** Sets the height of the section */ +void MReportSection::setHeight( int h ) +{ + height = h; +} + +/** Sets the level of the section */ +void MReportSection::setLevel( int l ) +{ + level = l; +} + +/** Gets the level of the section */ +int MReportSection::getLevel() +{ + return level; +} + +/** Set the current page number - used by special fields */ +void MReportSection::setPageNumber( int page ) +{ + pageNumber = page; +} + +/** Set the current date - used by special fields */ +void MReportSection::setReportDate( QDate date ) +{ + reportDate = date; +} + +/** Sets the print frequency of the section */ +void MReportSection::setPrintFrequency( int printFrequency ) +{ + frequency = printFrequency; +} + +/** Returns the print frequency of the section */ +int MReportSection::printFrequency() +{ + return frequency; +} + +/** Returns the name of the bound field for the calculated field object at the given index */ +QString MReportSection::getCalcFieldName( int idx ) +{ + MCalcObject * field = calculatedFields.at( idx ); + + return field->getFieldName(); +} + +/** Sets the data for the specified calculated field */ +void MReportSection::setCalcFieldData( int idx, QString data ) +{ + MCalcObject * field = calculatedFields.at( idx ); + + field->setText( data ); +} + +/** Sets the data for the all calculated fields - list size must number of calculated fields */ +void MReportSection::setCalcFieldData( QPtrList<QMemArray<double> >* values ) +{ + MCalcObject * field; + int i = 0; + + // Calculate and set the calculated field's data + for ( field = calculatedFields.first(); field != 0; field = calculatedFields.next() ) + { + switch ( field->getCalculationType() ) + { + case MCalcObject::Count: + field->setText( QString::number( MUtil::count( values->at( i ) ) ) ); + break; + case MCalcObject::Sum: + field->setText( QString::number( MUtil::sum( values->at( i ) ), 'f', 2 ) ); + break; + case MCalcObject::Average: + field->setText( QString::number( MUtil::average( values->at( i ) ) ) ); + break; + case MCalcObject::Variance: + field->setText( QString::number( MUtil::variance( values->at( i ) ) ) ); + break; + case MCalcObject::StandardDeviation: + field->setText( QString::number( MUtil::stdDeviation( values->at( i ) ) ) ); + break; + } + i++; + } +} + +/** Returns the index of the calculated field object for the given bound field */ +int MReportSection::getCalcFieldIndex( QString field ) +{ + MCalcObject * tmpField; + + // Find the field in the calculated field collection and return the index + for ( tmpField = calculatedFields.first(); tmpField != 0; tmpField = calculatedFields.next() ) + { + if ( tmpField->getFieldName() == field ) + break; + } + return calculatedFields.at(); +} + +/** Returns the number of calculated fields in the section */ +int MReportSection::getCalcFieldCount() +{ + return calculatedFields.count(); +} + +/** Draws the section to the specified painter & x/y-offsets */ +void MReportSection::draw( QPainter* p, int xoffset, int yoffset ) +{ + drawObjects( p, xoffset, yoffset ); +} + +/** Draws the section base objects to the specified painter & x/y offsets */ +void MReportSection::drawObjects( QPainter* p, int xoffset, int yoffset ) +{ + MLineObject * line; + MLabelObject* label; + MSpecialObject* special; + MCalcObject* cfield; + MFieldObject* field; + + // Set the offsets + int xcalc = xoffset; + int ycalc = yoffset; + + // Draw the line collection + for ( line = lines.first(); line != 0; line = lines.next() ) + { + line->draw( p, xcalc, ycalc ); + } + + // Draw the label collection + for ( label = labels.first(); label != 0; label = labels.next() ) + { + label->draw( p, xcalc, ycalc ); + } + + // Draw the field collection + for ( field = fields.first(); field != 0; field = fields.next() ) + { + field->draw( p, xcalc, ycalc ); + } + + // Draw the calculated field collection + for ( cfield = calculatedFields.first(); cfield != 0; cfield = calculatedFields.next() ) + { + cfield->draw( p, xcalc, ycalc ); + } + + // Draw the special field collection + for ( special = specialFields.first(); special != 0; special = specialFields.next() ) + { + switch ( special->getType() ) + { + case MSpecialObject::Date: + special->setText( reportDate ); + break; + case MSpecialObject::PageNumber: + special->setText( pageNumber ); + break; + } + special->draw( p, xcalc, ycalc ); + } +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MReportSection::copy( const MReportSection* mReportSection ) +{ + // Copy the section's geometry + height = mReportSection->height; + + // Copy the print frequency + frequency = mReportSection->frequency; + + // Copy the line list + lines = mReportSection->lines; + // Copy the label list + labels = mReportSection->labels; + // Copy the field list + fields = mReportSection->fields; + // Copy the special field list + specialFields = mReportSection->specialFields; + // Copy the calculated field list + calculatedFields = mReportSection->calculatedFields; +} + +void MReportSection::setFieldData( QString name, QString data ) +{ + MFieldObject * field; + for ( field = fields.first(); field != 0; field = fields.next() ) + { + qWarning( " checking field %s", field->getFieldName().ascii() ); + if ( field->getFieldName() == name ) + field->setText( data ); + } +} + +} + diff --git a/kugar/lib/mreportsection.h b/kugar/lib/mreportsection.h new file mode 100644 index 00000000..704daf4b --- /dev/null +++ b/kugar/lib/mreportsection.h @@ -0,0 +1,190 @@ +/*************************************************************************** + mreportsection.h - Kugar report section + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002-2004 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#ifndef MREPORTSECTION_H +#define MREPORTSECTION_H + +#include <qptrlist.h> +#include <qobject.h> + +#include "mlineobject.h" +#include "mlabelobject.h" +#include "mspecialobject.h" +#include "mcalcobject.h" +#include "mfieldobject.h" + +/**Kugar report section + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MReportSection : public QObject +{ + +public: + /** Section print frequency constants */ + enum PrintFrequency { FirstPage = 0, EveryPage, LastPage }; + + /** Constructor */ + MReportSection(); + /** Copy constructor */ + MReportSection( const MReportSection& mReportSection ); + /** Assignment operator */ + MReportSection operator=( const MReportSection& mReportSection ); + /** Destructor */ + virtual ~MReportSection(); + +protected: + /** Sections's height */ + int height; + /** Sections's level in hierarchy */ + int level; + /** Section print frequency */ + int frequency; + /** Page number - used by special fields */ + int pageNumber; + /** Report date - used by special fields */ + QDate reportDate; + + /** Section's line collection */ + QPtrList<MLineObject> lines; + /** Section's label collection */ + QPtrList<MLabelObject> labels; + /** Section's special field collection */ + QPtrList<MSpecialObject> specialFields; + /** Section's calculated field collection */ + QPtrList<MCalcObject> calculatedFields; + /** Section's field collection (for use as report variables) */ + QPtrList<MFieldObject> fields; + +public: + /** Adds a new line object to the section's line collection */ + void addLine( MLineObject* line ); + /** Adds a new label object to the section's label collection */ + void addLabel( MLabelObject* label ); + /** Adds a new field object to the section's field collection */ + void addField( MFieldObject* field ); + /** Adds a new special field object to the section's special field collection */ + void addSpecialField( MSpecialObject* special ); + /** Adds a new calculated field object to the section's calculated field collection */ + void addCalculatedField( MCalcObject* calc ); + /** Sets the height of the section */ + void setHeight( int h ); + /** Gets the height of the section */ + int getHeight(); + /** Sets the level of the section */ + void setLevel( int l ); + /** Gets the level of the section */ + int getLevel(); + /** Set the current page number - used by special fields */ + void setPageNumber( int page ); + /** Set the current date - used by special fields */ + void setReportDate( QDate date ); + /** Sets the print frequency of the section */ + void setPrintFrequency( int printFrequency ); + /** Returns the print frequency of the section */ + int printFrequency(); + /** Returns the name of the bound field for the calculated field object at the given index */ + QString getCalcFieldName( int idx ); + /** Returns the index of the calculated field object for the given bound field */ + int getCalcFieldIndex( QString field ); + /** Sets the data for the specified calculated field */ + void setCalcFieldData( int idx, QString data ); + /** Sets the data for the all calculated fields - list size must match number of calculated fields */ + void setCalcFieldData( QPtrList<QMemArray<double> >* values ); + /** Returns the number of calculated fields in the section */ + int getCalcFieldCount(); + /** Sets the field data */ + void setFieldData( QString name, QString data ); + /** Draws the section to the specified painter & x/y-offsets */ + virtual void draw( QPainter* p, int xoffset, int yoffset ); + /** Frees all resources allocated by the report section */ + virtual void clear(); + +protected: + /** Frees base resources allocated by the report section */ + void clearBase(); + /** Draws the section base objects to the specified painter & x/y offsets */ + void drawObjects( QPainter* p, int xoffset, int yoffset ); + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MReportSection* mReportSection ); +}; + +} + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kugar/lib/mreportviewer.cpp b/kugar/lib/mreportviewer.cpp new file mode 100644 index 00000000..da825f7a --- /dev/null +++ b/kugar/lib/mreportviewer.cpp @@ -0,0 +1,411 @@ +/*************************************************************************** + mreportviewer.cpp - Kugar QT report viewer widget + ------------------- + begin : Fri Aug 13 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#include <qapplication.h> +#include <kmessagebox.h> +#include <kprinter.h> +#include <klocale.h> + +#include "mreportviewer.h" + +namespace Kugar +{ + +/** Constructor */ +MReportViewer::MReportViewer( MReportEngine *engine, QWidget *parent, const char *name ) : QWidget( parent, name ), progress( 0 ) +{ + rptEngine = engine; + rptEngine->addRef(); + init(); +} + +MReportViewer::MReportViewer( QWidget *parent, const char *name ) : QWidget( parent, name ), progress( 0 ) +{ + // Create the scrollview + rptEngine = new MReportEngine(); + init(); +} + +void MReportViewer::init() +{ + scroller = new QScrollView( this ); + + // Connect the rendering update signal and slot + connect( rptEngine, SIGNAL( signalRenderStatus( int ) ), + SLOT( slotRenderProgress( int ) ) ); + + connect( rptEngine, SIGNAL( preferedTemplate( const QString & ) ), + SIGNAL( preferedTemplate( const QString & ) ) ); + + // Get the current color palette + QPalette p = palette(); + QColorGroup g = p.active(); + + // Set the scroller's background color + scroller->viewport() ->setBackgroundColor( g.mid() ); + + // Create the report display widget + display = new MPageDisplay( scroller->viewport() ); + + // Set the display's default background color + display->setBackgroundColor( white ); + + // Add the display to the scrollview + scroller->addChild( display ); + + //Hide the display, we don't have a report yet .. + display->hide(); +} + +/** Destructor */ +MReportViewer::~MReportViewer() +{ + clearReport(); + rptEngine->removeRef(); +} + +/** Report viewer's paint event */ +void MReportViewer::paintEvent( QPaintEvent* event ) +{} + +/** Report viewer's resize event */ +void MReportViewer::resizeEvent( QResizeEvent* event ) +{ + scroller->resize( event->size() ); +} + +// Set the report's data from an in-line string. + +bool MReportViewer::setReportData( const QString &data ) +{ + return rptEngine -> setReportData( data ); +} + + +// Set the report's data from an i/o device. + +bool MReportViewer::setReportData( QIODevice *dev ) +{ + return rptEngine -> setReportData( dev ); +} + + +// Set the report's template from an in-line string. + +bool MReportViewer::setReportTemplate( const QString &tpl ) +{ + return rptEngine -> setReportTemplate( tpl ); +} + + +// Set the report's template from an i/o device. + +bool MReportViewer::setReportTemplate( QIODevice *dev ) +{ + return rptEngine -> setReportTemplate( dev ); +} + + +/** Generates the report's page collection */ +bool MReportViewer::renderReport() +{ + // Render the report + report = rptEngine->renderReport(); + + // Display the first page of the report + if ( report && report->getFirstPage() != 0 ) + { + display->setPageDimensions( report->pageDimensions() ); + display->setPage( report->getFirstPage() ); + display->show(); + + return true; + } + + return false; +} + +/** Clears the report's page collection */ +void MReportViewer::clearReport() +{ + // Hide the display + display->hide(); +} + +/** Prints the rendered report to the selected printer - displays KDE print dialog */ +void MReportViewer::printReport() +{ + // Check for a report + if ( !report ) + return ; + + // Get the page count + int cnt = report->pageCount(); + + // Check if there is a report or any pages to print + if ( cnt == 0 ) + { + KMessageBox::error( this, i18n( "There are no pages in the\nreport to print." ) ); + return ; + } + + // Set the printer dialog + KPrinter printer; + + setupPrinter( printer ); + if ( printer.setup( this ) ) + printReport( printer ); +} + +/** Shows the first page in the report */ +void MReportViewer::slotFirstPage() +{ + QPicture * page; + + if ( !report ) + return ; + + if ( ( page = report->getFirstPage() ) != 0 ) + { + display->setPage( page ); + display->repaint(); + } +} + +/** Shows the next page in the report */ +void MReportViewer::slotNextPage() +{ + QPicture * page; + + if ( !report ) + return ; + + int index = report->getCurrentIndex(); + + if ( ( page = report->getNextPage() ) != 0 ) + { + display->setPage( page ); + display->repaint(); + } + else + report->setCurrentPage( index ); +} + +/** Shows the prevoius page in the report */ +void MReportViewer::slotPrevPage() +{ + QPicture * page; + + if ( !report ) + return ; + + int index = report->getCurrentIndex(); + + if ( ( page = report->getPreviousPage() ) != 0 ) + { + display->setPage( page ); + display->repaint(); + } + else + report->setCurrentPage( index ); +} + +/** Shows the last page in the report */ +void MReportViewer::slotLastPage() +{ + QPicture * page; + + if ( !report ) + return ; + + if ( ( page = report->getLastPage() ) != 0 ) + { + display->setPage( page ); + display->repaint(); + } +} + +/** Cancel printing of the report */ +void MReportViewer::slotCancelPrinting() +{ + printer->abort(); +} + +/** Updates rendering progress */ +void MReportViewer::slotRenderProgress( int p ) +{ + + // Check if the dialog was created + if ( progress == 0 ) + { + totalSteps = rptEngine->getRenderSteps(); + progress = new QProgressDialog( i18n("Creating report..."), i18n("Cancel"), + totalSteps, this, "progress", true ); + progress->setMinimumDuration( M_PROGRESS_DELAY ); + } + + // Update the dialog + progress->setProgress( p ); + qApp->processEvents(); + + // Check if the action was canceled + if ( progress->wasCancelled() ) + { + progress->setProgress( totalSteps ); + rptEngine->slotCancelRendering(); + } + + // Cleanup dialog if necessary + if ( progress->progress() == -1 ) + { + delete progress; + progress = 0; + } +} + + +// Return the preferred size. + +QSize MReportViewer::sizeHint() const +{ + return scroller -> sizeHint(); +} + +void MReportViewer::printReport( KPrinter &printer ) +{ + // Check for a report + if ( !report ) + return ; + + // Get the page count + int cnt = report->pageCount(); + + // Check if there is a report or any pages to print + if ( cnt == 0 ) + { + KMessageBox::error( this, i18n( "There are no pages in the\nreport to print." ) ); + return ; + } + + + QPicture* page; + QPainter painter; + bool printRev; + + // Save the viewer's page index + int viewIdx = report->getCurrentIndex(); + + // Check the order we are printing the pages + if ( printer.pageOrder() == KPrinter::FirstPageFirst ) + printRev = false; + else + printRev = true; + + // Get the count of pages and copies to print + int printFrom = printer.fromPage() - 1; + int printTo = printer.toPage(); + int printCnt = ( printTo - printFrom ); + int printCopies = printer.numCopies(); + int totalSteps = printCnt * printCopies; + int currentStep = 1; + + // Set copies to 1, KPrinter copies does not appear to work ... + printer.setNumCopies( 1 ); + + // Setup the progress dialog + QProgressDialog progress( i18n( "Printing report..." ), + i18n( "Cancel" ), + totalSteps, this, "progress", true ); + progress.setMinimumDuration( M_PROGRESS_DELAY ); + QObject::connect( &progress, SIGNAL( cancelled() ), this, SLOT( slotCancelPrinting() ) ); + progress.setProgress( 0 ); + qApp->processEvents(); + + // Start the printer + painter.begin( &printer ); + + // Print each copy + for ( int j = 0; j < printCopies; j++ ) + { + // Print each page in the collection + for ( int i = printFrom ; i < printTo; i++, currentStep++ ) + { + if ( !printer.aborted() ) + { + progress.setProgress( currentStep ); + qApp->processEvents(); + + if ( printRev ) + report->setCurrentPage( ( printCnt == 1 ) ? i : ( printCnt - 1 ) - i ); + else + report->setCurrentPage( i ); + + page = report->getCurrentPage(); + page->play( &painter ); + if ( i < printCnt - 1 ) + printer.newPage(); + } + else + { + j = printCopies; + break; + } + } + if ( j < printCopies - 1 ) + printer.newPage(); + } + + // Cleanup printing + setCursor( arrowCursor ); + painter.end(); + report->setCurrentPage( viewIdx ); +} + +void MReportViewer::setupPrinter( KPrinter &printer ) +{ + int cnt = report->pageCount(); + + printer.setPageSize( ( KPrinter::PageSize ) report->pageSize() ); + printer.setOrientation( ( KPrinter::Orientation ) report->pageOrientation() ); + printer.setMinMax( 1, cnt ); + printer.setFromTo( 1, cnt ); + printer.setFullPage( true ); +} + +void MReportViewer::printReportSilent( int printFrom, int printTo, int printCopies, QString printerName ) +{ + int cnt = report->pageCount(); + if ( printFrom == -1 ) + printFrom = 1; + if ( printTo == -1 ) + printTo = cnt; + if ( printCopies == -1 ) + printCopies = 1; + + + printer = new KPrinter(); + + printer->setPageSize( ( KPrinter::PageSize ) report->pageSize() ); + printer->setOrientation( ( KPrinter::Orientation ) report->pageOrientation() ); + printer->setMinMax( 1, cnt ); + printer->setFullPage( true ); + printer->setNumCopies( printCopies ); + printer->setFromTo( printFrom, printTo ); + if ( !printerName.isEmpty() ) + printer->setPrinterName( printerName ); + + printReport( *printer ); + + delete printer; +} + +} + +#include "mreportviewer.moc" diff --git a/kugar/lib/mreportviewer.h b/kugar/lib/mreportviewer.h new file mode 100644 index 00000000..1c6f4c03 --- /dev/null +++ b/kugar/lib/mreportviewer.h @@ -0,0 +1,94 @@ +/*************************************************************************** + mreportviewer.h - Kugar QT report viewer widget + ------------------- + begin : Fri Aug 13 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#ifndef MREPORTVIEWER_H +#define MREPORTVIEWER_H + +#include <qapplication.h> +#include <qwidget.h> +#include <qscrollview.h> +#include <qpixmap.h> +#include <qpainter.h> +#include <qpaintdevicemetrics.h> +#include <qprogressdialog.h> +#include <qguardedptr.h> +#include <koffice_export.h> +#include "mreportengine.h" +#include "mpagecollection.h" +#include "mpagedisplay.h" + +#define M_PROGRESS_DELAY 500 // Number of ms to delay progress dialog display + +class KPrinter; + +/** Application reference, required for event processing */ +extern QApplication *mAppRef; + +/**Kugar QT report viewer widget + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class KUGAR_EXPORT MReportViewer : public QWidget +{ + Q_OBJECT + +public: + MReportViewer( QWidget *parent = 0, const char *name = 0 ); + MReportViewer( MReportEngine* engine, QWidget *parent = 0, const char *name = 0 ); + virtual ~MReportViewer(); + + bool setReportData( const QString & ); + bool setReportData( QIODevice * ); + bool setReportTemplate( const QString & ); + bool setReportTemplate( QIODevice * ); + bool renderReport(); + void clearReport(); + void printReport(); + void printReport( KPrinter &printer ); + void setupPrinter( KPrinter &printer ); + void printReportSilent( int printFrom = -1, int printTo = -1, int printCopies = -1, QString printerName = QString::null ); + + QSize sizeHint() const; + +public slots: + void slotFirstPage(); + void slotNextPage(); + void slotPrevPage(); + void slotLastPage(); + +signals: + void preferedTemplate( const QString & ); + +private slots: + void slotCancelPrinting(); + void slotRenderProgress( int ); + +protected: + void paintEvent( QPaintEvent *event ); + void resizeEvent( QResizeEvent *event ); + + QScrollView *scroller; + MPageDisplay *display; + MReportEngine *rptEngine; + QGuardedPtr<MPageCollection> report; + KPrinter *printer; + +private: + QProgressDialog* progress; + int totalSteps; + void init(); +}; + +} + +#endif diff --git a/kugar/lib/mspecialobject.cpp b/kugar/lib/mspecialobject.cpp new file mode 100644 index 00000000..c06830fd --- /dev/null +++ b/kugar/lib/mspecialobject.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + mspecialobject.cpp - Kugar report special field object + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#include "mspecialobject.h" +#include "mutil.h" + +namespace Kugar +{ + +/** Constructor */ +MSpecialObject::MSpecialObject() : MLabelObject() +{ + // Set the defaults + type = MSpecialObject::Date; + format = MUtil::MDY_SLASH; +} + +/** Copy constructor */ +MSpecialObject::MSpecialObject( const MSpecialObject& mSpecialObject ) : MLabelObject( ( MLabelObject & ) mSpecialObject ) +{ + copy( &mSpecialObject ); +} + +/** Assignment operator */ +MSpecialObject MSpecialObject::operator=( const MSpecialObject& mSpecialObject ) +{ + if ( &mSpecialObject == this ) + return * this; + + // Copy the derived class's data + copy( &mSpecialObject ); + + // Copy the base class's data + ( ( MLabelObject & ) * this ) = mSpecialObject; + + return *this; +} + +/** Destructor */ +MSpecialObject::~MSpecialObject() +{} + +/** Sets the field's data string with a date */ +void MSpecialObject::setText( QDate d ) +{ + text = MUtil::formatDate( d, format ); +} + +/** Sets the field's data string with a page number */ +void MSpecialObject::setText( int page ) +{ + text.setNum( page ); +} + +/** Sets the field's data type */ +void MSpecialObject::setType( int t ) +{ + type = t; +} + +/** Gets the field's type */ +int MSpecialObject::getType() +{ + return type; +} + +/** Sets the field's date formatting */ +void MSpecialObject::setDateFormat( int f ) +{ + format = f; +} + +/** Copies member data from one object to another. + Used by the copy constructor and assignment operator */ +void MSpecialObject::copy( const MSpecialObject* mSpecialObject ) +{ + // Copy the fields's data type and format + type = mSpecialObject->type; +} + +} diff --git a/kugar/lib/mspecialobject.h b/kugar/lib/mspecialobject.h new file mode 100644 index 00000000..58d18ca8 --- /dev/null +++ b/kugar/lib/mspecialobject.h @@ -0,0 +1,91 @@ +/*************************************************************************** + mspecialobject.h - Kugar report special field object + ------------------- + begin : Mon Aug 23 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com +***************************************************************************/ + +#ifndef MSPECIALOBJECT_H +#define MSPECIALOBJECT_H + +#include <qdatetime.h> + +#include "mlabelobject.h" + +/**Kugar report special field object - report date, page number, etc. + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MSpecialObject : public MLabelObject +{ + +public: + /** Data type constants */ + enum SpecialType { Date = 0, PageNumber }; + + /** Constructor */ + MSpecialObject(); + /** Copy constructor */ + MSpecialObject( const MSpecialObject& mSpecialObject ); + /** Assignment operator */ + MSpecialObject operator=( const MSpecialObject& mSpecialObject ); + /** Destructor */ + virtual ~MSpecialObject(); + +protected: + /** Field type */ + int type; + /** Format type */ + int format; +public: + /** Sets the field's data string with a date */ + void setText( QDate d ); + /** Sets the field's data string with a page number */ + void setText( int page ); + /** Sets the field's type */ + void setType( int t ); + /** Gets the field's type */ + int getType(); + /** Sets the field's date formatting */ + void setDateFormat( int f ); + +private: + /** Copies member data from one object to another. + * Used by the copy constructor and assignment operator + */ + void copy( const MSpecialObject* mSpecialObject ); + +}; + +} + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/kugar/lib/mutil.cpp b/kugar/lib/mutil.cpp new file mode 100644 index 00000000..158d64e1 --- /dev/null +++ b/kugar/lib/mutil.cpp @@ -0,0 +1,127 @@ +/*************************************************************************** + mutil.cpp - Kugar utlity class + ------------------- + begin : Tue Aug 17 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#include <math.h> + +#include "mutil.h" + + +namespace Kugar +{ + +/** Formats a date using one of the pre-defined formats */ +QString MUtil::formatDate( const QDate& value, int format ) +{ + QString string; + QString month, day, year; + + // Reformat date parts - not necessarily required + month.setNum( value.month() ); + day.setNum( value.day() ); + + // Add leading zeros to month and day + if ( value.month() < 10 ) + month = "0" + month; + if ( value.day() < 10 ) + day = "0" + day; + + // Create a two digit year + year.setNum( value.year() ); + year = year.right( 2 ); + + // Create the formatted date string + switch ( format ) + { + case MUtil::MDY_SLASH: + string = QString( "%1/%2/%3" ).arg( value.month() ).arg( value.day() ).arg( year ); + break; + case MUtil::MDY_DASH: + string = QString( "%1-%2-%3" ).arg( value.month() ).arg( value.day() ).arg( year ); + break; + case MUtil::MMDDY_SLASH: + string = QString( "%1/%2/%3" ).arg( month ).arg( day ).arg( year ); + break; + case MUtil::MMDDY_DASH: + string = QString( "%1-%2-%3" ).arg( month ).arg( day ).arg( year ); + break; + case MUtil::MDYYYY_SLASH: + string = QString( "%1/%2/%3" ).arg( value.month() ).arg( value.day() ).arg( value.year() ); + break; + case MUtil::MDYYYY_DASH: + string = QString( "%1-%2-%3" ).arg( value.month() ).arg( value.day() ).arg( value.year() ); + break; + case MUtil::MMDDYYYY_SLASH: + string = QString( "%1/%2/%3" ).arg( month ).arg( day ).arg( value.year() ); + break; + case MUtil::MMDDYYYY_DASH: + string = QString( "%1-%2-%3" ).arg( month ).arg( day ).arg( value.year() ); + break; + case MUtil::YYYYMD_SLASH: + string = QString( "%1/%2/%3" ).arg( value.year() ).arg( value.month() ).arg( value.day() ); + break; + case MUtil::YYYYMD_DASH: + string = QString( "%1-%2-%3" ).arg( value.year() ).arg( value.month() ).arg( value.day() ); + break; + case MUtil::DDMMYY_PERIOD: + string = QString( "%1.%2.%3" ).arg( day ).arg( month ).arg( year ); + break; + case MUtil::DDMMYYYY_PERIOD: + string = QString( "%1.%2.%3" ).arg( day ).arg( month ).arg( value.year() ); + break; + default: + string = value.toString(); + } + return string; +} + +/** Returns the count for an array of doubles */ +int MUtil::count( QMemArray<double>* values ) +{ + return values->size(); +} + +/** Returns the sum for an array of doubles */ +double MUtil::sum( QMemArray<double>* values ) +{ + double tmpSum = 0.0; + int size = count( values ); + + for ( int i = 0; i < size; i++ ) + tmpSum += values->at( i ); + + return tmpSum; +} + +/** Returns the average value for an array of doubles */ +double MUtil::average( QMemArray<double>* values ) +{ + return sum( values ) / count( values ); +} + +/** Returns the variance for an array of doubles */ +double MUtil::variance( QMemArray<double>* values ) +{ + double tmpVar = 0.0; + double tmpAvg = average( values ); + int size = count( values ); + + for ( int i = 0; i < size; i++ ) + tmpVar += pow( ( values->at( i ) - tmpAvg ), 2 ) / size; + + return tmpVar; +} + +/** Returns the standard deviation for an array of doubles */ +double MUtil::stdDeviation( QMemArray<double>* values ) +{ + return sqrt( variance( values ) ); +} + +} diff --git a/kugar/lib/mutil.h b/kugar/lib/mutil.h new file mode 100644 index 00000000..b7aa764f --- /dev/null +++ b/kugar/lib/mutil.h @@ -0,0 +1,59 @@ +/*************************************************************************** + mutil.h - Kugar utlity class + ------------------- + begin : Tue Aug 17 1999 + copyright : (C) 1999 by Mutiny Bay Software + email : info@mutinybaysoftware.com + copyright : (C) 2002 Alexander Dymo + email : cloudtemple@mksat.net +***************************************************************************/ + +#ifndef MUTIL_H +#define MUTIL_H + +#include <qobject.h> +#include <qstring.h> +#include <qdatetime.h> +#include <qmemarray.h> + + +/**Kugar utlity class + *@author Mutiny Bay Software + */ + +namespace Kugar +{ + +class MUtil +{ + +public: + /** Formatting constants */ + enum DateFormatType { + MDY_SLASH = 0, MDY_DASH, + MMDDY_SLASH, MMDDY_DASH, + MDYYYY_SLASH, MDYYYY_DASH, + MMDDYYYY_SLASH, MMDDYYYY_DASH, + YYYYMD_SLASH, YYYYMD_DASH, + DDMMYY_PERIOD, DDMMYYYY_PERIOD + }; + + /** Formats a date using one of the pre-defined formats */ + static QString formatDate( const QDate& value, int format ); + + /** Returns the count for an array of doubles */ + static int count( QMemArray<double>* values ); + /** Returns the sum for an array of doubles */ + static double sum( QMemArray<double>* values ); + /** Returns the average value for an array of doubles */ + static double average( QMemArray<double>* values ); + /** Returns the variance for an array of doubles */ + static double variance( QMemArray<double>* values ); + /** Returns the standard deviation for an array of doubles */ + static double stdDeviation( QMemArray<double>* values ); + +}; + +} + +#endif |