kaddressbook

mikesstyle.cpp

00001 /*
00002     This file is part of KAddressBook.
00003     Copyright (c) 1996-2002 Mirko Boehm <mirko@kde.org>
00004                        2002 Mike Pilone <mpilone@slac.com>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include <qpaintdevicemetrics.h>
00026 #include <qpainter.h>
00027 
00028 #include <kabc/addressee.h>
00029 #include <kapplication.h>
00030 #include <kdebug.h>
00031 #include <kglobal.h>
00032 #include <klocale.h>
00033 #include <kprinter.h>
00034 #include <kprogress.h>
00035 
00036 #include "printingwizard.h"
00037 #include "printprogress.h"
00038 #include "printstyle.h"
00039 
00040 #include "mikesstyle.h"
00041 
00042 using namespace KABPrinting;
00043 
00044 const int mFieldSpacingHint = 2;
00045 
00046 MikesStyle::MikesStyle( PrintingWizard *parent, const char *name )
00047   : PrintStyle( parent, name )
00048 {
00049   setPreview( "mike-style.png" );
00050 }
00051 
00052 MikesStyle::~MikesStyle()
00053 {
00054 }
00055 
00056 void MikesStyle::print( const KABC::Addressee::List &contacts, PrintProgress *progress )
00057 {
00058   QFont mFont;
00059   QFont mBoldFont;
00060   QPainter p;
00061 
00062   p.begin( wizard()->printer() );
00063   int yPos = 0, count = 0;
00064   int spacingHint = 10;
00065 
00066   // Now do the actual printing
00067   mFont = p.font();
00068   mBoldFont = p.font();
00069   mBoldFont.setBold( true );
00070   QFontMetrics fm( mFont );
00071   QPaintDeviceMetrics metrics( p.device() );
00072 
00073   int height = 0;
00074   KABC::Addressee::List::ConstIterator it;
00075 
00076   progress->addMessage( i18n( "Preparing" ) );
00077   progress->addMessage( i18n( "Printing" ) );
00078 
00079   for ( it = contacts.begin(); it != contacts.end(); ++it ) {
00080     progress->setProgress( (count++ * 100) / contacts.count() );
00081     kapp->processEvents();
00082 
00083     // Get the total height so we know if it will fit on the current page
00084     height = calcHeight( *it, mFont, mBoldFont );
00085     if ( (yPos + spacingHint + height) > (metrics.height() - fm.height() - 5) ) {
00086       p.save();
00087       p.translate( 0, metrics.height() - fm.height() - 5 );
00088       paintTagLine( p, mFont );
00089       p.restore();
00090 
00091       wizard()->printer()->newPage();
00092       yPos = 0;
00093     }
00094 
00095     // Move the painter to the proper position and then paint the addressee
00096     yPos += spacingHint;
00097     p.save();
00098     p.translate( 0, yPos );
00099     doPaint( p, *it, height, mFont, mBoldFont );
00100     p.restore();
00101 
00102     yPos += height;
00103   }
00104 
00105   progress->addMessage( i18n( "Done" ) );
00106 
00107   // print the tag line on the last page
00108   p.save();
00109   p.translate( 0, metrics.height() - fm.height() - 5 );
00110   paintTagLine( p, mFont );
00111   p.restore();
00112 
00113   // send to the printer
00114   p.end();
00115 }
00116 
00117 QString MikesStyle::trimString( const QString &text, int width, QFontMetrics &fm )
00118 {
00119   if ( fm.width( text ) <= width )
00120     return text;
00121 
00122   QString dots = "...";
00123   int dotWidth = fm.width( dots );
00124   QString trimmed;
00125   int charNum = 0;
00126 
00127   while ( fm.width( trimmed ) + dotWidth < width ) {
00128     trimmed += text[ charNum ];
00129     charNum++;
00130   }
00131 
00132   // Now trim the last char, since it put the width over the top
00133   trimmed = trimmed.left( trimmed.length() - 1 );
00134   trimmed += dots;
00135 
00136   return trimmed;
00137 }
00138 
00139 void MikesStyle::doPaint( QPainter &painter, const KABC::Addressee &addr,
00140                           int maxHeight, const QFont &font, const QFont &bFont )
00141 {
00142   QFontMetrics fm( font );
00143   QFontMetrics bfm( bFont );
00144   QPaintDeviceMetrics metrics( painter.device() );
00145   int margin = 10;
00146   int width = metrics.width() - 10;
00147   int xPos = 5;
00148   int yPos = 0;
00149   QBrush brush( Qt::lightGray );
00150 
00151   painter.setPen( Qt::black );
00152   painter.drawRect( xPos, yPos, width, maxHeight );
00153 
00154   // The header
00155   painter.fillRect( xPos + 1, yPos + 1, width - 2,
00156                     bfm.height() + 2 * mFieldSpacingHint - 2, brush );
00157   painter.setFont( bFont );
00158   xPos += mFieldSpacingHint;
00159   painter.drawText( xPos, yPos + bfm.height(), addr.formattedName() );
00160 
00161   yPos += bfm.height() + 2 * mFieldSpacingHint;
00162   xPos = margin;
00163 
00164   // now the fields, in two halves
00165   painter.setFont( font );
00166 
00167   KABC::Field::List fields = wizard()->addressBook()->fields();
00168   int numFields = fields.count();
00169   QString label;
00170   QString value;
00171 
00172   for ( int i = 0; i < numFields / 2; i++ ) {
00173     label = fields[ i ]->label();
00174     value = trimString( fields[ i ]->value( addr ), (width - 10) / 4, fm );
00175 
00176     yPos += fm.height();
00177     painter.drawText( xPos, yPos, label + ":" );
00178 
00179     xPos += (width - (2 * margin)) / 4;
00180     painter.drawText( xPos, yPos, value );
00181 
00182     yPos += mFieldSpacingHint;
00183     xPos = margin;
00184   }
00185 
00186   yPos = bfm.height() + 2 * mFieldSpacingHint;
00187   xPos = margin + width / 2;
00188   for ( int i = numFields / 2; i < numFields; i++ ) {
00189     label = fields[ i ]->label();
00190     value = value = trimString( fields[ i ]->value( addr ), (width - 10) / 4, fm );
00191 
00192     yPos += fm.height();
00193     painter.drawText( xPos, yPos, label + ":" );
00194 
00195     xPos += (width - (2 * margin)) / 4;
00196     painter.drawText( xPos, yPos, value );
00197 
00198     yPos += mFieldSpacingHint;
00199     xPos = margin + width / 2;
00200   }
00201 }
00202 
00203 void MikesStyle::paintTagLine( QPainter &p, const QFont &font )
00204 {
00205   QFontMetrics fm( font );
00206 
00207   QString text = i18n( "Printed on %1 by KAddressBook (http://www.kde.org)" )
00208                  .arg( KGlobal::locale()->formatDateTime( QDateTime::currentDateTime() ) );
00209 
00210   p.setPen( Qt::black );
00211   p.drawText( 0, fm.height(), text );
00212 }
00213 
00214 int MikesStyle::calcHeight( const KABC::Addressee &addr,
00215                             const QFont &font, const QFont &bFont )
00216 {
00217   QFontMetrics fm( font );
00218   QFontMetrics bfm( bFont );
00219 
00220   int height = 0;
00221 
00222   // get the fields
00223   KABC::Field::List fieldList = wizard()->addressBook()->fields();
00224   int numFields = fieldList.count();
00225   int halfHeight = 0;
00226 
00227   // Determine which half of the fields is higher
00228   for ( int i = 0; i < numFields / 2; i++ )
00229     halfHeight += fm.height() * (fieldList[ i ]->value( addr ).contains( '\n' ) + 1);
00230 
00231   height = halfHeight;
00232 
00233   // now the second half
00234   halfHeight = 0;
00235   for ( int i = numFields / 2; i < numFields; i++ )
00236     halfHeight += fm.height() * (fieldList[ i ]->value( addr ).contains( '\n' ) + 1);
00237 
00238   height = QMAX( height, halfHeight );
00239 
00240   // Add the title and the spacing
00241   height += bfm.height() + ((numFields / 2 + 3) * mFieldSpacingHint);
00242 
00243   return height;
00244 }
00245 
00246 
00247 MikesStyleFactory::MikesStyleFactory( PrintingWizard *parent, const char *name )
00248   : PrintStyleFactory( parent, name )
00249 {
00250 }
00251 
00252 PrintStyle *MikesStyleFactory::create() const
00253 {
00254   return new MikesStyle( mParent, mName );
00255 }
00256 
00257 QString MikesStyleFactory::description() const
00258 {
00259   return i18n( "Mike's Printing Style" );
00260 }
00261 
00262 #include "mikesstyle.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys