1 /***************************************************************************
2                           twintablemember.cpp  -  description
3                              -------------------
4     begin                : Tue Oct 29 2002
5     copyright            : (C) 2002, 2006, 2007, 2009, 2010, 2012 by Thomas Friedrichsmeier
6     email                : thomas.friedrichsmeier@kdemail.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "twintablemember.h"
19 
20 #include <QKeyEvent>
21 #include <QScrollBar>
22 #include <QHeaderView>
23 
24 #include "twintable.h"
25 #include "rktextmatrix.h"
26 #include "rkvareditmodel.h"
27 
28 #include "../debug.h"
29 
TwinTableMember(QWidget * parent)30 TwinTableMember::TwinTableMember (QWidget *parent) : RKTableView (parent){
31 	RK_TRACE (EDITOR);
32 
33 	rw = true;
34 
35 	setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOn);
36 	setSelectionMode (QAbstractItemView::ContiguousSelection);
37 
38 	verticalHeader ()->setContextMenuPolicy (Qt::CustomContextMenu);
39 	connect (verticalHeader (), &QWidget::customContextMenuRequested, this, &TwinTableMember::handleContextMenuRequest);
40 	horizontalHeader ()->setContextMenuPolicy (Qt::CustomContextMenu);
41 	connect (horizontalHeader (), &QWidget::customContextMenuRequested, this, &TwinTableMember::handleContextMenuRequest);
42 	setContextMenuPolicy (Qt::CustomContextMenu);
43 	connect (this, &QWidget::customContextMenuRequested, this, &TwinTableMember::handleContextMenuRequest);
44 
45 	updating_twin = false;
46 	connect (this, &TwinTableMember::blankSelectionRequest, this, &TwinTableMember::blankSelected);
47 }
48 
~TwinTableMember()49 TwinTableMember::~TwinTableMember(){
50 	RK_TRACE (EDITOR);
51 }
52 
setRKModel(RKVarEditModelBase * model)53 void TwinTableMember::setRKModel (RKVarEditModelBase* model) {
54 	RK_TRACE (EDITOR);
55 
56 	mymodel = model;
57 	setModel (model);
58 
59 	// now we should also have a selectionModel() (but not before)
60 	connect (selectionModel (), &QItemSelectionModel::selectionChanged, this, &TwinTableMember::tableSelectionChanged);
61 }
62 
setTwin(TwinTableMember * new_twin)63 void TwinTableMember::setTwin (TwinTableMember * new_twin) {
64 	RK_TRACE (EDITOR);
65 	twin = new_twin;
66 
67 	// probably we only need this one way (metaview->dataview), but why not be safe, when it's so easy
68 	connect (twin->horizontalHeader (), &QHeaderView::sectionResized, this, &TwinTableMember::updateColWidth);
69 }
70 
tableSelectionChanged(const QItemSelection & selected,const QItemSelection &)71 void TwinTableMember::tableSelectionChanged (const QItemSelection& selected, const QItemSelection&) {
72 	RK_TRACE (EDITOR);
73 	RK_ASSERT (twin);
74 
75 	if (!selected.isEmpty ()) twin->clearSelection ();
76 }
77 
trueColumns() const78 int TwinTableMember::trueColumns () const {
79     return mymodel->trueCols ();
80 }
81 
trueRows() const82 int TwinTableMember::trueRows () const {
83     return mymodel->trueRows();
84 }
85 
stopEditing()86 void TwinTableMember::stopEditing () {
87 	RK_TRACE (EDITOR);
88 
89 	// I wonder why Qt 4.3 doe not provide a function like this...
90 	if (state () != QAbstractItemView::EditingState) return;
91 
92 	QModelIndex current = currentIndex ();
93 	setCurrentIndex (QModelIndex ());
94 	setCurrentIndex (current);
95 }
96 
copy()97 void TwinTableMember::copy () {
98 	RK_TRACE (EDITOR);
99 
100 	QItemSelectionRange range = getSelectionBoundaries ();
101 	if (range.isValid ()) {
102 		RKTextMatrix mat = mymodel->getTextMatrix (range);
103 		mat.copyToClipboard ();
104 	}
105 }
106 
blankSelected()107 void TwinTableMember::blankSelected () {
108 	RK_TRACE (EDITOR);
109 
110 	if (!rw) return;
111 
112 	QItemSelectionRange range = getSelectionBoundaries ();
113 	if (range.isValid ()) mymodel->blankRange (range);
114 }
115 
paste(RKEditor::PasteMode mode)116 void TwinTableMember::paste (RKEditor::PasteMode mode) {
117 	RK_TRACE (EDITOR);
118 
119 	if (!rw) return;
120 
121 	RKTextMatrix pasted = RKTextMatrix::matrixFromClipboard ();
122 	QItemSelectionRange selrange = getSelectionBoundaries ();
123 	QItemSelectionRange limrange;
124 	if (mode == RKEditor::PasteToSelection) {
125 		limrange = selrange;
126 	} else if (mode == RKEditor::PasteToTable) {
127 		limrange = QItemSelectionRange (mymodel->index (0, 0), mymodel->index (mymodel->trueRows () - 1, mymodel->trueCols () - 1));
128 	} // else: range not set means not confined = PasteAnywhere
129 	mymodel->setTextMatrix (selrange.topLeft (), pasted, limrange);
130 }
131 
scrollContentsBy(int dx,int dy)132 void TwinTableMember::scrollContentsBy (int dx, int dy) {
133 	RK_TRACE (EDITOR);
134 
135 	if (updating_twin) return;
136 	updating_twin = true;
137 	RK_ASSERT (twin);
138 	QTableView::scrollContentsBy (dx, dy);
139 	twin->horizontalScrollBar ()->setValue (horizontalScrollBar ()->value ());
140 	updating_twin = false;
141 }
142 
updateColWidth(int section,int,int new_w)143 void TwinTableMember::updateColWidth (int section, int, int new_w) {
144 	RK_TRACE (EDITOR);
145 
146 	if (updating_twin) return;
147 	updating_twin = true;
148 	setColumnWidth (section, new_w);
149 	twin->setColumnWidth (section, new_w);
150 	updating_twin = false;
151 }
152 
handleContextMenuRequest(const QPoint & pos)153 void TwinTableMember::handleContextMenuRequest (const QPoint& pos) {
154 	RK_TRACE (EDITOR);
155 
156 	if (sender () == horizontalHeader ()) {
157 		int col = horizontalHeader ()->logicalIndexAt (pos);
158 		if (col >= 0) emit (contextMenuRequest (-1, col, horizontalHeader ()->mapToGlobal (pos)));
159 	} else if (sender () == verticalHeader ()) {
160 		int row = verticalHeader ()->logicalIndexAt (pos);
161 		if (row >= 0) emit (contextMenuRequest (row, -1, verticalHeader ()->mapToGlobal (pos)));
162 	} else {
163 		RK_ASSERT (sender () == this);
164 
165 		int col = columnAt (pos.x ());
166 		int row = rowAt (pos.y ());
167 		if ((row < 0) || (col < 0)) {
168 			row = col = -2;	// to differentiate from the headers, above
169 		}
170 		emit (contextMenuRequest (row, col, mapToGlobal (pos)));
171 	}
172 }
173 
174