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  Q_UNUSED( ascending )
171  if ( parentListView->showIM() ) {
172  // in this case, one column is reserved for IM presence
173  // so we have to process it differently
174  if ( column == parentListView->imColumn() ) {
175  // increment by one before converting to string so that -1 is not greater than 1
176  // create the sort key by taking the numeric status 0 low, 5 high, and subtracting it from 5
177  // so that the default ascending gives online before offline, etc.
178  TQString key = TQString::number( 5 - ( mIMProxy->presenceNumeric( mAddressee.uid() ) + 1 ) );
179  return key;
180  }
181  else {
182  return mFields[ column ]->sortKey( mAddressee );
183  }
184  }
185  else
186  return mFields[ column ]->sortKey( mAddressee );
187 }
188 
189 void ContactListViewItem::paintCell(TQPainter * p,
190  const TQColorGroup & cg,
191  int column,
192  int width,
193  int align)
194 {
195  TDEListViewItem::paintCell(p, cg, column, width, align);
196 
197  if ( !p )
198  return;
199 
200  if (parentListView->singleLine()) {
201  p->setPen( parentListView->alternateColor() );
202  p->drawLine( 0, height() - 1, width, height() - 1 );
203  }
204 }
205 
206 
207 ContactListView *ContactListViewItem::parent()
208 {
209  return parentListView;
210 }
211 
212 
213 void ContactListViewItem::refresh()
214 {
215  // Avoid crash on exit
216  if ( !mDocument ) {
217  return;
218  }
219 
220  // Update our addressee, since it may have changed elsewhere
221  mAddressee = mDocument->findByUid(mAddressee.uid());
222  if (mAddressee.isEmpty())
223  return;
224 
225  int i = 0;
226  // don't show unknown presence, it's not interesting
227  if ( mHasIM ) {
228  if ( mIMProxy->presenceNumeric( mAddressee.uid() ) > 0 )
229  setPixmap( parentListView->imColumn(), mIMProxy->presenceIcon( mAddressee.uid() ) );
230  else
231  setPixmap( parentListView->imColumn(), TQPixmap() );
232  }
233 
234  TDEABC::Field::List::ConstIterator it;
235  for ( it = mFields.begin(); it != mFields.end(); ++it ) {
236  if ( (*it)->label() == TDEABC::Addressee::birthdayLabel() ) {
237  TQDate date = mAddressee.birthday().date();
238  if ( date.isValid() )
239  setText( i++, TDEGlobal::locale()->formatDate( date, true ) );
240  else
241  setText( i++, "" );
242  } else
243  setText( i++, (*it)->value( mAddressee ) );
244  }
245 }
246 
247 void ContactListViewItem::setHasIM( bool hasIM )
248 {
249  mHasIM = hasIM;
250 }
251 
253 // ContactListView
254 
255 ContactListView::ContactListView(KAddressBookTableView *view,
256  TDEABC::AddressBook* /* doc */,
257  TQWidget *parent,
258  const char *name )
259  : TDEListView( parent, name ),
260  pabWidget( view ),
261  oldColumn( 0 )
262 {
263  mABackground = true;
264  mSingleLine = false;
265  mToolTips = true;
266  mShowIM = true;
267  mAlternateColor = TDEGlobalSettings::alternateBackgroundColor();
268 
269  setAlternateBackgroundEnabled(mABackground);
270  setAcceptDrops( true );
271  viewport()->setAcceptDrops( true );
272  setAllColumnsShowFocus( true );
273  setShowSortIndicator(true);
274  setSelectionModeExt( TDEListView::Extended );
275  setDropVisualizer(false);
276 
277  connect(this, TQ_SIGNAL(dropped(TQDropEvent*)),
278  this, TQ_SLOT(itemDropped(TQDropEvent*)));
279 
280  new DynamicTip( this );
281 }
282 
283 void ContactListView::paintEmptyArea( TQPainter * p, const TQRect & rect )
284 {
285  TQBrush b = palette().brush(TQPalette::Active, TQColorGroup::Base);
286 
287  // Get the brush, which will have the background pixmap if there is one.
288  if (b.pixmap())
289  {
290  p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(),
291  *(b.pixmap()),
292  rect.left() + contentsX(),
293  rect.top() + contentsY() );
294  }
295 
296  else
297  {
298  // Do a normal paint
299  TDEListView::paintEmptyArea(p, rect);
300  }
301 }
302 
303 void ContactListView::contentsMousePressEvent(TQMouseEvent* e)
304 {
305  presspos = e->pos();
306  TDEListView::contentsMousePressEvent(e);
307 }
308 
309 
310 // To initiate a drag operation
311 void ContactListView::contentsMouseMoveEvent( TQMouseEvent *e )
312 {
313  if ((e->state() & TQt::LeftButton) && (e->pos() - presspos).manhattanLength() > 4 ) {
314  emit startAddresseeDrag();
315  }
316  else
317  TDEListView::contentsMouseMoveEvent( e );
318 }
319 
320 bool ContactListView::acceptDrag(TQDropEvent *e) const
321 {
322  return TQTextDrag::canDecode(e);
323 }
324 
325 void ContactListView::itemDropped(TQDropEvent *e)
326 {
327  contentsDropEvent(e);
328 }
329 
330 void ContactListView::contentsDropEvent( TQDropEvent *e )
331 {
332  emit addresseeDropped(e);
333 }
334 
335 void ContactListView::setAlternateBackgroundEnabled(bool enabled)
336 {
337  mABackground = enabled;
338 
339  if (mABackground)
340  {
341  setAlternateBackground(mAlternateColor);
342  }
343  else
344  {
345  setAlternateBackground(TQColor());
346  }
347 }
348 
349 void ContactListView::setBackgroundPixmap(const TQString &filename)
350 {
351  if (filename.isEmpty())
352  {
353  unsetPalette();
354  }
355  else
356  {
357  setPaletteBackgroundPixmap(TQPixmap(filename));
358  }
359 }
360 
361 void ContactListView::setShowIM( bool enabled )
362 {
363  mShowIM = enabled;
364 }
365 
366 bool ContactListView::showIM()
367 {
368  return mShowIM;
369 }
370 
371 void ContactListView::setIMColumn( int column )
372 {
373  mInstantMsgColumn = column;
374 }
375 
376 int ContactListView::imColumn()
377 {
378  return mInstantMsgColumn;
379 }
380 
381 #include "contactlistview.moc"
The whole tooltip design needs a lot of work.
This class is the table view for kaddressbook.