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 TQt, and distribute the resulting executable,
00021     without including the source code for TQt in the source distribution.
00022 */
00023 
00024 #include <tqheader.h>
00025 #include <tqiconset.h>
00026 #include <tqimage.h>
00027 #include <tqdragobject.h>
00028 #include <tqcombobox.h>
00029 #include <tqpainter.h>
00030 #include <tqbrush.h>
00031 #include <tqevent.h>
00032 
00033 #include <tdelocale.h>
00034 #include <tdeglobalsettings.h>
00035 #include <kdebug.h>
00036 #include <tdeconfig.h>
00037 #include <tdeapplication.h>
00038 #include <kurl.h>
00039 #include <tdeabc/addressbook.h>
00040 #include <tdeabc/addressee.h>
00041 #include <tdeimproxy.h>
00042 
00043 #include "kaddressbooktableview.h"
00044 
00045 #include "contactlistview.h"
00046 
00048 // DynamicTip Methods
00049 
00050 DynamicTip::DynamicTip( ContactListView *parent)
00051   : TQToolTip( parent )
00052 {
00053 }
00054 
00055 void DynamicTip::maybeTip( const TQPoint &pos )
00056 {
00057   if (!parentWidget()->inherits( "ContactListView" ))
00058     return;
00059 
00060   ContactListView *plv = (ContactListView*)parentWidget();
00061   if (!plv->tooltips())
00062     return;
00063 
00064   TQPoint posVp = plv->viewport()->pos();
00065 
00066   TQListViewItem *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   TQString s;
00075   TQRect 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   TDEABC::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   TQString notes = a.note().stripWhiteSpace();
00093   if ( !notes.isEmpty() ) {
00094     notes += '\n';
00095     s += '\n' + i18n("label: value", "%1: \n").arg(a.noteLabel());
00096     TQFontMetrics fm( font() );
00097 
00098     // Begin word wrap code based on TQMultiLineEdit 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 = TQMAX( 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 TDEABC::Addressee &a,
00150                                          ContactListView *parent,
00151                                          TDEABC::AddressBook *doc,
00152                                          const TDEABC::Field::List &fields,
00153                                          KIMProxy *proxy )
00154   : TDEListViewItem(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 TQString ContactListViewItem::key(int column, bool ascending) const
00165 {
00166   // Preserve behaviour of TQListViewItem::key(), otherwise we cause a crash if the column does not exist
00167   if ( column >= parentListView->columns() )
00168     return TQString();
00169 
00170 #if TDE_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       TQString key = TQString::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 TQListViewItem::key( column, ascending ).lower();
00190 #endif
00191 }
00192 
00193 void ContactListViewItem::paintCell(TQPainter * p,
00194                                     const TQColorGroup & cg,
00195                                     int column,
00196                                     int width,
00197                                     int align)
00198 {
00199   TDEListViewItem::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   // Avoid crash on exit
00220   if ( !mDocument ) {
00221       return;
00222   }
00223 
00224   // Update our addressee, since it may have changed elsewhere
00225   mAddressee = mDocument->findByUid(mAddressee.uid());
00226   if (mAddressee.isEmpty())
00227     return;
00228 
00229   int i = 0;
00230   // don't show unknown presence, it's not interesting
00231   if ( mHasIM ) {
00232     if ( mIMProxy->presenceNumeric( mAddressee.uid() ) > 0 )
00233       setPixmap( parentListView->imColumn(), mIMProxy->presenceIcon( mAddressee.uid() ) );
00234     else
00235       setPixmap( parentListView->imColumn(), TQPixmap() );
00236   }
00237 
00238   TDEABC::Field::List::ConstIterator it;
00239   for ( it = mFields.begin(); it != mFields.end(); ++it ) {
00240     if ( (*it)->label() == TDEABC::Addressee::birthdayLabel() ) {
00241       TQDate date = mAddressee.birthday().date();
00242       if ( date.isValid() )
00243         setText( i++, TDEGlobal::locale()->formatDate( date, true ) );
00244       else
00245         setText( i++, "" );
00246     } else
00247       setText( i++, (*it)->value( mAddressee ) );
00248   }
00249 }
00250 
00251 void ContactListViewItem::setHasIM( bool hasIM )
00252 {
00253   mHasIM = hasIM;
00254 }
00255 
00257 // ContactListView
00258 
00259 ContactListView::ContactListView(KAddressBookTableView *view,
00260                                  TDEABC::AddressBook* /* doc */,
00261                                  TQWidget *parent,
00262                                  const char *name )
00263   : TDEListView( parent, name ),
00264     pabWidget( view ),
00265     oldColumn( 0 )
00266 {
00267   mABackground = true;
00268   mSingleLine = false;
00269   mToolTips = true;
00270   mShowIM = true;
00271   mAlternateColor = TDEGlobalSettings::alternateBackgroundColor();
00272 
00273   setAlternateBackgroundEnabled(mABackground);
00274   setAcceptDrops( true );
00275   viewport()->setAcceptDrops( true );
00276   setAllColumnsShowFocus( true );
00277   setShowSortIndicator(true);
00278   setSelectionModeExt( TDEListView::Extended );
00279   setDropVisualizer(false);
00280 
00281   connect(this, TQT_SIGNAL(dropped(TQDropEvent*)),
00282           this, TQT_SLOT(itemDropped(TQDropEvent*)));
00283 
00284   new DynamicTip( this );
00285 }
00286 
00287 void ContactListView::paintEmptyArea( TQPainter * p, const TQRect & rect )
00288 {
00289   TQBrush b = palette().brush(TQPalette::Active, TQColorGroup::Base);
00290 
00291   // Get the brush, which will have the background pixmap if there is one.
00292   if (b.pixmap())
00293   {
00294     p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(),
00295       *(b.pixmap()),
00296       rect.left() + contentsX(),
00297       rect.top() + contentsY() );
00298   }
00299 
00300   else
00301   {
00302     // Do a normal paint
00303     TDEListView::paintEmptyArea(p, rect);
00304   }
00305 }
00306 
00307 void ContactListView::contentsMousePressEvent(TQMouseEvent* e)
00308 {
00309   presspos = e->pos();
00310   TDEListView::contentsMousePressEvent(e);
00311 }
00312 
00313 
00314 // To initiate a drag operation
00315 void ContactListView::contentsMouseMoveEvent( TQMouseEvent *e )
00316 {
00317   if ((e->state() & Qt::LeftButton) && (e->pos() - presspos).manhattanLength() > 4 ) {
00318     emit startAddresseeDrag();
00319   }
00320   else
00321     TDEListView::contentsMouseMoveEvent( e );
00322 }
00323 
00324 bool ContactListView::acceptDrag(TQDropEvent *e) const
00325 {
00326   return TQTextDrag::canDecode(e);
00327 }
00328 
00329 void ContactListView::itemDropped(TQDropEvent *e)
00330 {
00331   contentsDropEvent(e);
00332 }
00333 
00334 void ContactListView::contentsDropEvent( TQDropEvent *e )
00335 {
00336   emit addresseeDropped(e);
00337 }
00338 
00339 void ContactListView::setAlternateBackgroundEnabled(bool enabled)
00340 {
00341   mABackground = enabled;
00342 
00343   if (mABackground)
00344   {
00345     setAlternateBackground(mAlternateColor);
00346   }
00347   else
00348   {
00349     setAlternateBackground(TQColor());
00350   }
00351 }
00352 
00353 void ContactListView::setBackgroundPixmap(const TQString &filename)
00354 {
00355   if (filename.isEmpty())
00356   {
00357     unsetPalette();
00358   }
00359   else
00360   {
00361     setPaletteBackgroundPixmap(TQPixmap(filename));
00362   }
00363 }
00364 
00365 void ContactListView::setShowIM( bool enabled )
00366 {
00367   mShowIM = enabled;
00368 }
00369 
00370 bool ContactListView::showIM()
00371 {
00372   return mShowIM;
00373 }
00374 
00375 void ContactListView::setIMColumn( int column )
00376 {
00377   mInstantMsgColumn = column;
00378 }
00379 
00380 int ContactListView::imColumn()
00381 {
00382   return mInstantMsgColumn;
00383 }
00384 
00385 #include "contactlistview.moc"