-rw-r--r-- | kaddressbook/views/cardview.cpp | 1719 | ||||
-rw-r--r-- | kaddressbook/views/cardview.desktop | 18 | ||||
-rw-r--r-- | kaddressbook/views/cardview.h | 473 | ||||
-rw-r--r-- | kaddressbook/views/colorlistbox.cpp | 230 | ||||
-rw-r--r-- | kaddressbook/views/colorlistbox.h | 76 | ||||
-rw-r--r-- | kaddressbook/views/configurecardviewdialog.cpp | 364 | ||||
-rw-r--r-- | kaddressbook/views/configurecardviewdialog.h | 117 | ||||
-rw-r--r-- | kaddressbook/views/configuretableviewdialog.cpp | 155 | ||||
-rw-r--r-- | kaddressbook/views/configuretableviewdialog.h | 88 | ||||
-rw-r--r-- | kaddressbook/views/contactlistview.cpp | 340 | ||||
-rw-r--r-- | kaddressbook/views/contactlistview.h | 128 | ||||
-rw-r--r-- | kaddressbook/views/kaddressbookcardview.cpp | 394 | ||||
-rw-r--r-- | kaddressbook/views/kaddressbookcardview.h | 117 | ||||
-rw-r--r-- | kaddressbook/views/kaddressbookiconview.cpp | 378 | ||||
-rw-r--r-- | kaddressbook/views/kaddressbookiconview.h | 130 | ||||
-rw-r--r-- | kaddressbook/views/kaddressbooktableview.cpp | 337 | ||||
-rw-r--r-- | kaddressbook/views/kaddressbooktableview.h | 114 |
17 files changed, 5178 insertions, 0 deletions
diff --git a/kaddressbook/views/cardview.cpp b/kaddressbook/views/cardview.cpp new file mode 100644 index 0000000..65f793c --- a/dev/null +++ b/kaddressbook/views/cardview.cpp | |||
@@ -0,0 +1,1719 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | //BEGIN Includes | ||
25 | #include "cardview.h" | ||
26 | |||
27 | #include <limits.h> | ||
28 | |||
29 | #include <qpainter.h> | ||
30 | #include <qtimer.h> | ||
31 | #include <qdatetime.h> | ||
32 | #include <qlabel.h> | ||
33 | #include <qstyle.h> | ||
34 | #include <qcursor.h> | ||
35 | #include <qtooltip.h> | ||
36 | |||
37 | #include <kdebug.h> | ||
38 | #include <kglobalsettings.h> | ||
39 | //END includes | ||
40 | |||
41 | #define MIN_ITEM_WIDTH 80 | ||
42 | |||
43 | //BEGIN Helpers | ||
44 | ////////////////////////////////////// | ||
45 | // CardViewTip | ||
46 | class CardViewTip : public QLabel { | ||
47 | public: | ||
48 | CardViewTip(QWidget *parent=0, const char *name=0) : QLabel( parent, name ) | ||
49 | { | ||
50 | setPalette( QToolTip::palette() ); | ||
51 | setFrameStyle( Panel|Plain ); | ||
52 | setMidLineWidth(0); | ||
53 | setIndent(1); | ||
54 | } | ||
55 | |||
56 | ~CardViewTip() {}; | ||
57 | protected: | ||
58 | void leaveEvent( QEvent * ) | ||
59 | { | ||
60 | hide(); | ||
61 | } | ||
62 | }; | ||
63 | |||
64 | ////////////////////////////////////// | ||
65 | // CardViewItemList | ||
66 | |||
67 | |||
68 | // | ||
69 | // Warning: make sure you use findRef() instead of find() to find an | ||
70 | // item! Only the pointer value is unique in the list. | ||
71 | // | ||
72 | class CardViewItemList : public QPtrList<CardViewItem> | ||
73 | { | ||
74 | protected: | ||
75 | virtual int compareItems(QPtrCollection::Item item1, | ||
76 | QPtrCollection::Item item2) | ||
77 | { | ||
78 | CardViewItem *cItem1 = (CardViewItem*)item1; | ||
79 | CardViewItem *cItem2 = (CardViewItem*)item2; | ||
80 | |||
81 | if ( cItem1 == cItem2 ) | ||
82 | return 0; | ||
83 | |||
84 | if ((cItem1 == 0) || (cItem2 == 0)) | ||
85 | return cItem1 ? -1 : 1; | ||
86 | |||
87 | if (cItem1->caption() < cItem2->caption()) | ||
88 | return -1; | ||
89 | |||
90 | else if (cItem1->caption() > cItem2->caption()) | ||
91 | return 1; | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | private: | ||
97 | /*int find( const CardViewItem * ) | ||
98 | { | ||
99 | qDebug("DON'T USE CardViewItemList::find( item )! Use findRef( item )!"); | ||
100 | }*/ | ||
101 | }; | ||
102 | |||
103 | ////////////////////////////////////// | ||
104 | // CardViewSeparator | ||
105 | class CardViewSeparator | ||
106 | { | ||
107 | friend class CardView; | ||
108 | |||
109 | public: | ||
110 | CardViewSeparator(CardView *view) | ||
111 | : mView(view) | ||
112 | { | ||
113 | mRect = QRect(0, 0, view->separatorWidth(), 0); | ||
114 | } | ||
115 | |||
116 | ~CardViewSeparator() {} | ||
117 | |||
118 | void paintSeparator(QPainter *p, QColorGroup &cg) | ||
119 | { | ||
120 | p->fillRect(0, 0, mRect.width(), mRect.height(), | ||
121 | cg.brush(QColorGroup::Button)); | ||
122 | } | ||
123 | |||
124 | void repaintSeparator() | ||
125 | { | ||
126 | mView->repaintContents(mRect); | ||
127 | } | ||
128 | |||
129 | private: | ||
130 | CardView *mView; | ||
131 | QRect mRect; | ||
132 | }; | ||
133 | |||
134 | //END Helpers | ||
135 | |||
136 | //BEGIN Private Data | ||
137 | |||
138 | class CardViewPrivate | ||
139 | { | ||
140 | public: | ||
141 | CardViewPrivate() | ||
142 | : mSelectionMode( CardView::Multi ), | ||
143 | mDrawCardBorder( true ), | ||
144 | mDrawFieldLabels( true ), | ||
145 | mDrawSeparators( true), | ||
146 | mSepWidth( 2 ), | ||
147 | mShowEmptyFields( false ), | ||
148 | mLayoutDirty( true ), | ||
149 | mLastClickOnItem( false ), | ||
150 | mItemMargin( 0 ), | ||
151 | mItemSpacing( 10 ), | ||
152 | mItemWidth( 200 ), | ||
153 | mMaxFieldLines( INT_MAX ), | ||
154 | mCurrentItem( 0L ), | ||
155 | mLastClickPos( QPoint(0, 0) ), | ||
156 | mRubberBandAnchor( 0 ), | ||
157 | mCompText( QString::null ), | ||
158 | mResizeAnchor(0) | ||
159 | {}; | ||
160 | |||
161 | CardViewItemList mItemList; | ||
162 | QPtrList<CardViewSeparator> mSeparatorList; | ||
163 | QFontMetrics *mFm; | ||
164 | QFontMetrics *mBFm; // bold font | ||
165 | QFont mHeaderFont; // custom header font | ||
166 | CardView::SelectionMode mSelectionMode; | ||
167 | bool mDrawCardBorder; | ||
168 | bool mDrawFieldLabels; | ||
169 | bool mDrawSeparators; | ||
170 | int mSepWidth; | ||
171 | bool mShowEmptyFields; | ||
172 | bool mLayoutDirty; | ||
173 | bool mLastClickOnItem; | ||
174 | uint mItemMargin; // internal margin in items | ||
175 | uint mItemSpacing; // spacing between items, column seperators and border | ||
176 | int mItemWidth; // width of all items | ||
177 | uint mMaxFieldLines; // Max lines to dispaly pr field | ||
178 | CardViewItem *mCurrentItem; | ||
179 | QPoint mLastClickPos; | ||
180 | QTimer *mTimer; // times out if mouse rests for more than 500 msecs | ||
181 | CardViewTip *mTip; // passed to the item under a resting cursor to display full text | ||
182 | bool mOnSeparator; // set/reset on mouse movement | ||
183 | // for resizing by dragging the separators | ||
184 | int mResizeAnchor; // uint, ulong? the mouse down separator left | ||
185 | int mRubberBandAnchor; // for erasing rubber bands | ||
186 | // data used for resizing. | ||
187 | // as they are beeded by each mouse move while resizing, we store them here, | ||
188 | // saving 8 calculations in each mouse move. | ||
189 | int colspace; // amount of space between items pr column | ||
190 | uint first; // the first col to anchor at for painting rubber bands | ||
191 | int firstX; // X position of first in pixel | ||
192 | int pressed; // the colummn that was pressed on at resizing start | ||
193 | int span; // pressed - first | ||
194 | // key completion | ||
195 | QString mCompText; // current completion string | ||
196 | QDateTime mCompUpdated; // ...was updated at this time | ||
197 | }; | ||
198 | |||
199 | class CardViewItemPrivate | ||
200 | { | ||
201 | public: | ||
202 | CardViewItemPrivate() : | ||
203 | x( 0 ), | ||
204 | y( 0 ), | ||
205 | mSelected( false ){}; | ||
206 | |||
207 | |||
208 | QString mCaption; | ||
209 | QPtrList< CardViewItem::Field > mFieldList; | ||
210 | bool mSelected; | ||
211 | int x; // horizontal position, set by the view | ||
212 | int y; // vertical position, set by the view | ||
213 | int maxLabelWidth; // the width of the widest label, according to the view font. | ||
214 | int hcache; // height cache | ||
215 | }; | ||
216 | //END Private Data | ||
217 | |||
218 | //BEGIN CardViewItem | ||
219 | |||
220 | CardViewItem::CardViewItem(CardView *parent, QString caption) | ||
221 | : d(new CardViewItemPrivate()), mView(parent) | ||
222 | { | ||
223 | d->mCaption = caption; | ||
224 | |||
225 | initialize(); | ||
226 | } | ||
227 | |||
228 | CardViewItem::~CardViewItem() | ||
229 | { | ||
230 | // Remove ourself from the view | ||
231 | if (mView != 0) | ||
232 | mView->takeItem(this); | ||
233 | |||
234 | delete d; | ||
235 | d = 0; | ||
236 | } | ||
237 | |||
238 | void CardViewItem::initialize() | ||
239 | { | ||
240 | d->mSelected = false; | ||
241 | d->mFieldList.setAutoDelete(true); | ||
242 | d->maxLabelWidth = 0; | ||
243 | d->hcache=0; | ||
244 | |||
245 | //calcRect(); | ||
246 | |||
247 | // Add ourself to the view | ||
248 | if (mView != 0) | ||
249 | mView->insertItem(this); | ||
250 | } | ||
251 | |||
252 | void CardViewItem::paintCard(QPainter *p, QColorGroup &cg) | ||
253 | { | ||
254 | |||
255 | if (!mView) | ||
256 | return; | ||
257 | |||
258 | QPen pen; | ||
259 | QBrush brush; | ||
260 | QFontMetrics fm = *(mView->d->mFm); | ||
261 | QFontMetrics bFm = *(mView->d->mBFm); | ||
262 | bool drawLabels = mView->d->mDrawFieldLabels; | ||
263 | bool drawBorder = mView->d->mDrawCardBorder; | ||
264 | int mg = mView->itemMargin(); | ||
265 | int w = mView->itemWidth() - (mg*2); | ||
266 | int h = height() - (mg*2); | ||
267 | const int colonWidth( fm.width(":") ); | ||
268 | int labelXPos = 2 + mg; | ||
269 | int labelWidth = QMIN( w/2 - 4 - mg, d->maxLabelWidth + colonWidth + 4 ); | ||
270 | int valueXPos = labelWidth + 4 + mg; | ||
271 | int valueWidth = w - labelWidth - 4 - mg; | ||
272 | |||
273 | p->setFont( mView->font() ); | ||
274 | labelWidth -= colonWidth; // extra space for the colon | ||
275 | |||
276 | if (!drawLabels) | ||
277 | { | ||
278 | valueXPos = labelXPos; | ||
279 | valueWidth = w - 4; | ||
280 | } | ||
281 | |||
282 | // Draw a simple box | ||
283 | if (isSelected()) | ||
284 | pen = QPen(cg.highlight(), 1); | ||
285 | else | ||
286 | pen = QPen(cg.button(), 1); | ||
287 | p->setPen(pen); | ||
288 | |||
289 | // Draw the border - this is only draw if the user asks for it. | ||
290 | if (drawBorder) | ||
291 | p->drawRect( mg, mg, w, h ); | ||
292 | |||
293 | // set the proper pen color for the caption box | ||
294 | if (isSelected()) | ||
295 | brush = cg.brush(QColorGroup::Highlight); | ||
296 | else | ||
297 | brush = cg.brush(QColorGroup::Button); | ||
298 | |||
299 | p->fillRect(mg, mg, w, 4 + bFm.height(), brush); | ||
300 | |||
301 | // Now paint the caption | ||
302 | p->save(); | ||
303 | QFont bFont = mView->headerFont(); | ||
304 | //bFont.setBold(true); | ||
305 | p->setFont(bFont); | ||
306 | if (isSelected()) | ||
307 | p->setPen(cg.highlightedText()); | ||
308 | else | ||
309 | p->setPen(cg.buttonText()); | ||
310 | p->drawText(2+mg, 2+mg + bFm.ascent()/*bFm.height()*//*-bFm.descent()*//*-bFm.leading()*/, trimString(d->mCaption, w-4, bFm)); | ||
311 | p->restore(); | ||
312 | |||
313 | // Go through the fields and draw them | ||
314 | QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); | ||
315 | QString label, value; | ||
316 | int yPos = mg + 4 + bFm.height()/* + 1*/ + fm.height(); // why the + 1 ??? (anders) | ||
317 | p->setPen(cg.text()); | ||
318 | |||
319 | int fh = fm.height(); | ||
320 | int cln( 0 ); | ||
321 | QString tmp; | ||
322 | int maxLines = mView->maxFieldLines(); | ||
323 | for (iter.toFirst(); iter.current(); ++iter) | ||
324 | { | ||
325 | value = (*iter)->second; | ||
326 | if ( value.isEmpty() && ! mView->d->mShowEmptyFields ) | ||
327 | continue; | ||
328 | |||
329 | if (drawLabels) | ||
330 | { | ||
331 | label = trimString((*iter)->first, labelWidth, fm); | ||
332 | p->drawText(labelXPos, yPos, label + ":"); | ||
333 | } | ||
334 | /* US original | ||
335 | for (cln=0; cln <= maxLines; cln++) | ||
336 | { | ||
337 | tmp = value.section('\n',cln,cln); | ||
338 | if ( !tmp.isEmpty() ) p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) ); | ||
339 | else break; | ||
340 | } | ||
341 | */ | ||
342 | |||
343 | //US new implementation | ||
344 | QStringList strlst = QStringList::split('\n', value, true); | ||
345 | |||
346 | for (cln=0; cln <= maxLines && cln <= (int)strlst.count(); cln++) | ||
347 | { | ||
348 | tmp = strlst[cln]; | ||
349 | |||
350 | if ( !tmp.isEmpty() ) | ||
351 | p->drawText( valueXPos, yPos + cln*fh, trimString( tmp, valueWidth, fm ) ); | ||
352 | else | ||
353 | break; | ||
354 | |||
355 | } | ||
356 | |||
357 | if ( cln == 0 ) cln = 1; | ||
358 | yPos += cln * fh + 2; | ||
359 | } | ||
360 | |||
361 | // if we are the current item and the view has focus, draw focus rect | ||
362 | if ( mView->currentItem() == this && mView->hasFocus() ) | ||
363 | { | ||
364 | /*US | ||
365 | mView->style().drawPrimitive( QStyle::PE_FocusRect, p, | ||
366 | QRect(0, 0, mView->itemWidth(), h+(2*mg)), cg, | ||
367 | QStyle::Style_FocusAtBorder, | ||
368 | QStyleOption( isSelected() ? cg.highlight() : cg.base() ) ); | ||
369 | */ | ||
370 | |||
371 | const QColor pHighl = isSelected() ? cg.highlight() : cg.base(); | ||
372 | const QRect r(0, 0, mView->itemWidth(), h+(2*mg)); | ||
373 | #ifndef DESKTOP_VERSION | ||
374 | mView->style().drawFocusRect(p, r, cg, &pHighl, true); | ||
375 | #endif | ||
376 | } | ||
377 | } | ||
378 | |||
379 | const QString &CardViewItem::caption() const | ||
380 | { | ||
381 | return d->mCaption; | ||
382 | } | ||
383 | |||
384 | |||
385 | int CardViewItem::height( bool allowCache ) const | ||
386 | { | ||
387 | // use cache | ||
388 | if ( allowCache && d->hcache ) | ||
389 | return d->hcache; | ||
390 | |||
391 | // Base height: | ||
392 | // 2 for line width | ||
393 | // 2 for top caption pad | ||
394 | // 2 for bottom caption pad | ||
395 | // 2 pad for the end | ||
396 | // + 2 times the advised margin | ||
397 | int baseHeight = 8 + ( 2 * mView->itemMargin() ); | ||
398 | |||
399 | // size of font for each field | ||
400 | // 2 pad for each field | ||
401 | |||
402 | // anders: if the view does not show empty fields, check for value | ||
403 | bool sef = mView->showEmptyFields(); | ||
404 | int fh = mView->d->mFm->height();//lineSpacing(); // font height | ||
405 | //int sp = QMAX( 0, 2- mView->d->mFm->leading() ); // field spacing NOTE make a property | ||
406 | int fieldHeight = 0; | ||
407 | int lines; | ||
408 | int maxLines( mView->maxFieldLines() ); | ||
409 | QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); | ||
410 | for (iter.toFirst(); iter.current(); ++iter) | ||
411 | { | ||
412 | if ( !sef && (*iter)->second.isEmpty() ) | ||
413 | continue; | ||
414 | lines = QMIN( (*iter)->second.contains('\n') + 1, maxLines ); | ||
415 | fieldHeight += ( lines * fh ) + 2;//sp; | ||
416 | } | ||
417 | |||
418 | // height of caption font (bold) | ||
419 | fieldHeight += mView->d->mBFm->height(); | ||
420 | d->hcache = baseHeight + fieldHeight; | ||
421 | return d->hcache; | ||
422 | } | ||
423 | |||
424 | bool CardViewItem::isSelected() const | ||
425 | { | ||
426 | return d->mSelected; | ||
427 | } | ||
428 | |||
429 | void CardViewItem::setSelected(bool selected) | ||
430 | { | ||
431 | d->mSelected = selected; | ||
432 | } | ||
433 | |||
434 | void CardViewItem::insertField(const QString &label, const QString &value) | ||
435 | { | ||
436 | CardViewItem::Field *f = new CardViewItem::Field(label, value); | ||
437 | d->mFieldList.append(f); | ||
438 | d->hcache=0; | ||
439 | |||
440 | if (mView) | ||
441 | { | ||
442 | mView->setLayoutDirty(true); | ||
443 | d->maxLabelWidth = QMAX( mView->d->mFm->width( label ), d->maxLabelWidth ); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | void CardViewItem::removeField(const QString &label) | ||
448 | { | ||
449 | CardViewItem::Field *f; | ||
450 | |||
451 | QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); | ||
452 | for (iter.toFirst(); iter.current(); ++iter) | ||
453 | { | ||
454 | f = *iter; | ||
455 | if (f->first == label) | ||
456 | break; | ||
457 | } | ||
458 | |||
459 | if (*iter) | ||
460 | d->mFieldList.remove(*iter); | ||
461 | d->hcache = 0; | ||
462 | |||
463 | if (mView) | ||
464 | mView->setLayoutDirty(true); | ||
465 | } | ||
466 | |||
467 | void CardViewItem::clearFields() | ||
468 | { | ||
469 | d->mFieldList.clear(); | ||
470 | d->hcache = 0; | ||
471 | |||
472 | if (mView) | ||
473 | mView->setLayoutDirty(true); | ||
474 | } | ||
475 | |||
476 | QString CardViewItem::trimString(const QString &text, int width, | ||
477 | QFontMetrics &fm) | ||
478 | { | ||
479 | if (fm.width(text) <= width) | ||
480 | return text; | ||
481 | |||
482 | QString dots = "..."; | ||
483 | int dotWidth = fm.width(dots); | ||
484 | QString trimmed; | ||
485 | int charNum = 0; | ||
486 | |||
487 | while (fm.width(trimmed) + dotWidth < width) | ||
488 | { | ||
489 | trimmed += text[charNum]; | ||
490 | charNum++; | ||
491 | } | ||
492 | |||
493 | // Now trim the last char, since it put the width over the top | ||
494 | trimmed = trimmed.left(trimmed.length()-1); | ||
495 | trimmed += dots; | ||
496 | |||
497 | return trimmed; | ||
498 | } | ||
499 | |||
500 | CardViewItem *CardViewItem::nextItem() | ||
501 | { | ||
502 | CardViewItem *item = 0; | ||
503 | |||
504 | if (mView) | ||
505 | item = mView->itemAfter(this); | ||
506 | |||
507 | return item; | ||
508 | } | ||
509 | |||
510 | void CardViewItem::repaintCard() | ||
511 | { | ||
512 | if (mView) | ||
513 | mView->repaintItem(this); | ||
514 | } | ||
515 | |||
516 | void CardViewItem::setCaption(const QString &caption) | ||
517 | { | ||
518 | d->mCaption = caption; | ||
519 | repaintCard(); | ||
520 | } | ||
521 | |||
522 | QString CardViewItem::fieldValue(const QString &label) | ||
523 | { | ||
524 | QPtrListIterator< CardViewItem::Field > iter(d->mFieldList); | ||
525 | for (iter.toFirst(); iter.current(); ++iter) | ||
526 | if ((*iter)->first == label) | ||
527 | return (*iter)->second; | ||
528 | |||
529 | return QString(); | ||
530 | } | ||
531 | |||
532 | |||
533 | void CardViewItem::showFullString( const QPoint &itempos, CardViewTip *tip ) | ||
534 | { | ||
535 | bool trimmed( false ); | ||
536 | QString s; | ||
537 | int mrg = mView->itemMargin(); | ||
538 | int y = mView->d->mBFm->height() + 6 + mrg; | ||
539 | int w = mView->itemWidth() - (2*mrg); | ||
540 | int lw; | ||
541 | bool drawLabels = mView->drawFieldLabels(); | ||
542 | bool isLabel = drawLabels && itempos.x() < w/2 ? true : false; | ||
543 | |||
544 | if ( itempos.y() < y ) | ||
545 | { | ||
546 | if ( itempos.y() < 8 + mrg || itempos.y() > y - 4 ) | ||
547 | return; | ||
548 | // this is the caption | ||
549 | s = caption(); | ||
550 | trimmed = mView->d->mBFm->width( s ) > w - 4; | ||
551 | y = 2 + mrg; | ||
552 | lw = 0; | ||
553 | isLabel=true; | ||
554 | } else { | ||
555 | // find the field | ||
556 | Field *f = fieldAt( itempos ); | ||
557 | if ( !f || ( !mView->showEmptyFields() && f->second.isEmpty() ) ) | ||
558 | return; | ||
559 | |||
560 | // y position: | ||
561 | // header font height + 4px hader margin + 2px leading + item margin | ||
562 | // + actual field index * (fontheight + 2px leading) | ||
563 | int maxLines = mView->maxFieldLines(); | ||
564 | bool se = mView->showEmptyFields(); | ||
565 | int fh = mView->d->mFm->height(); | ||
566 | // { | ||
567 | Field *_f; | ||
568 | for (_f = d->mFieldList.first(); _f != f; _f = d->mFieldList.next()) | ||
569 | if ( se || ! _f->second.isEmpty() ) | ||
570 | y += ( QMIN(_f->second.contains('\n')+1, maxLines) * fh ) + 2; | ||
571 | // } | ||
572 | if ( isLabel && itempos.y() > y + fh ) | ||
573 | return; | ||
574 | // label or data? | ||
575 | s = isLabel ? f->first : f->second; | ||
576 | // trimmed? | ||
577 | int colonWidth = mView->d->mFm->width(":"); | ||
578 | lw = drawLabels ? // label width | ||
579 | QMIN( w/2 - 4 - mrg, d->maxLabelWidth + colonWidth + 4 ) : | ||
580 | 0; | ||
581 | int mw = isLabel ? lw - colonWidth : w - lw - (mrg*2); // max width for string | ||
582 | if ( isLabel ) | ||
583 | { | ||
584 | trimmed = mView->d->mFm->width( s ) > mw - colonWidth; | ||
585 | } else { | ||
586 | QRect r( mView->d->mFm->boundingRect( 0, 0, INT_MAX, INT_MAX, Qt::AlignTop|Qt::AlignLeft, s ) ); | ||
587 | trimmed = r.width() > mw || r.height()/fh > QMIN(s.contains('\n') + 1, maxLines); | ||
588 | } | ||
589 | } | ||
590 | if ( trimmed ) | ||
591 | { | ||
592 | tip->setFont( (isLabel && !lw) ? mView->headerFont() : mView->font() ); // if condition is true, a header | ||
593 | tip->setText( s ); | ||
594 | tip->adjustSize(); | ||
595 | // find a proper position | ||
596 | int lx; | ||
597 | lx = isLabel || !drawLabels ? mrg : lw + mrg + 2 /*-1*/; | ||
598 | QPoint pnt(mView->contentsToViewport( QPoint(d->x, d->y) )); | ||
599 | pnt += QPoint(lx, y); | ||
600 | if ( pnt.x() < 0 ) | ||
601 | pnt.setX( 0 ); | ||
602 | if ( pnt.x() + tip->width() > mView->visibleWidth() ) | ||
603 | pnt.setX( mView->visibleWidth() - tip->width() ); | ||
604 | if ( pnt.y() + tip->height() > mView->visibleHeight() ) | ||
605 | pnt.setY( QMAX( 0, mView->visibleHeight() - tip->height() ) ); | ||
606 | // show | ||
607 | tip->move( pnt ); | ||
608 | tip->show(); | ||
609 | } | ||
610 | } | ||
611 | |||
612 | CardViewItem::Field *CardViewItem::fieldAt( const QPoint & itempos ) const | ||
613 | { | ||
614 | int ypos = mView->d->mBFm->height() + 7 + mView->d->mItemMargin; | ||
615 | int iy = itempos.y(); | ||
616 | // skip below caption | ||
617 | if ( iy <= ypos ) | ||
618 | return 0; | ||
619 | // try find a field | ||
620 | bool showEmpty = mView->showEmptyFields(); | ||
621 | int fh = mView->d->mFm->height(); | ||
622 | int maxLines = mView->maxFieldLines(); | ||
623 | Field *f; | ||
624 | for ( f = d->mFieldList.first(); f; f = d->mFieldList.next() ) | ||
625 | { | ||
626 | if ( showEmpty || !f->second.isEmpty() ) | ||
627 | ypos += ( QMIN( f->second.contains('\n')+1, maxLines ) *fh)+2; | ||
628 | if ( iy <= ypos ) | ||
629 | break; | ||
630 | } | ||
631 | return f ? f : 0; | ||
632 | } | ||
633 | //END CardViewItem | ||
634 | |||
635 | //BEGIN CardView | ||
636 | |||
637 | CardView::CardView(QWidget *parent, const char *name) | ||
638 | : QScrollView(parent, name), | ||
639 | d(new CardViewPrivate()) | ||
640 | { | ||
641 | d->mItemList.setAutoDelete(true); | ||
642 | d->mSeparatorList.setAutoDelete(true); | ||
643 | |||
644 | QFont f = font(); | ||
645 | d->mFm = new QFontMetrics(f); | ||
646 | f.setBold(true); | ||
647 | d->mHeaderFont = f; | ||
648 | d->mBFm = new QFontMetrics(f); | ||
649 | d->mTip = ( new CardViewTip( viewport() ) ), | ||
650 | d->mTip->hide(); | ||
651 | d->mTimer = ( new QTimer(this, "mouseTimer") ), | ||
652 | |||
653 | viewport()->setMouseTracking( true ); | ||
654 | viewport()->setFocusProxy(this); | ||
655 | viewport()->setFocusPolicy(WheelFocus); | ||
656 | viewport()->setBackgroundMode(PaletteBase); | ||
657 | |||
658 | connect( d->mTimer, SIGNAL(timeout()), this, SLOT(tryShowFullText()) ); | ||
659 | |||
660 | //US setBackgroundMode(PaletteBackground, PaletteBase); | ||
661 | setBackgroundMode(PaletteBackground); | ||
662 | |||
663 | // no reason for a vertical scrollbar | ||
664 | setVScrollBarMode(AlwaysOff); | ||
665 | } | ||
666 | |||
667 | CardView::~CardView() | ||
668 | { | ||
669 | delete d->mFm; | ||
670 | delete d->mBFm; | ||
671 | delete d; | ||
672 | d = 0; | ||
673 | } | ||
674 | |||
675 | void CardView::insertItem(CardViewItem *item) | ||
676 | { | ||
677 | d->mItemList.inSort(item); | ||
678 | setLayoutDirty(true); | ||
679 | } | ||
680 | |||
681 | void CardView::takeItem(CardViewItem *item) | ||
682 | { | ||
683 | if ( d->mCurrentItem == item ) | ||
684 | d->mCurrentItem = item->nextItem(); | ||
685 | d->mItemList.take(d->mItemList.findRef(item)); | ||
686 | |||
687 | setLayoutDirty(true); | ||
688 | } | ||
689 | |||
690 | void CardView::clear() | ||
691 | { | ||
692 | d->mItemList.clear(); | ||
693 | |||
694 | setLayoutDirty(true); | ||
695 | } | ||
696 | |||
697 | CardViewItem *CardView::currentItem() | ||
698 | { | ||
699 | if ( ! d->mCurrentItem && d->mItemList.count() ) | ||
700 | d->mCurrentItem = d->mItemList.first(); | ||
701 | return d->mCurrentItem; | ||
702 | } | ||
703 | |||
704 | void CardView::setCurrentItem( CardViewItem *item ) | ||
705 | { | ||
706 | if ( !item ) | ||
707 | return; | ||
708 | else if ( item->cardView() != this ) | ||
709 | { | ||
710 | kdDebug(5720)<<"CardView::setCurrentItem: Item ("<<item<<") not owned! Backing out.."<<endl; | ||
711 | return; | ||
712 | } | ||
713 | else if ( item == currentItem() ) | ||
714 | { | ||
715 | return; | ||
716 | } | ||
717 | |||
718 | if ( d->mSelectionMode == Single ) | ||
719 | { | ||
720 | setSelected( item, true ); | ||
721 | } | ||
722 | else | ||
723 | { | ||
724 | CardViewItem *it = d->mCurrentItem; | ||
725 | d->mCurrentItem = item; | ||
726 | if ( it ) | ||
727 | it->repaintCard(); | ||
728 | item->repaintCard(); | ||
729 | } | ||
730 | if ( ! d->mOnSeparator ) | ||
731 | ensureItemVisible( item ); | ||
732 | emit currentChanged( item ); | ||
733 | } | ||
734 | |||
735 | CardViewItem *CardView::itemAt(const QPoint &viewPos) | ||
736 | { | ||
737 | CardViewItem *item = 0; | ||
738 | QPtrListIterator<CardViewItem> iter(d->mItemList); | ||
739 | bool found = false; | ||
740 | for (iter.toFirst(); iter.current() && !found; ++iter) | ||
741 | { | ||
742 | item = *iter; | ||
743 | //if (item->d->mRect.contains(viewPos)) | ||
744 | if (QRect(item->d->x, item->d->y, d->mItemWidth, item->height()).contains(viewPos)) | ||
745 | found = true; | ||
746 | } | ||
747 | |||
748 | if (found) | ||
749 | return item; | ||
750 | |||
751 | return 0; | ||
752 | } | ||
753 | |||
754 | QRect CardView::itemRect(const CardViewItem *item) | ||
755 | { | ||
756 | //return item->d->mRect; | ||
757 | return QRect(item->d->x, item->d->y, d->mItemWidth, item->height()); | ||
758 | } | ||
759 | |||
760 | void CardView::ensureItemVisible(const CardViewItem *item) | ||
761 | { | ||
762 | ensureVisible(item->d->x , item->d->y, d->mItemSpacing, 0); | ||
763 | ensureVisible(item->d->x + d->mItemWidth, item->d->y, d->mItemSpacing, 0); | ||
764 | } | ||
765 | |||
766 | void CardView::repaintItem(const CardViewItem *item) | ||
767 | { | ||
768 | //repaintContents(item->d->mRect); | ||
769 | repaintContents( QRect(item->d->x, item->d->y, d->mItemWidth, item->height()) ); | ||
770 | } | ||
771 | |||
772 | void CardView::setSelectionMode(CardView::SelectionMode mode) | ||
773 | { | ||
774 | selectAll(false); | ||
775 | |||
776 | d->mSelectionMode = mode; | ||
777 | } | ||
778 | |||
779 | CardView::SelectionMode CardView::selectionMode() const | ||
780 | { | ||
781 | return d->mSelectionMode; | ||
782 | } | ||
783 | |||
784 | void CardView::selectAll(bool state) | ||
785 | { | ||
786 | QPtrListIterator<CardViewItem> iter(d->mItemList); | ||
787 | if (!state) | ||
788 | { | ||
789 | for (iter.toFirst(); iter.current(); ++iter) | ||
790 | { | ||
791 | if ((*iter)->isSelected()) | ||
792 | { | ||
793 | (*iter)->setSelected(false); | ||
794 | (*iter)->repaintCard(); | ||
795 | } | ||
796 | } | ||
797 | //emit selectionChanged(); // WARNING FIXME | ||
798 | emit selectionChanged(0); | ||
799 | } | ||
800 | else if (d->mSelectionMode != CardView::Single) | ||
801 | { | ||
802 | for (iter.toFirst(); iter.current(); ++iter) | ||
803 | { | ||
804 | (*iter)->setSelected(true); | ||
805 | } | ||
806 | |||
807 | if (d->mItemList.count() > 0) | ||
808 | { | ||
809 | // emit, since there must have been at least one selected | ||
810 | emit selectionChanged(); | ||
811 | //repaint();//??? | ||
812 | viewport()->update(); | ||
813 | } | ||
814 | } | ||
815 | } | ||
816 | |||
817 | void CardView::setSelected(CardViewItem *item, bool selected) | ||
818 | { | ||
819 | if ((item == 0) || (item->isSelected() == selected)) | ||
820 | return; | ||
821 | |||
822 | if ( selected && d->mCurrentItem != item ) | ||
823 | { | ||
824 | CardViewItem *it = d->mCurrentItem; | ||
825 | d->mCurrentItem = item; | ||
826 | if ( it ) | ||
827 | it->repaintCard(); | ||
828 | } | ||
829 | |||
830 | if (d->mSelectionMode == CardView::Single) | ||
831 | { | ||
832 | bool b = signalsBlocked(); | ||
833 | blockSignals(true); | ||
834 | selectAll(false); | ||
835 | blockSignals(b); | ||
836 | |||
837 | if (selected) | ||
838 | { | ||
839 | item->setSelected(selected); | ||
840 | item->repaintCard(); | ||
841 | emit selectionChanged(); | ||
842 | emit selectionChanged(item); | ||
843 | } | ||
844 | else | ||
845 | { | ||
846 | emit selectionChanged(); | ||
847 | emit selectionChanged(0); | ||
848 | } | ||
849 | } | ||
850 | else if (d->mSelectionMode == CardView::Multi) | ||
851 | { | ||
852 | item->setSelected(selected); | ||
853 | item->repaintCard(); | ||
854 | emit selectionChanged(); | ||
855 | } | ||
856 | else if (d->mSelectionMode == CardView::Extended) | ||
857 | { | ||
858 | bool b = signalsBlocked(); | ||
859 | blockSignals(true); | ||
860 | selectAll(false); | ||
861 | blockSignals(b); | ||
862 | |||
863 | item->setSelected(selected); | ||
864 | item->repaintCard(); | ||
865 | emit selectionChanged(); | ||
866 | } | ||
867 | } | ||
868 | |||
869 | bool CardView::isSelected(CardViewItem *item) const | ||
870 | { | ||
871 | return (item && item->isSelected()); | ||
872 | } | ||
873 | |||
874 | CardViewItem *CardView::selectedItem() const | ||
875 | { | ||
876 | // find the first selected item | ||
877 | QPtrListIterator<CardViewItem> iter(d->mItemList); | ||
878 | for (iter.toFirst(); iter.current(); ++iter) | ||
879 | { | ||
880 | if ((*iter)->isSelected()) | ||
881 | return *iter; | ||
882 | } | ||
883 | |||
884 | return 0; | ||
885 | } | ||
886 | |||
887 | CardViewItem *CardView::firstItem() const | ||
888 | { | ||
889 | return d->mItemList.first(); | ||
890 | } | ||
891 | |||
892 | int CardView::childCount() const | ||
893 | { | ||
894 | return d->mItemList.count(); | ||
895 | } | ||
896 | /*US | ||
897 | CardViewItem *CardView::findItem(const QString &text, const QString &label, | ||
898 | Qt::StringComparisonMode compare) | ||
899 | { | ||
900 | // IF the text is empty, we will return null, since empty text will | ||
901 | // match anything! | ||
902 | if (text.isEmpty()) | ||
903 | return 0; | ||
904 | |||
905 | QPtrListIterator<CardViewItem> iter(d->mItemList); | ||
906 | if (compare & Qt::BeginsWith) | ||
907 | { | ||
908 | QString value; | ||
909 | for (iter.toFirst(); iter.current(); ++iter) | ||
910 | { | ||
911 | value = (*iter)->fieldValue(label).upper(); | ||
912 | if (value.startsWith(text.upper())) | ||
913 | return *iter; | ||
914 | } | ||
915 | } | ||
916 | else | ||
917 | { | ||
918 | kdDebug(5720) << "CardView::findItem: search method not implemented" << endl; | ||
919 | } | ||
920 | |||
921 | return 0; | ||
922 | } | ||
923 | */ | ||
924 | |||
925 | uint CardView::columnWidth() | ||
926 | { | ||
927 | return d->mDrawSeparators ? | ||
928 | d->mItemWidth + ( 2 * d->mItemSpacing ) + d->mSepWidth : | ||
929 | d->mItemWidth + d->mItemSpacing; | ||
930 | } | ||
931 | |||
932 | void CardView::drawContents(QPainter *p, int clipx, int clipy, | ||
933 | int clipw, int cliph) | ||
934 | { | ||
935 | QScrollView::drawContents(p, clipx, clipy, clipw, cliph); | ||
936 | |||
937 | if (d->mLayoutDirty) | ||
938 | calcLayout(); | ||
939 | |||
940 | //kdDebug() << "CardView::drawContents: " << clipx << ", " << clipy | ||
941 | // << ", " << clipw << ", " << cliph << endl; | ||
942 | |||
943 | QColorGroup cg = viewport()->palette().active(); // allow setting costum colors in the viewport pale | ||
944 | |||
945 | QRect clipRect(clipx, clipy, clipw, cliph); | ||
946 | QRect cardRect; | ||
947 | QRect sepRect; | ||
948 | CardViewItem *item; | ||
949 | CardViewSeparator *sep; | ||
950 | |||
951 | // make sure the viewport is a pure background | ||
952 | viewport()->erase(clipRect); | ||
953 | |||
954 | // Now tell the cards to draw, if they are in the clip region | ||
955 | QPtrListIterator<CardViewItem> iter(d->mItemList); | ||
956 | for (iter.toFirst(); iter.current(); ++iter) | ||
957 | { | ||
958 | item = *iter; | ||
959 | cardRect.setRect( item->d->x, item->d->y, d->mItemWidth, item->height() ); | ||
960 | |||
961 | if (clipRect.intersects(cardRect) || clipRect.contains(cardRect)) | ||
962 | { | ||
963 | //kdDebug() << "\trepainting card at: " << cardRect.x() << ", " | ||
964 | // << cardRect.y() << endl; | ||
965 | |||
966 | // Tell the card to paint | ||
967 | p->save(); | ||
968 | p->translate(cardRect.x(), cardRect.y()); | ||
969 | item->paintCard(p, cg); | ||
970 | p->restore(); | ||
971 | } | ||
972 | } | ||
973 | |||
974 | // Followed by the separators if they are in the clip region | ||
975 | QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList); | ||
976 | for (sepIter.toFirst(); sepIter.current(); ++sepIter) | ||
977 | { | ||
978 | sep = *sepIter; | ||
979 | sepRect = sep->mRect; | ||
980 | |||
981 | if (clipRect.intersects(sepRect) || clipRect.contains(sepRect)) | ||
982 | { | ||
983 | p->save(); | ||
984 | p->translate(sepRect.x(), sepRect.y()); | ||
985 | sep->paintSeparator(p, cg); | ||
986 | p->restore(); | ||
987 | } | ||
988 | } | ||
989 | } | ||
990 | |||
991 | void CardView::resizeEvent(QResizeEvent *e) | ||
992 | { | ||
993 | QScrollView::resizeEvent(e); | ||
994 | |||
995 | setLayoutDirty(true); | ||
996 | } | ||
997 | |||
998 | void CardView::calcLayout() | ||
999 | { | ||
1000 | //kdDebug() << "CardView::calcLayout:" << endl; | ||
1001 | |||
1002 | // Start in the upper left corner and layout all the | ||
1003 | // cars using their height and width | ||
1004 | int maxWidth = 0; | ||
1005 | int maxHeight = 0; | ||
1006 | int xPos = 0; | ||
1007 | int yPos = 0; | ||
1008 | int cardSpacing = d->mItemSpacing; | ||
1009 | |||
1010 | // delete the old separators | ||
1011 | d->mSeparatorList.clear(); | ||
1012 | |||
1013 | QPtrListIterator<CardViewItem> iter(d->mItemList); | ||
1014 | CardViewItem *item = 0; | ||
1015 | CardViewSeparator *sep = 0; | ||
1016 | xPos += cardSpacing; | ||
1017 | |||
1018 | for (iter.toFirst(); iter.current(); ++iter) | ||
1019 | { | ||
1020 | item = *iter; | ||
1021 | |||
1022 | yPos += cardSpacing; | ||
1023 | |||
1024 | if (yPos + item->height() + cardSpacing >= height() - horizontalScrollBar()->height()) | ||
1025 | { | ||
1026 | maxHeight = QMAX(maxHeight, yPos); | ||
1027 | |||
1028 | // Drawing in this column would be greater than the height | ||
1029 | // of the scroll view, so move to next column | ||
1030 | yPos = cardSpacing; | ||
1031 | xPos += cardSpacing + maxWidth; | ||
1032 | if (d->mDrawSeparators) | ||
1033 | { | ||
1034 | // Create a separator since the user asked | ||
1035 | sep = new CardViewSeparator(this); | ||
1036 | sep->mRect.moveTopLeft(QPoint(xPos, yPos+d->mItemMargin)); | ||
1037 | xPos += d->mSepWidth + cardSpacing; | ||
1038 | d->mSeparatorList.append(sep); | ||
1039 | } | ||
1040 | |||
1041 | maxWidth = 0; | ||
1042 | } | ||
1043 | |||
1044 | item->d->x = xPos; | ||
1045 | item->d->y = yPos; | ||
1046 | |||
1047 | yPos += item->height(); | ||
1048 | maxWidth = QMAX(maxWidth, d->mItemWidth); | ||
1049 | } | ||
1050 | |||
1051 | xPos += maxWidth; | ||
1052 | resizeContents( xPos + cardSpacing, maxHeight ); | ||
1053 | |||
1054 | // Update the height of all the separators now that we know the | ||
1055 | // max height of a column | ||
1056 | QPtrListIterator<CardViewSeparator> sepIter(d->mSeparatorList); | ||
1057 | for (sepIter.toFirst(); sepIter.current(); ++sepIter) | ||
1058 | { | ||
1059 | (*sepIter)->mRect.setHeight(maxHeight - 2*cardSpacing - 2*d->mItemMargin); | ||
1060 | } | ||
1061 | |||
1062 | d->mLayoutDirty = false; | ||
1063 | } | ||
1064 | |||
1065 | CardViewItem *CardView::itemAfter(CardViewItem *item) | ||
1066 | { | ||
1067 | /*int pos = */d->mItemList.findRef(item); | ||
1068 | return d->mItemList.next();//at(pos+1); | ||
1069 | } | ||
1070 | |||
1071 | uint CardView::itemMargin() | ||
1072 | { | ||
1073 | return d->mItemMargin; | ||
1074 | } | ||
1075 | |||
1076 | void CardView::setItemMargin( uint margin ) | ||
1077 | { | ||
1078 | if ( margin == d->mItemMargin ) | ||
1079 | return; | ||
1080 | |||
1081 | d->mItemMargin = margin; | ||
1082 | setLayoutDirty( true ); | ||
1083 | } | ||
1084 | |||
1085 | uint CardView::itemSpacing() | ||
1086 | { | ||
1087 | return d->mItemSpacing; | ||
1088 | } | ||
1089 | |||
1090 | void CardView::setItemSpacing( uint spacing ) | ||
1091 | { | ||
1092 | if ( spacing == d->mItemSpacing ) | ||
1093 | return; | ||
1094 | |||
1095 | d->mItemSpacing = spacing; | ||
1096 | setLayoutDirty( true ); | ||
1097 | } | ||
1098 | |||
1099 | void CardView::contentsMousePressEvent(QMouseEvent *e) | ||
1100 | { | ||
1101 | QScrollView::contentsMousePressEvent(e); | ||
1102 | |||
1103 | QPoint pos = e->pos(); | ||
1104 | d->mLastClickPos = pos; | ||
1105 | |||
1106 | CardViewItem *item = itemAt(pos); | ||
1107 | |||
1108 | if (item == 0) | ||
1109 | { | ||
1110 | d->mLastClickOnItem = false; | ||
1111 | if ( d->mOnSeparator) | ||
1112 | { | ||
1113 | d->mResizeAnchor = e->x()+contentsX(); | ||
1114 | d->colspace = (2*d->mItemSpacing) /*+ (2*d->mItemMargin)*/; | ||
1115 | int ccw = d->mItemWidth + d->colspace + d->mSepWidth; | ||
1116 | d->first = (contentsX()+d->mSepWidth)/ccw; | ||
1117 | d->pressed = (d->mResizeAnchor+d->mSepWidth)/ccw; | ||
1118 | d->span = d->pressed - d->first; | ||
1119 | d->firstX = d->first * ccw; | ||
1120 | if ( d->firstX ) d->firstX -= d->mSepWidth; // (no sep in col 0) | ||
1121 | } | ||
1122 | else | ||
1123 | { | ||
1124 | selectAll(false); | ||
1125 | } | ||
1126 | return; | ||
1127 | } | ||
1128 | |||
1129 | d->mLastClickOnItem = true; | ||
1130 | |||
1131 | CardViewItem *other = d->mCurrentItem; | ||
1132 | setCurrentItem( item ); | ||
1133 | |||
1134 | // Always emit the selection | ||
1135 | emit clicked(item); | ||
1136 | |||
1137 | // Check the selection type and update accordingly | ||
1138 | if (d->mSelectionMode == CardView::Single) | ||
1139 | { | ||
1140 | // make sure it isn't already selected | ||
1141 | if (item->isSelected()) | ||
1142 | return; | ||
1143 | |||
1144 | bool b = signalsBlocked(); | ||
1145 | blockSignals(true); | ||
1146 | selectAll(false); | ||
1147 | blockSignals(b); | ||
1148 | |||
1149 | item->setSelected(true); | ||
1150 | item->repaintCard(); | ||
1151 | emit selectionChanged(item); | ||
1152 | } | ||
1153 | |||
1154 | else if (d->mSelectionMode == CardView::Multi) | ||
1155 | { | ||
1156 | // toggle the selection | ||
1157 | item->setSelected(!item->isSelected()); | ||
1158 | item->repaintCard(); | ||
1159 | emit selectionChanged(); | ||
1160 | } | ||
1161 | |||
1162 | else if (d->mSelectionMode == CardView::Extended) | ||
1163 | { | ||
1164 | if ((e->button() & Qt::LeftButton) && | ||
1165 | (e->state() & Qt::ShiftButton)) | ||
1166 | { | ||
1167 | if ( item == other ) return; | ||
1168 | |||
1169 | bool s = ! item->isSelected(); | ||
1170 | |||
1171 | if ( s && ! (e->state() & ControlButton) ) | ||
1172 | { | ||
1173 | bool b = signalsBlocked(); | ||
1174 | blockSignals(true); | ||
1175 | selectAll(false); | ||
1176 | blockSignals(b); | ||
1177 | } | ||
1178 | |||
1179 | int from, to, a, b; | ||
1180 | a = d->mItemList.findRef( item ); | ||
1181 | b = d->mItemList.findRef( other ); | ||
1182 | from = a < b ? a : b; | ||
1183 | to = a > b ? a : b; | ||
1184 | //kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl; | ||
1185 | CardViewItem *aItem; | ||
1186 | for ( ; from <= to; from++ ) | ||
1187 | { | ||
1188 | aItem = d->mItemList.at( from ); | ||
1189 | aItem->setSelected( s ); | ||
1190 | repaintItem( aItem ); | ||
1191 | } | ||
1192 | emit selectionChanged(); | ||
1193 | } | ||
1194 | else if ((e->button() & Qt::LeftButton) && | ||
1195 | (e->state() & Qt::ControlButton)) | ||
1196 | { | ||
1197 | item->setSelected(!item->isSelected()); | ||
1198 | item->repaintCard(); | ||
1199 | emit selectionChanged(); | ||
1200 | } | ||
1201 | |||
1202 | else if (e->button() & Qt::LeftButton) | ||
1203 | { | ||
1204 | bool b = signalsBlocked(); | ||
1205 | blockSignals(true); | ||
1206 | selectAll(false); | ||
1207 | blockSignals(b); | ||
1208 | |||
1209 | item->setSelected(true); | ||
1210 | item->repaintCard(); | ||
1211 | emit selectionChanged(); | ||
1212 | } | ||
1213 | } | ||
1214 | |||
1215 | } | ||
1216 | |||
1217 | void CardView::contentsMouseReleaseEvent(QMouseEvent *e) | ||
1218 | { | ||
1219 | QScrollView::contentsMouseReleaseEvent(e); | ||
1220 | |||
1221 | if ( d->mResizeAnchor ) | ||
1222 | { | ||
1223 | // finish the resizing: | ||
1224 | unsetCursor(); | ||
1225 | // hide rubber bands | ||
1226 | int newiw = d->mItemWidth - ((d->mResizeAnchor - d->mRubberBandAnchor)/d->span); | ||
1227 | drawRubberBands( 0 ); | ||
1228 | // we should move to reflect the new position if we are scrolled. | ||
1229 | if ( contentsX() ) | ||
1230 | { | ||
1231 | int newX = QMAX( 0, ( d->pressed * ( newiw + d->colspace + d->mSepWidth ) ) - e->x() ); | ||
1232 | setContentsPos( newX, contentsY() ); | ||
1233 | } | ||
1234 | // set new item width | ||
1235 | setItemWidth( newiw ); | ||
1236 | // reset anchors | ||
1237 | d->mResizeAnchor = 0; | ||
1238 | d->mRubberBandAnchor = 0; | ||
1239 | return; | ||
1240 | } | ||
1241 | |||
1242 | // If there are accel keys, we will not emit signals | ||
1243 | if ((e->state() & Qt::ShiftButton) || (e->state() & Qt::ControlButton)) | ||
1244 | return; | ||
1245 | |||
1246 | // Get the item at this position | ||
1247 | CardViewItem *item = itemAt(e->pos()); | ||
1248 | |||
1249 | if (item && KGlobalSettings::singleClick()) | ||
1250 | { | ||
1251 | emit executed(item); | ||
1252 | } | ||
1253 | } | ||
1254 | |||
1255 | void CardView::contentsMouseDoubleClickEvent(QMouseEvent *e) | ||
1256 | { | ||
1257 | QScrollView::contentsMouseDoubleClickEvent(e); | ||
1258 | |||
1259 | CardViewItem *item = itemAt(e->pos()); | ||
1260 | |||
1261 | if (item) | ||
1262 | { | ||
1263 | d->mCurrentItem = item; | ||
1264 | } | ||
1265 | |||
1266 | if (item && !KGlobalSettings::singleClick()) | ||
1267 | { | ||
1268 | emit executed(item); | ||
1269 | } | ||
1270 | emit doubleClicked(item); | ||
1271 | } | ||
1272 | |||
1273 | void CardView::contentsMouseMoveEvent( QMouseEvent *e ) | ||
1274 | { | ||
1275 | // resizing | ||
1276 | if ( d->mResizeAnchor ) | ||
1277 | { | ||
1278 | int x = e->x(); | ||
1279 | if ( x != d->mRubberBandAnchor ) | ||
1280 | drawRubberBands( x ); | ||
1281 | return; | ||
1282 | } | ||
1283 | |||
1284 | if (d->mLastClickOnItem && (e->state() & Qt::LeftButton) && | ||
1285 | ((e->pos() - d->mLastClickPos).manhattanLength() > 4)) { | ||
1286 | |||
1287 | startDrag(); | ||
1288 | return; | ||
1289 | } | ||
1290 | |||
1291 | d->mTimer->start( 500 ); | ||
1292 | |||
1293 | // see if we are over a separator | ||
1294 | // only if we actually have them painted? | ||
1295 | if ( d->mDrawSeparators ) | ||
1296 | { | ||
1297 | int colcontentw = d->mItemWidth + (2*d->mItemSpacing); | ||
1298 | int colw = colcontentw + d->mSepWidth; | ||
1299 | int m = e->x()%colw; | ||
1300 | if ( m >= colcontentw && m > 0 ) | ||
1301 | { | ||
1302 | setCursor( SplitVCursor ); // Why does this fail sometimes? | ||
1303 | d->mOnSeparator = true; | ||
1304 | } | ||
1305 | else | ||
1306 | { | ||
1307 | setCursor( ArrowCursor ); | ||
1308 | d->mOnSeparator = false; | ||
1309 | } | ||
1310 | } | ||
1311 | } | ||
1312 | |||
1313 | void CardView::enterEvent( QEvent * ) | ||
1314 | { | ||
1315 | d->mTimer->start( 500 ); | ||
1316 | } | ||
1317 | |||
1318 | void CardView::leaveEvent( QEvent * ) | ||
1319 | { | ||
1320 | d->mTimer->stop(); | ||
1321 | if (d->mOnSeparator) | ||
1322 | { | ||
1323 | d->mOnSeparator = false; | ||
1324 | setCursor( ArrowCursor ); | ||
1325 | } | ||
1326 | } | ||
1327 | |||
1328 | void CardView::focusInEvent( QFocusEvent * ) | ||
1329 | { | ||
1330 | if (!d->mCurrentItem && d->mItemList.count() ) | ||
1331 | { | ||
1332 | setCurrentItem( d->mItemList.first() ); | ||
1333 | } | ||
1334 | else if ( d->mCurrentItem ) | ||
1335 | { | ||
1336 | d->mCurrentItem->repaintCard(); | ||
1337 | } | ||
1338 | } | ||
1339 | |||
1340 | void CardView::focusOutEvent( QFocusEvent * ) | ||
1341 | { | ||
1342 | if (d->mCurrentItem) | ||
1343 | d->mCurrentItem->repaintCard(); | ||
1344 | } | ||
1345 | |||
1346 | void CardView::keyPressEvent( QKeyEvent *e ) | ||
1347 | { | ||
1348 | if ( ! ( childCount() && d->mCurrentItem ) ) | ||
1349 | { | ||
1350 | e->ignore(); | ||
1351 | return; | ||
1352 | } | ||
1353 | |||
1354 | uint pos = d->mItemList.findRef( d->mCurrentItem ); | ||
1355 | CardViewItem *aItem = 0L; // item that gets the focus | ||
1356 | CardViewItem *old = d->mCurrentItem; | ||
1357 | |||
1358 | switch ( e->key() ) | ||
1359 | { | ||
1360 | case Key_Up: | ||
1361 | if ( pos > 0 ) | ||
1362 | { | ||
1363 | aItem = d->mItemList.at( pos - 1 ); | ||
1364 | setCurrentItem( aItem ); | ||
1365 | } | ||
1366 | break; | ||
1367 | case Key_Down: | ||
1368 | if ( pos < d->mItemList.count() - 1 ) | ||
1369 | { | ||
1370 | aItem = d->mItemList.at( pos + 1 ); | ||
1371 | setCurrentItem( aItem ); | ||
1372 | } | ||
1373 | break; | ||
1374 | case Key_Left: | ||
1375 | { | ||
1376 | // look for an item in the previous/next column, starting from | ||
1377 | // the vertical middle of the current item. | ||
1378 | // FIXME use nice calculatd measures!!! | ||
1379 | QPoint aPoint( d->mCurrentItem->d->x, d->mCurrentItem->d->y ); | ||
1380 | aPoint -= QPoint( 30,-(d->mCurrentItem->height()/2) ); | ||
1381 | aItem = itemAt( aPoint ); | ||
1382 | // maybe we hit some space below an item | ||
1383 | while ( !aItem && aPoint.y() > 27 ) | ||
1384 | { | ||
1385 | aPoint -= QPoint( 0, 16 ); | ||
1386 | aItem = itemAt( aPoint ); | ||
1387 | } | ||
1388 | if ( aItem ) | ||
1389 | setCurrentItem( aItem ); | ||
1390 | } | ||
1391 | break; | ||
1392 | case Key_Right: | ||
1393 | { | ||
1394 | // FIXME use nice calculated measures!!! | ||
1395 | QPoint aPoint( d->mCurrentItem->d->x + d->mItemWidth, d->mCurrentItem->d->y ); | ||
1396 | aPoint += QPoint( 30,(d->mCurrentItem->height()/2) ); | ||
1397 | aItem = itemAt( aPoint ); | ||
1398 | while ( !aItem && aPoint.y() > 27 ) | ||
1399 | { | ||
1400 | aPoint -= QPoint( 0, 16 ); | ||
1401 | aItem = itemAt( aPoint ); | ||
1402 | } | ||
1403 | if ( aItem ) | ||
1404 | setCurrentItem( aItem ); | ||
1405 | } | ||
1406 | break; | ||
1407 | case Key_Home: | ||
1408 | aItem = d->mItemList.first(); | ||
1409 | setCurrentItem( aItem ); | ||
1410 | break; | ||
1411 | case Key_End: | ||
1412 | aItem = d->mItemList.last(); | ||
1413 | setCurrentItem( aItem ); | ||
1414 | break; | ||
1415 | case Key_Prior: // PageUp | ||
1416 | { | ||
1417 | // QListView: "Make the item above the top visible and current" | ||
1418 | // TODO if contentsY(), pick the top item of the leftmost visible column | ||
1419 | if ( contentsX() <= 0 ) | ||
1420 | return; | ||
1421 | int cw = columnWidth(); | ||
1422 | int theCol = ( QMAX( 0, ( contentsX()/cw) * cw ) ) + d->mItemSpacing; | ||
1423 | aItem = itemAt( QPoint( theCol + 1, d->mItemSpacing + 1 ) ); | ||
1424 | if ( aItem ) | ||
1425 | setCurrentItem( aItem ); | ||
1426 | } | ||
1427 | break; | ||
1428 | case Key_Next: // PageDown | ||
1429 | { | ||
1430 | // QListView: "Make the item below the bottom visible and current" | ||
1431 | // find the first not fully visible column. | ||
1432 | // TODO: consider if a partly visible (or even hidden) item at the | ||
1433 | // bottom of the rightmost column exists | ||
1434 | int cw = columnWidth(); | ||
1435 | int theCol = ( (( contentsX() + visibleWidth() )/cw) * cw ) + d->mItemSpacing + 1; | ||
1436 | // if separators are on, we may need to we may be one column further right if only the spacing/sep is hidden | ||
1437 | if ( d->mDrawSeparators && cw - (( contentsX() + visibleWidth() )%cw) <= int( d->mItemSpacing + d->mSepWidth ) ) | ||
1438 | theCol += cw; | ||
1439 | |||
1440 | // make sure this is not too far right | ||
1441 | while ( theCol > contentsWidth() ) | ||
1442 | theCol -= columnWidth(); | ||
1443 | |||
1444 | aItem = itemAt( QPoint( theCol, d->mItemSpacing + 1 ) ); | ||
1445 | |||
1446 | if ( aItem ) | ||
1447 | setCurrentItem( aItem ); | ||
1448 | } | ||
1449 | break; | ||
1450 | case Key_Space: | ||
1451 | setSelected( d->mCurrentItem, !d->mCurrentItem->isSelected() ); | ||
1452 | emit selectionChanged(); | ||
1453 | break; | ||
1454 | case Key_Return: | ||
1455 | case Key_Enter: | ||
1456 | emit returnPressed( d->mCurrentItem ); | ||
1457 | emit executed( d->mCurrentItem ); | ||
1458 | break; | ||
1459 | default: | ||
1460 | if ( (e->state() & ControlButton) && e->key() == Key_A ) | ||
1461 | { | ||
1462 | // select all | ||
1463 | selectAll( true ); | ||
1464 | break; | ||
1465 | } | ||
1466 | // if we have a string, do autosearch | ||
1467 | else if ( ! e->text().isEmpty() && e->text()[0].isPrint() ) | ||
1468 | { | ||
1469 | |||
1470 | } | ||
1471 | break; | ||
1472 | } | ||
1473 | // handle selection | ||
1474 | if ( aItem ) | ||
1475 | { | ||
1476 | if ( d->mSelectionMode == CardView::Extended ) | ||
1477 | { | ||
1478 | if ( (e->state() & ShiftButton) ) | ||
1479 | { | ||
1480 | // shift button: toggle range | ||
1481 | // if control button is pressed, leave all items | ||
1482 | // and toggle selection current->old current | ||
1483 | // otherwise, ?????? | ||
1484 | bool s = ! aItem->isSelected(); | ||
1485 | int from, to, a, b; | ||
1486 | a = d->mItemList.findRef( aItem ); | ||
1487 | b = d->mItemList.findRef( old ); | ||
1488 | from = a < b ? a : b; | ||
1489 | to = a > b ? a : b; | ||
1490 | |||
1491 | if ( to - from > 1 ) | ||
1492 | { | ||
1493 | bool b = signalsBlocked(); | ||
1494 | blockSignals(true); | ||
1495 | selectAll(false); | ||
1496 | blockSignals(b); | ||
1497 | } | ||
1498 | |||
1499 | //kdDebug()<<"selecting items "<<from<<" - "<<to<<" ( "<<s<<" )"<<endl; | ||
1500 | CardViewItem *item; | ||
1501 | for ( ; from <= to; from++ ) | ||
1502 | { | ||
1503 | item = d->mItemList.at( from ); | ||
1504 | item->setSelected( s ); | ||
1505 | repaintItem( item ); | ||
1506 | } | ||
1507 | emit selectionChanged(); | ||
1508 | } | ||
1509 | else if ( (e->state() & ControlButton) ) | ||
1510 | { | ||
1511 | // control button: do nothing | ||
1512 | } | ||
1513 | else | ||
1514 | { | ||
1515 | // no button: move selection to this item | ||
1516 | bool b = signalsBlocked(); | ||
1517 | blockSignals(true); | ||
1518 | selectAll(false); | ||
1519 | blockSignals(b); | ||
1520 | |||
1521 | setSelected( aItem, true ); | ||
1522 | emit selectionChanged(); | ||
1523 | } | ||
1524 | } | ||
1525 | } | ||
1526 | } | ||
1527 | |||
1528 | void CardView::contentsWheelEvent( QWheelEvent * e ) | ||
1529 | { | ||
1530 | scrollBy(2*e->delta()/-3, 0); | ||
1531 | } | ||
1532 | |||
1533 | void CardView::setLayoutDirty(bool dirty) | ||
1534 | { | ||
1535 | if (d->mLayoutDirty != dirty) | ||
1536 | { | ||
1537 | d->mLayoutDirty = dirty; | ||
1538 | repaint(); | ||
1539 | } | ||
1540 | } | ||
1541 | |||
1542 | void CardView::setDrawCardBorder(bool enabled) | ||
1543 | { | ||
1544 | if (enabled != d->mDrawCardBorder) | ||
1545 | { | ||
1546 | d->mDrawCardBorder = enabled; | ||
1547 | repaint(); | ||
1548 | } | ||
1549 | } | ||
1550 | |||
1551 | bool CardView::drawCardBorder() const | ||
1552 | { | ||
1553 | return d->mDrawCardBorder; | ||
1554 | } | ||
1555 | |||
1556 | void CardView::setDrawColSeparators(bool enabled) | ||
1557 | { | ||
1558 | if (enabled != d->mDrawSeparators) | ||
1559 | { | ||
1560 | d->mDrawSeparators = enabled; | ||
1561 | setLayoutDirty(true); | ||
1562 | } | ||
1563 | } | ||
1564 | |||
1565 | bool CardView::drawColSeparators() const | ||
1566 | { | ||
1567 | return d->mDrawSeparators; | ||
1568 | } | ||
1569 | |||
1570 | void CardView::setDrawFieldLabels(bool enabled) | ||
1571 | { | ||
1572 | if (enabled != d->mDrawFieldLabels) | ||
1573 | { | ||
1574 | d->mDrawFieldLabels = enabled; | ||
1575 | repaint(); | ||
1576 | } | ||
1577 | } | ||
1578 | |||
1579 | bool CardView::drawFieldLabels() const | ||
1580 | { | ||
1581 | return d->mDrawFieldLabels; | ||
1582 | } | ||
1583 | |||
1584 | void CardView::setShowEmptyFields(bool show) | ||
1585 | { | ||
1586 | if (show != d->mShowEmptyFields) | ||
1587 | { | ||
1588 | d->mShowEmptyFields = show; | ||
1589 | setLayoutDirty(true); | ||
1590 | } | ||
1591 | } | ||
1592 | |||
1593 | bool CardView::showEmptyFields() const | ||
1594 | { | ||
1595 | return d->mShowEmptyFields; | ||
1596 | } | ||
1597 | |||
1598 | void CardView::startDrag() | ||
1599 | { | ||
1600 | // The default implementation is a no-op. It must be | ||
1601 | // reimplemented in a subclass to be useful | ||
1602 | } | ||
1603 | void CardView::tryShowFullText() | ||
1604 | { | ||
1605 | d->mTimer->stop(); | ||
1606 | // if we have an item | ||
1607 | QPoint cpos = viewportToContents( viewport()->mapFromGlobal( QCursor::pos() ) ); | ||
1608 | CardViewItem *item = itemAt( cpos ); | ||
1609 | if ( item ) | ||
1610 | { | ||
1611 | // query it for a value to display | ||
1612 | //QString s = item ? item->caption() : "(no item)"; | ||
1613 | //kdDebug()<<"MOUSE REST: "<<s<<endl; | ||
1614 | QPoint ipos = cpos - itemRect( item ).topLeft(); | ||
1615 | item->showFullString( ipos, d->mTip ); | ||
1616 | } | ||
1617 | } | ||
1618 | |||
1619 | void CardView::drawRubberBands( int pos ) | ||
1620 | { | ||
1621 | if ( pos && ((pos-d->firstX)/d->span) - d->colspace - d->mSepWidth < MIN_ITEM_WIDTH ) return; | ||
1622 | |||
1623 | int tmpcw = (d->mRubberBandAnchor-d->firstX)/d->span; | ||
1624 | int x = d->firstX + tmpcw - d->mSepWidth - contentsX(); | ||
1625 | int h = visibleHeight(); | ||
1626 | |||
1627 | QPainter p( viewport() ); | ||
1628 | p.setRasterOp( XorROP ); | ||
1629 | p.setPen( gray ); | ||
1630 | p.setBrush( gray ); | ||
1631 | uint n = d->first; | ||
1632 | // erase | ||
1633 | if ( d->mRubberBandAnchor ) | ||
1634 | do { | ||
1635 | p.drawRect( x, 0, 2, h ); | ||
1636 | x += tmpcw; | ||
1637 | n++; | ||
1638 | } while ( x < visibleWidth() && n < d->mSeparatorList.count() ); | ||
1639 | // paint new | ||
1640 | if ( ! pos ) return; | ||
1641 | tmpcw = (pos - d->firstX)/d->span; | ||
1642 | n = d->first; | ||
1643 | x = d->firstX + tmpcw - d->mSepWidth - contentsX(); | ||
1644 | do { | ||
1645 | p.drawRect( x, 0, 2, h ); | ||
1646 | x += tmpcw; | ||
1647 | n++; | ||
1648 | } while ( x < visibleWidth() && n < d->mSeparatorList.count() ); | ||
1649 | d->mRubberBandAnchor = pos; | ||
1650 | } | ||
1651 | |||
1652 | |||
1653 | int CardView::itemWidth() const | ||
1654 | { | ||
1655 | return d->mItemWidth; | ||
1656 | } | ||
1657 | |||
1658 | void CardView::setItemWidth( int w ) | ||
1659 | { | ||
1660 | if ( w == d->mItemWidth ) | ||
1661 | return; | ||
1662 | if ( w < MIN_ITEM_WIDTH ) | ||
1663 | w = MIN_ITEM_WIDTH; | ||
1664 | d->mItemWidth = w; | ||
1665 | setLayoutDirty( true ); | ||
1666 | #ifndef KAB_EMBEDDED | ||
1667 | updateContents(); | ||
1668 | #else //KAB_EMBEDDED | ||
1669 | //US updateContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight() ); | ||
1670 | qDebug("CardView::setItemWidth has to be verified"); | ||
1671 | updateContents( contentsX(), contentsY(), visibleWidth(), visibleHeight() ); | ||
1672 | #endif //KAB_EMBEDDED | ||
1673 | } | ||
1674 | |||
1675 | void CardView::setHeaderFont( const QFont &fnt ) | ||
1676 | { | ||
1677 | d->mHeaderFont = fnt; | ||
1678 | delete d->mBFm; | ||
1679 | d->mBFm = new QFontMetrics( fnt ); | ||
1680 | } | ||
1681 | |||
1682 | QFont CardView::headerFont() const | ||
1683 | { | ||
1684 | return d->mHeaderFont; | ||
1685 | } | ||
1686 | |||
1687 | void CardView::setFont( const QFont &fnt ) | ||
1688 | { | ||
1689 | QScrollView::setFont( fnt ); | ||
1690 | delete d->mFm; | ||
1691 | d->mFm = new QFontMetrics( fnt ); | ||
1692 | } | ||
1693 | |||
1694 | int CardView::separatorWidth() | ||
1695 | { | ||
1696 | return d->mSepWidth; | ||
1697 | } | ||
1698 | |||
1699 | void CardView::setSeparatorWidth( int width ) | ||
1700 | { | ||
1701 | d->mSepWidth = width; | ||
1702 | setLayoutDirty( true ); // hmm, actually I could just adjust the x'es... | ||
1703 | } | ||
1704 | |||
1705 | int CardView::maxFieldLines() const | ||
1706 | { | ||
1707 | return d->mMaxFieldLines; | ||
1708 | } | ||
1709 | |||
1710 | void CardView::setMaxFieldLines( int howmany ) | ||
1711 | { | ||
1712 | d->mMaxFieldLines = howmany ? howmany : INT_MAX; | ||
1713 | // FIXME update, forcing the items to recalc height!! | ||
1714 | } | ||
1715 | //END Cardview | ||
1716 | |||
1717 | #ifndef KAB_EMBEDDED | ||
1718 | #include "cardview.moc" | ||
1719 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/cardview.desktop b/kaddressbook/views/cardview.desktop new file mode 100644 index 0000000..8507360 --- a/dev/null +++ b/kaddressbook/views/cardview.desktop | |||
@@ -0,0 +1,18 @@ | |||
1 | [Desktop Entry] | ||
2 | Encoding=UTF-8 | ||
3 | X-KDE-Library=libkaddrbk_cardview | ||
4 | Name=Card View | ||
5 | Name[be]=У выглядзе картак | ||
6 | Name[ca]=Vista de targeta | ||
7 | Name[da]=Kort-visning | ||
8 | Name[el]=Προβολή καρτών | ||
9 | Name[es]=Vista de tarjeta | ||
10 | Name[hu]=Kártyanézet | ||
11 | Name[pt_BR]=Visualização de Cartão | ||
12 | Name[ru]=Карточка | ||
13 | Name[sk]=Prezeranie karty | ||
14 | Name[sv]=Kortvy | ||
15 | Name[tr]=Kart Görünümü | ||
16 | Name[zh_CN]=卡片视图 | ||
17 | Type=Service | ||
18 | ServiceTypes=KAddressBook/View | ||
diff --git a/kaddressbook/views/cardview.h b/kaddressbook/views/cardview.h new file mode 100644 index 0000000..37dddb6 --- a/dev/null +++ b/kaddressbook/views/cardview.h | |||
@@ -0,0 +1,473 @@ | |||
1 | #ifndef CARDVIEW_H | ||
2 | #define CARDVIEW_H | ||
3 | |||
4 | #include <qscrollview.h> | ||
5 | #include <qptrlist.h> | ||
6 | #include <qstring.h> | ||
7 | #include <qrect.h> | ||
8 | #include <qpair.h> | ||
9 | #include <qpoint.h> | ||
10 | |||
11 | class QLabel; | ||
12 | class QPainter; | ||
13 | class QResizeEvent; | ||
14 | class QMouseEvent; | ||
15 | class CardView; | ||
16 | class CardViewPrivate; | ||
17 | class CardViewItemPrivate; | ||
18 | class CardViewTip; | ||
19 | |||
20 | /** Represents a single card (item) in the card view. A card has a caption | ||
21 | * and a list of fields. A Field is a label<->value pair. The labels in a | ||
22 | * card should be unique, since they will be used to index the values. | ||
23 | */ | ||
24 | class CardViewItem | ||
25 | { | ||
26 | friend class CardView; | ||
27 | |||
28 | public: | ||
29 | /** A single field in the card view. The first item is the label | ||
30 | * and the second item is the value. | ||
31 | */ | ||
32 | typedef QPair<QString, QString> Field; | ||
33 | |||
34 | /** Constructor. | ||
35 | * | ||
36 | * @param parent The CardView that this card should be displayed on. | ||
37 | * @param caption The caption of the card. This is the text that will | ||
38 | * appear at the top of the card. This is also the string that will | ||
39 | * be used to sort the cards in the view. | ||
40 | */ | ||
41 | CardViewItem(CardView *parent, QString caption = QString::null); | ||
42 | virtual ~CardViewItem(); | ||
43 | |||
44 | /** @return The caption of the card, or QString::null if none was ever | ||
45 | * set. | ||
46 | */ | ||
47 | const QString &caption() const; | ||
48 | |||
49 | /** Sets the caption of the card. This is the text that will | ||
50 | * appear at the top of the card. This is also the string that will | ||
51 | * be used to sort the cards in the view. | ||
52 | */ | ||
53 | void setCaption(const QString &caption); | ||
54 | |||
55 | /** Paints the card using the given painter and color group. The | ||
56 | * card will handle painting itself selected if it is selected. | ||
57 | */ | ||
58 | virtual void paintCard(QPainter *p, QColorGroup &cg); | ||
59 | |||
60 | /** Repaints the card. This is done by sending a repaint event to the | ||
61 | * view with the clip rect defined as this card. | ||
62 | */ | ||
63 | virtual void repaintCard(); | ||
64 | |||
65 | /** Adds a field to the card. | ||
66 | * | ||
67 | * @param label The label of the field. The field labels must be unique | ||
68 | * within a card. | ||
69 | * @param The value of the field. | ||
70 | */ | ||
71 | void insertField(const QString &label, const QString &value); | ||
72 | |||
73 | /** Removes the field with label <i>label</i> from the card. | ||
74 | */ | ||
75 | void removeField(const QString &label); | ||
76 | |||
77 | /** @return The value of the field with label <i>label</i>. | ||
78 | */ | ||
79 | QString fieldValue(const QString &label); | ||
80 | |||
81 | /** Removes all the fields from this card. | ||
82 | */ | ||
83 | void clearFields(); | ||
84 | |||
85 | /** @return The next card item. The order of the items will be the same | ||
86 | * as the display order in the view. 0 will be returned if this is the | ||
87 | * last card. | ||
88 | */ | ||
89 | CardViewItem *nextItem(); | ||
90 | |||
91 | /** @return True if this card is currently selected, false otherwise. | ||
92 | */ | ||
93 | bool isSelected() const; | ||
94 | |||
95 | /** Called by the parent card view when the mouse has been resting for | ||
96 | * a certain amount of time. If the label or value at pos is obscured | ||
97 | * (trimmed) make the label display the full text. | ||
98 | */ | ||
99 | void showFullString( const QPoint &pos, CardViewTip *tip ); | ||
100 | |||
101 | /** @return a pointer to the Field at the position itempos | ||
102 | * in this item. 0 is returned if itempos is in the caption. | ||
103 | * @param itempos the position in item coordinates | ||
104 | */ | ||
105 | Field *fieldAt( const QPoint &itempos ) const; | ||
106 | |||
107 | CardView *cardView() { return mView; }; | ||
108 | |||
109 | /** @return The height of this item as rendered, in pixels. | ||
110 | |||
111 | if @p allowCache is true, the item may use an internally | ||
112 | cached value rather than recalculating from scratch. The | ||
113 | argument is mainly to allow the cardView to change global settings (like | ||
114 | maxFieldLines) that might influence the items heights | ||
115 | */ | ||
116 | int height( bool allowCache=true ) const; | ||
117 | |||
118 | protected: | ||
119 | /** Sets the card as selected. This is usually only called from the | ||
120 | * card view. | ||
121 | */ | ||
122 | void setSelected(bool selected); | ||
123 | |||
124 | private: | ||
125 | /** Sets the default values. | ||
126 | */ | ||
127 | void initialize(); | ||
128 | |||
129 | /** Trims a string to the width <i>width</i> using the font metrics | ||
130 | * to determine the width of each char. If the string is longer than | ||
131 | * <i>width</i>, then the string will be trimmed and a '...' will | ||
132 | * be appended. | ||
133 | */ | ||
134 | QString trimString(const QString &text, int width, QFontMetrics &fm); | ||
135 | |||
136 | CardViewItemPrivate *d; | ||
137 | CardView *mView; | ||
138 | }; | ||
139 | |||
140 | /** The CardView is a method of displaying data in cards. This idea is | ||
141 | * similar to the idea of a rolodex or business cards. Each card has a | ||
142 | * caption and a list of fields, which are label<->value pairs. The CardView | ||
143 | * displays multiple cards in a grid. The Cards are sorted based on their | ||
144 | * caption. | ||
145 | * | ||
146 | * The CardView class is designed to mirror the API of the QListView or | ||
147 | * QIconView. The CardView is also completely independant of KAddressBook and | ||
148 | * can be used elsewhere. With the exception of a few simple config checks, | ||
149 | * the CardView is also 100% independant of KDE. | ||
150 | */ | ||
151 | class CardView : public QScrollView | ||
152 | { | ||
153 | friend class CardViewItem; | ||
154 | |||
155 | Q_OBJECT | ||
156 | |||
157 | public: | ||
158 | /** Constructor. | ||
159 | */ | ||
160 | CardView(QWidget *parent, const char *name); | ||
161 | virtual ~CardView(); | ||
162 | |||
163 | /** Inserts the item into the card view. This method does not have | ||
164 | * to be called if you created the item with a proper parent. Once | ||
165 | * inserted, the CardView takes ownership of the item. | ||
166 | */ | ||
167 | void insertItem(CardViewItem *item); | ||
168 | |||
169 | /** Takes the item from the view. The item will not be deleted and | ||
170 | * ownership of the item is returned to the caller. | ||
171 | */ | ||
172 | void takeItem(CardViewItem *item); | ||
173 | |||
174 | /** Clears the view and deletes all card view items | ||
175 | */ | ||
176 | void clear(); | ||
177 | |||
178 | /** @return The current item, the item that has the focus. | ||
179 | * Whenever the view has focus, this item has a focus rectangle painted | ||
180 | * at it's border. | ||
181 | * @sa setCurrentItem() | ||
182 | */ | ||
183 | CardViewItem *currentItem(); | ||
184 | |||
185 | /** Sets the CardViewItem @p item to the current item in the view. | ||
186 | */ | ||
187 | void setCurrentItem( CardViewItem *item ); | ||
188 | |||
189 | /** @return The item found at the given point, or 0 if there is no item | ||
190 | * at that point. | ||
191 | */ | ||
192 | CardViewItem *itemAt(const QPoint &viewPos); | ||
193 | |||
194 | /** @return The bounding rect of the given item. | ||
195 | */ | ||
196 | QRect itemRect(const CardViewItem *item); | ||
197 | |||
198 | /** Ensures that the given item is in the viewable area of the widget | ||
199 | */ | ||
200 | void ensureItemVisible(const CardViewItem *item); | ||
201 | |||
202 | /** Repaints the given item. | ||
203 | */ | ||
204 | void repaintItem(const CardViewItem *item); | ||
205 | |||
206 | enum SelectionMode { Single, Multi, Extended, NoSelection }; | ||
207 | |||
208 | /** Sets the selection mode. | ||
209 | * | ||
210 | * @see QListView | ||
211 | */ | ||
212 | void setSelectionMode(SelectionMode mode); | ||
213 | |||
214 | /** @return The current selection mode. | ||
215 | */ | ||
216 | SelectionMode selectionMode() const; | ||
217 | |||
218 | /** Selects or deselects the given item. This method honors the current | ||
219 | * selection mode, so if other items are selected, they may be unselected. | ||
220 | */ | ||
221 | void setSelected(CardViewItem *item, bool selected); | ||
222 | |||
223 | /** Selects or deselects all items. | ||
224 | */ | ||
225 | void selectAll(bool state); | ||
226 | |||
227 | /** @return True if the given item is selected, false otherwise. | ||
228 | */ | ||
229 | bool isSelected(CardViewItem *item) const; | ||
230 | |||
231 | /** @return The first selected item. In single select mode, this will be | ||
232 | * the only selected item, in other modes this will be the first selected | ||
233 | * item, but others may exist. 0 if no item is selected. | ||
234 | */ | ||
235 | CardViewItem *selectedItem() const; | ||
236 | |||
237 | /** @return The first item in the view. This may be 0 if no items have | ||
238 | * been inserted. This method combined with CardViewItem::nextItem() | ||
239 | * can be used to iterator through the list of items. | ||
240 | */ | ||
241 | CardViewItem *firstItem() const; | ||
242 | |||
243 | /** @return The item after the given item or 0 if the item is the last | ||
244 | * item. | ||
245 | */ | ||
246 | CardViewItem *itemAfter(CardViewItem *item); | ||
247 | |||
248 | /** @return The number of items in the view. | ||
249 | */ | ||
250 | int childCount() const; | ||
251 | |||
252 | /** Attempts to find the first item matching the params. | ||
253 | * | ||
254 | * @param text The text to match. | ||
255 | * @param label The label of the field to match against. | ||
256 | * @param compare The compare method to use in doing the search. | ||
257 | * | ||
258 | * @return The first matching item, or 0 if no items match. | ||
259 | */ | ||
260 | /*US | ||
261 | CardViewItem *findItem(const QString &text, const QString &label, | ||
262 | Qt::StringComparisonMode compare = Qt::BeginsWith); | ||
263 | */ | ||
264 | |||
265 | /** Returns the amounts of pixels required for one column. | ||
266 | * This depends on wheather drawSeparators is enabled: | ||
267 | * If so, it is itemWidth + 2*itemSpacing + separatorWidth | ||
268 | * If not, it is itemWidth + itemSpacing | ||
269 | * @see itemWidth(), setItemWidth(), itemSpacing() and setItemSpacing() | ||
270 | */ | ||
271 | uint columnWidth(); | ||
272 | |||
273 | /** Sets if the border around a card should be draw. The border is a thing | ||
274 | * (1 or 2 pixel) line that bounds the card. When drawn, it shows when | ||
275 | * a card is highlighted and when it isn't. | ||
276 | */ | ||
277 | void setDrawCardBorder(bool enabled); | ||
278 | |||
279 | /** @return True if borders are drawn, false otherwise. | ||
280 | */ | ||
281 | bool drawCardBorder() const; | ||
282 | |||
283 | /** Sets if the column separator should be drawn. The column separator | ||
284 | * is a thin verticle line (1 or 2 pixels) that is used to separate the | ||
285 | * columns in the list view. The separator is just for esthetics and it | ||
286 | * does not serve a functional purpose. | ||
287 | */ | ||
288 | void setDrawColSeparators(bool enabled); | ||
289 | |||
290 | /** @return True if column separators are drawn, false otherwise. | ||
291 | */ | ||
292 | bool drawColSeparators() const; | ||
293 | |||
294 | /** Sets if the field labels should be drawn. The field labels are the | ||
295 | * unique strings used to identify the fields. Sometimes drawing these | ||
296 | * labels makes sense as a source of clarity for the user, othertimes they | ||
297 | * waste too much space and do not assist the user. | ||
298 | */ | ||
299 | void setDrawFieldLabels(bool enabled); | ||
300 | |||
301 | /** @return True if the field labels are drawn, false otherwise. | ||
302 | */ | ||
303 | bool drawFieldLabels() const; | ||
304 | |||
305 | /** Sets if fields with no value should be drawn (of cause the label only, | ||
306 | * but it allows for embedded editing sometimes...) | ||
307 | */ | ||
308 | void setShowEmptyFields(bool show); | ||
309 | |||
310 | /** @return Wheather empty fields should be shown | ||
311 | */ | ||
312 | bool showEmptyFields() const; | ||
313 | |||
314 | /** @return the advisory internal margin in items. Setting a value above 1 means | ||
315 | * a space between the item contents and the focus recttangle drawn around | ||
316 | * the current item. The default value is 0. | ||
317 | * The value should be used by CardViewItem and derived classes. | ||
318 | * Note that this should not be greater than half of the minimal item width, | ||
319 | * which is 80. It is currently not checked, so setting a value greater than 40 | ||
320 | * will probably mean a crash in the items painting routine. | ||
321 | * @private Note: I looked for a value in QStyle::PixelMetric to use, but I could | ||
322 | * not see a usefull one. One may turn up in a future version of Qt. | ||
323 | */ | ||
324 | uint itemMargin(); | ||
325 | |||
326 | /** Sets the internal item margin. @see itemMargin(). | ||
327 | */ | ||
328 | void setItemMargin( uint margin ); | ||
329 | |||
330 | /** @return the item spacing. | ||
331 | * The item spacing is the space (in pixels) between each item in a | ||
332 | * column, between the items and column separators if drawn, and between | ||
333 | * the items and the borders of the widget. The default value is set to | ||
334 | * 10. | ||
335 | * @private Note: There is no usefull QStyle::PixelMetric to use for this atm. | ||
336 | * An option would be using KDialog::spacingHint(). | ||
337 | */ | ||
338 | uint itemSpacing(); | ||
339 | |||
340 | /** Sets the item spacing. | ||
341 | * @see itemSpacing() | ||
342 | */ | ||
343 | void setItemSpacing( uint spacing ); | ||
344 | |||
345 | /** @return the width made available to the card items. */ | ||
346 | int itemWidth() const; | ||
347 | |||
348 | /** Sets the width made available to card items. */ | ||
349 | void setItemWidth( int width ); | ||
350 | |||
351 | /** Sets the header font */ | ||
352 | void setHeaderFont( const QFont &fnt ); | ||
353 | |||
354 | /** @return the header font */ | ||
355 | QFont headerFont() const; | ||
356 | |||
357 | /** @reimp */ | ||
358 | void setFont( const QFont &fnt ); | ||
359 | |||
360 | /** Sets the column separator width */ | ||
361 | void setSeparatorWidth( int width ); | ||
362 | |||
363 | /** @return the column separator width */ | ||
364 | int separatorWidth(); | ||
365 | |||
366 | /** Sets the maximum number of lines to display pr field. | ||
367 | If set to 0 (the default) all lines will be displayed. | ||
368 | */ | ||
369 | void setMaxFieldLines( int howmany ); | ||
370 | |||
371 | /** @return the maximum number of lines pr field */ | ||
372 | int maxFieldLines() const; | ||
373 | |||
374 | signals: | ||
375 | /** Emitted whenever the selection changes. This means a user highlighted | ||
376 | * a new item or unhighlighted a currently selected item. | ||
377 | */ | ||
378 | void selectionChanged(); | ||
379 | |||
380 | /** Same as above method, only it carries the item that was selected. This | ||
381 | * method will only be emitted in single select mode, since it defineds | ||
382 | * which item was selected. | ||
383 | */ | ||
384 | void selectionChanged(CardViewItem *); | ||
385 | |||
386 | /** This method is emitted whenever an item is clicked. | ||
387 | */ | ||
388 | void clicked(CardViewItem *); | ||
389 | |||
390 | /** Emitted whenever the user 'executes' an item. This is dependant on | ||
391 | * the KDE global config. This could be a single click or a doubleclick. | ||
392 | * Also emitted when the return key is pressed on an item. | ||
393 | */ | ||
394 | void executed(CardViewItem *); | ||
395 | |||
396 | /** Emitted whenever the user double clicks on an item. | ||
397 | */ | ||
398 | void doubleClicked(CardViewItem *); | ||
399 | |||
400 | /** Emitted when the current item changes | ||
401 | */ | ||
402 | void currentChanged( CardViewItem * ); | ||
403 | |||
404 | /** Emitted when the return key is pressed in an item. | ||
405 | */ | ||
406 | void returnPressed( CardViewItem * ); | ||
407 | |||
408 | protected: | ||
409 | /** Determines which cards intersect that region and tells them to paint | ||
410 | * themselves. | ||
411 | */ | ||
412 | void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph); | ||
413 | |||
414 | /** Sets the layout to dirty and repaints. | ||
415 | */ | ||
416 | void resizeEvent(QResizeEvent *e); | ||
417 | |||
418 | /** Changes the direction the canvas scolls. | ||
419 | */ | ||
420 | void contentsWheelEvent(QWheelEvent *e); | ||
421 | |||
422 | /** Sets the layout to dirty and calls for a repaint. | ||
423 | */ | ||
424 | void setLayoutDirty(bool dirty); | ||
425 | |||
426 | /** Does the math based on the bounding rect of the cards to properly | ||
427 | * lay the cards out on the screen. This is only done if the layout is | ||
428 | * marked as dirty. | ||
429 | */ | ||
430 | void calcLayout(); | ||
431 | |||
432 | // virtual void mousePressEvent(QMouseEvent *e); | ||
433 | // virtual void mouseReleaseEvent(QMouseEvent *e); | ||
434 | // virtual void mouseMoveEvent(QMouseEvent *e); | ||
435 | |||
436 | virtual void contentsMousePressEvent(QMouseEvent *e); | ||
437 | virtual void contentsMouseMoveEvent(QMouseEvent *e); | ||
438 | virtual void contentsMouseReleaseEvent(QMouseEvent *e); | ||
439 | virtual void contentsMouseDoubleClickEvent(QMouseEvent *e); | ||
440 | |||
441 | virtual void enterEvent( QEvent * ); | ||
442 | virtual void leaveEvent( QEvent * ); | ||
443 | |||
444 | virtual void focusInEvent( QFocusEvent * ); | ||
445 | virtual void focusOutEvent( QFocusEvent * ); | ||
446 | |||
447 | virtual void keyPressEvent( QKeyEvent * ); | ||
448 | |||
449 | /** Overload this method to be told when a drag should be started. | ||
450 | * In most cases you will want to start a drag event with the currently | ||
451 | * selected item. | ||
452 | */ | ||
453 | virtual void startDrag(); | ||
454 | |||
455 | private slots: | ||
456 | /** Called by a timer to display a label with truncated text. | ||
457 | * Pop up a label, if there is a field with obscured text or | ||
458 | * label at the cursor position. | ||
459 | */ | ||
460 | void tryShowFullText(); | ||
461 | |||
462 | private: | ||
463 | /** draws and erases the rubber bands while columns are resized. | ||
464 | * @p pos is the horizontal position inside the viewport to use as | ||
465 | * the anchor. | ||
466 | * If pos is 0, only erase is done. | ||
467 | */ | ||
468 | void drawRubberBands( int pos ); | ||
469 | |||
470 | CardViewPrivate *d; | ||
471 | }; | ||
472 | |||
473 | #endif | ||
diff --git a/kaddressbook/views/colorlistbox.cpp b/kaddressbook/views/colorlistbox.cpp new file mode 100644 index 0000000..c243fa0 --- a/dev/null +++ b/kaddressbook/views/colorlistbox.cpp | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | * kmail: KDE mail client | ||
3 | * This file: Copyright (C) 2000 Espen Sand, espen@kde.org | ||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <qpainter.h> | ||
22 | |||
23 | #include <kcolordialog.h> | ||
24 | |||
25 | #ifndef KAB_EMBEDDED | ||
26 | #include <kcolordrag.h> | ||
27 | #endif //KAB_EMBEDDED | ||
28 | |||
29 | #include "colorlistbox.h" | ||
30 | |||
31 | ColorListBox::ColorListBox( QWidget *parent, const char *name, WFlags f ) | ||
32 | :KListBox( parent, name, f ), mCurrentOnDragEnter(-1) | ||
33 | { | ||
34 | connect( this, SIGNAL(selected(int)), this, SLOT(newColor(int)) ); | ||
35 | setAcceptDrops( true); | ||
36 | } | ||
37 | |||
38 | |||
39 | void ColorListBox::setEnabled( bool state ) | ||
40 | { | ||
41 | if( state == isEnabled() ) | ||
42 | { | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | QListBox::setEnabled( state ); | ||
47 | for( uint i=0; i<count(); i++ ) | ||
48 | { | ||
49 | updateItem( i ); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | |||
54 | void ColorListBox::setColor( uint index, const QColor &color ) | ||
55 | { | ||
56 | if( index < count() ) | ||
57 | { | ||
58 | ColorListItem *colorItem = (ColorListItem*)item(index); | ||
59 | colorItem->setColor(color); | ||
60 | updateItem( colorItem ); | ||
61 | } | ||
62 | } | ||
63 | |||
64 | |||
65 | QColor ColorListBox::color( uint index ) const | ||
66 | { | ||
67 | if( index < count() ) | ||
68 | { | ||
69 | ColorListItem *colorItem = (ColorListItem*)item(index); | ||
70 | return( colorItem->color() ); | ||
71 | } | ||
72 | else | ||
73 | { | ||
74 | return( black ); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | |||
79 | void ColorListBox::newColor( int index ) | ||
80 | { | ||
81 | if( isEnabled() == false ) | ||
82 | { | ||
83 | return; | ||
84 | } | ||
85 | |||
86 | if( (uint)index < count() ) | ||
87 | { | ||
88 | QColor c = color( index ); | ||
89 | #ifndef KAB_EMBEDDED | ||
90 | if( KColorDialog::getColor( c, this ) != QDialog::Rejected ) | ||
91 | { | ||
92 | setColor( index, c ); | ||
93 | } | ||
94 | #else //KAB_EMBEDDED | ||
95 | KColorDialog* k = new KColorDialog( this ); | ||
96 | k->setColor( c ); | ||
97 | int res = k->exec(); | ||
98 | if ( res ) { | ||
99 | setColor( index, k->getColor() ); | ||
100 | } | ||
101 | delete k; | ||
102 | #endif //KAB_EMBEDDED | ||
103 | |||
104 | } | ||
105 | } | ||
106 | |||
107 | |||
108 | void ColorListBox::dragEnterEvent( QDragEnterEvent *e ) | ||
109 | { | ||
110 | #ifndef KAB_EMBEDDED | ||
111 | if( KColorDrag::canDecode(e) && isEnabled() ) | ||
112 | { | ||
113 | mCurrentOnDragEnter = currentItem(); | ||
114 | e->accept( true ); | ||
115 | } | ||
116 | else | ||
117 | { | ||
118 | mCurrentOnDragEnter = -1; | ||
119 | e->accept( false ); | ||
120 | } | ||
121 | #else //KAB_EMBEDDED | ||
122 | qDebug("ColorListBox::dragEnterEvent drag&drop currently not supported"); | ||
123 | #endif //KAB_EMBEDDED | ||
124 | |||
125 | } | ||
126 | |||
127 | |||
128 | void ColorListBox::dragLeaveEvent( QDragLeaveEvent * ) | ||
129 | { | ||
130 | #ifndef KAB_EMBEDDED | ||
131 | |||
132 | if( mCurrentOnDragEnter != -1 ) | ||
133 | { | ||
134 | setCurrentItem( mCurrentOnDragEnter ); | ||
135 | mCurrentOnDragEnter = -1; | ||
136 | } | ||
137 | #else //KAB_EMBEDDED | ||
138 | qDebug("ColorListBox::dragLeaveEvent drag&drop currently not supported"); | ||
139 | #endif //KAB_EMBEDDED | ||
140 | } | ||
141 | |||
142 | |||
143 | void ColorListBox::dragMoveEvent( QDragMoveEvent *e ) | ||
144 | { | ||
145 | #ifndef KAB_EMBEDDED | ||
146 | if( KColorDrag::canDecode(e) && isEnabled() ) | ||
147 | { | ||
148 | ColorListItem *item = (ColorListItem*)itemAt( e->pos() ); | ||
149 | if( item != 0 ) | ||
150 | { | ||
151 | setCurrentItem ( item ); | ||
152 | } | ||
153 | } | ||
154 | #else //KAB_EMBEDDED | ||
155 | qDebug("ColorListBox::dragMoveEvent drag&drop currently not supported"); | ||
156 | #endif //KAB_EMBEDDED | ||
157 | |||
158 | } | ||
159 | |||
160 | |||
161 | void ColorListBox::dropEvent( QDropEvent *e ) | ||
162 | { | ||
163 | #ifndef KAB_EMBEDDED | ||
164 | QColor color; | ||
165 | if( KColorDrag::decode( e, color ) ) | ||
166 | { | ||
167 | int index = currentItem(); | ||
168 | if( index != -1 ) | ||
169 | { | ||
170 | ColorListItem *colorItem = (ColorListItem*)item(index); | ||
171 | colorItem->setColor(color); | ||
172 | triggerUpdate( false ); // Redraw item | ||
173 | } | ||
174 | mCurrentOnDragEnter = -1; | ||
175 | } | ||
176 | |||
177 | #else //KAB_EMBEDDED | ||
178 | qDebug("ColorListBox::dropEvent drag&drop currently not supported"); | ||
179 | #endif //KAB_EMBEDDED | ||
180 | |||
181 | } | ||
182 | |||
183 | |||
184 | |||
185 | ColorListItem::ColorListItem( const QString &text, const QColor &color ) | ||
186 | : QListBoxItem(), mColor( color ), mBoxWidth( 30 ) | ||
187 | { | ||
188 | setText( text ); | ||
189 | } | ||
190 | |||
191 | |||
192 | const QColor &ColorListItem::color( void ) | ||
193 | { | ||
194 | return( mColor ); | ||
195 | } | ||
196 | |||
197 | |||
198 | void ColorListItem::setColor( const QColor &color ) | ||
199 | { | ||
200 | mColor = color; | ||
201 | } | ||
202 | |||
203 | |||
204 | void ColorListItem::paint( QPainter *p ) | ||
205 | { | ||
206 | QFontMetrics fm = p->fontMetrics(); | ||
207 | int h = fm.height(); | ||
208 | |||
209 | p->drawText( mBoxWidth+3*2, fm.ascent() + fm.leading()/2, text() ); | ||
210 | |||
211 | p->setPen( Qt::black ); | ||
212 | p->drawRect( 3, 1, mBoxWidth, h-1 ); | ||
213 | p->fillRect( 4, 2, mBoxWidth-2, h-3, mColor ); | ||
214 | } | ||
215 | |||
216 | |||
217 | int ColorListItem::height(const QListBox *lb ) const | ||
218 | { | ||
219 | return( lb->fontMetrics().lineSpacing()+1 ); | ||
220 | } | ||
221 | |||
222 | |||
223 | int ColorListItem::width(const QListBox *lb ) const | ||
224 | { | ||
225 | return( mBoxWidth + lb->fontMetrics().width( text() ) + 6 ); | ||
226 | } | ||
227 | |||
228 | #ifndef KAB_EMBEDDED | ||
229 | #include "colorlistbox.moc" | ||
230 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/colorlistbox.h b/kaddressbook/views/colorlistbox.h new file mode 100644 index 0000000..4a0e705 --- a/dev/null +++ b/kaddressbook/views/colorlistbox.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * kmail: KDE mail client | ||
3 | * This file: Copyright (C) 2000 Espen Sand, espen@kde.org | ||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #ifndef _COLOR_LISTBOX_H_ | ||
22 | #define _COLOR_LISTBOX_H_ | ||
23 | |||
24 | #include <klistbox.h> | ||
25 | |||
26 | class QDragEnterEvent; | ||
27 | class QDragLeaveEvent; | ||
28 | class QDragMoveEvent; | ||
29 | class QDropEvent; | ||
30 | |||
31 | class ColorListBox : public KListBox | ||
32 | { | ||
33 | Q_OBJECT | ||
34 | |||
35 | public: | ||
36 | ColorListBox( QWidget *parent=0, const char * name=0, WFlags f=0 ); | ||
37 | void setColor( uint index, const QColor &color ); | ||
38 | QColor color( uint index ) const; | ||
39 | |||
40 | public slots: | ||
41 | virtual void setEnabled( bool state ); | ||
42 | |||
43 | protected: | ||
44 | void dragEnterEvent( QDragEnterEvent *e ); | ||
45 | void dragLeaveEvent( QDragLeaveEvent *e ); | ||
46 | void dragMoveEvent( QDragMoveEvent *e ); | ||
47 | void dropEvent( QDropEvent *e ); | ||
48 | |||
49 | private slots: | ||
50 | void newColor( int index ); | ||
51 | |||
52 | private: | ||
53 | int mCurrentOnDragEnter; | ||
54 | |||
55 | }; | ||
56 | |||
57 | |||
58 | class ColorListItem : public QListBoxItem | ||
59 | { | ||
60 | public: | ||
61 | ColorListItem( const QString &text, const QColor &color=Qt::black ); | ||
62 | const QColor &color( void ); | ||
63 | void setColor( const QColor &color ); | ||
64 | |||
65 | protected: | ||
66 | virtual void paint( QPainter * ); | ||
67 | virtual int height( const QListBox * ) const; | ||
68 | virtual int width( const QListBox * ) const; | ||
69 | |||
70 | private: | ||
71 | QColor mColor; | ||
72 | int mBoxWidth; | ||
73 | }; | ||
74 | |||
75 | #endif | ||
76 | |||
diff --git a/kaddressbook/views/configurecardviewdialog.cpp b/kaddressbook/views/configurecardviewdialog.cpp new file mode 100644 index 0000000..d518cf7 --- a/dev/null +++ b/kaddressbook/views/configurecardviewdialog.cpp | |||
@@ -0,0 +1,364 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #include <qstring.h> | ||
25 | #include <qlayout.h> | ||
26 | #include <qlabel.h> | ||
27 | #include <qcheckbox.h> | ||
28 | #include <qvbox.h> | ||
29 | #include <qgroupbox.h> | ||
30 | #include <qspinbox.h> | ||
31 | #include <qtabwidget.h> | ||
32 | #include <qwhatsthis.h> | ||
33 | |||
34 | #include <kdebug.h> | ||
35 | #include <kglobal.h> | ||
36 | #include <kglobalsettings.h> | ||
37 | #include <klocale.h> | ||
38 | #include <kiconloader.h> | ||
39 | #include <kconfig.h> | ||
40 | #include <kfontdialog.h> | ||
41 | |||
42 | #ifndef KAB_EMBEDDED | ||
43 | #include <kpushbutton.h> | ||
44 | #else //KAB_EMBEDDED | ||
45 | #include <qpushbutton.h> | ||
46 | #endif //KAB_EMBEDDED | ||
47 | |||
48 | #include "colorlistbox.h" | ||
49 | |||
50 | #include "configurecardviewdialog.h" | ||
51 | |||
52 | ///////////////////////////////// | ||
53 | // ConfigureCardViewDialog | ||
54 | |||
55 | ConfigureCardViewWidget::ConfigureCardViewWidget( KABC::AddressBook *ab, QWidget *parent, | ||
56 | const char *name ) | ||
57 | : ViewConfigureWidget( ab, parent, name ) | ||
58 | { | ||
59 | #ifndef KAB_EMBEDDED | ||
60 | QWidget *page = addPage( i18n( "Look & Feel" ), QString::null, | ||
61 | DesktopIcon( "looknfeel" ) ); | ||
62 | #else //KAB_EMBEDDED | ||
63 | QWidget *page = addPage( i18n( "Look & Feel" ), QString::null, | ||
64 | KGlobal::iconLoader()->loadIcon( "looknfeel", | ||
65 | KIcon::Panel ) ); | ||
66 | #endif //KAB_EMBEDDED | ||
67 | |||
68 | mAdvancedPage = new CardViewLookNFeelPage( page ); | ||
69 | } | ||
70 | |||
71 | ConfigureCardViewWidget::~ConfigureCardViewWidget() | ||
72 | { | ||
73 | } | ||
74 | |||
75 | void ConfigureCardViewWidget::restoreSettings( KConfig *config ) | ||
76 | { | ||
77 | ViewConfigureWidget::restoreSettings( config ); | ||
78 | |||
79 | mAdvancedPage->restoreSettings( config ); | ||
80 | } | ||
81 | |||
82 | void ConfigureCardViewWidget::saveSettings( KConfig *config ) | ||
83 | { | ||
84 | ViewConfigureWidget::saveSettings( config ); | ||
85 | |||
86 | mAdvancedPage->saveSettings( config ); | ||
87 | } | ||
88 | |||
89 | //////////////////////// | ||
90 | // CardViewLookNFeelPage | ||
91 | CardViewLookNFeelPage::CardViewLookNFeelPage( QWidget *parent, const char *name ) | ||
92 | : QVBox( parent, name ) | ||
93 | { | ||
94 | initGUI(); | ||
95 | } | ||
96 | |||
97 | CardViewLookNFeelPage::~CardViewLookNFeelPage() | ||
98 | { | ||
99 | } | ||
100 | |||
101 | void CardViewLookNFeelPage::restoreSettings( KConfig *config ) | ||
102 | { | ||
103 | // colors | ||
104 | cbEnableCustomColors->setChecked( config->readBoolEntry( "EnableCustomColors", false ) ); | ||
105 | QColor c; | ||
106 | qDebug("CardViewLookNFeelPage::restoreSettings make base color configurable"); | ||
107 | |||
108 | #ifndef KAB_EMBEDDED | ||
109 | c = KGlobalSettings::baseColor(); | ||
110 | #else //KAB_EMBEDDED | ||
111 | c = QColor(0,0,0); | ||
112 | #endif //KAB_EMBEDDED | ||
113 | |||
114 | lbColors->insertItem( new ColorListItem( i18n("Background Color"), | ||
115 | config->readColorEntry( "BackgroundColor", &c ) ) ); | ||
116 | c = colorGroup().foreground(); | ||
117 | lbColors->insertItem( new ColorListItem( i18n("Text Color"), | ||
118 | config->readColorEntry( "TextColor", &c ) ) ); | ||
119 | c = colorGroup().button(); | ||
120 | lbColors->insertItem( new ColorListItem( i18n("Header, Border and Separator Color"), | ||
121 | config->readColorEntry( "HeaderColor", &c ) ) ); | ||
122 | c = colorGroup().buttonText(); | ||
123 | lbColors->insertItem( new ColorListItem( i18n("Header Text Color"), | ||
124 | config->readColorEntry( "HeaderTextColor", &c ) ) ); | ||
125 | c = colorGroup().highlight(); | ||
126 | lbColors->insertItem( new ColorListItem( i18n("Highlight Color"), | ||
127 | config->readColorEntry( "HighlightColor", &c ) ) ); | ||
128 | c = colorGroup().highlightedText(); | ||
129 | lbColors->insertItem( new ColorListItem( i18n("Highlighted Text Color"), | ||
130 | config->readColorEntry( "HighlightedTextColor", &c ) ) ); | ||
131 | |||
132 | enableColors(); | ||
133 | |||
134 | // fonts | ||
135 | QFont fnt = font(); | ||
136 | updateFontLabel( config->readFontEntry( "TextFont", &fnt ), (QLabel*)lTextFont ); | ||
137 | fnt.setBold( true ); | ||
138 | updateFontLabel( config->readFontEntry( "HeaderFont", &fnt ), (QLabel*)lHeaderFont ); | ||
139 | cbEnableCustomFonts->setChecked( config->readBoolEntry( "EnableCustomFonts", false ) ); | ||
140 | enableFonts(); | ||
141 | |||
142 | // layout | ||
143 | sbMargin->setValue( config->readNumEntry( "ItemMargin", 0 ) ); | ||
144 | sbSpacing->setValue( config->readNumEntry( "ItemSpacing", 10 ) ); | ||
145 | sbSepWidth->setValue( config->readNumEntry( "SeparatorWidth", 2 ) ); | ||
146 | cbDrawSeps->setChecked( config->readBoolEntry( "DrawSeparators", true ) ); | ||
147 | cbDrawBorders->setChecked( config->readBoolEntry( "DrawBorder", true ) ); | ||
148 | |||
149 | // behaviour | ||
150 | cbShowFieldLabels->setChecked( config->readBoolEntry( "DrawFieldLabels", false ) ); | ||
151 | cbShowEmptyFields->setChecked( config->readBoolEntry( "ShowEmptyFields", false ) ); | ||
152 | } | ||
153 | |||
154 | void CardViewLookNFeelPage::saveSettings( KConfig *config ) | ||
155 | { | ||
156 | // colors | ||
157 | config->writeEntry( "EnableCustomColors", cbEnableCustomColors->isChecked() ); | ||
158 | if ( cbEnableCustomColors->isChecked() ) // ?? - Hmmm. | ||
159 | { | ||
160 | config->writeEntry( "BackgroundColor", lbColors->color( 0 ) ); | ||
161 | config->writeEntry( "TextColor", lbColors->color( 1 ) ); | ||
162 | config->writeEntry( "HeaderColor", lbColors->color( 2 ) ); | ||
163 | config->writeEntry( "HeaderTextColor", lbColors->color( 3 ) ); | ||
164 | config->writeEntry( "HighlightColor", lbColors->color( 4 ) ); | ||
165 | config->writeEntry( "HighlightedTextColor", lbColors->color( 5 ) ); | ||
166 | } | ||
167 | // fonts | ||
168 | config->writeEntry( "EnableCustomFonts", cbEnableCustomFonts->isChecked() ); | ||
169 | if ( cbEnableCustomFonts->isChecked() ) | ||
170 | { | ||
171 | config->writeEntry( "TextFont", lTextFont->font() ); | ||
172 | config->writeEntry( "HeaderFont", lHeaderFont->font() ); | ||
173 | } | ||
174 | // layout | ||
175 | config->writeEntry( "ItemMargin", sbMargin->value() ); | ||
176 | config->writeEntry( "ItemSpacing", sbSpacing->value() ); | ||
177 | config->writeEntry( "SeparatorWidth", sbSepWidth->value() ); | ||
178 | config->writeEntry("DrawBorder", cbDrawBorders->isChecked()); | ||
179 | config->writeEntry("DrawSeparators", cbDrawSeps->isChecked()); | ||
180 | |||
181 | // behaviour | ||
182 | config->writeEntry("DrawFieldLabels", cbShowFieldLabels->isChecked()); | ||
183 | config->writeEntry("ShowEmptyFields", cbShowEmptyFields->isChecked()); | ||
184 | } | ||
185 | |||
186 | void CardViewLookNFeelPage::setTextFont() | ||
187 | { | ||
188 | QFont f( lTextFont->font() ); | ||
189 | #ifndef KAB_EMBEDDED | ||
190 | if ( KFontDialog::getFont( f, false, this ) == QDialog::Accepted ) | ||
191 | updateFontLabel( f, lTextFont ); | ||
192 | #else //KAB_EMBEDDED | ||
193 | bool ok; | ||
194 | QFont fout = KFontDialog::getFont( f, ok); | ||
195 | if ( ok ) | ||
196 | updateFontLabel( fout, lTextFont ); | ||
197 | #endif //KAB_EMBEDDED | ||
198 | } | ||
199 | |||
200 | void CardViewLookNFeelPage::setHeaderFont() | ||
201 | { | ||
202 | QFont f( lHeaderFont->font() ); | ||
203 | #ifndef KAB_EMBEDDED | ||
204 | if ( KFontDialog::getFont( f,false, this ) == QDialog::Accepted ) | ||
205 | updateFontLabel( f, lHeaderFont ); | ||
206 | #else //KAB_EMBEDDED | ||
207 | bool ok; | ||
208 | QFont fout = KFontDialog::getFont( f, ok); | ||
209 | if ( ok ) | ||
210 | updateFontLabel( fout, lHeaderFont ); | ||
211 | #endif //KAB_EMBEDDED | ||
212 | } | ||
213 | |||
214 | void CardViewLookNFeelPage::enableFonts() | ||
215 | { | ||
216 | vbFonts->setEnabled( cbEnableCustomFonts->isChecked() ); | ||
217 | } | ||
218 | |||
219 | void CardViewLookNFeelPage::enableColors() | ||
220 | { | ||
221 | lbColors->setEnabled( cbEnableCustomColors->isChecked() ); | ||
222 | } | ||
223 | |||
224 | void CardViewLookNFeelPage::initGUI() | ||
225 | { | ||
226 | int spacing = KDialog::spacingHint(); | ||
227 | int margin = KDialog::marginHint(); | ||
228 | |||
229 | QTabWidget *tabs = new QTabWidget( this ); | ||
230 | |||
231 | // Layout | ||
232 | QVBox *loTab = new QVBox( this, "layouttab" ); | ||
233 | |||
234 | loTab->setSpacing( spacing ); | ||
235 | loTab->setMargin( margin ); | ||
236 | |||
237 | QGroupBox *gbGeneral = new QGroupBox( 1, Qt::Horizontal, i18n("General"), loTab ); | ||
238 | |||
239 | cbDrawSeps = new QCheckBox( i18n("Draw &separators"), gbGeneral ); | ||
240 | |||
241 | QHBox *hbSW = new QHBox( gbGeneral ); | ||
242 | QLabel *lSW = new QLabel( i18n("Separator &width:"), hbSW ); | ||
243 | sbSepWidth = new QSpinBox( 1, 50, 1, hbSW ); | ||
244 | lSW->setBuddy( sbSepWidth); | ||
245 | |||
246 | QHBox *hbPadding = new QHBox( gbGeneral ); | ||
247 | QLabel *lSpacing = new QLabel( i18n("&Padding:"), hbPadding ); | ||
248 | sbSpacing = new QSpinBox( 0, 100, 1, hbPadding ); | ||
249 | lSpacing->setBuddy( sbSpacing ); | ||
250 | |||
251 | QGroupBox *gbCards = new QGroupBox( 1, Qt::Horizontal, i18n("Cards"), loTab ); | ||
252 | |||
253 | QHBox *hbMargin = new QHBox( gbCards ); | ||
254 | QLabel *lMargin = new QLabel( i18n("&Margin:"), hbMargin ); | ||
255 | sbMargin = new QSpinBox( 0, 100, 1, hbMargin ); | ||
256 | lMargin->setBuddy( sbMargin ); | ||
257 | |||
258 | cbDrawBorders = new QCheckBox( i18n("Draw &borders"), gbCards ); | ||
259 | |||
260 | loTab->setStretchFactor( new QWidget( loTab ), 1 ); | ||
261 | |||
262 | QWhatsThis::add( sbMargin, i18n( | ||
263 | "The item margin is the distance (in pixels) between the item edge and the item data. Most noticeably, " | ||
264 | "incrementing the item margin will add space between the focus rectangle and the item data." | ||
265 | ) ); | ||
266 | QWhatsThis::add( lMargin, QWhatsThis::textFor( sbMargin ) ); | ||
267 | QWhatsThis::add( sbSpacing, i18n( | ||
268 | "The Item Spacing decides the distance (in pixels) between the items and anything else: the view " | ||
269 | "borders, other items or column separators." | ||
270 | ) ); | ||
271 | QWhatsThis::add( lSpacing, QWhatsThis::textFor( sbSpacing ) ); | ||
272 | QWhatsThis::add( sbSepWidth, i18n("Sets the width of column separators") ); | ||
273 | QWhatsThis::add( lSW, QWhatsThis::textFor( sbSepWidth ) ); | ||
274 | |||
275 | tabs->addTab( loTab, i18n("&Layout") ); | ||
276 | |||
277 | // Colors | ||
278 | QVBox *colorTab = new QVBox( this, "colortab" ); | ||
279 | colorTab->setSpacing( spacing ); | ||
280 | colorTab->setMargin( spacing ); | ||
281 | cbEnableCustomColors = new QCheckBox( i18n("&Enable custom Colors"), colorTab ); | ||
282 | connect( cbEnableCustomColors, SIGNAL(clicked()), this, SLOT(enableColors()) ); | ||
283 | lbColors = new ColorListBox( colorTab ); | ||
284 | tabs->addTab( colorTab, i18n("&Colors") ); | ||
285 | |||
286 | QWhatsThis::add( cbEnableCustomColors, i18n( | ||
287 | "If custom colors are enabled, you may choose the colors for the view below. " | ||
288 | "Otherwise colors from your current KDE color scheme are used." | ||
289 | ) ); | ||
290 | QWhatsThis::add( lbColors, i18n( | ||
291 | "Double click or press RETURN on a item to select a color for the related strings in the view." | ||
292 | ) ); | ||
293 | |||
294 | // Fonts | ||
295 | QVBox *fntTab = new QVBox( this, "fonttab" ); | ||
296 | |||
297 | fntTab->setSpacing( spacing ); | ||
298 | fntTab->setMargin( spacing ); | ||
299 | |||
300 | cbEnableCustomFonts = new QCheckBox( i18n("&Enable custom fonts"), fntTab ); | ||
301 | connect( cbEnableCustomFonts, SIGNAL(clicked()), this, SLOT(enableFonts()) ); | ||
302 | |||
303 | vbFonts = new QWidget( fntTab ); | ||
304 | QGridLayout *gFnts = new QGridLayout( vbFonts, 2, 3 ); | ||
305 | gFnts->setSpacing( spacing ); | ||
306 | gFnts->setAutoAdd( true ); | ||
307 | gFnts->setColStretch( 1, 1 ); | ||
308 | QLabel *lTFnt = new QLabel( i18n("&Text font:"), vbFonts ); | ||
309 | lTextFont = new QLabel( vbFonts ); | ||
310 | lTextFont->setFrameStyle( QFrame::Panel|QFrame::Sunken ); | ||
311 | #ifndef KAB_EMBEDDED | ||
312 | btnFont = new KPushButton( i18n("Choose..."), vbFonts ); | ||
313 | #else //KAB_EMBEDDED | ||
314 | btnFont = new QPushButton( i18n("Choose..."), vbFonts ); | ||
315 | #endif //KAB_EMBEDDED | ||
316 | |||
317 | lTFnt->setBuddy( btnFont ); | ||
318 | |||
319 | connect( btnFont, SIGNAL(clicked()), this, SLOT(setTextFont()) ); | ||
320 | |||
321 | QLabel *lHFnt = new QLabel( i18n("&Header font:"), vbFonts ); | ||
322 | lHeaderFont = new QLabel( vbFonts ); | ||
323 | lHeaderFont->setFrameStyle( QFrame::Panel|QFrame::Sunken ); | ||
324 | #ifndef KAB_EMBEDDED | ||
325 | btnHeaderFont = new KPushButton( i18n("Choose..."), vbFonts ); | ||
326 | #else //KAB_EMBEDDED | ||
327 | btnHeaderFont = new QPushButton( i18n("Choose..."), vbFonts ); | ||
328 | #endif //KAB_EMBEDDED | ||
329 | lHFnt->setBuddy( btnHeaderFont ); | ||
330 | connect( btnHeaderFont, SIGNAL(clicked()), this, SLOT(setHeaderFont()) ); | ||
331 | |||
332 | fntTab->setStretchFactor( new QWidget( fntTab ), 1 ); | ||
333 | |||
334 | QWhatsThis::add( cbEnableCustomFonts, i18n( | ||
335 | "If custom fonts are enabled, you may choose which fonts to use for this view below. " | ||
336 | "Otherwise the default KDE font will be used, in bold style for the header and " | ||
337 | "normal style for the data." | ||
338 | ) ); | ||
339 | |||
340 | tabs->addTab( fntTab, i18n("&Fonts") ); | ||
341 | |||
342 | // Behaviour | ||
343 | QVBox *behaviourTab = new QVBox( this ); | ||
344 | behaviourTab->setMargin( margin ); | ||
345 | behaviourTab->setSpacing( spacing ); | ||
346 | |||
347 | cbShowEmptyFields = new QCheckBox( i18n("Show &empty fields"), behaviourTab ); | ||
348 | cbShowFieldLabels = new QCheckBox( i18n("Show field &labels"), behaviourTab ); | ||
349 | |||
350 | behaviourTab->setStretchFactor( new QWidget( behaviourTab ), 1 ); | ||
351 | |||
352 | tabs->addTab( behaviourTab, i18n("Be&havior") ); | ||
353 | |||
354 | } | ||
355 | |||
356 | void CardViewLookNFeelPage::updateFontLabel( QFont fnt, QLabel *l ) | ||
357 | { | ||
358 | l->setFont( fnt ); | ||
359 | l->setText( QString( fnt.family() + " %1" ).arg( fnt.pointSize() ) ); | ||
360 | } | ||
361 | |||
362 | #ifndef KAB_EMBEDDED | ||
363 | #include "configurecardviewdialog.moc" | ||
364 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/configurecardviewdialog.h b/kaddressbook/views/configurecardviewdialog.h new file mode 100644 index 0000000..7a62226 --- a/dev/null +++ b/kaddressbook/views/configurecardviewdialog.h | |||
@@ -0,0 +1,117 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #ifndef CONFIGURECARDVIEWDIALOG_H | ||
25 | #define CONFIGURECARDVIEWDIALOG_H | ||
26 | |||
27 | #include "viewconfigurewidget.h" | ||
28 | |||
29 | #include <qvbox.h> | ||
30 | #include <qwidget.h> | ||
31 | #include <qfont.h> | ||
32 | |||
33 | class QString; | ||
34 | class QWidget; | ||
35 | class QCheckBox; | ||
36 | class QLabel; | ||
37 | class KConfig; | ||
38 | |||
39 | namespace KABC { class AddressBook; } | ||
40 | |||
41 | class CardViewLookAndFeelPage; | ||
42 | |||
43 | /** | ||
44 | Configure dialog for the card view. This dialog inherits from the | ||
45 | standard view dialog in order to add a custom page for the card | ||
46 | view. | ||
47 | */ | ||
48 | class ConfigureCardViewWidget : public ViewConfigureWidget | ||
49 | { | ||
50 | public: | ||
51 | ConfigureCardViewWidget( KABC::AddressBook *ab, QWidget *parent, const char *name ); | ||
52 | virtual ~ConfigureCardViewWidget(); | ||
53 | |||
54 | virtual void restoreSettings( KConfig* ); | ||
55 | virtual void saveSettings( KConfig* ); | ||
56 | |||
57 | private: | ||
58 | class CardViewLookNFeelPage *mAdvancedPage; | ||
59 | }; | ||
60 | |||
61 | /** | ||
62 | Card View Advanced LookNFeel settings widget: | ||
63 | this is a tabbed widget with 3 tabs: | ||
64 | Fonts | ||
65 | * text font | ||
66 | * header font | ||
67 | |||
68 | Colors | ||
69 | * background color | ||
70 | * text color | ||
71 | * highlight color | ||
72 | * title/sep text color | ||
73 | * title/sep bg color | ||
74 | |||
75 | Layout | ||
76 | * item margin | ||
77 | * item spacing | ||
78 | */ | ||
79 | |||
80 | class CardViewLookNFeelPage : public QVBox { | ||
81 | |||
82 | Q_OBJECT | ||
83 | |||
84 | public: | ||
85 | CardViewLookNFeelPage( QWidget *parent=0, const char *name=0 ); | ||
86 | ~CardViewLookNFeelPage(); | ||
87 | |||
88 | void restoreSettings( KConfig* ); | ||
89 | void saveSettings( KConfig* ); | ||
90 | |||
91 | private slots: | ||
92 | void setTextFont(); | ||
93 | void setHeaderFont(); | ||
94 | void enableFonts(); | ||
95 | void enableColors(); | ||
96 | |||
97 | private: | ||
98 | void initGUI(); | ||
99 | void updateFontLabel( QFont, QLabel * ); | ||
100 | |||
101 | QCheckBox *cbEnableCustomFonts, | ||
102 | *cbEnableCustomColors, | ||
103 | *cbDrawSeps, *cbDrawBorders, | ||
104 | *cbShowFieldLabels, *cbShowEmptyFields; | ||
105 | class ColorListBox *lbColors; | ||
106 | QLabel *lTextFont, *lHeaderFont; | ||
107 | #ifndef KAB_EMBEDDED | ||
108 | class KPushButton *btnFont, *btnHeaderFont; | ||
109 | #else //KAB_EMBEDDED | ||
110 | class QPushButton *btnFont, *btnHeaderFont; | ||
111 | #endif //KAB_EMBEDDED | ||
112 | class QSpinBox *sbMargin, *sbSpacing, *sbSepWidth; | ||
113 | |||
114 | class QWidget *vbFonts; | ||
115 | }; | ||
116 | |||
117 | #endif | ||
diff --git a/kaddressbook/views/configuretableviewdialog.cpp b/kaddressbook/views/configuretableviewdialog.cpp new file mode 100644 index 0000000..e1cc63e --- a/dev/null +++ b/kaddressbook/views/configuretableviewdialog.cpp | |||
@@ -0,0 +1,155 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #include <qstring.h> | ||
25 | #include <qwidget.h> | ||
26 | #include <qlayout.h> | ||
27 | #include <qradiobutton.h> | ||
28 | #include <qcheckbox.h> | ||
29 | #include <qvbox.h> | ||
30 | #include <qbuttongroup.h> | ||
31 | |||
32 | #include <kglobal.h> | ||
33 | #include <klocale.h> | ||
34 | #include <klineedit.h> | ||
35 | #include <kurlrequester.h> | ||
36 | #include <kiconloader.h> | ||
37 | |||
38 | #ifndef KAB_EMBEDDED | ||
39 | #include <kimageio.h> | ||
40 | #else //KAB_EMBEDDED | ||
41 | #endif //KAB_EMBEDDED | ||
42 | |||
43 | #include <kconfig.h> | ||
44 | |||
45 | #include "configuretableviewdialog.h" | ||
46 | |||
47 | ConfigureTableViewWidget::ConfigureTableViewWidget( KABC::AddressBook *ab, | ||
48 | QWidget *parent, | ||
49 | const char *name ) | ||
50 | : ViewConfigureWidget( ab, parent, name ) | ||
51 | { | ||
52 | QWidget *page = addPage( i18n( "Look & Feel" ), QString::null, | ||
53 | KGlobal::iconLoader()->loadIcon( "looknfeel", | ||
54 | KIcon::Panel ) ); | ||
55 | |||
56 | mPage = new LookAndFeelPage( page ); | ||
57 | } | ||
58 | |||
59 | ConfigureTableViewWidget::~ConfigureTableViewWidget() | ||
60 | { | ||
61 | } | ||
62 | |||
63 | void ConfigureTableViewWidget::restoreSettings( KConfig *config ) | ||
64 | { | ||
65 | ViewConfigureWidget::restoreSettings( config ); | ||
66 | |||
67 | mPage->restoreSettings( config ); | ||
68 | } | ||
69 | |||
70 | void ConfigureTableViewWidget::saveSettings( KConfig *config ) | ||
71 | { | ||
72 | ViewConfigureWidget::saveSettings( config ); | ||
73 | |||
74 | mPage->saveSettings( config ); | ||
75 | } | ||
76 | |||
77 | |||
78 | |||
79 | LookAndFeelPage::LookAndFeelPage(QWidget *parent, const char *name) | ||
80 | : QWidget(parent, name) | ||
81 | { | ||
82 | initGUI(); | ||
83 | |||
84 | // Set initial state | ||
85 | enableBackgroundToggled(mBackgroundBox->isChecked()); | ||
86 | } | ||
87 | |||
88 | void LookAndFeelPage::restoreSettings( KConfig *config ) | ||
89 | { | ||
90 | mAlternateButton->setChecked(config->readBoolEntry("ABackground", true)); | ||
91 | mLineButton->setChecked(config->readBoolEntry("SingleLine", false)); | ||
92 | mToolTipBox->setChecked(config->readBoolEntry("ToolTips", true)); | ||
93 | |||
94 | if (!mAlternateButton->isChecked() & !mLineButton->isChecked()) | ||
95 | mNoneButton->setChecked(true); | ||
96 | |||
97 | mBackgroundBox->setChecked(config->readBoolEntry("Background", false)); | ||
98 | mBackgroundName->lineEdit()->setText(config->readEntry("BackgroundName")); | ||
99 | } | ||
100 | |||
101 | void LookAndFeelPage::saveSettings( KConfig *config ) | ||
102 | { | ||
103 | config->writeEntry("ABackground", mAlternateButton->isChecked()); | ||
104 | config->writeEntry("SingleLine", mLineButton->isChecked()); | ||
105 | config->writeEntry("ToolTips", mToolTipBox->isChecked()); | ||
106 | config->writeEntry("Background", mBackgroundBox->isChecked()); | ||
107 | config->writeEntry("BackgroundName", mBackgroundName->lineEdit()->text()); | ||
108 | } | ||
109 | |||
110 | void LookAndFeelPage::initGUI() | ||
111 | { | ||
112 | QVBoxLayout *layout = new QVBoxLayout(this, 0, KDialogBase::spacingHint()); | ||
113 | |||
114 | QButtonGroup *group = new QButtonGroup(1, Qt::Horizontal, | ||
115 | i18n("Row Separator"), this); | ||
116 | layout->addWidget(group); | ||
117 | |||
118 | mAlternateButton = new QRadioButton(i18n("Alternating backgrounds"), | ||
119 | group, "mAlternateButton"); | ||
120 | mLineButton = new QRadioButton(i18n("Single line"), group, "mLineButton"); | ||
121 | mNoneButton = new QRadioButton(i18n("None"), group, "mNoneButton"); | ||
122 | |||
123 | // Background Checkbox/Selector | ||
124 | QHBoxLayout *backgroundLayout = new QHBoxLayout(); | ||
125 | layout->addLayout(backgroundLayout); | ||
126 | |||
127 | mBackgroundBox = new QCheckBox(i18n("Enable background image:"), this, | ||
128 | "mBackgroundBox"); | ||
129 | connect(mBackgroundBox, SIGNAL(toggled(bool)), | ||
130 | SLOT(enableBackgroundToggled(bool))); | ||
131 | backgroundLayout->addWidget(mBackgroundBox); | ||
132 | |||
133 | mBackgroundName = new KURLRequester(this, "mBackgroundName"); | ||
134 | #ifndef KAB_EMBEDDED | ||
135 | mBackgroundName->setMode(KFile::File | KFile::ExistingOnly | | ||
136 | KFile::LocalOnly); | ||
137 | mBackgroundName->setFilter(KImageIO::pattern(KImageIO::Reading)); | ||
138 | #endif //KAB_EMBEDDED | ||
139 | |||
140 | backgroundLayout->addWidget(mBackgroundName); | ||
141 | |||
142 | // ToolTip Checkbox | ||
143 | mToolTipBox = new QCheckBox(i18n("Enable contact tooltips"), this, | ||
144 | "mToolTipBox"); | ||
145 | layout->addWidget(mToolTipBox); | ||
146 | } | ||
147 | |||
148 | void LookAndFeelPage::enableBackgroundToggled(bool enabled) | ||
149 | { | ||
150 | mBackgroundName->setEnabled(enabled); | ||
151 | } | ||
152 | |||
153 | #ifndef KAB_EMBEDDED | ||
154 | #include "configuretableviewdialog.moc" | ||
155 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/configuretableviewdialog.h b/kaddressbook/views/configuretableviewdialog.h new file mode 100644 index 0000000..8392710 --- a/dev/null +++ b/kaddressbook/views/configuretableviewdialog.h | |||
@@ -0,0 +1,88 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #ifndef CONFIGURETABLEVIEWDIALOG_H | ||
25 | #define CONFIGURETABLEVIEWDIALOG_H | ||
26 | |||
27 | #include "viewconfigurewidget.h" | ||
28 | |||
29 | class QString; | ||
30 | class QWidget; | ||
31 | class QRadioButton; | ||
32 | class QCheckBox; | ||
33 | class KURLRequester; | ||
34 | class KConfig; | ||
35 | |||
36 | namespace KABC { class AddressBook; } | ||
37 | |||
38 | class LookAndFeelPage; | ||
39 | |||
40 | /** | ||
41 | Configure dialog for the table view. This dialog inherits from the | ||
42 | standard view dialog in order to add a custom page for the table | ||
43 | view. | ||
44 | */ | ||
45 | class ConfigureTableViewWidget : public ViewConfigureWidget | ||
46 | { | ||
47 | public: | ||
48 | ConfigureTableViewWidget( KABC::AddressBook *ab, QWidget *parent, const char *name ); | ||
49 | virtual ~ConfigureTableViewWidget(); | ||
50 | |||
51 | virtual void restoreSettings( KConfig* ); | ||
52 | virtual void saveSettings( KConfig* ); | ||
53 | |||
54 | private: | ||
55 | void initGUI(); | ||
56 | |||
57 | LookAndFeelPage *mPage; | ||
58 | }; | ||
59 | |||
60 | /** | ||
61 | Internal class. It is only defined here for moc | ||
62 | */ | ||
63 | class LookAndFeelPage : public QWidget | ||
64 | { | ||
65 | Q_OBJECT | ||
66 | |||
67 | public: | ||
68 | LookAndFeelPage( QWidget *parent, const char *name = 0 ); | ||
69 | ~LookAndFeelPage() {} | ||
70 | |||
71 | void restoreSettings( KConfig* ); | ||
72 | void saveSettings( KConfig* ); | ||
73 | |||
74 | protected slots: | ||
75 | void enableBackgroundToggled( bool ); | ||
76 | |||
77 | private: | ||
78 | void initGUI(); | ||
79 | |||
80 | QRadioButton *mAlternateButton; | ||
81 | QRadioButton *mLineButton; | ||
82 | QRadioButton *mNoneButton; | ||
83 | QCheckBox *mToolTipBox; | ||
84 | KURLRequester *mBackgroundName; | ||
85 | QCheckBox *mBackgroundBox; | ||
86 | }; | ||
87 | |||
88 | #endif | ||
diff --git a/kaddressbook/views/contactlistview.cpp b/kaddressbook/views/contactlistview.cpp new file mode 100644 index 0000000..98b2fb2 --- a/dev/null +++ b/kaddressbook/views/contactlistview.cpp | |||
@@ -0,0 +1,340 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #include <qheader.h> | ||
25 | #include <qiconset.h> | ||
26 | #include <qimage.h> | ||
27 | #include <qdragobject.h> | ||
28 | #include <qcombobox.h> | ||
29 | #include <qpainter.h> | ||
30 | #include <qbrush.h> | ||
31 | #include <qevent.h> | ||
32 | |||
33 | #include <klocale.h> | ||
34 | #include <kglobalsettings.h> | ||
35 | #include <kiconloader.h> | ||
36 | #include <kdebug.h> | ||
37 | #include <kconfig.h> | ||
38 | #include <kapplication.h> | ||
39 | #include <kurl.h> | ||
40 | |||
41 | #include "kaddressbooktableview.h" | ||
42 | |||
43 | #include "contactlistview.h" | ||
44 | |||
45 | ///////////////////////////////// | ||
46 | // DynamicTip Methods | ||
47 | |||
48 | DynamicTip::DynamicTip( ContactListView *parent) | ||
49 | : QToolTip( parent ) | ||
50 | { | ||
51 | } | ||
52 | |||
53 | void DynamicTip::maybeTip( const QPoint &pos ) | ||
54 | { | ||
55 | static bool ishidden = true; | ||
56 | if (!parentWidget()->inherits( "ContactListView" )) | ||
57 | return; | ||
58 | |||
59 | ContactListView *plv = (ContactListView*)parentWidget(); | ||
60 | if (!plv->tooltips()) | ||
61 | return; | ||
62 | |||
63 | QPoint posVp = plv->viewport()->pos(); | ||
64 | |||
65 | QListViewItem *lvi = plv->itemAt( pos - posVp ); | ||
66 | if (!lvi) | ||
67 | return; | ||
68 | |||
69 | #ifndef KAB_EMBEDDED | ||
70 | ContactListViewItem *plvi = dynamic_cast< ContactListViewItem* >(lvi); | ||
71 | #else //KAB_EMBEDDED | ||
72 | ContactListViewItem *plvi = (ContactListViewItem*)(lvi); | ||
73 | #endif //KAB_EMBEDDED | ||
74 | |||
75 | if (!plvi) | ||
76 | return; | ||
77 | |||
78 | if (ishidden) { | ||
79 | QString s; | ||
80 | QRect r = plv->itemRect( lvi ); | ||
81 | r.moveBy( posVp.x(), posVp.y() ); | ||
82 | |||
83 | //kdDebug() << "Tip rec: " << r.x() << "," << r.y() << "," << r.width() | ||
84 | // << "," << r.height() << endl; | ||
85 | |||
86 | KABC::Addressee a = plvi->addressee(); | ||
87 | if (a.isEmpty()) | ||
88 | return; | ||
89 | |||
90 | s += i18n("label: value", "%1: %2").arg(a.formattedNameLabel()) | ||
91 | .arg(a.formattedName()); | ||
92 | |||
93 | s += '\n'; | ||
94 | s += i18n("label: value", "%1: %2").arg(a.organizationLabel()) | ||
95 | .arg(a.organization()); | ||
96 | |||
97 | QString notes = a.note().stripWhiteSpace(); | ||
98 | if ( !notes.isEmpty() ) { | ||
99 | notes += '\n'; | ||
100 | s += '\n' + i18n("label: value", "%1: \n").arg(a.noteLabel()); | ||
101 | QFontMetrics fm( font() ); | ||
102 | |||
103 | // Begin word wrap code based on QMultiLineEdit code | ||
104 | int i = 0; | ||
105 | bool doBreak = false; | ||
106 | int linew = 0; | ||
107 | int lastSpace = -1; | ||
108 | int a = 0; | ||
109 | int lastw = 0; | ||
110 | |||
111 | while ( i < int(notes.length()) ) { | ||
112 | doBreak = FALSE; | ||
113 | if ( notes[i] != '\n' ) | ||
114 | linew += fm.width( notes[i] ); | ||
115 | |||
116 | if ( lastSpace >= a && notes[i] != '\n' ) | ||
117 | if (linew >= parentWidget()->width()) { | ||
118 | doBreak = TRUE; | ||
119 | if ( lastSpace > a ) { | ||
120 | i = lastSpace; | ||
121 | linew = lastw; | ||
122 | } | ||
123 | else | ||
124 | i = QMAX( a, i-1 ); | ||
125 | } | ||
126 | |||
127 | if ( notes[i] == '\n' || doBreak ) { | ||
128 | s += notes.mid( a, i - a + (doBreak?1:0) ) +"\n"; | ||
129 | |||
130 | a = i + 1; | ||
131 | lastSpace = a; | ||
132 | linew = 0; | ||
133 | } | ||
134 | |||
135 | if ( notes[i].isSpace() ) { | ||
136 | lastSpace = i; | ||
137 | lastw = linew; | ||
138 | } | ||
139 | |||
140 | if ( lastSpace <= a ) { | ||
141 | lastw = linew; | ||
142 | } | ||
143 | |||
144 | ++i; | ||
145 | } | ||
146 | } | ||
147 | |||
148 | tip( r, s ); | ||
149 | } | ||
150 | else | ||
151 | hide(); | ||
152 | ishidden = !ishidden; | ||
153 | |||
154 | } | ||
155 | |||
156 | /////////////////////////// | ||
157 | // ContactListViewItem Methods | ||
158 | |||
159 | ContactListViewItem::ContactListViewItem(const KABC::Addressee &a, | ||
160 | ContactListView *parent, | ||
161 | KABC::AddressBook *doc, | ||
162 | const KABC::Field::List &fields ) | ||
163 | : KListViewItem(parent), mAddressee(a), mFields( fields ), | ||
164 | parentListView( parent ), mDocument(doc) | ||
165 | { | ||
166 | refresh(); | ||
167 | } | ||
168 | |||
169 | QString ContactListViewItem::key(int column, bool ascending) const | ||
170 | { | ||
171 | return QListViewItem::key(column, ascending).lower(); | ||
172 | } | ||
173 | |||
174 | void ContactListViewItem::paintCell(QPainter * p, | ||
175 | const QColorGroup & cg, | ||
176 | int column, | ||
177 | int width, | ||
178 | int align) | ||
179 | { | ||
180 | KListViewItem::paintCell(p, cg, column, width, align); | ||
181 | |||
182 | if ( !p ) | ||
183 | return; | ||
184 | |||
185 | if (parentListView->singleLine()) { | ||
186 | p->setPen( parentListView->alternateColor() ); | ||
187 | p->drawLine( 0, height() - 1, width, height() - 1 ); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | |||
192 | ContactListView *ContactListViewItem::parent() | ||
193 | { | ||
194 | return parentListView; | ||
195 | } | ||
196 | |||
197 | |||
198 | void ContactListViewItem::refresh() | ||
199 | { | ||
200 | // Update our addressee, since it may have changed else were | ||
201 | mAddressee = mDocument->findByUid(mAddressee.uid()); | ||
202 | if (mAddressee.isEmpty()) | ||
203 | return; | ||
204 | |||
205 | int i = 0; | ||
206 | KABC::Field::List::ConstIterator it; | ||
207 | for( it = mFields.begin(); it != mFields.end(); ++it ) { | ||
208 | setText( i++, (*it)->value( mAddressee ) ); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | /////////////////////////////// | ||
213 | // ContactListView | ||
214 | |||
215 | ContactListView::ContactListView(KAddressBookTableView *view, | ||
216 | KABC::AddressBook* /* doc */, | ||
217 | QWidget *parent, | ||
218 | const char *name ) | ||
219 | : KListView( parent, name ), | ||
220 | pabWidget( view ), | ||
221 | oldColumn( 0 ) | ||
222 | { | ||
223 | mABackground = true; | ||
224 | mSingleLine = false; | ||
225 | mToolTips = true; | ||
226 | #ifndef KAB_EMBEDDED | ||
227 | mAlternateColor = KGlobalSettings::alternateBackgroundColor(); | ||
228 | #else //KAB_EMBEDDED | ||
229 | mAlternateColor = QColor(240, 240, 240); | ||
230 | #endif //KAB_EMBEDDED | ||
231 | |||
232 | setAlternateBackgroundEnabled(mABackground); | ||
233 | setAcceptDrops( true ); | ||
234 | viewport()->setAcceptDrops( true ); | ||
235 | setAllColumnsShowFocus( true ); | ||
236 | setShowSortIndicator(true); | ||
237 | |||
238 | setSelectionModeExt( KListView::Extended ); | ||
239 | setDropVisualizer(false); | ||
240 | // setFrameStyle(QFrame::NoFrame); | ||
241 | setLineWidth ( 0 ); | ||
242 | setMidLineWidth ( 0 ); | ||
243 | setMargin ( 0 ); | ||
244 | #ifndef KAB_EMBEDDED | ||
245 | connect(this, SIGNAL(dropped(QDropEvent*)), | ||
246 | this, SLOT(itemDropped(QDropEvent*))); | ||
247 | #endif //KAB_EMBEDDED | ||
248 | |||
249 | |||
250 | new DynamicTip( this ); | ||
251 | } | ||
252 | |||
253 | void ContactListView::paintEmptyArea( QPainter * p, const QRect & rect ) | ||
254 | { | ||
255 | QBrush b = palette().brush(QPalette::Active, QColorGroup::Base); | ||
256 | |||
257 | // Get the brush, which will have the background pixmap if there is one. | ||
258 | if (b.pixmap()) | ||
259 | { | ||
260 | p->drawTiledPixmap( rect.left(), rect.top(), rect.width(), rect.height(), | ||
261 | *(b.pixmap()), | ||
262 | rect.left() + contentsX(), | ||
263 | rect.top() + contentsY() ); | ||
264 | } | ||
265 | |||
266 | else | ||
267 | { | ||
268 | // Do a normal paint | ||
269 | KListView::paintEmptyArea(p, rect); | ||
270 | } | ||
271 | } | ||
272 | |||
273 | void ContactListView::contentsMousePressEvent(QMouseEvent* e) | ||
274 | { | ||
275 | presspos = e->pos(); | ||
276 | KListView::contentsMousePressEvent(e); | ||
277 | } | ||
278 | |||
279 | |||
280 | // To initiate a drag operation | ||
281 | void ContactListView::contentsMouseMoveEvent( QMouseEvent *e ) | ||
282 | { | ||
283 | if ((e->state() & LeftButton) && (e->pos() - presspos).manhattanLength() > 4 ) { | ||
284 | emit startAddresseeDrag(); | ||
285 | } | ||
286 | else | ||
287 | KListView::contentsMouseMoveEvent( e ); | ||
288 | } | ||
289 | |||
290 | bool ContactListView::acceptDrag(QDropEvent *e) const | ||
291 | { | ||
292 | #ifndef KAB_EMBEDDED | ||
293 | return QTextDrag::canDecode(e); | ||
294 | #else //KAB_EMBEDDED | ||
295 | qDebug("ContactListView::acceptDrag has to be fixed"); | ||
296 | return false; | ||
297 | #endif //KAB_EMBEDDED | ||
298 | } | ||
299 | |||
300 | void ContactListView::itemDropped(QDropEvent *e) | ||
301 | { | ||
302 | contentsDropEvent(e); | ||
303 | } | ||
304 | |||
305 | void ContactListView::contentsDropEvent( QDropEvent *e ) | ||
306 | { | ||
307 | emit addresseeDropped(e); | ||
308 | } | ||
309 | |||
310 | void ContactListView::setAlternateBackgroundEnabled(bool enabled) | ||
311 | { | ||
312 | mABackground = enabled; | ||
313 | |||
314 | if (mABackground) | ||
315 | { | ||
316 | setAlternateBackground(mAlternateColor); | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | setAlternateBackground(QColor()); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | void ContactListView::setBackgroundPixmap(const QString &filename) | ||
325 | { | ||
326 | if (filename.isEmpty()) | ||
327 | { | ||
328 | unsetPalette(); | ||
329 | } | ||
330 | else | ||
331 | { | ||
332 | qDebug("ContactListView::setBackgroundPixmap has to be verified"); | ||
333 | //US setPaletteBackgroundPixmap(QPixmap(filename)); | ||
334 | KListView::setBackgroundPixmap((const QPixmap&)QPixmap(filename)); | ||
335 | } | ||
336 | |||
337 | } | ||
338 | #ifndef KAB_EMBEDDED | ||
339 | #include "contactlistview.moc" | ||
340 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/contactlistview.h b/kaddressbook/views/contactlistview.h new file mode 100644 index 0000000..ae9c994 --- a/dev/null +++ b/kaddressbook/views/contactlistview.h | |||
@@ -0,0 +1,128 @@ | |||
1 | #ifndef CONTACTLISTVIEW_H | ||
2 | #define CONTACTLISTVIEW_H | ||
3 | |||
4 | #include <qcolor.h> | ||
5 | #include <qpixmap.h> | ||
6 | #include <qtooltip.h> | ||
7 | #include <qstring.h> | ||
8 | |||
9 | #include <klistview.h> | ||
10 | |||
11 | #include <kabc/field.h> | ||
12 | #include <kabc/addressee.h> | ||
13 | #include <kabc/addressbook.h> | ||
14 | |||
15 | |||
16 | class QDropEvent; | ||
17 | class KAddressBookTableView; | ||
18 | class ContactListView; | ||
19 | |||
20 | /** The whole tooltip design needs a lot of work. Currently it is | ||
21 | * hacked together to function. | ||
22 | */ | ||
23 | class DynamicTip : public QToolTip | ||
24 | { | ||
25 | public: | ||
26 | DynamicTip( ContactListView * parent ); | ||
27 | |||
28 | protected: | ||
29 | void maybeTip( const QPoint & ); | ||
30 | |||
31 | private: | ||
32 | }; | ||
33 | |||
34 | class ContactListViewItem : public KListViewItem | ||
35 | { | ||
36 | |||
37 | public: | ||
38 | ContactListViewItem(const KABC::Addressee &a, ContactListView* parent, | ||
39 | KABC::AddressBook *doc, const KABC::Field::List &fields ); | ||
40 | const KABC::Addressee &addressee() const { return mAddressee; } | ||
41 | virtual void refresh(); | ||
42 | virtual ContactListView* parent(); | ||
43 | virtual QString key ( int, bool ) const; | ||
44 | |||
45 | /** Adds the border around the cell if the user wants it. | ||
46 | * This is how the single line config option is implemented. | ||
47 | */ | ||
48 | virtual void paintCell(QPainter * p, const QColorGroup & cg, | ||
49 | int column, int width, int align ); | ||
50 | |||
51 | private: | ||
52 | KABC::Addressee mAddressee; | ||
53 | KABC::Field::List mFields; | ||
54 | ContactListView *parentListView; | ||
55 | KABC::AddressBook *mDocument; | ||
56 | }; | ||
57 | |||
58 | |||
59 | ///////////////////////////////////////////// | ||
60 | // ContactListView | ||
61 | |||
62 | class ContactListView : public KListView | ||
63 | { | ||
64 | Q_OBJECT | ||
65 | |||
66 | public: | ||
67 | ContactListView(KAddressBookTableView *view, | ||
68 | KABC::AddressBook *doc, | ||
69 | QWidget *parent, | ||
70 | const char *name = 0L ); | ||
71 | virtual ~ContactListView() {} | ||
72 | //void resort(); | ||
73 | |||
74 | /** Returns true if tooltips should be displayed, false otherwise | ||
75 | */ | ||
76 | bool tooltips() const { return mToolTips; } | ||
77 | void setToolTipsEnabled(bool enabled) { mToolTips = enabled; } | ||
78 | |||
79 | bool alternateBackground() const { return mABackground; } | ||
80 | void setAlternateBackgroundEnabled(bool enabled); | ||
81 | |||
82 | bool singleLine() const { return mSingleLine; } | ||
83 | void setSingleLineEnabled(bool enabled) { mSingleLine = enabled; } | ||
84 | |||
85 | const QColor &alternateColor() const { return mAlternateColor; } | ||
86 | |||
87 | /** Sets the background pixmap to <i>filename</i>. If the | ||
88 | * QString is empty (QString::isEmpty()), then the background | ||
89 | * pixmap will be disabled. | ||
90 | */ | ||
91 | void setBackgroundPixmap(const QString &filename); | ||
92 | |||
93 | protected: | ||
94 | /** Paints the background pixmap in the empty area. This method is needed | ||
95 | * since Qt::FixedPixmap will not scroll with the list view. | ||
96 | */ | ||
97 | virtual void paintEmptyArea( QPainter * p, const QRect & rect ); | ||
98 | virtual void contentsMousePressEvent(QMouseEvent*); | ||
99 | void contentsMouseMoveEvent( QMouseEvent *e ); | ||
100 | void contentsDropEvent( QDropEvent *e ); | ||
101 | virtual bool acceptDrag(QDropEvent *e) const; | ||
102 | |||
103 | protected slots: | ||
104 | void itemDropped(QDropEvent *e); | ||
105 | |||
106 | public slots: | ||
107 | |||
108 | signals: | ||
109 | void startAddresseeDrag(); | ||
110 | void addresseeDropped(QDropEvent *); | ||
111 | |||
112 | private: | ||
113 | KAddressBookTableView *pabWidget; | ||
114 | int oldColumn; | ||
115 | int column; | ||
116 | bool ascending; | ||
117 | |||
118 | bool mABackground; | ||
119 | bool mSingleLine; | ||
120 | bool mToolTips; | ||
121 | |||
122 | QColor mAlternateColor; | ||
123 | |||
124 | QPoint presspos; | ||
125 | }; | ||
126 | |||
127 | |||
128 | #endif | ||
diff --git a/kaddressbook/views/kaddressbookcardview.cpp b/kaddressbook/views/kaddressbookcardview.cpp new file mode 100644 index 0000000..239429f --- a/dev/null +++ b/kaddressbook/views/kaddressbookcardview.cpp | |||
@@ -0,0 +1,394 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #include <qdragobject.h> | ||
25 | #include <qevent.h> | ||
26 | #include <qiconview.h> | ||
27 | #include <qlayout.h> | ||
28 | #include <qstringlist.h> | ||
29 | |||
30 | #include <kabc/addressbook.h> | ||
31 | #include <kabc/addressee.h> | ||
32 | #include <kconfig.h> | ||
33 | #include <kdebug.h> | ||
34 | #include <klocale.h> | ||
35 | |||
36 | #include "kabprefs.h" | ||
37 | #include "viewmanager.h" | ||
38 | |||
39 | #include "kaddressbookcardview.h" | ||
40 | |||
41 | #ifndef KAB_EMBEDDED | ||
42 | extern "C" { | ||
43 | void *init_libkaddrbk_cardview() | ||
44 | { | ||
45 | return ( new CardViewFactory ); | ||
46 | } | ||
47 | } | ||
48 | #endif //KAB_EMBEDDED | ||
49 | |||
50 | //////////////////////////////// | ||
51 | // AddresseeCardViewItem (internal class) | ||
52 | class AddresseeCardViewItem : public CardViewItem | ||
53 | { | ||
54 | public: | ||
55 | AddresseeCardViewItem(const KABC::Field::List &fields, | ||
56 | bool showEmptyFields, | ||
57 | KABC::AddressBook *doc, const KABC::Addressee &a, | ||
58 | CardView *parent) | ||
59 | : CardViewItem(parent, a.formattedName()), | ||
60 | mFields( fields ), mShowEmptyFields(showEmptyFields), | ||
61 | mDocument(doc), mAddressee(a) | ||
62 | { | ||
63 | if ( mFields.isEmpty() ) { | ||
64 | mFields = KABC::Field::defaultFields(); | ||
65 | } | ||
66 | refresh(); | ||
67 | } | ||
68 | |||
69 | const KABC::Addressee &addressee() const { return mAddressee; } | ||
70 | |||
71 | void refresh() | ||
72 | { | ||
73 | // Update our addressee, since it may have changed elsewhere | ||
74 | mAddressee = mDocument->findByUid(mAddressee.uid()); | ||
75 | |||
76 | if (!mAddressee.isEmpty()) | ||
77 | { | ||
78 | clearFields(); | ||
79 | |||
80 | // Try all the selected fields until we find one with text. | ||
81 | // This will limit the number of unlabeled icons in the view | ||
82 | KABC::Field::List::Iterator iter; | ||
83 | for (iter = mFields.begin(); iter != mFields.end(); ++iter) | ||
84 | { | ||
85 | // insert empty fields or not? not doing so saves a bit of memory and CPU | ||
86 | // (during geometry calculations), but prevents having equally | ||
87 | // wide label columns in all cards, unless CardViewItem/CardView search | ||
88 | // globally for the widest label. (anders) | ||
89 | //if (mShowEmptyFields || !(*iter)->value( mAddressee ).isEmpty()) | ||
90 | insertField((*iter)->label(), (*iter)->value( mAddressee )); | ||
91 | } | ||
92 | |||
93 | // We might want to make this the first field. hmm... -mpilone | ||
94 | setCaption( mAddressee.realName() ); | ||
95 | } | ||
96 | } | ||
97 | |||
98 | private: | ||
99 | KABC::Field::List mFields; | ||
100 | bool mShowEmptyFields; | ||
101 | KABC::AddressBook *mDocument; | ||
102 | KABC::Addressee mAddressee; | ||
103 | }; | ||
104 | |||
105 | /////////////////////////////// | ||
106 | // AddresseeCardView | ||
107 | |||
108 | AddresseeCardView::AddresseeCardView(QWidget *parent, const char *name) | ||
109 | : CardView(parent, name) | ||
110 | { | ||
111 | setAcceptDrops(true); | ||
112 | } | ||
113 | |||
114 | AddresseeCardView::~AddresseeCardView() | ||
115 | { | ||
116 | } | ||
117 | |||
118 | void AddresseeCardView::dragEnterEvent(QDragEnterEvent *e) | ||
119 | { | ||
120 | #ifndef KAB_EMBEDDED | ||
121 | if (QTextDrag::canDecode(e)) | ||
122 | e->accept(); | ||
123 | #else //KAB_EMBEDDED | ||
124 | qDebug("AddresseeCardView::dragEnterEvent drag&drop is not implemented"); | ||
125 | #endif //KAB_EMBEDDED | ||
126 | } | ||
127 | |||
128 | void AddresseeCardView::dropEvent(QDropEvent *e) | ||
129 | { | ||
130 | emit addresseeDropped(e); | ||
131 | } | ||
132 | |||
133 | void AddresseeCardView::startDrag() | ||
134 | { | ||
135 | emit startAddresseeDrag(); | ||
136 | } | ||
137 | |||
138 | |||
139 | /////////////////////////////// | ||
140 | // KAddressBookCardView | ||
141 | |||
142 | KAddressBookCardView::KAddressBookCardView( KABC::AddressBook *ab, | ||
143 | QWidget *parent, const char *name ) | ||
144 | : KAddressBookView( ab, parent, name ) | ||
145 | { | ||
146 | mShowEmptyFields = false; | ||
147 | |||
148 | // Init the GUI | ||
149 | QVBoxLayout *layout = new QVBoxLayout(viewWidget()); | ||
150 | |||
151 | mCardView = new AddresseeCardView(viewWidget(), "mCardView"); | ||
152 | mCardView->setSelectionMode(CardView::Extended); | ||
153 | layout->addWidget(mCardView); | ||
154 | |||
155 | // Connect up the signals | ||
156 | connect(mCardView, SIGNAL(executed(CardViewItem *)), | ||
157 | this, SLOT(addresseeExecuted(CardViewItem *))); | ||
158 | connect(mCardView, SIGNAL(selectionChanged()), | ||
159 | this, SLOT(addresseeSelected())); | ||
160 | connect(mCardView, SIGNAL(addresseeDropped(QDropEvent*)), | ||
161 | this, SIGNAL(dropped(QDropEvent*))); | ||
162 | connect(mCardView, SIGNAL(startAddresseeDrag()), | ||
163 | this, SIGNAL(startDrag())); | ||
164 | } | ||
165 | |||
166 | KAddressBookCardView::~KAddressBookCardView() | ||
167 | { | ||
168 | } | ||
169 | |||
170 | void KAddressBookCardView::readConfig(KConfig *config) | ||
171 | { | ||
172 | KAddressBookView::readConfig(config); | ||
173 | |||
174 | // costum colors? | ||
175 | if ( config->readBoolEntry( "EnableCustomColors", false ) ) | ||
176 | { | ||
177 | QPalette p( mCardView->palette() ); | ||
178 | QColor c = p.color(QPalette::Normal, QColorGroup::Base ); | ||
179 | p.setColor( QPalette::Normal, QColorGroup::Base, config->readColorEntry( "BackgroundColor", &c ) ); | ||
180 | c = p.color(QPalette::Normal, QColorGroup::Text ); | ||
181 | p.setColor( QPalette::Normal, QColorGroup::Text, config->readColorEntry( "TextColor", &c ) ); | ||
182 | c = p.color(QPalette::Normal, QColorGroup::Button ); | ||
183 | p.setColor( QPalette::Normal, QColorGroup::Button, config->readColorEntry( "HeaderColor", &c ) ); | ||
184 | c = p.color(QPalette::Normal, QColorGroup::ButtonText ); | ||
185 | p.setColor( QPalette::Normal, QColorGroup::ButtonText, config->readColorEntry( "HeaderTextColor", &c ) ); | ||
186 | c = p.color(QPalette::Normal, QColorGroup::Highlight ); | ||
187 | p.setColor( QPalette::Normal, QColorGroup::Highlight, config->readColorEntry( "HighlightColor", &c ) ); | ||
188 | c = p.color(QPalette::Normal, QColorGroup::HighlightedText ); | ||
189 | p.setColor( QPalette::Normal, QColorGroup::HighlightedText, config->readColorEntry( "HighlightedTextColor", &c ) ); | ||
190 | mCardView->viewport()->setPalette( p ); | ||
191 | } | ||
192 | else | ||
193 | { | ||
194 | // needed if turned off during a session. | ||
195 | mCardView->viewport()->setPalette( mCardView->palette() ); | ||
196 | } | ||
197 | |||
198 | //custom fonts? | ||
199 | QFont f( font() ); | ||
200 | if ( config->readBoolEntry( "EnableCustomFonts", false ) ) | ||
201 | { | ||
202 | mCardView->setFont( config->readFontEntry( "TextFont", &f) ); | ||
203 | f.setBold( true ); | ||
204 | mCardView->setHeaderFont( config->readFontEntry( "HeaderFont", &f ) ); | ||
205 | } | ||
206 | else | ||
207 | { | ||
208 | mCardView->setFont( f ); | ||
209 | f.setBold( true ); | ||
210 | mCardView->setHeaderFont( f ); | ||
211 | } | ||
212 | |||
213 | mCardView->setDrawCardBorder(config->readBoolEntry("DrawBorder", true)); | ||
214 | mCardView->setDrawColSeparators(config->readBoolEntry("DrawSeparators", | ||
215 | true)); | ||
216 | mCardView->setDrawFieldLabels(config->readBoolEntry("DrawFieldLabels",false)); | ||
217 | mShowEmptyFields = config->readBoolEntry("ShowEmptyFields", false); | ||
218 | |||
219 | mCardView->setShowEmptyFields( mShowEmptyFields ); | ||
220 | |||
221 | mCardView->setItemWidth( config->readNumEntry( "ItemWidth", 200 ) ); | ||
222 | mCardView->setItemMargin( config->readNumEntry( "ItemMargin", 0 ) ); | ||
223 | mCardView->setItemSpacing( config->readNumEntry( "ItemSpacing", 10 ) ); | ||
224 | mCardView->setSeparatorWidth( config->readNumEntry( "SeparatorWidth", 2 ) ); | ||
225 | |||
226 | disconnect(mCardView, SIGNAL(executed(CardViewItem *)), | ||
227 | this, SLOT(addresseeExecuted(CardViewItem *))); | ||
228 | |||
229 | if (KABPrefs::instance()->mHonorSingleClick) | ||
230 | connect(mCardView, SIGNAL(executed(CardViewItem *)), | ||
231 | this, SLOT(addresseeExecuted(CardViewItem *))); | ||
232 | else | ||
233 | connect(mCardView, SIGNAL(doubleClicked(CardViewItem *)), | ||
234 | this, SLOT(addresseeExecuted(CardViewItem *))); | ||
235 | |||
236 | } | ||
237 | |||
238 | void KAddressBookCardView::writeConfig( KConfig *config ) | ||
239 | { | ||
240 | config->writeEntry( "ItemWidth", mCardView->itemWidth() ); | ||
241 | KAddressBookView::writeConfig( config ); | ||
242 | } | ||
243 | |||
244 | QStringList KAddressBookCardView::selectedUids() | ||
245 | { | ||
246 | QStringList uidList; | ||
247 | CardViewItem *item; | ||
248 | AddresseeCardViewItem *aItem; | ||
249 | |||
250 | for (item = mCardView->firstItem(); item; item = item->nextItem()) | ||
251 | { | ||
252 | if (item->isSelected()) | ||
253 | { | ||
254 | #ifndef KAB_EMBEDDED | ||
255 | aItem = dynamic_cast<AddresseeCardViewItem*>(item); | ||
256 | #else //KAB_EMBEDDED | ||
257 | aItem = (AddresseeCardViewItem*)(item); | ||
258 | #endif //KAB_EMBEDDED | ||
259 | if (aItem) | ||
260 | uidList << aItem->addressee().uid(); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | return uidList; | ||
265 | } | ||
266 | |||
267 | void KAddressBookCardView::refresh(QString uid) | ||
268 | { | ||
269 | CardViewItem *item; | ||
270 | AddresseeCardViewItem *aItem; | ||
271 | |||
272 | if (uid.isNull()) | ||
273 | { | ||
274 | // Rebuild the view | ||
275 | mCardView->viewport()->setUpdatesEnabled( false ); | ||
276 | mCardView->clear(); | ||
277 | |||
278 | KABC::Addressee::List addresseeList = addressees(); | ||
279 | KABC::Addressee::List::Iterator iter; | ||
280 | for (iter = addresseeList.begin(); iter != addresseeList.end(); ++iter) | ||
281 | { | ||
282 | aItem = new AddresseeCardViewItem(fields(), mShowEmptyFields, | ||
283 | addressBook(), *iter, mCardView); | ||
284 | } | ||
285 | mCardView->viewport()->setUpdatesEnabled( true ); | ||
286 | mCardView->viewport()->update(); | ||
287 | |||
288 | // by default nothing is selected | ||
289 | emit selected(QString::null); | ||
290 | } | ||
291 | else | ||
292 | { | ||
293 | // Try to find the one to refresh | ||
294 | bool found = false; | ||
295 | for (item = mCardView->firstItem(); item && !found; | ||
296 | item = item->nextItem()) | ||
297 | { | ||
298 | #ifndef KAB_EMBEDDED | ||
299 | aItem = dynamic_cast<AddresseeCardViewItem*>(item); | ||
300 | #else //KAB_EMBEDDED | ||
301 | aItem = (AddresseeCardViewItem*)(item); | ||
302 | #endif //KAB_EMBEDDED | ||
303 | |||
304 | if ((aItem) && (aItem->addressee().uid() == uid)) | ||
305 | { | ||
306 | aItem->refresh(); | ||
307 | found = true; | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | void KAddressBookCardView::setSelected(QString uid, bool selected) | ||
314 | { | ||
315 | CardViewItem *item; | ||
316 | AddresseeCardViewItem *aItem; | ||
317 | |||
318 | if (uid.isNull()) | ||
319 | { | ||
320 | mCardView->selectAll(selected); | ||
321 | } | ||
322 | else | ||
323 | { | ||
324 | bool found = false; | ||
325 | for (item = mCardView->firstItem(); item && !found; | ||
326 | item = item->nextItem()) | ||
327 | { | ||
328 | #ifndef KAB_EMBEDDED | ||
329 | aItem = dynamic_cast<AddresseeCardViewItem*>(item); | ||
330 | #else //KAB_EMBEDDED | ||
331 | aItem = (AddresseeCardViewItem*)(item); | ||
332 | #endif //KAB_EMBEDDED | ||
333 | |||
334 | if ((aItem) && (aItem->addressee().uid() == uid)) | ||
335 | { | ||
336 | mCardView->setSelected(aItem, selected); | ||
337 | mCardView->ensureItemVisible(item); | ||
338 | found = true; | ||
339 | } | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | //US added an additional method without parameter | ||
345 | void KAddressBookCardView::setSelected() | ||
346 | { | ||
347 | setSelected(QString::null, true); | ||
348 | } | ||
349 | |||
350 | void KAddressBookCardView::addresseeExecuted(CardViewItem *item) | ||
351 | { | ||
352 | #ifndef KAB_EMBEDDED | ||
353 | AddresseeCardViewItem *aItem = dynamic_cast<AddresseeCardViewItem*>(item); | ||
354 | #else //KAB_EMBEDDED | ||
355 | AddresseeCardViewItem *aItem = (AddresseeCardViewItem*)(item); | ||
356 | #endif //KAB_EMBEDDED | ||
357 | if (aItem) | ||
358 | { | ||
359 | //kdDebug()<<"... even has a valid item:)"<<endl; | ||
360 | emit executed(aItem->addressee().uid()); | ||
361 | } | ||
362 | } | ||
363 | |||
364 | void KAddressBookCardView::addresseeSelected() | ||
365 | { | ||
366 | CardViewItem *item; | ||
367 | AddresseeCardViewItem *aItem; | ||
368 | |||
369 | bool found = false; | ||
370 | for (item = mCardView->firstItem(); item && !found; | ||
371 | item = item->nextItem()) | ||
372 | { | ||
373 | if (item->isSelected()) | ||
374 | { | ||
375 | #ifndef KAB_EMBEDDED | ||
376 | aItem = dynamic_cast<AddresseeCardViewItem*>(item); | ||
377 | #else //KAB_EMBEDDED | ||
378 | aItem = (AddresseeCardViewItem*)(item); | ||
379 | #endif //KAB_EMBEDDED | ||
380 | if ( aItem ) | ||
381 | { | ||
382 | emit selected(aItem->addressee().uid()); | ||
383 | found = true; | ||
384 | } | ||
385 | } | ||
386 | } | ||
387 | |||
388 | if (!found) | ||
389 | emit selected(QString::null); | ||
390 | |||
391 | } | ||
392 | #ifndef KAB_EMBEDDED | ||
393 | #include "kaddressbookcardview.moc" | ||
394 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/kaddressbookcardview.h b/kaddressbook/views/kaddressbookcardview.h new file mode 100644 index 0000000..cd70371 --- a/dev/null +++ b/kaddressbook/views/kaddressbookcardview.h | |||
@@ -0,0 +1,117 @@ | |||
1 | #ifndef KADDRESSBOOKCARDVIEW_H | ||
2 | #define KADDRESSBOOKCARDVIEW_H | ||
3 | |||
4 | /* | ||
5 | This file is part of KAddressBook. | ||
6 | Copyright (c) 2002 Mike Pilone <mpilone@slac.com> | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
21 | |||
22 | As a special exception, permission is given to link this program | ||
23 | with any edition of Qt, and distribute the resulting executable, | ||
24 | without including the source code for Qt in the source distribution. | ||
25 | */ | ||
26 | |||
27 | #include <qstring.h> | ||
28 | #ifndef KAB_EMBEDDED | ||
29 | #include <kiconview.h> | ||
30 | #else //KAB_EMBEDDED | ||
31 | #include <klocale.h> | ||
32 | #endif //KAB_EMBEDDED | ||
33 | |||
34 | #include "cardview.h" | ||
35 | #include "kaddressbookview.h" | ||
36 | #include "configurecardviewdialog.h" | ||
37 | |||
38 | class QDragEnterEvent; | ||
39 | class QDragEntryEvent; | ||
40 | class QDropEvent; | ||
41 | class KConfig; | ||
42 | class AddresseeCardView; | ||
43 | |||
44 | /** | ||
45 | This view uses the CardView class to create a card view. At some | ||
46 | point in the future I think this will be the default view of | ||
47 | KAddressBook. | ||
48 | */ | ||
49 | class KAddressBookCardView : public KAddressBookView | ||
50 | { | ||
51 | Q_OBJECT | ||
52 | |||
53 | public: | ||
54 | KAddressBookCardView( KABC::AddressBook *ab, QWidget *parent, | ||
55 | const char *name = 0 ); | ||
56 | virtual ~KAddressBookCardView(); | ||
57 | |||
58 | virtual QStringList selectedUids(); | ||
59 | virtual QString type() const { return "Card"; } | ||
60 | |||
61 | virtual void readConfig(KConfig *config); | ||
62 | virtual void writeConfig(KConfig *); | ||
63 | |||
64 | public slots: | ||
65 | void refresh(QString uid = QString::null); | ||
66 | void setSelected(QString uid/*US = QString::null*/, bool selected/*US = true*/); | ||
67 | //US added an additional method without parameter | ||
68 | void setSelected(); | ||
69 | |||
70 | protected slots: | ||
71 | void addresseeExecuted(CardViewItem *item); | ||
72 | void addresseeSelected(); | ||
73 | |||
74 | private: | ||
75 | AddresseeCardView *mCardView; | ||
76 | bool mShowEmptyFields; | ||
77 | }; | ||
78 | |||
79 | class AddresseeCardView : public CardView | ||
80 | { | ||
81 | Q_OBJECT | ||
82 | public: | ||
83 | AddresseeCardView(QWidget *parent, const char *name = 0); | ||
84 | ~AddresseeCardView(); | ||
85 | |||
86 | signals: | ||
87 | void startAddresseeDrag(); | ||
88 | void addresseeDropped(QDropEvent *); | ||
89 | |||
90 | protected: | ||
91 | virtual void dragEnterEvent(QDragEnterEvent *); | ||
92 | virtual void dropEvent(QDropEvent *); | ||
93 | virtual void startDrag(); | ||
94 | }; | ||
95 | |||
96 | |||
97 | class CardViewFactory : public ViewFactory | ||
98 | { | ||
99 | public: | ||
100 | KAddressBookView *view( KABC::AddressBook *ab, QWidget *parent, const char *name ) | ||
101 | { | ||
102 | return new KAddressBookCardView( ab, parent, name ); | ||
103 | } | ||
104 | |||
105 | QString type() const { return "Card"; } | ||
106 | |||
107 | QString description() const { return i18n( "Rolodex style cards represent contacts." ); } | ||
108 | |||
109 | ViewConfigureWidget *configureWidget( KABC::AddressBook *ab, QWidget *parent, | ||
110 | const char *name = 0 ) | ||
111 | { | ||
112 | return new ConfigureCardViewWidget( ab, parent, name ); | ||
113 | } | ||
114 | }; | ||
115 | |||
116 | |||
117 | #endif | ||
diff --git a/kaddressbook/views/kaddressbookiconview.cpp b/kaddressbook/views/kaddressbookiconview.cpp new file mode 100644 index 0000000..50ff285 --- a/dev/null +++ b/kaddressbook/views/kaddressbookiconview.cpp | |||
@@ -0,0 +1,378 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #ifndef KAB_EMBEDDED | ||
25 | #include <qiconview.h> | ||
26 | #include <qstringlist.h> | ||
27 | |||
28 | #include <kabc/addressee.h> | ||
29 | #include <kconfig.h> | ||
30 | #include <kdebug.h> | ||
31 | #include <kglobal.h> | ||
32 | #include <kiconloader.h> | ||
33 | #include <klocale.h> | ||
34 | |||
35 | #else //KAB_EMBEDDED | ||
36 | #endif //KAB_EMBEDDED | ||
37 | |||
38 | #include <kabc/addressbook.h> | ||
39 | #include "kabprefs.h" | ||
40 | #include "viewmanager.h" | ||
41 | #include "kaddressbookiconview.h" | ||
42 | #include <qlayout.h> | ||
43 | #include <kglobal.h> | ||
44 | /*US transfered to the headerfile | ||
45 | class IconViewFactory : public ViewFactory | ||
46 | { | ||
47 | public: | ||
48 | KAddressBookView *view( KABC::AddressBook *ab, QWidget *parent, const char *name ) | ||
49 | { | ||
50 | return new KAddressBookIconView( ab, parent, name ); | ||
51 | } | ||
52 | |||
53 | QString type() const { return "Icon"; } | ||
54 | |||
55 | QString description() const { return i18n( "Icons represent contacts. Very simple view." ); } | ||
56 | }; | ||
57 | |||
58 | */ | ||
59 | |||
60 | extern "C" { | ||
61 | void *init_libkaddrbk_iconview() | ||
62 | { | ||
63 | return ( new IconViewFactory ); | ||
64 | } | ||
65 | } | ||
66 | |||
67 | //////////////////////////////// | ||
68 | // AddresseeIconView (internal class) | ||
69 | #ifndef KAB_EMBEDDED | ||
70 | AddresseeIconView::AddresseeIconView(QWidget *parent, const char *name) | ||
71 | : KIconView(parent, name) | ||
72 | #else //KAB_EMBEDDED | ||
73 | AddresseeIconView::AddresseeIconView(QWidget *parent, const char *name) | ||
74 | : QIconView(parent, name) | ||
75 | #endif //KAB_EMBEDDED | ||
76 | |||
77 | { | ||
78 | setSelectionMode( QIconView::Extended ); | ||
79 | setResizeMode( QIconView::Adjust ); | ||
80 | setWordWrapIconText( true ); | ||
81 | setGridX( 100 ); | ||
82 | setItemsMovable(false); | ||
83 | setSorting(true, true); | ||
84 | |||
85 | |||
86 | //US ??? setMode( KIconView::Select ); | ||
87 | |||
88 | #ifndef KAB_EMBEDDED | ||
89 | |||
90 | connect(this, SIGNAL(dropped(QDropEvent*, const QValueList<QIconDragItem>&)), | ||
91 | this, SLOT(itemDropped(QDropEvent*, const QValueList<QIconDragItem>&))); | ||
92 | #endif //KAB_EMBEDDED | ||
93 | } | ||
94 | |||
95 | AddresseeIconView::~AddresseeIconView() | ||
96 | { | ||
97 | } | ||
98 | |||
99 | void AddresseeIconView::itemDropped(QDropEvent *e, | ||
100 | const QValueList<QIconDragItem> &) | ||
101 | { | ||
102 | emit addresseeDropped(e); | ||
103 | } | ||
104 | |||
105 | QDragObject *AddresseeIconView::dragObject() | ||
106 | { | ||
107 | emit startAddresseeDrag(); | ||
108 | |||
109 | // We never want IconView to start the drag | ||
110 | return 0; | ||
111 | } | ||
112 | //////////////////////////////// | ||
113 | // AddresseeIconViewItem (internal class) | ||
114 | #ifndef KAB_EMBEDDED | ||
115 | class AddresseeIconViewItem : public KIconViewItem | ||
116 | #else //KAB_EMBEDDED | ||
117 | class AddresseeIconViewItem : public QIconViewItem | ||
118 | #endif //KAB_EMBEDDED | ||
119 | { | ||
120 | public: | ||
121 | #ifndef KAB_EMBEDDED | ||
122 | AddresseeIconViewItem(const KABC::Field::List &fields, | ||
123 | KABC::AddressBook *doc, const KABC::Addressee &a, | ||
124 | QIconView *parent) | ||
125 | : KIconViewItem(parent), mFields( fields ), mDocument(doc), mAddressee(a) | ||
126 | #else //KAB_EMBEDDED | ||
127 | AddresseeIconViewItem(const KABC::Field::List &fields, | ||
128 | KABC::AddressBook *doc, const KABC::Addressee &a, | ||
129 | QIconView *parent) | ||
130 | : QIconViewItem(parent), mFields( fields ), mDocument(doc), mAddressee(a) | ||
131 | #endif //KAB_EMBEDDED | ||
132 | { | ||
133 | if ( mFields.isEmpty() ) { | ||
134 | mFields = KABC::Field::defaultFields(); | ||
135 | } | ||
136 | refresh(); | ||
137 | } | ||
138 | |||
139 | const KABC::Addressee &addressee() const { return mAddressee; } | ||
140 | |||
141 | void refresh() | ||
142 | { | ||
143 | // Update our addressee, since it may have changed elsewhere | ||
144 | mAddressee = mDocument->findByUid(mAddressee.uid()); | ||
145 | |||
146 | if (!mAddressee.isEmpty()) | ||
147 | setText( mAddressee.givenName() + " " + mAddressee.familyName() ); | ||
148 | |||
149 | QPixmap icon; | ||
150 | QPixmap defaultIcon( KGlobal::iconLoader()->loadIcon( "vcard", KIcon::Desktop, 128 ) ); | ||
151 | KABC::Picture pic = mAddressee.photo(); | ||
152 | if ( pic.data().isNull() ) | ||
153 | pic = mAddressee.logo(); | ||
154 | |||
155 | if ( pic.isIntern() && !pic.data().isNull() ) { | ||
156 | QImage img = pic.data(); | ||
157 | #ifndef KAB_EMBEDDED | ||
158 | if ( img.width() > img.height() ) | ||
159 | icon = img.scaleWidth( 32 ); | ||
160 | else | ||
161 | icon = img.scaleHeight( 32 ); | ||
162 | #else //KAB_EMBEDDED | ||
163 | qDebug("AddresseeIconViewItem::refresh - scale here dependend of the displaysize and the right factor"); | ||
164 | icon.convertFromImage(img.smoothScale(32, 32)); | ||
165 | #endif //KAB_EMBEDDED | ||
166 | |||
167 | } else | ||
168 | icon = defaultIcon; | ||
169 | |||
170 | setPixmap( icon ); | ||
171 | } | ||
172 | |||
173 | private: | ||
174 | KABC::Field::List mFields; | ||
175 | KABC::AddressBook *mDocument; | ||
176 | KABC::Addressee mAddressee; | ||
177 | }; | ||
178 | |||
179 | /////////////////////////////// | ||
180 | // KAddressBookView | ||
181 | |||
182 | KAddressBookIconView::KAddressBookIconView( KABC::AddressBook *ab, | ||
183 | QWidget *parent, const char *name) | ||
184 | : KAddressBookView( ab, parent, name ) | ||
185 | { | ||
186 | // Init the GUI | ||
187 | QVBoxLayout *layout = new QVBoxLayout(viewWidget()); | ||
188 | |||
189 | mIconView = new AddresseeIconView(viewWidget(), "mIconView"); | ||
190 | layout->addWidget(mIconView); | ||
191 | |||
192 | // Connect up the signals | ||
193 | |||
194 | //US method executed is part of KIconView | ||
195 | //US connect(mIconView, SIGNAL(executed(QIconViewItem *)), | ||
196 | //US this, SLOT(addresseeExecuted(QIconViewItem *))); | ||
197 | connect(mIconView, SIGNAL(selectionChanged(QIconViewItem *)), | ||
198 | this, SLOT(addresseeExecuted(QIconViewItem *))); | ||
199 | |||
200 | connect(mIconView, SIGNAL(selectionChanged()), | ||
201 | this, SLOT(addresseeSelected())); | ||
202 | connect(mIconView, SIGNAL(addresseeDropped(QDropEvent*)), | ||
203 | this, SIGNAL(dropped(QDropEvent*))); | ||
204 | connect(mIconView, SIGNAL(startAddresseeDrag()), | ||
205 | this, SIGNAL(startDrag())); | ||
206 | } | ||
207 | |||
208 | KAddressBookIconView::~KAddressBookIconView() | ||
209 | { | ||
210 | } | ||
211 | |||
212 | void KAddressBookIconView::readConfig(KConfig *config) | ||
213 | { | ||
214 | KAddressBookView::readConfig(config); | ||
215 | |||
216 | //US method executed is part of KIconView | ||
217 | //US disconnect(mIconView, SIGNAL(executed(QIconViewItem *)), | ||
218 | //US this, SLOT(addresseeExecuted(QIconViewItem *))); | ||
219 | disconnect(mIconView, SIGNAL(selectionChanged(QIconViewItem *)), | ||
220 | this, SLOT(addresseeExecuted(QIconViewItem *))); | ||
221 | |||
222 | //US method executed is part of KIconView. Use selectionChanged instead | ||
223 | /*US | ||
224 | if (KABPrefs::instance()->mHonorSingleClick) | ||
225 | connect(mIconView, SIGNAL(executed(QIconViewItem *)), | ||
226 | this, SLOT(addresseeExecuted(QIconViewItem *))); | ||
227 | else | ||
228 | connect(mIconView, SIGNAL(doubleClicked(QIconViewItem *)), | ||
229 | this, SLOT(addresseeExecuted(QIconViewItem *))); | ||
230 | */ | ||
231 | connect(mIconView, SIGNAL(selectionChanged(QIconViewItem *)), | ||
232 | this, SLOT(addresseeExecuted(QIconViewItem *))); | ||
233 | |||
234 | } | ||
235 | |||
236 | QStringList KAddressBookIconView::selectedUids() | ||
237 | { | ||
238 | QStringList uidList; | ||
239 | QIconViewItem *item; | ||
240 | AddresseeIconViewItem *aItem; | ||
241 | |||
242 | for (item = mIconView->firstItem(); item; item = item->nextItem()) | ||
243 | { | ||
244 | if (item->isSelected()) | ||
245 | { | ||
246 | #ifndef KAB_EMBEDDED | ||
247 | aItem = dynamic_cast<AddresseeIconViewItem*>(item); | ||
248 | #else //KAB_EMBEDDED | ||
249 | aItem = (AddresseeIconViewItem*)(item); | ||
250 | #endif //KAB_EMBEDDED | ||
251 | if (aItem) | ||
252 | uidList << aItem->addressee().uid(); | ||
253 | } | ||
254 | } | ||
255 | |||
256 | return uidList; | ||
257 | } | ||
258 | |||
259 | void KAddressBookIconView::refresh(QString uid) | ||
260 | { | ||
261 | QIconViewItem *item; | ||
262 | AddresseeIconViewItem *aItem; | ||
263 | |||
264 | if ( uid.isNull() ) { | ||
265 | // Rebuild the view | ||
266 | mIconView->clear(); | ||
267 | mIconList.clear(); | ||
268 | |||
269 | KABC::Addressee::List addresseeList = addressees(); | ||
270 | KABC::Addressee::List::Iterator iter; | ||
271 | for ( iter = addresseeList.begin(); iter != addresseeList.end(); ++iter ) | ||
272 | aItem = new AddresseeIconViewItem( fields(), addressBook(), *iter, mIconView ); | ||
273 | |||
274 | mIconView->arrangeItemsInGrid( true ); | ||
275 | |||
276 | for ( item = mIconView->firstItem(); item; item = item->nextItem() ) | ||
277 | { | ||
278 | #ifndef KAB_EMBEDDED | ||
279 | AddresseeIconViewItem* aivi = dynamic_cast<AddresseeIconViewItem*>( item ); | ||
280 | #else //KAB_EMBEDDED | ||
281 | AddresseeIconViewItem* aivi = (AddresseeIconViewItem*)( item ); | ||
282 | #endif //KAB_EMBEDDED | ||
283 | mIconList.append( aivi ); | ||
284 | } | ||
285 | |||
286 | } else { | ||
287 | // Try to find the one to refresh | ||
288 | for ( item = mIconView->firstItem(); item; item = item->nextItem() ) { | ||
289 | #ifndef KAB_EMBEDDED | ||
290 | aItem = dynamic_cast<AddresseeIconViewItem*>(item); | ||
291 | #else //KAB_EMBEDDED | ||
292 | aItem = (AddresseeIconViewItem*)(item); | ||
293 | #endif //KAB_EMBEDDED | ||
294 | if ((aItem) && (aItem->addressee().uid() == uid)) { | ||
295 | aItem->refresh(); | ||
296 | mIconView->arrangeItemsInGrid( true ); | ||
297 | return; | ||
298 | } | ||
299 | } | ||
300 | refresh( QString::null ); | ||
301 | } | ||
302 | } | ||
303 | |||
304 | void KAddressBookIconView::setSelected(QString uid, bool selected) | ||
305 | { | ||
306 | QIconViewItem *item; | ||
307 | AddresseeIconViewItem *aItem; | ||
308 | |||
309 | if (uid.isNull()) | ||
310 | { | ||
311 | mIconView->selectAll(selected); | ||
312 | } | ||
313 | else | ||
314 | { | ||
315 | bool found = false; | ||
316 | for (item = mIconView->firstItem(); item && !found; | ||
317 | item = item->nextItem()) | ||
318 | { | ||
319 | #ifndef KAB_EMBEDDED | ||
320 | aItem = dynamic_cast<AddresseeIconViewItem*>(item); | ||
321 | #else //KAB_EMBEDDED | ||
322 | aItem = (AddresseeIconViewItem*)(item); | ||
323 | #endif //KAB_EMBEDDED | ||
324 | |||
325 | if ((aItem) && (aItem->addressee().uid() == uid)) | ||
326 | { | ||
327 | mIconView->setSelected(aItem, selected); | ||
328 | mIconView->ensureItemVisible( aItem ); | ||
329 | found = true; | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
335 | void KAddressBookIconView::addresseeExecuted(QIconViewItem *item) | ||
336 | { | ||
337 | #ifndef KAB_EMBEDDED | ||
338 | AddresseeIconViewItem *aItem = dynamic_cast<AddresseeIconViewItem*>(item); | ||
339 | #else //KAB_EMBEDDED | ||
340 | AddresseeIconViewItem *aItem = (AddresseeIconViewItem*)(item); | ||
341 | #endif //KAB_EMBEDDED | ||
342 | |||
343 | if (aItem) { | ||
344 | emit executed(aItem->addressee().uid()); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | void KAddressBookIconView::addresseeSelected() | ||
349 | { | ||
350 | QIconViewItem *item; | ||
351 | AddresseeIconViewItem *aItem; | ||
352 | |||
353 | bool found = false; | ||
354 | for (item = mIconView->firstItem(); item && !found; | ||
355 | item = item->nextItem()) | ||
356 | { | ||
357 | if (item->isSelected()) | ||
358 | { | ||
359 | #ifndef KAB_EMBEDDED | ||
360 | aItem = dynamic_cast<AddresseeIconViewItem*>(item); | ||
361 | #else //KAB_EMBEDDED | ||
362 | aItem = (AddresseeIconViewItem*)(item); | ||
363 | #endif //KAB_EMBEDDED | ||
364 | if (aItem) | ||
365 | { | ||
366 | emit selected(aItem->addressee().uid()); | ||
367 | found = true; | ||
368 | } | ||
369 | } | ||
370 | } | ||
371 | |||
372 | if (!found) | ||
373 | emit selected(QString::null); | ||
374 | } | ||
375 | |||
376 | #ifndef KAB_EMBEDDED | ||
377 | #include "kaddressbookiconview.moc" | ||
378 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/kaddressbookiconview.h b/kaddressbook/views/kaddressbookiconview.h new file mode 100644 index 0000000..3afada3 --- a/dev/null +++ b/kaddressbook/views/kaddressbookiconview.h | |||
@@ -0,0 +1,130 @@ | |||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
18 | |||
19 | As a special exception, permission is given to link this program | ||
20 | with any edition of Qt, and distribute the resulting executable, | ||
21 | without including the source code for Qt in the source distribution. | ||
22 | */ | ||
23 | |||
24 | #ifndef KADDRESSBOOKICONVIEW_H | ||
25 | #define KADDRESSBOOKICONVIEW_H | ||
26 | |||
27 | #include <qstring.h> | ||
28 | #ifndef KAB_EMBEDDED | ||
29 | #include <kiconview.h> | ||
30 | #else //KAB_EMBEDDED | ||
31 | #include <qiconview.h> | ||
32 | #include <qptrlist.h> | ||
33 | #include <klocale.h> | ||
34 | #endif //KAB_EMBEDDED | ||
35 | #include "kaddressbookview.h" | ||
36 | |||
37 | class QIconViewItem; | ||
38 | class KConfig; | ||
39 | class AddresseeIconView; | ||
40 | class AddresseeIconViewItem; | ||
41 | class QIconDragItem; | ||
42 | class KAddressBookIconView; | ||
43 | |||
44 | namespace KABC { class AddressBook; } | ||
45 | |||
46 | /** This is an example kaddressbook view that is implemented using | ||
47 | * KIconView. This view is not the most useful view, but it displays | ||
48 | * how simple implementing a new view can be. | ||
49 | */ | ||
50 | class KAddressBookIconView : public KAddressBookView | ||
51 | { | ||
52 | Q_OBJECT | ||
53 | |||
54 | public: | ||
55 | KAddressBookIconView( KABC::AddressBook *ab, QWidget *parent, | ||
56 | const char *name = 0 ); | ||
57 | virtual ~KAddressBookIconView(); | ||
58 | |||
59 | virtual QStringList selectedUids(); | ||
60 | virtual QString type() const { return "Icon"; } | ||
61 | |||
62 | virtual void readConfig(KConfig *config); | ||
63 | |||
64 | public slots: | ||
65 | void refresh(QString uid = QString::null); | ||
66 | #ifndef KAB_EMBEDDED | ||
67 | //MOC_SKIP_BEGIN | ||
68 | void setSelected(QString uid = QString::null, bool selected = true); | ||
69 | //MOC_SKIP_END | ||
70 | #else //KAB_EMBEDDED | ||
71 | //US my MOC do not like default parameters ??? | ||
72 | void setSelected(QString uid, bool selected); | ||
73 | #endif //KAB_EMBEDDED | ||
74 | |||
75 | protected slots: | ||
76 | void addresseeExecuted(QIconViewItem *item); | ||
77 | void addresseeSelected(); | ||
78 | |||
79 | private: | ||
80 | AddresseeIconView *mIconView; | ||
81 | QPtrList<AddresseeIconViewItem> mIconList; | ||
82 | }; | ||
83 | |||
84 | |||
85 | #ifndef KAB_EMBEDDED | ||
86 | //MOC_SKIP_BEGIN | ||
87 | class AddresseeIconView : public KIconView | ||
88 | //MOC_SKIP_END | ||
89 | #else //KAB_EMBEDDED | ||
90 | class AddresseeIconView : public QIconView | ||
91 | #endif //KAB_EMBEDDED | ||
92 | { | ||
93 | Q_OBJECT | ||
94 | |||
95 | public: | ||
96 | AddresseeIconView(QWidget *parent, const char *name); | ||
97 | ~AddresseeIconView(); | ||
98 | |||
99 | signals: | ||
100 | void addresseeDropped(QDropEvent *); | ||
101 | void startAddresseeDrag(); | ||
102 | |||
103 | protected: | ||
104 | virtual QDragObject *dragObject(); | ||
105 | |||
106 | protected slots: | ||
107 | void itemDropped(QDropEvent *, const QValueList<QIconDragItem> &); | ||
108 | }; | ||
109 | |||
110 | class IconViewFactory : public ViewFactory | ||
111 | { | ||
112 | public: | ||
113 | KAddressBookView *view( KABC::AddressBook *ab, QWidget *parent, const char *name ) | ||
114 | { | ||
115 | return new KAddressBookIconView( ab, parent, name ); | ||
116 | } | ||
117 | |||
118 | QString type() const { return "Icon"; } | ||
119 | |||
120 | QString description() const { return i18n( "Icons represent contacts. Very simple view." ); } | ||
121 | }; | ||
122 | /* | ||
123 | extern "C" { | ||
124 | void *init_libkaddrbk_iconview() | ||
125 | { | ||
126 | return ( new IconViewFactory ); | ||
127 | } | ||
128 | } | ||
129 | */ | ||
130 | #endif | ||
diff --git a/kaddressbook/views/kaddressbooktableview.cpp b/kaddressbook/views/kaddressbooktableview.cpp new file mode 100644 index 0000000..ee2fcf8 --- a/dev/null +++ b/kaddressbook/views/kaddressbooktableview.cpp | |||
@@ -0,0 +1,337 @@ | |||
1 | // $Id$ | ||
2 | |||
3 | #include <qvbox.h> | ||
4 | #include <qlistbox.h> | ||
5 | #include <qwidget.h> | ||
6 | #include <qfile.h> | ||
7 | #include <qimage.h> | ||
8 | #include <qcombobox.h> | ||
9 | #include <qapplication.h> | ||
10 | #include <qdragobject.h> | ||
11 | #include <qevent.h> | ||
12 | #include <qurl.h> | ||
13 | #include <qpixmap.h> | ||
14 | |||
15 | #include <kabc/addressbook.h> | ||
16 | #include <kapplication.h> | ||
17 | #include <kconfig.h> | ||
18 | #include <kcolorbutton.h> | ||
19 | #include <kdebug.h> | ||
20 | #include <kglobal.h> | ||
21 | #include <kiconloader.h> | ||
22 | #include <klineedit.h> | ||
23 | #include <klocale.h> | ||
24 | #include <kmessagebox.h> | ||
25 | #include <kurl.h> | ||
26 | #include <kurlrequester.h> | ||
27 | |||
28 | //US#include "configuretableviewdialog.h" | ||
29 | #include "contactlistview.h" | ||
30 | #include "kabprefs.h" | ||
31 | #include "undocmds.h" | ||
32 | #include "viewmanager.h" | ||
33 | |||
34 | #include <qlayout.h> | ||
35 | |||
36 | |||
37 | #include "kaddressbooktableview.h" | ||
38 | |||
39 | |||
40 | KAddressBookTableView::KAddressBookTableView( KABC::AddressBook *ab, | ||
41 | QWidget *parent, const char *name ) | ||
42 | : KAddressBookView( ab, parent, name ) | ||
43 | { | ||
44 | mainLayout = new QVBoxLayout( viewWidget(), 2 ); | ||
45 | |||
46 | // The list view will be created when the config is read. | ||
47 | mListView = 0; | ||
48 | } | ||
49 | |||
50 | KAddressBookTableView::~KAddressBookTableView() | ||
51 | { | ||
52 | } | ||
53 | |||
54 | void KAddressBookTableView::reconstructListView() | ||
55 | { | ||
56 | if (mListView) | ||
57 | { | ||
58 | disconnect(mListView, SIGNAL(selectionChanged()), | ||
59 | this, SLOT(addresseeSelected())); | ||
60 | disconnect(mListView, SIGNAL(executed(QListViewItem*)), | ||
61 | this, SLOT(addresseeExecuted(QListViewItem*))); | ||
62 | disconnect(mListView, SIGNAL(doubleClicked(QListViewItem*)), | ||
63 | this, SLOT(addresseeExecuted(QListViewItem*))); | ||
64 | disconnect(mListView, SIGNAL(startAddresseeDrag()), this, | ||
65 | SIGNAL(startDrag())); | ||
66 | disconnect(mListView, SIGNAL(returnPressed(QListViewItem*)), | ||
67 | this, SLOT(addresseeExecuted(QListViewItem*))); | ||
68 | |||
69 | disconnect(mListView, SIGNAL(addresseeDropped(QDropEvent*)), this, | ||
70 | SIGNAL(dropped(QDropEvent*))); | ||
71 | delete mListView; | ||
72 | } | ||
73 | |||
74 | mListView = new ContactListView( this, addressBook(), viewWidget() ); | ||
75 | |||
76 | // Add the columns | ||
77 | KABC::Field::List fieldList = fields(); | ||
78 | KABC::Field::List::ConstIterator it; | ||
79 | |||
80 | int c = 0; | ||
81 | for( it = fieldList.begin(); it != fieldList.end(); ++it ) { | ||
82 | mListView->addColumn( (*it)->label() ); | ||
83 | mListView->setColumnWidthMode(c++, QListView::Manual); | ||
84 | //US | ||
85 | // qDebug("KAddressBookTableView::reconstructListView: field %s", (*it)->label().latin1()); | ||
86 | } | ||
87 | |||
88 | connect(mListView, SIGNAL(selectionChanged()), | ||
89 | this, SLOT(addresseeSelected())); | ||
90 | connect(mListView, SIGNAL(startAddresseeDrag()), this, | ||
91 | SIGNAL(startDrag())); | ||
92 | connect(mListView, SIGNAL(addresseeDropped(QDropEvent*)), this, | ||
93 | SIGNAL(dropped(QDropEvent*))); | ||
94 | |||
95 | if (KABPrefs::instance()->mHonorSingleClick) | ||
96 | connect(mListView, SIGNAL(executed(QListViewItem*)), | ||
97 | this, SLOT(addresseeExecuted(QListViewItem*))); | ||
98 | else | ||
99 | connect(mListView, SIGNAL(doubleClicked(QListViewItem*)), | ||
100 | this, SLOT(addresseeExecuted(QListViewItem*))); | ||
101 | connect(mListView, SIGNAL(returnPressed(QListViewItem*)), | ||
102 | this, SLOT(addresseeExecuted(QListViewItem*))); | ||
103 | connect(mListView, SIGNAL(signalDelete()), | ||
104 | this, SLOT(addresseeDeleted())); | ||
105 | |||
106 | refresh(); | ||
107 | |||
108 | mListView->setSorting( 0, true ); | ||
109 | mainLayout->addWidget( mListView ); | ||
110 | mainLayout->activate(); | ||
111 | mListView->show(); | ||
112 | } | ||
113 | |||
114 | void KAddressBookTableView::writeConfig(KConfig *config) | ||
115 | { | ||
116 | KAddressBookView::writeConfig(config); | ||
117 | |||
118 | mListView->saveLayout(config, config->group()); | ||
119 | } | ||
120 | |||
121 | void KAddressBookTableView::readConfig(KConfig *config) | ||
122 | { | ||
123 | KAddressBookView::readConfig( config ); | ||
124 | |||
125 | // The config could have changed the fields, so we need to reconstruct | ||
126 | // the listview. | ||
127 | reconstructListView(); | ||
128 | |||
129 | // Set the list view options | ||
130 | mListView->setAlternateBackgroundEnabled(config->readBoolEntry("ABackground", | ||
131 | true)); | ||
132 | mListView->setSingleLineEnabled(config->readBoolEntry("SingleLine", false)); | ||
133 | mListView->setToolTipsEnabled(config->readBoolEntry("ToolTips", true)); | ||
134 | |||
135 | if (config->readBoolEntry("Background", false)) | ||
136 | mListView->setBackgroundPixmap(config->readEntry("BackgroundName")); | ||
137 | |||
138 | // Restore the layout of the listview | ||
139 | mListView->restoreLayout(config, config->group()); | ||
140 | } | ||
141 | |||
142 | void KAddressBookTableView::refresh(QString uid) | ||
143 | { | ||
144 | // For now just repopulate. In reality this method should | ||
145 | // check the value of uid, and if valid iterate through | ||
146 | // the listview to find the entry, then tell it to refresh. | ||
147 | |||
148 | if (uid.isNull()) { | ||
149 | // Clear the list view | ||
150 | QString currentUID, nextUID; | ||
151 | #ifndef KAB_EMBEDDED | ||
152 | ContactListViewItem *currentItem = dynamic_cast<ContactListViewItem*>( mListView->currentItem() ); | ||
153 | #else //KAB_EMBEDDED | ||
154 | ContactListViewItem *currentItem = (ContactListViewItem*)( mListView->currentItem() ); | ||
155 | #endif //KAB_EMBEDDED | ||
156 | |||
157 | if ( currentItem ) { | ||
158 | #ifndef KAB_EMBEDDED | ||
159 | ContactListViewItem *nextItem = dynamic_cast<ContactListViewItem*>( currentItem->itemBelow() ); | ||
160 | #else //KAB_EMBEDDED | ||
161 | ContactListViewItem *nextItem = (ContactListViewItem*)( currentItem->itemBelow() ); | ||
162 | #endif //KAB_EMBEDDED | ||
163 | if ( nextItem ) | ||
164 | nextUID = nextItem->addressee().uid(); | ||
165 | currentUID = currentItem->addressee().uid(); | ||
166 | } | ||
167 | |||
168 | mListView->clear(); | ||
169 | |||
170 | currentItem = 0; | ||
171 | KABC::Addressee::List addresseeList = addressees(); | ||
172 | KABC::Addressee::List::Iterator it; | ||
173 | for (it = addresseeList.begin(); it != addresseeList.end(); ++it ) { | ||
174 | ContactListViewItem *item = new ContactListViewItem(*it, mListView, addressBook(), fields()); | ||
175 | if ( (*it).uid() == currentUID ) | ||
176 | currentItem = item; | ||
177 | else if ( (*it).uid() == nextUID && !currentItem ) | ||
178 | currentItem = item; | ||
179 | } | ||
180 | |||
181 | // Sometimes the background pixmap gets messed up when we add lots | ||
182 | // of items. | ||
183 | mListView->repaint(); | ||
184 | |||
185 | if ( currentItem ) { | ||
186 | mListView->setCurrentItem( currentItem ); | ||
187 | mListView->ensureItemVisible( currentItem ); | ||
188 | } | ||
189 | } else { | ||
190 | // Only need to update on entry. Iterate through and try to find it | ||
191 | ContactListViewItem *ceItem; | ||
192 | QListViewItemIterator it( mListView ); | ||
193 | while ( it.current() ) { | ||
194 | #ifndef KAB_EMBEDDED | ||
195 | ceItem = dynamic_cast<ContactListViewItem*>( it.current() ); | ||
196 | #else //KAB_EMBEDDED | ||
197 | ceItem = (ContactListViewItem*)( it.current() ); | ||
198 | #endif //KAB_EMBEDDED | ||
199 | |||
200 | if ( ceItem && ceItem->addressee().uid() == uid ) { | ||
201 | ceItem->refresh(); | ||
202 | return; | ||
203 | } | ||
204 | ++it; | ||
205 | } | ||
206 | |||
207 | refresh( QString::null ); | ||
208 | } | ||
209 | } | ||
210 | |||
211 | QStringList KAddressBookTableView::selectedUids() | ||
212 | { | ||
213 | QStringList uidList; | ||
214 | QListViewItem *item; | ||
215 | ContactListViewItem *ceItem; | ||
216 | |||
217 | for(item = mListView->firstChild(); item; item = item->itemBelow()) | ||
218 | { | ||
219 | if (mListView->isSelected( item )) | ||
220 | { | ||
221 | #ifndef KAB_EMBEDDED | ||
222 | ceItem = dynamic_cast<ContactListViewItem*>(item); | ||
223 | #else //KAB_EMBEDDED | ||
224 | ceItem = (ContactListViewItem*)(item); | ||
225 | #endif //KAB_EMBEDDED | ||
226 | |||
227 | if (ceItem != 0L) | ||
228 | uidList << ceItem->addressee().uid(); | ||
229 | } | ||
230 | } | ||
231 | if ( uidList.count() == 0 ) | ||
232 | if ( mListView->currentItem() ) { | ||
233 | ceItem = (ContactListViewItem*)(mListView->currentItem()) ; | ||
234 | uidList << ceItem->addressee().uid(); | ||
235 | } | ||
236 | |||
237 | return uidList; | ||
238 | } | ||
239 | |||
240 | void KAddressBookTableView::setSelected(QString uid, bool selected) | ||
241 | { | ||
242 | QListViewItem *item; | ||
243 | ContactListViewItem *ceItem; | ||
244 | |||
245 | if (uid.isNull()) | ||
246 | { | ||
247 | mListView->selectAll(selected); | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | for(item = mListView->firstChild(); item; item = item->itemBelow()) | ||
252 | { | ||
253 | #ifndef KAB_EMBEDDED | ||
254 | ceItem = dynamic_cast<ContactListViewItem*>(item); | ||
255 | #else //KAB_EMBEDDED | ||
256 | ceItem = (ContactListViewItem*)(item); | ||
257 | #endif //KAB_EMBEDDED | ||
258 | |||
259 | |||
260 | if ((ceItem != 0L) && (ceItem->addressee().uid() == uid)) | ||
261 | { | ||
262 | mListView->setSelected(item, selected); | ||
263 | |||
264 | if (selected) | ||
265 | mListView->ensureItemVisible(item); | ||
266 | } | ||
267 | } | ||
268 | } | ||
269 | } | ||
270 | |||
271 | void KAddressBookTableView::addresseeSelected() | ||
272 | { | ||
273 | // We need to try to find the first selected item. This might not be the | ||
274 | // last selected item, but when QListView is in multiselection mode, | ||
275 | // there is no way to figure out which one was | ||
276 | // selected last. | ||
277 | QListViewItem *item; | ||
278 | bool found =false; | ||
279 | for (item = mListView->firstChild(); item && !found; | ||
280 | item = item->nextSibling()) | ||
281 | { | ||
282 | if (item->isSelected()) | ||
283 | { | ||
284 | found = true; | ||
285 | #ifndef KAB_EMBEDDED | ||
286 | ContactListViewItem *ceItem | ||
287 | = dynamic_cast<ContactListViewItem*>(item); | ||
288 | #else //KAB_EMBEDDED | ||
289 | ContactListViewItem *ceItem | ||
290 | = (ContactListViewItem*)(item); | ||
291 | #endif //KAB_EMBEDDED | ||
292 | |||
293 | if ( ceItem ) emit selected(ceItem->addressee().uid()); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | if (!found) | ||
298 | emit selected(QString::null); | ||
299 | } | ||
300 | |||
301 | void KAddressBookTableView::addresseeExecuted(QListViewItem *item) | ||
302 | { | ||
303 | if (item) | ||
304 | { | ||
305 | #ifndef KAB_EMBEDDED | ||
306 | ContactListViewItem *ceItem | ||
307 | = dynamic_cast<ContactListViewItem*>(item); | ||
308 | #else //KAB_EMBEDDED | ||
309 | ContactListViewItem *ceItem | ||
310 | = (ContactListViewItem*)(item); | ||
311 | #endif //KAB_EMBEDDED | ||
312 | |||
313 | if (ceItem) | ||
314 | { | ||
315 | emit executed(ceItem->addressee().uid()); | ||
316 | } | ||
317 | } | ||
318 | else | ||
319 | { | ||
320 | emit executed(QString::null); | ||
321 | } | ||
322 | } | ||
323 | |||
324 | void KAddressBookTableView::addresseeDeleted() | ||
325 | { | ||
326 | |||
327 | emit deleteRequest(); | ||
328 | |||
329 | } | ||
330 | |||
331 | |||
332 | |||
333 | |||
334 | |||
335 | #ifndef KAB_EMBEDDED | ||
336 | #include "kaddressbooktableview.moc" | ||
337 | #endif //KAB_EMBEDDED | ||
diff --git a/kaddressbook/views/kaddressbooktableview.h b/kaddressbook/views/kaddressbooktableview.h new file mode 100644 index 0000000..bb991bc --- a/dev/null +++ b/kaddressbook/views/kaddressbooktableview.h | |||
@@ -0,0 +1,114 @@ | |||
1 | #ifndef KADDRESSBOOKTABLEVIEW_H | ||
2 | #define KADDRESSBOOKTABLEVIEW_H | ||
3 | |||
4 | |||
5 | #ifndef KAB_EMBEDDED | ||
6 | |||
7 | |||
8 | #ifdef HAVE_CONFIG_H | ||
9 | #include <config.h> | ||
10 | #endif | ||
11 | |||
12 | #include <qwidget.h> | ||
13 | #include <qlistview.h> | ||
14 | #include <qstring.h> | ||
15 | #include <qdialog.h> | ||
16 | #include <qtabdialog.h> | ||
17 | #include <qstringlist.h> | ||
18 | #include <qvaluelist.h> | ||
19 | |||
20 | #include "undo.h" | ||
21 | |||
22 | #else //KAB_EMBEDDED | ||
23 | #include "views/configuretableviewdialog.h" | ||
24 | #endif //KAB_EMBEDDED | ||
25 | |||
26 | #include "klocale.h" | ||
27 | #include "kaddressbookview.h" | ||
28 | |||
29 | class QListViewItem; | ||
30 | class QListBox; | ||
31 | class QVBoxLayout; | ||
32 | class KConfig; | ||
33 | |||
34 | class ContactListViewItem; | ||
35 | class ContactListView; | ||
36 | |||
37 | |||
38 | namespace KABC { class AddressBook; } | ||
39 | |||
40 | /** | ||
41 | * This class is the table view for kaddressbook. This view is a KListView | ||
42 | * with multiple columns for the selected fields. | ||
43 | * | ||
44 | * @short Table View | ||
45 | * @author Don Sanders <dsanders@kde.org> | ||
46 | * @version 0.1 | ||
47 | */ | ||
48 | class KAddressBookTableView : public KAddressBookView | ||
49 | { | ||
50 | friend class ContactListView; | ||
51 | |||
52 | Q_OBJECT | ||
53 | |||
54 | public: | ||
55 | KAddressBookTableView( KABC::AddressBook *ab, QWidget *parent, | ||
56 | const char *name = 0 ); | ||
57 | virtual ~KAddressBookTableView(); | ||
58 | |||
59 | virtual void refresh(QString uid = QString::null); | ||
60 | virtual QStringList selectedUids(); | ||
61 | virtual void setSelected(QString uid = QString::null, bool selected = false); | ||
62 | virtual void readConfig(KConfig *config); | ||
63 | virtual void writeConfig(KConfig *config); | ||
64 | virtual QString type() const { return "Table"; } | ||
65 | |||
66 | public slots: | ||
67 | virtual void reconstructListView(); | ||
68 | |||
69 | protected slots: | ||
70 | /** Called whenever the user selects an addressee in the list view. | ||
71 | */ | ||
72 | void addresseeSelected(); | ||
73 | void addresseeDeleted(); | ||
74 | |||
75 | /** Called whenever the user executes an addressee. In terms of the | ||
76 | * list view, this is probably a double click | ||
77 | */ | ||
78 | void addresseeExecuted(QListViewItem*); | ||
79 | |||
80 | private: | ||
81 | QVBoxLayout *mainLayout; | ||
82 | ContactListView *mListView; | ||
83 | }; | ||
84 | |||
85 | |||
86 | class TableViewFactory : public ViewFactory | ||
87 | { | ||
88 | public: | ||
89 | KAddressBookView *view( KABC::AddressBook *ab, QWidget *parent, const char *name ) | ||
90 | { | ||
91 | return new KAddressBookTableView( ab, parent, name ); | ||
92 | } | ||
93 | |||
94 | QString type() const { return "Table"; } | ||
95 | |||
96 | QString description() const { return i18n( "A listing of contacts in a table. Each cell of " | ||
97 | "the table holds a field of the contact." ); } | ||
98 | |||
99 | ViewConfigureWidget *configureWidget( KABC::AddressBook *ab, QWidget *parent, | ||
100 | const char *name = 0 ) | ||
101 | { | ||
102 | return new ConfigureTableViewWidget( ab, parent, name ); | ||
103 | } | ||
104 | }; | ||
105 | /*US | ||
106 | extern "C" { | ||
107 | void *init_libkaddrbk_tableview() | ||
108 | { | ||
109 | return ( new TableViewFactory ); | ||
110 | } | ||
111 | } | ||
112 | */ | ||
113 | |||
114 | #endif | ||