kaddressbook Library API Documentation

kabentrypainter.cpp

00001 /*                                                                      
00002     This file is part of KAddressBook.
00003     Copyright (c) 1996-2002 Mirko Boehm <mirko@kde.org>
00004                                                                         
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or   
00008     (at your option) any later version.                                 
00009                                                                         
00010     This program is distributed in the hope that it will be useful,     
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of      
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the        
00013     GNU General Public License for more details.                        
00014                                                                         
00015     You should have received a copy of the GNU General Public License   
00016     along with this program; if not, write to the Free Software         
00017     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.           
00018                                                                         
00019     As a special exception, permission is given to link this program    
00020     with any edition of Qt, and distribute the resulting executable,    
00021     without including the source code for Qt in the source distribution.
00022 */                                                                      
00023 
00024 
00025 #include <qpaintdevicemetrics.h>
00026 #include <qpainter.h>
00027 
00028 #include <kdebug.h>
00029 #include <kglobal.h>
00030 #include <klocale.h>
00031 #include <knotifyclient.h>
00032 #include <kprinter.h>
00033 #include <kurl.h>
00034 
00035 #include "look_basic.h"
00036 
00037 #include "kabentrypainter.h"
00038 
00039 KABEntryPainter::KABEntryPainter()
00040   : mShowAddresses( true ), mShowEmails( true ), mShowPhones( true ),
00041     mShowURLs( true )
00042 {
00043 }
00044 
00045 KABEntryPainter::~KABEntryPainter()
00046 {
00047   mEmailRects.clear();
00048   mPhoneRects.clear();
00049   mURLRects.clear();
00050   mTalkRects.clear();
00051 }
00052 
00053 void KABEntryPainter::setForegroundColor( const QColor &color )
00054 {
00055   mForegroundColor = color;
00056 }
00057 
00058 void KABEntryPainter::setBackgroundColor( const QColor &color )
00059 {
00060   mBackgroundColor = color;
00061 }
00062 
00063 void KABEntryPainter::setHeaderColor( const QColor &color )
00064 {
00065   mHeaderColor = color;
00066 }
00067 
00068 void KABEntryPainter::setHeaderFont( const QFont &font )
00069 {
00070   mHeaderFont = font;
00071 }
00072 
00073 void KABEntryPainter::setHeadLineFont( const QFont &font )
00074 {
00075   mHeadLineFont = font;
00076 }
00077 
00078 void KABEntryPainter::setBodyFont( const QFont &font )
00079 {
00080   mBodyFont = font;
00081 }
00082 
00083 void KABEntryPainter::setFixedFont( const QFont &font )
00084 {
00085   mFixedFont = font;
00086 }
00087 
00088 void KABEntryPainter::setCommentFont( const QFont &font )
00089 {
00090   mCommentFont = font;
00091 }
00092 
00093 void KABEntryPainter::setUseHeaderColor( bool value )
00094 {
00095   mUseHeaderColor = value;
00096 }
00097 
00098 void KABEntryPainter::setShowAddresses( bool value )
00099 {
00100   mShowAddresses = value;
00101 }
00102 
00103 void KABEntryPainter::setShowEmails( bool value )
00104 {
00105   mShowEmails = value;
00106 }
00107 
00108 void KABEntryPainter::setShowPhones( bool value )
00109 {
00110   mShowPhones = value;
00111 }
00112 
00113 void KABEntryPainter::setShowURLs( bool value )
00114 {
00115   mShowURLs = value;
00116 }
00117 
00118 int KABEntryPainter::hitsEmail( QPoint p )
00119 {
00120   return hits( mEmailRects, p );
00121 }
00122 
00123 int KABEntryPainter::hitsURL( QPoint p )
00124 {
00125   return hits( mURLRects, p );
00126 }
00127 
00128 int KABEntryPainter::hitsPhone( QPoint p )
00129 {
00130   return hits( mPhoneRects, p );
00131 }
00132 
00133 int KABEntryPainter::hitsTalk( QPoint p )
00134 {
00135   return hits( mTalkRects, p );
00136 }
00137 
00138 int KABEntryPainter::hits( const QRectList& list, QPoint p )
00139 {
00140   QRectList::const_iterator pos;
00141   int count = 0;
00142 
00143   for( pos = list.begin(); pos != list.end(); ++pos ) {
00144     if ( (*pos).contains( p ) )
00145       return count;
00146 
00147     ++count;
00148   }
00149 
00150   return -1;
00151 }
00152 
00153 bool KABEntryPainter::printAddressee( const KABC::Addressee &addr,
00154                                       const QRect &window, QPainter *painter,
00155                                       int top, bool fake, QRect *brect )
00156 {
00157   // TODO: custom fields, custom (?) for Entry
00158   const int Width = window.width();
00159   const int Height = window.height();
00160   const int Ruler1 = Width/32;
00161   const int Ruler2 = 2 * Ruler1;
00162   const int Ruler3 = 3 * Ruler1;
00163   QString text, line1, line2, line3, line4;
00164   QRect rect;
00165 
00166   // settings derived from the options:
00167   QFontMetrics fmHeader( mHeaderFont );
00168   QFontMetrics fmHeadLine( mHeadLineFont );
00169   QFontMetrics fmBody( mBodyFont );
00170   QFontMetrics fmFixed( mFixedFont );
00171   QFontMetrics fmComment( mCommentFont );
00172 
00173   int y = top;
00174   KABC::Address address;
00175 
00176   // this is used to prepare some fields for printing and decide about
00177   // the layout later:
00178   QValueList<QStringList> parts;
00179   QValueList<QRectList*> contents;
00180 
00181   mEmailRects.clear();
00182   mPhoneRects.clear();
00183   mURLRects.clear();
00184 
00185   // set window the painter works on:
00186   painter->setWindow( window );
00187 
00188   // first draw a black rectangle on top, containing the entries name, centered:
00189   painter->setFont( mHeaderFont );
00190   painter->setBrush( QBrush( mBackgroundColor ) );
00191   painter->setPen( mBackgroundColor );
00192   text = addr.realName();
00193 
00194   // replacement for: api->addressbook()->literalName(entry, text);
00195   rect = painter->boundingRect( Ruler1, y, Width, Height,
00196                                 Qt::AlignVCenter | Qt::AlignLeft, text );
00197   rect.setHeight( (int)( 1.25 * rect.height() ) );
00198 
00199   if ( !fake && mUseHeaderColor )
00200     painter->drawRect( 0, y, Width, rect.height() );
00201 
00202   painter->setPen( mUseHeaderColor ? mHeaderColor : mForegroundColor );
00203   if ( !fake ) {
00204     // create a little (1/8) space on top of the letters:
00205     float ypos = y + ( (float)rect.height() ) * 0.125;
00206     painter->drawText( Ruler1, (int)ypos, Width, rect.height(),
00207                        Qt::AlignVCenter | Qt::AlignLeft, text );
00208   }
00209 
00210   // paint the birthday to the right:
00211   QDateTime dt = addr.birthday();
00212   if ( dt.isValid() ) {
00213     line1 = KGlobal::locale()->formatDate( dt.date(), true );
00214     if ( !fake ) {
00215       // create a little (1/8) space on top of the letters:
00216       float ypos = y + ( (float)rect.height() ) * 0.125;
00217       painter->drawText( 0, (int)ypos, Width-Ruler1, rect.height(),
00218                          Qt::AlignVCenter | Qt::AlignRight, line1 );
00219     }
00220   }
00221 
00222   y += rect.height();
00223 
00224   // now draw the data according to the person:
00225   painter->setFont( mBodyFont );
00226   y += fmBody.lineSpacing() / 2;
00227 
00228   painter->setPen( mForegroundColor );
00229   if ( !addr.prefix().isEmpty() ) {
00230     line1 = addr.prefix().stripWhiteSpace();
00231 
00232     if ( fake ) {
00233       rect = painter->boundingRect( Ruler1, y, Width-Ruler1, Height,
00234                                     Qt::AlignTop | Qt::AlignLeft, line1 );
00235     } else {
00236       painter->drawText( Ruler1, y, Width-Ruler1, Height, Qt::AlignTop | Qt::AlignLeft,
00237                          line1, -1, &rect );
00238     }
00239 
00240     y += rect.height();
00241   }
00242 
00243   if ( !( addr.prefix().isEmpty() ) )
00244     y += fmBody.lineSpacing() / 2;
00245 
00246   // fill the parts stringlist, it contains "parts" (printable areas)
00247   // that will be combined to fill the page as effectively as possible:
00248   // Email addresses:
00249   if ( !addr.emails().isEmpty() && mShowEmails ) {
00250     contents.push_back( &mEmailRects );
00251     QStringList list;
00252 
00253     list.append( addr.emails().count() == 1 ? i18n( "Email address:" )
00254                  : i18n( "Email addresses:" ) );
00255     list += addr.emails();
00256     parts.push_back( list );
00257   }
00258 
00259   // Telephones:
00260   KABC::PhoneNumber::List phoneNumbers = addr.phoneNumbers();
00261   if ( !phoneNumbers.isEmpty() && mShowPhones ) {
00262     contents.push_back( &mPhoneRects );
00263     QStringList list;
00264     QString line;
00265 
00266     list.append( phoneNumbers.count() == 1 ? i18n( "Telephone:" )
00267                  : i18n( "Telephones:" ) );
00268 
00269     KABC::PhoneNumber::List::Iterator it;
00270     for ( it = phoneNumbers.begin(); it != phoneNumbers.end(); ++it ) {
00271       line = (*it).typeLabel();
00272       line += ": " + (*it).number();
00273       list.append( line.stripWhiteSpace() );
00274     }
00275 
00276     parts.push_back( list );
00277   }
00278 
00279   // Web pages/URLs:
00280   if ( !addr.url().isEmpty() && addr.url().isValid() && mShowURLs ) {
00281     contents.push_back( &mURLRects );
00282     QStringList list;
00283 
00284     list.append( i18n( "Web page:" ) );
00285     list += addr.url().prettyURL();
00286     parts.push_back( list );
00287   }
00288 
00289   /*
00290   // Talk addresses:
00291   if ( !addr.talk.isEmpty() ) {
00292     contents.push_back( &mTalkRects );
00293     QStringList list;
00294 
00295     list.append( addr.talk.count() == 1 ? i18n( "Talk address:" )
00296                  : i18n( "Talk addresses:" ) );
00297     list += addr.talk;
00298     parts.push_back( list );
00299   }
00300   */
00301 
00302   QRect limits[] = { QRect( 0, y, Width / 2, Height ),
00303                      QRect( Width / 2, y, Width / 2, Height ),
00304                      QRect( 0, y, Width / 2, Height ),
00305                      QRect( Width / 2, y, Width / 2, Height ) };
00306   int heights[ 4 ]= { 0, 0, 0, 0 };
00307 
00308   QValueList<QStringList>::iterator pos = parts.begin();
00309   QValueList<QRectList*>::iterator rpos = contents.begin();
00310 
00311   for ( uint counter = 0; counter < parts.count(); ++counter ) {
00312     const int Offset = counter > 1 ? QMAX( heights[ 0 ], heights[ 1 ] ) : 0;
00313     QStringList list = *pos;
00314 
00315     painter->setFont( mHeadLineFont );
00316     if ( fake ) {
00317       rect = painter->boundingRect( limits[ counter ].left(),
00318                                     limits[ counter ].top() + heights[counter]
00319                                     + Offset, limits[ counter ].width(),
00320                                     limits[ counter ].height(),
00321                                     Qt::AlignTop | Qt::AlignLeft, *list.at( 0 ) );
00322     } else {
00323       painter->drawText( limits[ counter ].left(), limits[ counter ].top() + 
00324                          heights[ counter ] + Offset, limits[ counter ].width(),
00325                          limits[ counter ].height(), Qt::AlignTop | Qt::AlignLeft,
00326                          *list.at( 0 ), -1, &rect );
00327     }
00328 
00329     heights[ counter ] += rect.height();
00330 
00331     // paint the other elements at Ruler1:
00332     painter->setFont( mFixedFont );
00333     for ( uint c2 = 1; c2 < list.count(); ++c2 ) {
00334       // TODO: implement proper line breaking!
00335       if ( fake ) {
00336         rect = painter->boundingRect ( limits[ counter ].left() + Ruler1,
00337                                        limits[ counter ].top() + heights[ counter ]
00338                                        + Offset, limits[ counter ].width() - Ruler1,
00339                                        limits[ counter ].height(), Qt::AlignTop | Qt::AlignLeft,
00340                                        *list.at( c2 ) );
00341       } else {
00342         painter->drawText( limits[ counter ].left() + Ruler1, limits[ counter ].top()
00343                            + heights[ counter ] + Offset, limits[ counter ].width()
00344                            - Ruler1, limits[ counter ].height(), Qt::AlignTop | Qt::AlignLeft,
00345                            *list.at( c2 ), -1, &rect );
00346       }
00347       (*rpos)->push_back( rect );
00348       heights[ counter ] += rect.height();
00349     }
00350 
00351     ++pos;
00352     ++rpos;
00353   }
00354 
00355   y = y + QMAX( heights[ 0 ], heights[ 1 ] ) + QMAX( heights[ 2 ], heights[ 3 ] );
00356   // ^^^^^ done with emails, telephone, URLs and talk addresses
00357 
00358   // now print the addresses:
00359   KABC::Address::List addresses = addr.addresses();
00360   if ( addresses.count() > 0 && mShowAddresses ) {
00361     y += fmBody.lineSpacing() / 2;
00362     painter->setFont( mHeadLineFont );
00363     if ( fake ) {
00364       rect = painter->boundingRect( 0, y, Width, Height, Qt::AlignTop | Qt::AlignLeft,
00365                                     addresses.count() == 1 ? i18n( "Address:" )
00366                                     : i18n( "Addresses:" ) );
00367     } else {
00368       painter->drawText( 0, y, Width, Height, Qt::AlignTop | Qt::AlignLeft,
00369                          addresses.count() == 1 ? i18n( "Address:" )
00370                          : i18n( "Addresses:" ), -1, &rect );
00371     }
00372 
00373     y += rect.height();
00374     y += fmBody.lineSpacing() / 4;
00375     painter->setFont( mBodyFont );
00376 
00377     KABC::Address::List::iterator it;
00378     for ( it = addresses.begin(); it != addresses.end(); ++it ) {
00379       address = *it;
00380       switch ( address.type() ) {
00381         case KABC::Address::Dom:
00382           line1 = i18n( "Domestic Address" );
00383           break;
00384         case KABC::Address::Intl:
00385           line1 = i18n( "International Address" );
00386           break;
00387         case KABC::Address::Postal:
00388           line1 = i18n( "Postal Address" );
00389           break;
00390         case KABC::Address::Parcel:
00391           line1 = i18n( "Parcel Address" );
00392           break;
00393         case KABC::Address::Home:
00394           line1 = i18n( "Home Address" );
00395           break;
00396         case KABC::Address::Work:
00397           line1 = i18n( "Work Address" );
00398           break;
00399         case KABC::Address::Pref:
00400         default:
00401           line1 = i18n( "Preferred Address" );
00402       }
00403 
00404       line1 += QString::fromLatin1( ":" );
00405       text = QString::null;
00406 
00407       if ( !address.extended().isEmpty() )
00408         text = address.extended().stripWhiteSpace();
00409 
00410       if ( !text.isEmpty() ) {
00411         line1 = line1 + QString::fromLatin1( " (" ) + text +
00412         QString::fromLatin1( ")" );
00413       }
00414 
00415       line1 = line1.stripWhiteSpace();
00416       line2 = address.street();
00417       if ( !address.postOfficeBox().isEmpty() )
00418         line2 += QString::fromLatin1( " - " ) + address.postOfficeBox();
00419 
00420       // print address in american style, this will need localisation:
00421       line3 = address.locality() + ( address.region().isEmpty() ?
00422               QString::fromLatin1( "" ) : QString::fromLatin1( ", " ) + 
00423               address.region() ) + ( address.postalCode().isEmpty()
00424               ? QString::fromLatin1( "" ) : QString::fromLatin1( " " )
00425               + address.postalCode() );
00426       line4 = address.country();
00427 
00428       if ( fake ) {
00429         rect = painter->boundingRect( Ruler1, y, Width - Ruler1, Height,
00430                                       Qt::AlignTop | Qt::AlignLeft, line1 );
00431       } else {
00432         painter->drawText( Ruler1, y, Width - Ruler1, Height,
00433                            Qt::AlignTop | Qt::AlignLeft, line1, -1, &rect );
00434       }
00435 
00436       y += rect.height();
00437       if ( !line2.isEmpty() ) {
00438         if ( fake ) {
00439           rect = painter->boundingRect( Ruler2, y, Width - Ruler2, Height,
00440                                         Qt::AlignTop | Qt::AlignLeft, line2 );
00441         } else {
00442           painter->drawText( Ruler2, y, Width - Ruler2, Height,
00443                              Qt::AlignTop | Qt::AlignLeft, line2, -1, &rect );
00444         }
00445         y += rect.height();
00446       }
00447 
00448       if ( !line3.isEmpty() ) {
00449         if ( fake ) {
00450           rect = painter->boundingRect( Ruler2, y, Width - Ruler2, Height,
00451                                         Qt::AlignTop | Qt::AlignLeft, line3 );
00452         } else {
00453           painter->drawText( Ruler2, y, Width - Ruler2, Height,
00454                              Qt::AlignTop | Qt::AlignLeft, line3, -1, &rect );
00455         }
00456         y += rect.height();
00457       }
00458 
00459       if ( !line4.isEmpty() ) {
00460         if ( fake ) {
00461           rect = painter->boundingRect( Ruler2, y, Width - Ruler2, Height,
00462                                         Qt::AlignTop | Qt::AlignLeft, line4 );
00463         } else {
00464           painter->drawText( Ruler2, y, Width - Ruler2, Height,
00465                              Qt::AlignTop | Qt::AlignLeft, line4, -1, &rect );
00466         }
00467         y += rect.height();
00468       }
00469 
00470       y += fmBody.lineSpacing() / 4;
00471       if ( !address.label().isEmpty() ) {
00472         if ( fake ) {
00473           rect = painter->boundingRect( Ruler2, y, Width - Ruler2, Height,
00474                                         Qt::AlignTop | Qt::AlignLeft,
00475                                         i18n( "(Deliver to:)" ) );
00476         } else {
00477           painter->drawText( Ruler2, y, Width - Ruler2, Height,
00478                              Qt::AlignTop | Qt::AlignLeft,
00479                              i18n( "(Deliver to:)" ), -1, &rect );
00480         }
00481 
00482         y += rect.height();
00483         y += fmBody.lineSpacing() / 4;
00484         if ( fake ) {
00485           rect = painter->boundingRect( Ruler3, y, Width - Ruler3, Height,
00486                                         Qt::AlignTop | Qt::AlignLeft, address.label() );
00487         } else {
00488           painter->drawText( Ruler3, y, Width - Ruler3, Height,
00489                              Qt::AlignTop | Qt::AlignLeft, address.label(), -1, &rect );
00490         }
00491 
00492         y += rect.height();
00493         y += fmBody.lineSpacing() / 2;
00494       }
00495     }
00496   }
00497 
00498   if ( !addr.note().isEmpty() ) {
00499     painter->setFont( mCommentFont );
00500     y += fmBody.lineSpacing() / 2;
00501     if ( fake ) {
00502       rect = painter->boundingRect( 0, y, Width, Height,
00503                                     Qt::AlignTop | Qt::AlignLeft | Qt::WordBreak,
00504                                     addr.note() );
00505     } else {
00506       painter->drawText( 0, y, Width, Height,
00507                          Qt::AlignTop | Qt::AlignLeft | Qt::WordBreak,
00508                          addr.note(), -1, &rect );
00509     }
00510 
00511     y += rect.height();
00512   }
00513 
00514   y += fmBody.lineSpacing() / 2;
00515 
00516   if ( brect != 0 )
00517     *brect = QRect( 0, top, Width, y - top );
00518 
00519   if ( y < Height )
00520     return true;
00521   else
00522     return false;
00523 }
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:38:52 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003