1 /****************************************************************************
2 * QTableView with some adjustments like storing header layout *
3 * (C) 2007 Michal Rudolf <mrudolf@kdewebdev.org> *
4 * Copyright (C) 2012 by Jens Nissen jens-chessx@gmx.net *
5 ****************************************************************************/
6
7 #include "settings.h"
8 #include "tableview.h"
9
10 #include <QAction>
11 #include <QApplication>
12 #include <QClipboard>
13 #include <QHeaderView>
14 #include <QMenu>
15 #include <QScrollBar>
16 #include <QWheelEvent>
17
18 #if defined(_MSC_VER) && defined(_DEBUG)
19 #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
20 #define new DEBUG_NEW
21 #endif // _MSC_VER
22
TableView(QWidget * parent)23 TableView::TableView(QWidget *parent)
24 : QTableView(parent),
25 m_alignDecoration(Qt::AlignCenter),
26 m_posDecoration(QStyleOptionViewItem::Left)
27 {
28 setShowGrid(false);
29 setSelectionBehavior(QAbstractItemView::SelectRows);
30 setSelectionMode(QAbstractItemView::SingleSelection);
31 setWordWrap(false);
32 setTextElideMode(Qt::ElideRight);
33 verticalHeader()->setDefaultSectionSize(fontMetrics().lineSpacing());
34 verticalHeader()->hide();
35 horizontalHeader()->setHighlightSections(false);
36 horizontalHeader()->setStretchLastSection(true);
37 #if QT_VERSION < 0x050000
38 horizontalHeader()->setMovable(true);
39 #else
40 horizontalHeader()->setSectionsMovable(true);
41 #endif
42 setTabKeyNavigation(false);
43 setContextMenuPolicy(Qt::CustomContextMenu);
44 horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
45
46 connect(horizontalHeader(), SIGNAL(customContextMenuRequested(const QPoint&)),
47 this, SLOT(ShowContextMenu(const QPoint&)));
48 connect(&m_dragTimer, SIGNAL(timeout()), this, SLOT(SlotDragTimer()));
49 m_dragTimer.setSingleShot(true);
50 }
51
~TableView()52 TableView::~TableView()
53 {
54 }
55
wheelEvent(QWheelEvent * e)56 void TableView::wheelEvent(QWheelEvent* e)
57 {
58 unsigned int button = e->modifiers() & Qt::KeyboardModifierMask;
59 if (button == (Qt::ControlModifier|Qt::AltModifier))
60 {
61 QFont f = font();
62 int n = e->delta()>0 ? 1 : -1;
63 int fontSize = f.pointSize() + n;
64 setFontSize(fontSize);
65 }
66 QTableView::wheelEvent(e);
67 }
68
viewOptions() const69 QStyleOptionViewItem TableView::viewOptions() const
70 {
71 QStyleOptionViewItem option = QTableView::viewOptions();
72 option.decorationAlignment = m_alignDecoration;
73 option.decorationPosition = m_posDecoration;
74 return option;
75 }
76
posDecoration() const77 QStyleOptionViewItem::Position TableView::posDecoration() const
78 {
79 return m_posDecoration;
80 }
81
setPosDecoration(const QStyleOptionViewItem::Position & posDecoration)82 void TableView::setPosDecoration(const QStyleOptionViewItem::Position &posDecoration)
83 {
84 m_posDecoration = posDecoration;
85 }
86
alignDecoration() const87 Qt::Alignment TableView::alignDecoration() const
88 {
89 return m_alignDecoration;
90 }
91
setAlignDecoration(const Qt::Alignment & alignDecoration)92 void TableView::setAlignDecoration(const Qt::Alignment &alignDecoration)
93 {
94 m_alignDecoration = alignDecoration;
95 }
96
saveConfig()97 void TableView::saveConfig()
98 {
99 if (model())
100 {
101 AppSettings->setLayout(this);
102 AppSettings->beginGroup(objectName());
103 int n = model()->columnCount();
104 AppSettings->setValue("ColumnCount", n);
105 QByteArray visualIndex = horizontalHeader()->saveState();
106 AppSettings->setByteArray("VisualIndex", visualIndex);
107 AppSettings->endGroup();
108 }
109 }
110
setFontSize(int fontSize)111 void TableView::setFontSize(int fontSize)
112 {
113 fontSize = std::max(fontSize, 8);
114 QFont f = font();
115 f.setPointSize(fontSize);
116 setFont(f);
117
118 QFontMetrics fm(f);
119 int rowHeight = std::max(minRowHeight(), fm.height()+2);
120
121 QHeaderView *vh = verticalHeader();
122 #if QT_VERSION < 0x050000
123 vh->setResizeMode(QHeaderView::Fixed);
124 #else
125 vh->sectionResizeMode(QHeaderView::Fixed);
126 #endif
127 vh->setDefaultSectionSize(rowHeight);
128 }
129
slotReconfigure()130 void TableView::slotReconfigure()
131 {
132 bool sortIndicator = horizontalHeader()->isSortIndicatorShown();
133 AppSettings->layout(this);
134 QString objName = objectName();
135
136 AppSettings->beginGroup(objName);
137
138 int n = model()->columnCount();
139 int nRestore = AppSettings->getValue("ColumnCount").toInt();
140 if (n==nRestore)
141 {
142 QByteArray visualIndex = AppSettings->byteArray("VisualIndex");
143 horizontalHeader()->restoreState(visualIndex);
144 }
145 else
146 {
147 for(int i = 0; i < n; ++i)
148 {
149 showColumn(i);
150 }
151 AppSettings->setValue("ColumnCount", n);
152 resizeColumnsToContents();
153 }
154 AppSettings->endGroup();
155
156 int fontSize = AppSettings->getValue("/General/ListFontSize").toInt();
157 setFontSize(fontSize);
158
159 horizontalHeader()->setSortIndicatorShown(sortIndicator);
160 update();
161 }
162
ShowContextMenu(const QPoint & pos)163 void TableView::ShowContextMenu(const QPoint& pos)
164 {
165 QMenu headerMenu;
166 QAction* hide = headerMenu.addAction(tr("Hide Column"));
167
168 QAction* resizeAll = headerMenu.addAction(tr("Resize visible Columns"));
169 QAction* showAll = headerMenu.addAction(tr("Show all Columns"));
170 headerMenu.addSeparator();
171 QAction* copyHTML = headerMenu.addAction(tr("Copy as HTML"));
172 QAction* copyImage = headerMenu.addAction(tr("Copy as Image"));
173
174 QAction* selectedItem = headerMenu.exec(mapToGlobal(pos));
175 if(selectedItem == hide)
176 {
177 int column = columnAt(pos.x());
178 if(column > 0)
179 {
180 hideColumn(column);
181 }
182 }
183 else if(selectedItem == showAll)
184 {
185 for(int i = 0; i < model()->columnCount(); ++i)
186 {
187 showColumn(i);
188 }
189 }
190 else if (selectedItem == resizeAll)
191 {
192 resizeColumnsToContents();
193 }
194 else if (selectedItem == copyHTML)
195 {
196 QString html = renderToHTML();
197 QApplication::clipboard()->setText(html);
198 }
199 else if (selectedItem == copyImage)
200 {
201 QImage img = renderToImage();
202 QApplication::clipboard()->setImage(img);
203 }
204 }
205
renderHTMLitem(int row,int column) const206 QString TableView::renderHTMLitem(int row,int column) const
207 {
208 QString result = "<td>";
209 QVariant data = model()->data(model()->index(row, column));
210 QString s = data.toString();
211 result += s;
212 result += "</td>";
213 return result;
214 }
215
renderHTMLrow(int row) const216 QString TableView::renderHTMLrow(int row) const
217 {
218 QString result = "<tr>\n";
219 int columns = model()->columnCount();
220 for (int i=0; i<columns; ++i)
221 {
222 result += renderHTMLitem(row,i);
223 }
224 result += "</tr>\n";
225 return result;
226 }
227
renderHeaderToHTML() const228 QString TableView::renderHeaderToHTML() const
229 {
230 QString result = "<tr>\n";
231 int columns = model()->columnCount();
232 for (int i=0; i<columns; ++i)
233 {
234 result += "<th>";
235 result += horizontalHeader()->model()->headerData(i, Qt::Horizontal).toString();
236 result += "</th>";
237 }
238 result += "</tr>\n";
239 return result;
240 }
241
renderToHTML() const242 QString TableView::renderToHTML() const
243 {
244 QString result = "<table border='1'>\n";
245 result += renderHeaderToHTML();
246 int rows = model()->rowCount();
247 for (int i=0; i<rows; ++i)
248 {
249 result += renderHTMLrow(i);
250 }
251 result += "</table>\n";
252 return result;
253 }
254
renderToImage() const255 QImage TableView::renderToImage() const
256 {
257 QTableView* pTableView = new QTableView;
258 pTableView->setModel(model());
259
260 int width = 0;
261 int height = 0;
262 int columns = model()->columnCount();
263 int rows = model()->rowCount();
264
265 pTableView->resizeColumnsToContents();
266
267 for( int i = 0; i < columns; ++i ) {
268 width += pTableView->columnWidth(i);
269 }
270
271 for( int i = 0; i < rows; ++i ) {
272 height += pTableView->rowHeight(i);
273 }
274
275 height += horizontalHeader()->height();
276
277 pTableView->setFixedSize(width, height);
278 pTableView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
279 pTableView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
280
281 QPixmap pixmap(width, height);
282 pixmap.fill(Qt::transparent);
283
284 pTableView->render(&pixmap);
285 QImage image = pixmap.toImage();
286
287 delete pTableView;
288 return image;
289 }
290
startDrag(Qt::DropActions supportedActions)291 void TableView::startDrag(Qt::DropActions supportedActions)
292 {
293 Q_UNUSED(supportedActions);
294 m_dragTimer.stop();
295 }
296
dragEnterEvent(QDragEnterEvent * event)297 void TableView::dragEnterEvent(QDragEnterEvent *event)
298 {
299 Q_UNUSED(event);
300 m_dragTimer.stop();
301 }
302
dragMoveEvent(QDragMoveEvent * event)303 void TableView::dragMoveEvent(QDragMoveEvent *event)
304 {
305 Q_UNUSED(event);
306 }
307
dragLeaveEvent(QDragLeaveEvent * event)308 void TableView::dragLeaveEvent(QDragLeaveEvent *event)
309 {
310 Q_UNUSED(event);
311 m_dragTimer.start(250);
312 }
313
dropEvent(QDropEvent * event)314 void TableView::dropEvent(QDropEvent *event)
315 {
316 Q_UNUSED(event);
317 m_dragTimer.stop();
318 }
319
SlotDragTimer()320 void TableView::SlotDragTimer()
321 {
322 //qDebug()<< "TableView::SlotDragTimer" << endl;
323 QPoint p = QCursor::pos();
324 QPoint tl = mapToGlobal(pos());
325 QRect r = rect();
326 if (p.x()>tl.x() && p.x()<tl.x()+r.width())
327 {
328 if (p.y()<tl.y()) // Move above the view
329 {
330 verticalScrollBar()->setValue(verticalScrollBar()->value()-10);
331 }
332 else if (p.y()>tl.y()+r.height()) // Move below the view
333 {
334 verticalScrollBar()->setValue(verticalScrollBar()->value()+10);
335 }
336 m_dragTimer.start();
337 }
338 else // Move to the left or right of the view
339 {
340 m_dragTimer.stop();
341 }
342 }
343
344