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