1 //=============================================================================
2 //
3 // File : KviTreeWindowList.cpp
4 // Creation date : Thu Jan 7 1999 03:56:50 by Szymon Stefanek
5 //
6 // This file is part of the KVIrc IRC client distribution
7 // Copyright (C) 1999 Szymon Stefanek (pragma at kvirc dot net)
8 // Copyright (C) 2008 Fabio Bas (ctrlaltca at gmail dot com)
9 //
10 // This program is FREE software. You can redistribute it and/or
11 // modify it under the terms of the GNU General Public License
12 // as published by the Free Software Foundation; either version 2
13 // of the License, or (at your option) any later version.
14 //
15 // This program is distributed in the HOPE that it will be USEFUL,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18 // See the GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with this program. If not, write to the Free Software Foundation,
22 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 //
24 //=============================================================================
25
26 #include "KviChannelWindow.h"
27 #include "KviConsoleWindow.h"
28 #include "KviDynamicToolTip.h"
29 #include "KviMainWindow.h"
30 #include "KviLocale.h"
31 #include "KviOptions.h"
32 #include "KviWindow.h"
33 #include "KviTreeWindowList.h"
34 #include "KviPixmapUtils.h"
35 #include "KviTrayIcon.h"
36
37 #include <QHeaderView>
38 #include <QMouseEvent>
39 #include <QWheelEvent>
40 #include <QPainter>
41 #include <QTimer>
42 #include <QScrollBar>
43 #include <QStyleOptionViewItem>
44 #include <QStyle>
45 #include <QMenu>
46
47 #ifdef COMPILE_PSEUDO_TRANSPARENCY
48 extern QPixmap * g_pShadedChildGlobalDesktopBackground;
49 #endif
50
51 extern QPixmap * g_pActivityMeterPixmap;
52
53 // KviTreeWindowListItem
54
KviTreeWindowListItem(QTreeWidget * par,KviWindow * wnd)55 KviTreeWindowListItem::KviTreeWindowListItem(QTreeWidget * par, KviWindow * wnd)
56 : QTreeWidgetItem(par), KviWindowListItem(wnd)
57 {
58 applyOptions();
59 captionChanged();
60 }
61
KviTreeWindowListItem(KviTreeWindowListItem * par,KviWindow * wnd)62 KviTreeWindowListItem::KviTreeWindowListItem(KviTreeWindowListItem * par, KviWindow * wnd)
63 : QTreeWidgetItem(par), KviWindowListItem(wnd)
64 {
65 applyOptions();
66 captionChanged();
67 }
68
69 KviTreeWindowListItem::~KviTreeWindowListItem()
70 = default;
71
applyOptions()72 void KviTreeWindowListItem::applyOptions()
73 {
74 //sort the widget [FIXME: expensive?]
75 treeWidget()->sortItems(0, ((KviTreeWindowListTreeWidget *)treeWidget())->isReverseSort() ? Qt::DescendingOrder : Qt::AscendingOrder);
76 }
77
captionChanged()78 void KviTreeWindowListItem::captionChanged()
79 {
80 QString szText;
81
82 switch(m_pWindow->type())
83 {
84 case KviWindow::Console:
85 {
86 KviWindowListBase::getTextForConsole(szText, (KviConsoleWindow *)m_pWindow);
87 }
88 break;
89 case KviWindow::Channel:
90 case KviWindow::DeadChannel:
91 if(KVI_OPTION_BOOL(KviOption_boolShowUserFlagForChannelsInWindowList))
92 szText = ((KviChannelWindow *)m_pWindow)->nameWithUserFlag();
93 else
94 szText = ((KviChannelWindow *)m_pWindow)->target();
95 break;
96 case KviWindow::Query:
97 case KviWindow::DeadQuery:
98 szText = m_pWindow->windowName();
99 break;
100 default:
101 szText = m_pWindow->plainTextCaption();
102 break;
103 }
104
105 if(m_pWindow->isMinimized())
106 szText.prepend('(').append(')');
107
108 //sort the widget
109 treeWidget()->sortItems(0, ((KviTreeWindowListTreeWidget *)treeWidget())->isReverseSort() ? Qt::DescendingOrder : Qt::AscendingOrder);
110
111 setData(0, Qt::DisplayRole, szText);
112 }
113
unhighlight()114 void KviTreeWindowListItem::unhighlight()
115 {
116 if(m_iHighlightLevel < 1)
117 return;
118 m_iHighlightLevel = 0;
119 setData(0, KVI_TTBID_HIGHLIGHT, m_iHighlightLevel);
120
121 if(g_pMainWindow->trayIcon())
122 g_pMainWindow->trayIcon()->refresh();
123 }
124
highlight(int iLevel)125 void KviTreeWindowListItem::highlight(int iLevel)
126 {
127 if(iLevel <= m_iHighlightLevel)
128 return;
129 if(treeWidget()->currentItem() == this && g_pMainWindow->isActiveWindow())
130 return;
131 m_iHighlightLevel = iLevel;
132 setData(0, KVI_TTBID_HIGHLIGHT, m_iHighlightLevel);
133
134 if(g_pMainWindow->trayIcon())
135 g_pMainWindow->trayIcon()->refresh();
136 }
137
setProgress(int progress)138 void KviTreeWindowListItem::setProgress(int progress)
139 {
140 if(progress == m_iProgress)
141 return;
142 m_iProgress = progress;
143 setData(0, KVI_TTBID_PROGRESS, m_iProgress);
144 }
145
setActive(bool bActive)146 void KviTreeWindowListItem::setActive(bool bActive)
147 {
148 if(bActive)
149 {
150 unhighlight();
151 treeWidget()->setCurrentItem(this);
152 // treeWidget()->scrollToItem(this);
153 }
154 }
155
key() const156 QString KviTreeWindowListItem::key() const
157 {
158 // This is the sorting function for KviTreeTaskBarItem
159 // 1) window type (console, other window..) 2) unique id [to avoid bug #9] 3) windowname (for alphabetical sorting of children)
160 QString ret;
161 int iType = m_pWindow->type();
162
163 // ensure dead/alive channels and queries stay in the same position
164 if(iType == KviWindow::DeadChannel)
165 iType = KviWindow::Channel;
166 if(iType == KviWindow::DeadQuery)
167 iType = KviWindow::Query;
168
169 if(KVI_OPTION_BOOL(KviOption_boolSortWindowListItemsByName))
170 {
171 if(iType == KviWindow::Console)
172 {
173 QString szText;
174 KviWindowListBase::getTextForConsole(szText, (KviConsoleWindow *)m_pWindow);
175
176 ret.sprintf("%2d%s", iType, szText.toLower().toUtf8().data());
177 }
178 else
179 {
180 ret.sprintf("%2d%s", iType, m_pWindow->windowName().toLower().toUtf8().data());
181 }
182 }
183 else
184 {
185 if(iType == KviWindow::Console)
186 {
187 ret.sprintf("%2d%4u", iType, ((KviConsoleWindow *)m_pWindow)->context() ? ((KviConsoleWindow *)m_pWindow)->context()->id() : 9999);
188 }
189 else
190 {
191 ret.sprintf("%2d%4d", iType, parent() ? parent()->indexOfChild((QTreeWidgetItem *)this) : 9999);
192 }
193 }
194 return ret;
195 }
196
197 // KviTreeWindowListTreeWidget
198
KviTreeWindowListTreeWidget(QWidget * par)199 KviTreeWindowListTreeWidget::KviTreeWindowListTreeWidget(QWidget * par)
200 : QTreeWidget(par)
201 {
202 setObjectName("tree_windowlist");
203 bReverseSort = false;
204 setRootIsDecorated(true);
205 setSelectionMode(QAbstractItemView::NoSelection);
206 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
207 setFont(KVI_OPTION_FONT(KviOption_fontTreeWindowList));
208 setFocusPolicy(Qt::NoFocus);
209 setAutoFillBackground(false);
210 viewport()->setAutoFillBackground(false);
211 setFrameShape(QFrame::Box);
212 setFrameStyle(QFrame::Panel | QFrame::Sunken);
213 }
214
215 KviTreeWindowListTreeWidget::~KviTreeWindowListTreeWidget()
216 = default;
217
mouseMoveEvent(QMouseEvent *)218 void KviTreeWindowListTreeWidget::mouseMoveEvent(QMouseEvent *)
219 {
220 // dummy just to avoid bug #581:
221 // Clicking on item A and moving the mouse to item B selects item A first and then item B
222 // Hovewer item A remains current
223 }
224
wheelEvent(QWheelEvent * e)225 void KviTreeWindowListTreeWidget::wheelEvent(QWheelEvent * e)
226 {
227 // Mitigate bug #488:
228 // When there is a scroll bar the wheel scrolls up and down
229 // When there is no scroll bar the wheel changes selection in the tree
230
231 if(KVI_OPTION_BOOL(KviOption_boolWheelScrollsWindowsList))
232 {
233 if(e->delta() < 0)
234 ((KviTreeWindowList *)parent())->switchWindow(true, false);
235 else if(e->delta() > 0)
236 ((KviTreeWindowList *)parent())->switchWindow(false, false);
237 }
238 else
239 {
240 QScrollBar * pBar = verticalScrollBar();
241
242 if(!pBar)
243 return;
244 if(!pBar->isVisible())
245 return;
246
247 if(
248 ((e->delta() < 0) && (pBar->value() < pBar->maximum())) || ((e->delta() > 0) && (pBar->value() > pBar->minimum())))
249 QApplication::sendEvent(pBar, e);
250 }
251 }
252
mousePressEvent(QMouseEvent * e)253 void KviTreeWindowListTreeWidget::mousePressEvent(QMouseEvent * e)
254 {
255 KviTreeWindowListItem * it = (KviTreeWindowListItem *)itemAt(e->pos());
256 if(it)
257 {
258 //clicked over an item
259 KviWindow * wnd = it->kviWindow();
260 if(e->button() & Qt::LeftButton)
261 {
262 if(e->modifiers() & Qt::ShiftModifier)
263 {
264 //shitf+left click: close window
265 wnd->delayedClose();
266 }
267 else
268 {
269 //left click activate/deactivate window
270 if(g_pActiveWindow != wnd)
271 g_pMainWindow->setActiveWindow(wnd);
272
273 // let our parent handle clicks on branches, etc
274 QStyleOption option;
275 option.initFrom(this);
276 option.rect = visualItemRect(it);
277 if(!style()->subElementRect(QStyle::SE_TreeViewDisclosureItem, &option, this).contains(e->pos()))
278 QTreeWidget::mousePressEvent(e);
279 }
280 }
281 else if(e->button() & Qt::RightButton)
282 {
283 //right click: open popup
284 wnd->contextPopup();
285 }
286 else if(e->button() & Qt::MidButton)
287 {
288 //mid click: close window
289 wnd->delayedClose();
290 }
291 }
292 else
293 {
294 //clicked on empty space
295 if(e->button() & Qt::RightButton)
296 {
297 QMenu * pPopup = new QMenu();
298 pPopup->addAction(__tr2qs("Sort"), this, SLOT(sort()));
299 pPopup->addAction(__tr2qs("Reverse Sort"), this, SLOT(reverseSort()));
300 pPopup->popup(QCursor::pos());
301 }
302 }
303 }
304
mouseDoubleClickEvent(QMouseEvent * e)305 void KviTreeWindowListTreeWidget::mouseDoubleClickEvent(QMouseEvent * e)
306 {
307 QTreeWidgetItem * it = itemAt(e->pos());
308 if(it)
309 {
310 if(e->button() & Qt::LeftButton)
311 {
312 it->setExpanded(!(it->isExpanded()));
313 }
314 }
315 }
316
sort()317 void KviTreeWindowListTreeWidget::sort()
318 {
319 bReverseSort = false;
320 sortItems(0, Qt::AscendingOrder);
321 }
322
reverseSort()323 void KviTreeWindowListTreeWidget::reverseSort()
324 {
325 bReverseSort = true;
326 sortItems(0, Qt::DescendingOrder);
327 }
328
paintEvent(QPaintEvent * event)329 void KviTreeWindowListTreeWidget::paintEvent(QPaintEvent * event)
330 {
331 QPainter * p = new QPainter(viewport());
332 QStyleOptionViewItem option = viewOptions();
333 QRect rect = event->rect();
334
335 #ifdef COMPILE_PSEUDO_TRANSPARENCY
336 if(KVI_OPTION_BOOL(KviOption_boolUseCompositingForTransparency) && g_pApp->supportsCompositing())
337 {
338 p->save();
339 p->setCompositionMode(QPainter::CompositionMode_Source);
340 QColor col = KVI_OPTION_COLOR(KviOption_colorGlobalTransparencyFade);
341 col.setAlphaF((float)((float)KVI_OPTION_UINT(KviOption_uintGlobalTransparencyChildFadeFactor) / (float)100));
342 p->fillRect(rect, col);
343 p->restore();
344 }
345 else if(g_pShadedChildGlobalDesktopBackground)
346 {
347 QPoint pnt = mapTo(g_pMainWindow, rect.topLeft());
348 p->drawTiledPixmap(rect, *(g_pShadedChildGlobalDesktopBackground), pnt);
349 }
350 else
351 {
352 #endif
353 QPixmap * pix = KVI_OPTION_PIXMAP(KviOption_pixmapTreeWindowListBackground).pixmap();
354 if(pix)
355 {
356 KviPixmapUtils::drawPixmapWithPainter(p, pix, KVI_OPTION_UINT(KviOption_uintTreeWindowListPixmapAlign), rect, viewport()->width(), viewport()->height());
357 }
358 else
359 {
360 p->fillRect(rect, KVI_OPTION_COLOR(KviOption_colorTreeWindowListBackground));
361 }
362 #ifdef COMPILE_PSEUDO_TRANSPARENCY
363 }
364 #endif
365
366 delete p;
367
368 //call paint on all childrens
369 QTreeWidget::paintEvent(event);
370 }
371
372 // KviTreeWindowList
373
KviTreeWindowList()374 KviTreeWindowList::KviTreeWindowList()
375 : KviWindowListBase()
376 {
377 m_pTreeWidget = new KviTreeWindowListTreeWidget(this);
378 m_pTreeWidget->setColumnWidth(0, 135);
379 m_pTreeWidget->header()->hide();
380 setWidget(m_pTreeWidget);
381
382 //ad-hoc itemdelegate for this view
383 m_pItemDelegate = new KviTreeWindowListItemDelegate(m_pTreeWidget);
384 m_pTreeWidget->setItemDelegate(m_pItemDelegate);
385
386 //minimun and maximun width of the treeview
387 if(KVI_OPTION_UINT(KviOption_uintTreeWindowListMinimumWidth) < 48)
388 KVI_OPTION_UINT(KviOption_uintTreeWindowListMinimumWidth) = 48;
389 int iMin = m_pTreeWidget->minimumSize().width() + 4;
390 if(((unsigned int)iMin) < KVI_OPTION_UINT(KviOption_uintTreeWindowListMinimumWidth))
391 iMin = KVI_OPTION_UINT(KviOption_uintTreeWindowListMinimumWidth);
392 setMinimumWidth(iMin);
393
394 //tooltips
395 m_pToolTip = new KviDynamicToolTip(m_pTreeWidget->viewport(), "tree_windowlist_tooltip");
396 connect(m_pToolTip, SIGNAL(tipRequest(KviDynamicToolTip *, const QPoint &)), this, SLOT(tipRequest(KviDynamicToolTip *, const QPoint &)));
397
398 applyOptions();
399 }
400
401 KviTreeWindowList::~KviTreeWindowList()
402 = default;
403
updatePseudoTransparency()404 void KviTreeWindowList::updatePseudoTransparency()
405 {
406 #ifdef COMPILE_PSEUDO_TRANSPARENCY
407 m_pTreeWidget->viewport()->update();
408 #endif
409 }
410
moveEvent(QMoveEvent *)411 void KviTreeWindowList::moveEvent(QMoveEvent *)
412 {
413 #ifdef COMPILE_PSEUDO_TRANSPARENCY
414 updatePseudoTransparency();
415 #endif
416 }
417
tipRequest(KviDynamicToolTip *,const QPoint & pnt)418 void KviTreeWindowList::tipRequest(KviDynamicToolTip *, const QPoint & pnt)
419 {
420 if(KVI_OPTION_BOOL(KviOption_boolShowWindowListToolTips))
421 {
422 QTreeWidgetItem * it = m_pTreeWidget->itemAt(pnt);
423 if(it)
424 {
425 QString szText;
426 ((KviTreeWindowListItem *)it)->m_pWindow->getWindowListTipText(szText);
427 m_pToolTip->tip(QRect(pnt, QSize(16, 16)), szText);
428 }
429 }
430 }
431
addItem(KviWindow * wnd)432 KviWindowListItem * KviTreeWindowList::addItem(KviWindow * wnd)
433 {
434 // complex insertion task
435 if(wnd->console())
436 {
437 if(wnd->type() != KviWindow::Console)
438 {
439 ((KviTreeWindowListItem *)(wnd->console()->m_pWindowListItem))->setExpanded(true);
440 return new KviTreeWindowListItem(((KviTreeWindowListItem *)(wnd->console()->m_pWindowListItem)), wnd);
441 }
442 }
443
444 // console, or a window that has no irc context
445 return new KviTreeWindowListItem(m_pTreeWidget, wnd);
446 }
447
removeItem(KviWindowListItem * it)448 bool KviTreeWindowList::removeItem(KviWindowListItem * it)
449 {
450 if(it)
451 {
452 KviTreeWindowListItem * item = (KviTreeWindowListItem *)it;
453 if(m_pTreeWidget)
454 {
455 int index = m_pTreeWidget->indexOfTopLevelItem(item);
456 if(index >= 0)
457 {
458 delete(KviTreeWindowListItem *)m_pTreeWidget->takeTopLevelItem(index);
459 }
460 else
461 {
462 index = item->parent()->indexOfChild(item);
463 if(index >= 0)
464 delete(KviTreeWindowListItem *)item->parent()->takeChild(index);
465 }
466 }
467 }
468 return true;
469 }
470
setActiveItem(KviWindowListItem * it)471 void KviTreeWindowList::setActiveItem(KviWindowListItem * it)
472 {
473 if(it)
474 {
475 if(((KviTreeWindowListItem *)it)->parent())
476 {
477 if(!((KviTreeWindowListItem *)it)->parent()->isExpanded())
478 ((KviTreeWindowListItem *)it)->parent()->setExpanded(true);
479 }
480
481 ((KviTreeWindowListItem *)it)->setActive(true);
482 if(g_pMainWindow->trayIcon())
483 g_pMainWindow->trayIcon()->refresh();
484 }
485 }
486
updateActivityMeter()487 void KviTreeWindowList::updateActivityMeter()
488 {
489 if(KVI_OPTION_BOOL(KviOption_boolUseWindowListActivityMeter))
490 {
491 m_pTreeWidget->viewport()->update();
492 }
493 }
494
wheelEvent(QWheelEvent * e)495 void KviTreeWindowList::wheelEvent(QWheelEvent * e)
496 {
497 // Override KviWindowListBase::wheelEvent.
498 // Mouse wheel handling is done in
499 // KviTreeWindowListTreeWidget::wheelEvent.
500 }
501
firstItem()502 KviWindowListItem * KviTreeWindowList::firstItem()
503 {
504 m_pCurrentItem = (KviTreeWindowListItem *)m_pTreeWidget->topLevelItem(0);
505 return m_pCurrentItem;
506 }
507
nextItem()508 KviWindowListItem * KviTreeWindowList::nextItem()
509 {
510 if(!m_pCurrentItem)
511 return nullptr;
512 return m_pCurrentItem = (KviTreeWindowListItem *)m_pTreeWidget->itemBelow(m_pCurrentItem);
513 }
514
prevItem()515 KviWindowListItem * KviTreeWindowList::prevItem()
516 {
517 if(!m_pCurrentItem)
518 return nullptr;
519 return m_pCurrentItem = (KviTreeWindowListItem *)m_pTreeWidget->itemAbove(m_pCurrentItem);
520 }
521
lastItem()522 KviWindowListItem * KviTreeWindowList::lastItem()
523 {
524 // first find last toplevel item
525 int tops = m_pTreeWidget->topLevelItemCount();
526 if(tops > 0)
527 {
528 int ctops = m_pTreeWidget->topLevelItem(tops - 1)->childCount();
529 if(ctops)
530 {
531 return m_pCurrentItem = (KviTreeWindowListItem *)m_pTreeWidget->topLevelItem(tops - 1)->child(ctops - 1);
532 }
533 else
534 {
535 return m_pCurrentItem = (KviTreeWindowListItem *)m_pTreeWidget->topLevelItem(tops - 1);
536 }
537 }
538 else
539 {
540 return nullptr;
541 }
542 }
543
setIterationPointer(KviWindowListItem * it)544 bool KviTreeWindowList::setIterationPointer(KviWindowListItem * it)
545 {
546 m_pCurrentItem = (KviTreeWindowListItem *)it;
547 if(!m_pCurrentItem)
548 return true;
549 if(m_pTreeWidget == m_pCurrentItem->treeWidget())
550 return true;
551 m_pCurrentItem = nullptr;
552 return false;
553 }
554
555 // KviTreeWindowListItemDelegate
556
paint(QPainter * p,const QStyleOptionViewItem & option,const QModelIndex & index) const557 void KviTreeWindowListItemDelegate::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) const
558 {
559 QString szText = index.data(Qt::DisplayRole).toString();
560 int iProgress = index.data(KVI_TTBID_PROGRESS).toInt();
561
562 //FIXME not exactly model/view coding style.. but we need to access data on the associated window
563 KviTreeWindowListTreeWidget * treeWidget = (KviTreeWindowListTreeWidget *)parent();
564 KviTreeWindowListItem * item = (KviTreeWindowListItem *)treeWidget->itemFromIndex(index);
565 KviWindow * pWindow = item->kviWindow();
566
567 QStyleOptionViewItem opt(option);
568 opt.state = opt.state | QStyle::State_Selected;
569 opt.showDecorationSelected = true;
570 //paint cell background
571 if(treeWidget->currentItem() == item)
572 {
573 //selection colored background
574 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
575 if(treeWidget->style()->inherits("QStyleSheetStyle") || treeWidget->style()->inherits("QWindowsVistaStyle"))
576 {
577 // The Windows style does not honor our colors. It uses the system ones instead.
578 // We can't accept it.
579 p->fillRect(opt.rect, KVI_OPTION_COLOR(KviOption_colorTreeWindowListActiveBackground));
580 }
581 else
582 {
583 #endif
584 opt.palette.setColor(QPalette::Highlight, KVI_OPTION_COLOR(KviOption_colorTreeWindowListActiveBackground));
585 treeWidget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, p, treeWidget);
586 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
587 }
588 #endif
589 #ifndef COMPILE_ON_MAC
590 }
591 else
592 {
593 if(KVI_OPTION_BOOL(KviOption_boolEnableVisualEffects) && option.state & QStyle::State_MouseOver)
594 {
595 // paint mouse over effect
596 QColor col(KVI_OPTION_COLOR(KviOption_colorTreeWindowListActiveBackground));
597 col.setAlpha(127);
598
599 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
600 if(treeWidget->style()->inherits("QStyleSheetStyle") || treeWidget->style()->inherits("QWindowsVistaStyle"))
601 {
602 // The Windows style does not honor our colors. It uses the system ones instead.
603 // We can't accept it.
604 p->fillRect(opt.rect, col);
605 }
606 else
607 {
608 #endif
609 opt.palette.setColor(QPalette::Highlight, col);
610 treeWidget->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, p, treeWidget);
611 #if defined(COMPILE_ON_WINDOWS) || defined(COMPILE_ON_MINGW)
612 }
613 #endif
614 }
615 #endif
616 }
617 //draw window icon, irc context indicator (a colored square), set font properties for text
618 int im = option.rect.left() + 2;
619 int yPixmap = (option.rect.top() + (option.rect.height() / 2 - 8));
620
621 QRect cRect(im + 3, option.rect.top(), option.rect.width(), option.rect.height());
622
623 switch(pWindow->type())
624 {
625 case KviWindow::Console:
626 {
627 if(KVI_OPTION_BOOL(KviOption_boolUseWindowListIrcContextIndicator))
628 {
629 QColor base = option.palette.window().color();
630 QColor cntx = KVI_OPTION_ICCOLOR(pWindow->console()->context()->id() % KVI_NUM_ICCOLOR_OPTIONS);
631 base.setRgb((base.red() + cntx.red()) >> 1, (base.green() + cntx.green()) >> 1,
632 (base.blue() + cntx.blue()) >> 1);
633 p->fillRect(im + 2, yPixmap, 14, 15, base);
634 if(KVI_OPTION_BOOL(KviOption_boolUseWindowListIcons))
635 {
636 p->drawPixmap(im + 20, yPixmap, *(pWindow->myIconPtr()));
637 cRect.setLeft(cRect.left() + 37);
638 }
639 else
640 {
641 cRect.setLeft(cRect.left() + 20);
642 }
643 }
644 else
645 {
646 if(KVI_OPTION_BOOL(KviOption_boolUseWindowListIcons))
647 {
648 p->drawPixmap(im, yPixmap, *(pWindow->myIconPtr()));
649 cRect.setLeft(cRect.left() + 17);
650 }
651 }
652 //console window: bold font
653 QFont f = p->font();
654 f.setBold(true);
655 p->setFont(f);
656 }
657 break;
658 case KviWindow::Channel:
659 case KviWindow::DeadChannel:
660 case KviWindow::Query:
661 case KviWindow::DeadQuery:
662 default:
663 if(KVI_OPTION_BOOL(KviOption_boolUseWindowListIcons))
664 {
665 p->drawPixmap(im, yPixmap, *(pWindow->myIconPtr()));
666 cRect.setLeft(cRect.left() + 17);
667 }
668 //channels, other windows: normal font
669 QFont f = p->font();
670 f.setBold(false);
671 p->setFont(f);
672 break;
673 }
674
675 // paint the channel activity meter
676 if(KVI_OPTION_BOOL(KviOption_boolUseWindowListActivityMeter))
677 {
678 unsigned int uActivityValue;
679 unsigned int uActivityTemperature;
680 if(pWindow->activityMeter(&uActivityValue, &uActivityTemperature))
681 {
682 p->drawPixmap(cRect.left(), yPixmap, *g_pActivityMeterPixmap, uActivityValue * 5, uActivityTemperature * 16, 5, 16);
683 cRect.setLeft(cRect.left() + 7);
684 }
685 }
686
687 // paint the progress bar
688 if(iProgress >= 0)
689 {
690 int wdth = (iProgress * cRect.width()) / 100;
691 p->fillRect(cRect.x(), cRect.y(), wdth, cRect.height(), KVI_OPTION_COLOR(KviOption_colorTreeWindowListProgress));
692 }
693
694 //choose window name font color (highlighting)
695 if(treeWidget->currentItem() == item)
696 {
697 p->setPen(KVI_OPTION_COLOR(KviOption_colorTreeWindowListActiveForeground));
698 }
699 else
700 {
701 int iHighlightLevel = index.data(KVI_TTBID_HIGHLIGHT).toInt();
702 int iLevel;
703
704 switch(iHighlightLevel)
705 {
706 case 0:
707 iLevel = KviOption_colorTreeWindowListForeground;
708 break;
709 case 1:
710 iLevel = KviOption_colorTreeWindowListHighlight1Foreground;
711 break;
712 case 2:
713 iLevel = KviOption_colorTreeWindowListHighlight2Foreground;
714 break;
715 case 3:
716 iLevel = KviOption_colorTreeWindowListHighlight3Foreground;
717 break;
718 case 4:
719 iLevel = KviOption_colorTreeWindowListHighlight4Foreground;
720 break;
721 default:
722 iLevel = KviOption_colorTreeWindowListHighlight5Foreground;
723 break;
724 }
725
726 p->setPen(KVI_OPTION_COLOR(iLevel));
727 }
728
729 //qDebug("Draw text in %d,%d,%d,%d (%s)",cRect.left(),cRect.top(),cRect.width(),cRect.height(),szText.toUtf8().data());
730
731 //draw window name
732 p->drawText(cRect, Qt::AlignLeft | Qt::AlignVCenter, szText);
733 }
734
sizeHint(const QStyleOptionViewItem &,const QModelIndex &) const735 QSize KviTreeWindowListItemDelegate::sizeHint(const QStyleOptionViewItem &, const QModelIndex &) const
736 {
737 KviTreeWindowListTreeWidget * treeWidget = (KviTreeWindowListTreeWidget *)parent();
738 int iHeight = treeWidget->fontMetrics().lineSpacing();
739
740 iHeight += iHeight / 3;
741 if((KVI_OPTION_BOOL(KviOption_boolUseWindowListIrcContextIndicator) || KVI_OPTION_BOOL(KviOption_boolUseWindowListIcons) || KVI_OPTION_BOOL(KviOption_boolUseWindowListActivityMeter)) && iHeight < 20)
742 iHeight = 20;
743
744 return { treeWidget->viewport()->size().width(), iHeight };
745 }
746