kaddressbook

contactlistview.cpp

00001 /*
00002     This file is part of KAddressBook.
00003     Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 #include <qheader.h>
00025 #include <qiconset.h>
00026 #include <qimage.h>
00027 #include <qdragobject.h>
00028 #include <qcombobox.h>
00029 #include <qpainter.h>
00030 #include <qbrush.h>
00031 #include <qevent.h>
00032 
00033 #include <klocale.h>
00034 #include <kglobalsettings.h>
00035 #include <kdebug.h>
00036 #include <kconfig.h>
00037 #include <kapplication.h>
00038 #include <kurl.h>
00039 #include <kabc/addressbook.h>
00040 #include <kabc/addressee.h>
00041 #include <kimproxy.h>
00042 
00043 #include "kaddressbooktableview.h"
00044 
00045 #include "contactlistview.h"
00046 
00048 // DynamicTip Methods
00049 
00050 DynamicTip::DynamicTip( ContactListView *parent)
00051   : QToolTip( parent )
00052 {
00053 }
00054 
00055 void DynamicTip::maybeTip( const QPoint &pos )
00056 {
00057   if (!parentWidget()->inherits( "ContactListView" ))
00058     return;
00059 
00060   ContactListView *plv = (ContactListView*)parentWidget();
00061   if (!plv->tooltips())
00062     return;
00063 
00064   QPoint posVp = plv->viewport()->pos();
00065 
00066   QListViewItem *lvi = plv->itemAt( pos - posVp );
00067   if (!lvi)
00068     return;
00069 
00070   ContactListViewItem *plvi = dynamic_cast< ContactListViewItem* >(lvi);
00071   if (!plvi)
00072     return;
00073 
00074   QString s;
00075   QRect r = plv->itemRect( lvi );
00076   r.moveBy( posVp.x(), posVp.y() );
00077 
00078     //kdDebug(5720) << "Tip rec: " << r.x() << "," << r.y() << "," << r.width()
00079     //          << "," << r.height() << endl;
00080 
00081   KABC::Addressee a = plvi->addressee();
00082   if (a.isEmpty())
00083     return;
00084 
00085   s += i18n("label: value", "%1: %2").arg(a.formattedNameLabel())
00086                                      .arg(a.formattedName());
00087 
00088   s += '\n';
00089   s += i18n("label: value", "%1: %2").arg(a.organizationLabel())
00090                                        .arg(a.organization());
00091 
00092   QString notes = a.note().stripWhiteSpace();
00093   if ( !notes.isEmpty() ) {
00094     notes += '\n';
00095     s += '\n' + i18n("label: value", "%1: \n").arg(a.noteLabel());
00096     QFontMetrics fm( font() );
00097 
00098     // Begin word wrap code based on QMultiLineEdit code
00099     int i = 0;
00100     bool doBreak = false;
00101     int linew = 0;
00102     int lastSpace = -1;
00103     int a = 0;
00104     int lastw = 0;
00105 
00106     while ( i < int(notes.length()) ) {
00107       doBreak = false;
00108       if ( notes[i] != '\n' )
00109         linew += fm.width( notes[i] );
00110 
00111       if ( lastSpace >= a && notes[i] != '\n' )
00112         if  (linew >= parentWidget()->width()) {
00113           doBreak = true;
00114           if ( lastSpace > a ) {
00115             i = lastSpace;
00116             linew = lastw;
00117           }
00118           else
00119             i = QMAX( a, i-1 );
00120         }
00121 
00122       if ( notes[i] == '\n' || doBreak ) {
00123         s += notes.mid( a, i - a + (doBreak?1:0) ) +"\n";
00124 
00125         a = i + 1;
00126         lastSpace = a;
00127         linew = 0;
00128       }
00129 
00130       if ( notes[i].isSpace() ) {
00131         lastSpace = i;
00132         lastw = linew;
00133       }
00134 
00135       if ( lastSpace <= a ) {
00136         lastw = linew;
00137       }
00138 
00139       ++i;
00140     }
00141   }
00142 
00143   tip( r, s );
00144 }
00145 
00147 // ContactListViewItem Methods
00148 
00149 ContactListViewItem::ContactListViewItem(const KABC::Addressee &a,
00150                                          ContactListView *parent,
00151                                          KABC::AddressBook *doc,
00152                                          const KABC::Field::List &fields,
00153                                          KIMProxy *proxy )
00154   : KListViewItem(parent), mAddressee(a), mFields( fields ),
00155     parentListView( parent ), mDocument(doc), mIMProxy( proxy )
00156 {
00157   if ( mIMProxy )
00158     mHasIM = mIMProxy->isPresent( mAddressee.uid() );
00159   else
00160     mHasIM = false;
00161   refresh();
00162 }
00163 
00164 QString ContactListViewItem::key(int column, bool ascending) const
00165 {
00166   // Preserve behaviour of QListViewItem::key(), otherwise we cause a crash if the column does not exist
00167   if ( column >= parentListView->columns() )
00168     return QString::null;
00169 
00170 #if KDE_VERSION >= 319
00171   Q_UNUSED( ascending )
00172   if ( parentListView->showIM() ) {
00173     // in this case, one column is reserved for IM presence
00174     // so we have to process it differently
00175     if ( column == parentListView->imColumn() ) {
00176       // increment by one before converting to string so that -1 is not greater than 1
00177       // create the sort key by taking the numeric status 0 low, 5 high, and subtracting it from 5
00178       // so that the default ascending gives online before offline, etc.
00179       QString key = QString::number( 5 - ( mIMProxy->presenceNumeric( mAddressee.uid() ) + 1 ) );
00180       return key;
00181     }
00182     else {
00183       return mFields[ column ]->sortKey( mAddressee );
00184     }
00185   }
00186   else
00187     return mFields[ column ]->sortKey( mAddressee );
00188 #else
00189   return QListViewItem::key( column, ascending ).lower();
00190 #endif
00191 }
00192 
00193 void ContactListViewItem::paintCell(QPainter * p,
00194                                     const QColorGroup & cg,
00195                                     int column,
00196                                     int width,
00197                                     int align)
00198 {
00199   KListViewItem::paintCell(p, cg, column, width, align);
00200 
00201   if ( !p )
00202     return;
00203 
00204   if (parentListView->singleLine()) {
00205     p->setPen( parentListView->alternateColor() );
00206     p->drawLine( 0, height() - 1, width, height() - 1 );
00207   }
00208 }
00209 
00210 
00211 ContactListView *ContactListViewItem::parent()
00212 {
00213   return parentListView;
00214 }
00215 
00216 
00217 void ContactListViewItem::refresh()
00218 {
00219   // Update our addressee, since it may have changed else were
00220   mAddressee = mDocument->findByUid(mAddressee.uid());
00221   if (mAddressee.isEmpty())
00222     return;
00223 
00224   int i = 0;
00225   // don't show unknown presence, it's not interesting
00226   if ( mHasIM ) {
00227     if ( mIMProxy->presenceNumeric( mAddressee.uid() ) > 0 )
00228       setPixmap( parentListView->imColumn(), mIMProxy->presenceIcon( mAddressee.uid() ) );
00229     else
00230       setPixmap( parentListView->imColumn(), QPixmap() );
00231   }
00232 
00233   KABC::Field::List::ConstIterator it;
00234   for ( it = mFields.begin(); it != mFields.end(); ++it ) {
00235     if ( (*it)->label() == KABC::Addressee::birthdayLabel() ) {
00236       QDate date = mAddressee.birthday().date();
00237       if ( date.isValid() )
00238         setText( i++, KGlobal::locale()->formatDate( date, true ) );
00239       else
00240         setText( i++, "" );
00241     } else
00242       setText( i++, (*it)->value( mAddressee ) );
00243   }
00244 }
00245 
00246 void ContactListViewItem::setHasIM( bool hasIM )
00247 {
00248   mHasIM = hasIM;
00249 }
00250 
00252 // ContactListView
00253 
00254 ContactListView::ContactListView(KAddressBookTableView *view,
00255                                  KABC::AddressBook* /* doc */,
00256                                  QWidget *parent,
00257                                  const char *name )
00258   : KListView( parent, name ),
00259     pabWidget( view ),
00260     oldColumn( 0 )
00261 {
00262   mABackground = true;
00263   mSingleLine = false;
00264   mToolTips = true;
00265   mShowIM = true;
00266   mAlternateColor = KGlobalSettings::alternateBackgroundColor();
00267 
00268   setAlternateBackgroundEnabled(mABackground);
00269   setAcceptDrops( true );
00270   viewport()->setAcceptDrops( true );
00271   setAllColumnsShowFocus( true );
00272   setShowSortIndicator(true);
00273   setSelectionModeExt( KListView::Extended );
00274   setDropVisualizer(false);
00275 
00276   connect(this, SIGNAL(dropped(QDropEvent*)),
00277           this, SLOT(itemDropped(QDropEvent*)));
00278 
00279   new DynamicTip( this );
00280 }
00281 
00282 void ContactListView::paintEmptyArea( QPainter * p, const QRect & rect )
00283 {
00284   QBrush b = palette().brush(QPalette::Active, QColorGroup::Base);
00285 
00286   // Get the brush, which will have the background pixmap if there is one.
00287   if (b.pixmap())
00288   {
00289     p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(),
00290       *(b.pixmap()),
00291       rect.left() + contentsX(),
00292       rect.top() + contentsY() );
00293   }
00294 
00295   else
00296   {
00297     // Do a normal paint
00298     KListView::paintEmptyArea(p, rect);
00299   }
00300 }
00301 
00302 void ContactListView::contentsMousePressEvent(QMouseEvent* e)
00303 {
00304   presspos = e->pos();
00305   KListView::contentsMousePressEvent(e);
00306 }
00307 
00308 
00309 // To initiate a drag operation
00310 void ContactListView::contentsMouseMoveEvent( QMouseEvent *e )
00311 {
00312   if ((e->state() & LeftButton) && (e->pos() - presspos).manhattanLength() > 4 ) {
00313     emit startAddresseeDrag();
00314   }
00315   else
00316     KListView::contentsMouseMoveEvent( e );
00317 }
00318 
00319 bool ContactListView::acceptDrag(QDropEvent *e) const
00320 {
00321   return QTextDrag::canDecode(e);
00322 }
00323 
00324 void ContactListView::itemDropped(QDropEvent *e)
00325 {
00326   contentsDropEvent(e);
00327 }
00328 
00329 void ContactListView::contentsDropEvent( QDropEvent *e )
00330 {
00331   emit addresseeDropped(e);
00332 }
00333 
00334 void ContactListView::setAlternateBackgroundEnabled(bool enabled)
00335 {
00336   mABackground = enabled;
00337 
00338   if (mABackground)
00339   {
00340     setAlternateBackground(mAlternateColor);
00341   }
00342   else
00343   {
00344     setAlternateBackground(QColor());
00345   }
00346 }
00347 
00348 void ContactListView::setBackgroundPixmap(const QString &filename)
00349 {
00350   if (filename.isEmpty())
00351   {
00352     unsetPalette();
00353   }
00354   else
00355   {
00356     setPaletteBackgroundPixmap(QPixmap(filename));
00357   }
00358 }
00359 
00360 void ContactListView::setShowIM( bool enabled )
00361 {
00362   mShowIM = enabled;
00363 }
00364 
00365 bool ContactListView::showIM()
00366 {
00367   return mShowIM;
00368 }
00369 
00370 void ContactListView::setIMColumn( int column )
00371 {
00372   mInstantMsgColumn = column;
00373 }
00374 
00375 int ContactListView::imColumn()
00376 {
00377   return mInstantMsgColumn;
00378 }
00379 
00380 #include "contactlistview.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys