serverlistview.cpp
1 //------------------------------------------------------------------------------
2 // serverlistview.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301, USA.
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2009 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 
24 #include "gui/widgets/serverlistview.h"
25 
26 #include "configuration/doomseekerconfig.h"
27 #include <QDebug>
28 #include <QHeaderView>
29 #include <QItemDelegate>
30 #include <QMouseEvent>
31 #include <QPainter>
32 #include <QSortFilterProxyModel>
33 #include <QTextDocument>
34 
39 class CustomItemDelegate : public QItemDelegate
40 {
41  public:
42  void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
43  {
44  // First we're going to check for our new right aligned image
45  // option.
46  bool rightAligned = false;
47  QStyleOptionViewItem opt = option;
48 
49  QVariant userRole = index.data(Qt::UserRole);
50  if(userRole.isValid() && userRole.type() == QVariant::Int && userRole.toInt() == USERROLE_RIGHTALIGNDECORATION)
51  {
52  opt.decorationAlignment = Qt::AlignRight|Qt::AlignVCenter;
53  rightAligned = true;
54  }
55 
56  // Now we draw the table as usual.
57  QItemDelegate::paint(painter, opt, index);
58 
59  // If the row is selected and we are using the right aligned feature
60  // we must now redraw the decoration. The rectangle that was used
61  // in the previous function will cause the image to clip.
62  //
63  // The only other way I can think of for fixing that problem would
64  // be to completely rewrite this class, which I really don't want
65  // to do.
66  if(rightAligned && (opt.state & QStyle::State_Selected))
67  {
68  QVariant decorationRole = index.data(Qt::DecorationRole);
69  if(decorationRole.isValid())
70  {
71  painter->save();
72  painter->setClipRect(opt.rect);
73 
74  QPixmap pixmap = decoration(opt, decorationRole);
75  drawDecoration(painter, opt, opt.rect, pixmap);
76 
77  painter->restore();
78  }
79  }
80  }
81 
82  protected:
83  void drawDecoration(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QPixmap &pixmap) const
84  {
85  if(pixmap.isNull() || !rect.isValid())
86  return;
87 
88  if(option.decorationAlignment == (Qt::AlignRight|Qt::AlignVCenter)) // Special handling.
89  {
90  QPoint p = QStyle::alignedRect(option.direction, option.decorationAlignment, pixmap.size(), option.rect).topLeft();
91  painter->drawPixmap(p, pixmap);
92  }
93  else
94  QItemDelegate::drawDecoration(painter, option, rect, pixmap);
95  }
96 };
97 
99 
100 ServerListView::ServerListView(QWidget* parent) : QTableView(parent)
101 {
102  // Prevent the fat rows problem.
103  verticalHeader()->setDefaultSectionSize(fontMetrics().height() + 6);
104  setShowGrid(gConfig.doomseeker.bDrawGridInServerTable);
105 
106  bAllowAllRowsRefresh = true;
107  setItemDelegate(new CustomItemDelegate());
108 }
109 
110 void ServerListView::mouseReleaseEvent(QMouseEvent* event)
111 {
112  QModelIndex index = indexAt(event->pos());
113  switch (event->button())
114  {
115  case Qt::MidButton:
116  if (index.isValid())
117  {
118  emit middleMouseClick(index, event->pos());
119  }
120  break;
121 
122  case Qt::RightButton:
123  if (index.isValid())
124  {
125  emit rightMouseClick(index, event->pos());
126  }
127  break;
128 
129  default:
130  QTableView::mouseReleaseEvent(event);
131  break;
132  }
133 }
134 
135 void ServerListView::mouseDoubleClickEvent(QMouseEvent* event)
136 {
137  if (event->button() != Qt::LeftButton)
138  {
139  QTableView::mouseDoubleClickEvent(event);
140  }
141  else
142  {
143  QModelIndex index = indexAt(event->pos());
144  if (index.isValid())
145  {
146  emit leftMouseDoubleClicked(index, event->pos());
147  }
148  }
149 }
150 
151 void ServerListView::updateRowVisuals(int row)
152 {
153  resizeRowToContents(row);
154 }
155 
156 void ServerListView::updateAllRows()
157 {
158  if (bAllowAllRowsRefresh)
159  {
160  QSortFilterProxyModel* pModel = static_cast<QSortFilterProxyModel*>(model());
161  int rowCount = pModel->sourceModel()->rowCount();
162 
163  for (int i = 0; i < rowCount; ++i)
164  {
165  updateRowVisuals(i);
166  }
167  }
168 }