kaddressbook

contactlistview.cpp
1 /*
2  This file is part of KAddressBook.
3  Copyright (c) 2002 Mike Pilone <mpilone@slac.com>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 
19  As a special exception, permission is given to link this program
20  with any edition of TQt, and distribute the resulting executable,
21  without including the source code for TQt in the source distribution.
22 */
23 
24 #include <tqheader.h>
25 #include <tqiconset.h>
26 #include <tqimage.h>
27 #include <tqdragobject.h>
28 #include <tqcombobox.h>
29 #include <tqpainter.h>
30 #include <tqbrush.h>
31 #include <tqevent.h>
32 
33 #include <tdelocale.h>
34 #include <tdeglobalsettings.h>
35 #include <kdebug.h>
36 #include <tdeconfig.h>
37 #include <tdeapplication.h>
38 #include <kurl.h>
39 #include <tdeabc/addressbook.h>
40 #include <tdeabc/addressee.h>
41 #include <tdeimproxy.h>
42 
43 #include "kaddressbooktableview.h"
44 
45 #include "contactlistview.h"
46 
48 // DynamicTip Methods
49 
50 DynamicTip::DynamicTip( ContactListView *parent)
51  : TQToolTip( parent )
52 {
53 }
54 
55 void DynamicTip::maybeTip( const TQPoint &pos )
56 {
57  if (!parentWidget()->inherits( "ContactListView" ))
58  return;
59 
60  ContactListView *plv = (ContactListView*)parentWidget();
61  if (!plv->tooltips())
62  return;
63 
64  TQPoint posVp = plv->viewport()->pos();
65 
66  TQListViewItem *lvi = plv->itemAt( pos - posVp );
67  if (!lvi)
68  return;
69 
70  ContactListViewItem *plvi = dynamic_cast< ContactListViewItem* >(lvi);
71  if (!plvi)
72  return;
73 
74  TQString s;
75  TQRect r = plv->itemRect( lvi );
76  r.moveBy( posVp.x(), posVp.y() );
77 
78  //kdDebug(5720) << "Tip rec: " << r.x() << "," << r.y() << "," << r.width()
79  // << "," << r.height() << endl;
80 
81  TDEABC::Addressee a = plvi->addressee();
82  if (a.isEmpty())
83  return;
84 
85  s += i18n("label: value", "%1: %2").arg(a.formattedNameLabel())
86  .arg(a.formattedName());
87 
88  s += '\n';
89  s += i18n("label: value", "%1: %2").arg(a.organizationLabel())
90  .arg(a.organization());
91 
92  TQString notes = a.note().stripWhiteSpace();
93  if ( !notes.isEmpty() ) {
94  notes += '\n';
95  s += '\n' + i18n("label: value", "%1: \n").arg(a.noteLabel());
96  TQFontMetrics fm( font() );
97 
98  // Begin word wrap code based on TQMultiLineEdit code
99  int i = 0;
100  bool doBreak = false;
101  int linew = 0;
102  int lastSpace = -1;
103  int a = 0;
104  int lastw = 0;
105 
106  while ( i < int(notes.length()) ) {
107  doBreak = false;
108  if ( notes[i] != '\n' )
109  linew += fm.width( notes[i] );
110 
111  if ( lastSpace >= a && notes[i] != '\n' )
112  if (linew >= parentWidget()->width()) {
113  doBreak = true;
114  if ( lastSpace > a ) {
115  i = lastSpace;
116  linew = lastw;
117  }
118  else
119  i = TQMAX( a, i-1 );
120  }
121 
122  if ( notes[i] == '\n' || doBreak ) {
123  s += notes.mid( a, i - a + (doBreak?1:0) ) +"\n";
124 
125  a = i + 1;
126  lastSpace = a;
127  linew = 0;
128  }
129 
130  if ( notes[i].isSpace() ) {
131  lastSpace = i;
132  lastw = linew;
133  }
134 
135  if ( lastSpace <= a ) {
136  lastw = linew;
137  }
138 
139  ++i;
140  }
141  }
142 
143  tip( r, s );
144 }
145 
147 // ContactListViewItem Methods
148 
149 ContactListViewItem::ContactListViewItem(const TDEABC::Addressee &a,
150  ContactListView *parent,
151  TDEABC::AddressBook *doc,
152  const TDEABC::Field::List &fields,
153  KIMProxy *proxy )
154  : TDEListViewItem(parent), mAddressee(a), mFields( fields ),
155  parentListView( parent ), mDocument(doc), mIMProxy( proxy )
156 {
157  if ( mIMProxy )
158  mHasIM = mIMProxy->isPresent( mAddressee.uid() );
159  else
160  mHasIM = false;
161  refresh();
162 }
163 
164 TQString ContactListViewItem::key(int column, bool ascending) const
165 {
166  // Preserve behaviour of TQListViewItem::key(), otherwise we cause a crash if the column does not exist
167  if ( column >= parentListView->columns() )
168  return TQString();
169 
170 #if TDE_VERSION >= 319
171  Q_UNUSED( ascending )
172  if ( parentListView->showIM() ) {
173  // in this case, one column is reserved for IM presence
174  // so we have to process it differently
175  if ( column == parentListView->imColumn() ) {
176  // increment by one before converting to string so that -1 is not greater than 1
177  // create the sort key by taking the numeric status 0 low, 5 high, and subtracting it from 5
178  // so that the default ascending gives online before offline, etc.
179  TQString key = TQString::number( 5 - ( mIMProxy->presenceNumeric( mAddressee.uid() ) + 1 ) );
180  return key;
181  }
182  else {
183  return mFields[ column ]->sortKey( mAddressee );
184  }
185  }
186  else
187  return mFields[ column ]->sortKey( mAddressee );
188 #else
189  return TQListViewItem::key( column, ascending ).lower();
190 #endif
191 }
192 
193 void ContactListViewItem::paintCell(TQPainter * p,
194  const TQColorGroup & cg,
195  int column,
196  int width,
197  int align)
198 {
199  TDEListViewItem::paintCell(p, cg, column, width, align);
200 
201  if ( !p )
202  return;
203 
204  if (parentListView->singleLine()) {
205  p->setPen( parentListView->alternateColor() );
206  p->drawLine( 0, height() - 1, width, height() - 1 );
207  }
208 }
209 
210 
211 ContactListView *ContactListViewItem::parent()
212 {
213  return parentListView;
214 }
215 
216 
217 void ContactListViewItem::refresh()
218 {
219  // Avoid crash on exit
220  if ( !mDocument ) {
221  return;
222  }
223 
224  // Update our addressee, since it may have changed elsewhere
225  mAddressee = mDocument->findByUid(mAddressee.uid());
226  if (mAddressee.isEmpty())
227  return;
228 
229  int i = 0;
230  // don't show unknown presence, it's not interesting
231  if ( mHasIM ) {
232  if ( mIMProxy->presenceNumeric( mAddressee.uid() ) > 0 )
233  setPixmap( parentListView->imColumn(), mIMProxy->presenceIcon( mAddressee.uid() ) );
234  else
235  setPixmap( parentListView->imColumn(), TQPixmap() );
236  }
237 
238  TDEABC::Field::List::ConstIterator it;
239  for ( it = mFields.begin(); it != mFields.end(); ++it ) {
240  if ( (*it)->label() == TDEABC::Addressee::birthdayLabel() ) {
241  TQDate date = mAddressee.birthday().date();
242  if ( date.isValid() )
243  setText( i++, TDEGlobal::locale()->formatDate( date, true ) );
244  else
245  setText( i++, "" );
246  } else
247  setText( i++, (*it)->value( mAddressee ) );
248  }
249 }
250 
251 void ContactListViewItem::setHasIM( bool hasIM )
252 {
253  mHasIM = hasIM;
254 }
255 
257 // ContactListView
258 
259 ContactListView::ContactListView(KAddressBookTableView *view,
260  TDEABC::AddressBook* /* doc */,
261  TQWidget *parent,
262  const char *name )
263  : TDEListView( parent, name ),
264  pabWidget( view ),
265  oldColumn( 0 )
266 {
267  mABackground = true;
268  mSingleLine = false;
269  mToolTips = true;
270  mShowIM = true;
271  mAlternateColor = TDEGlobalSettings::alternateBackgroundColor();
272 
273  setAlternateBackgroundEnabled(mABackground);
274  setAcceptDrops( true );
275  viewport()->setAcceptDrops( true );
276  setAllColumnsShowFocus( true );
277  setShowSortIndicator(true);
278  setSelectionModeExt( TDEListView::Extended );
279  setDropVisualizer(false);
280 
281  connect(this, TQ_SIGNAL(dropped(TQDropEvent*)),
282  this, TQ_SLOT(itemDropped(TQDropEvent*)));
283 
284  new DynamicTip( this );
285 }
286 
287 void ContactListView::paintEmptyArea( TQPainter * p, const TQRect & rect )
288 {
289  TQBrush b = palette().brush(TQPalette::Active, TQColorGroup::Base);
290 
291  // Get the brush, which will have the background pixmap if there is one.
292  if (b.pixmap())
293  {
294  p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(),
295  *(b.pixmap()),
296  rect.left() + contentsX(),
297  rect.top() + contentsY() );
298  }
299 
300  else
301  {
302  // Do a normal paint
303  TDEListView::paintEmptyArea(p, rect);
304  }
305 }
306 
307 void ContactListView::contentsMousePressEvent(TQMouseEvent* e)
308 {
309  presspos = e->pos();
310  TDEListView::contentsMousePressEvent(e);
311 }
312 
313 
314 // To initiate a drag operation
315 void ContactListView::contentsMouseMoveEvent( TQMouseEvent *e )
316 {
317  if ((e->state() & TQt::LeftButton) && (e->pos() - presspos).manhattanLength() > 4 ) {
318  emit startAddresseeDrag();
319  }
320  else
321  TDEListView::contentsMouseMoveEvent( e );
322 }
323 
324 bool ContactListView::acceptDrag(TQDropEvent *e) const
325 {
326  return TQTextDrag::canDecode(e);
327 }
328 
329 void ContactListView::itemDropped(TQDropEvent *e)
330 {
331  contentsDropEvent(e);
332 }
333 
334 void ContactListView::contentsDropEvent( TQDropEvent *e )
335 {
336  emit addresseeDropped(e);
337 }
338 
339 void ContactListView::setAlternateBackgroundEnabled(bool enabled)
340 {
341  mABackground = enabled;
342 
343  if (mABackground)
344  {
345  setAlternateBackground(mAlternateColor);
346  }
347  else
348  {
349  setAlternateBackground(TQColor());
350  }
351 }
352 
353 void ContactListView::setBackgroundPixmap(const TQString &filename)
354 {
355  if (filename.isEmpty())
356  {
357  unsetPalette();
358  }
359  else
360  {
361  setPaletteBackgroundPixmap(TQPixmap(filename));
362  }
363 }
364 
365 void ContactListView::setShowIM( bool enabled )
366 {
367  mShowIM = enabled;
368 }
369 
370 bool ContactListView::showIM()
371 {
372  return mShowIM;
373 }
374 
375 void ContactListView::setIMColumn( int column )
376 {
377  mInstantMsgColumn = column;
378 }
379 
380 int ContactListView::imColumn()
381 {
382  return mInstantMsgColumn;
383 }
384 
385 #include "contactlistview.moc"
The whole tooltip design needs a lot of work.
This class is the table view for kaddressbook.