]> git.lyx.org Git - features.git/blob - src/frontends/qt4/TocWidget.C
Cleanup of the Toc model and controller: The objective is to let the View (TocWidget...
[features.git] / src / frontends / qt4 / TocWidget.C
1 /**
2  * \file TocWidget.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  * \author Abdelrazak Younes
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "TocWidget.h"
15
16 #include "QToc.h"
17 #include "qt_helpers.h"
18
19 #include "debug.h"
20
21 #include <QHeaderView>
22 #include <QPushButton>
23 #include <QTreeWidgetItem>
24
25 #include <vector>
26 #include <string>
27 #include <stack>
28
29 using std::endl;
30 using std::pair;
31 using std::stack;
32 using std::vector;
33 using std::string;
34
35
36 namespace lyx {
37 namespace frontend {
38
39
40 TocWidget::TocWidget(QToc * form, QWidget * parent)
41         : QWidget(parent), form_(form), depth_(0)
42 {
43         setupUi(this);
44
45         connect(form, SIGNAL(modelReset()),
46                 SLOT(updateGui()));
47
48         // avoid flickering
49         tocTV->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
50
51         tocTV->showColumn(0);
52
53         // hide the pointless QHeader for now
54         // in the future, new columns may appear
55         // like labels, bookmarks, etc...
56         // tocTV->header()->hide();
57         tocTV->header()->setVisible(false);
58 }
59
60
61 void TocWidget::selectionChanged(const QModelIndex & current,
62                                   const QModelIndex & /*previous*/)
63 {
64         lyxerr[Debug::GUI]
65                 << "selectionChanged index " << current.row()
66                 << ", " << current.column()
67                 << endl;
68
69         form_->goTo(typeCO->currentIndex(), current);
70 }
71
72
73 void TocWidget::on_updatePB_clicked()
74 {
75         form_->updateBackend();
76         form_->update();
77         update();
78 }
79
80 /* FIXME (Ugras 17/11/06):
81 I have implemented a getIndexDepth function to get the model indices. In my
82 opinion, somebody should derive a new qvariant class for tocModelItem
83 which saves the string data and depth information. that will save the
84 depth calculation.
85 */
86 int TocWidget::getIndexDepth(QModelIndex const & index, int depth)
87 {
88         ++depth;
89         return (index.parent() == QModelIndex())? depth : getIndexDepth(index.parent(),depth);
90 }
91
92
93 void TocWidget::on_depthSL_valueChanged(int depth)
94 {
95         if (depth == depth_)
96                 return;
97         setTreeDepth(depth);
98 }
99
100
101 void TocWidget::setTreeDepth(int depth)
102 {
103         depth_ = depth;
104
105         // expanding and then collapsing is probably better, 
106         // but my qt 4.1.2 doesn't have expandAll()..
107         //tocTV->expandAll(); 
108         QModelIndexList indices = tocTV->model()->match(
109                 tocTV->model()->index(0,0),
110                 Qt::DisplayRole, "*", -1, 
111                 Qt::MatchWildcard|Qt::MatchRecursive);
112         
113         int size = indices.size();
114         for (int i = 0; i < size; i++) {
115                 QModelIndex index = indices[i];
116                 if (getIndexDepth(index) < depth_) 
117                         tocTV->expand(index); 
118                 else
119                         tocTV->collapse(index); 
120         }
121 }
122
123
124 void TocWidget::on_typeCO_activated(int value)
125 {
126         setTocModel(value);
127 }
128
129
130 void TocWidget::on_moveUpPB_clicked()
131 {
132         enableButtons(false);
133         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
134         if (!list.isEmpty()) {
135                 enableButtons(false);
136                 form_->goTo(typeCO->currentIndex(), list[0]);
137                 form_->outlineUp();
138                 enableButtons(true);
139         }
140 }
141
142
143 void TocWidget::on_moveDownPB_clicked()
144 {
145         enableButtons(false);
146         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
147         if (!list.isEmpty()) {
148                 enableButtons(false);
149                 form_->goTo(typeCO->currentIndex(), list[0]);
150                 form_->outlineDown();
151                 enableButtons(true);
152         }
153 }
154
155
156 void TocWidget::on_moveInPB_clicked()
157 {
158         enableButtons(false);
159         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
160         if (!list.isEmpty()) {
161                 enableButtons(false);
162                 form_->goTo(typeCO->currentIndex(), list[0]);
163                 form_->outlineIn();
164                 enableButtons(true);
165         }
166 }
167
168
169 void TocWidget::on_moveOutPB_clicked()
170 {
171         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
172         if (!list.isEmpty()) {
173                 enableButtons(false);
174                 form_->goTo(typeCO->currentIndex(), list[0]);
175                 form_->outlineOut();
176                 enableButtons(true);
177         }
178 }
179
180
181 void TocWidget::select(QModelIndex const & index)
182 {
183         if (!index.isValid()) {
184                 lyxerr[Debug::GUI]
185                         << "TocWidget::select(): QModelIndex is invalid!" << endl;
186                 return;
187         }
188
189         tocTV->selectionModel()->blockSignals(true);
190         tocTV->scrollTo(index);
191         tocTV->selectionModel()->setCurrentIndex(index,
192                 QItemSelectionModel::ClearAndSelect);
193         tocTV->selectionModel()->blockSignals(false);
194 }
195
196
197 void TocWidget::enableButtons(bool enable)
198 {
199         updatePB->setEnabled(enable);
200
201         if (!form_->canOutline(typeCO->currentIndex()))
202                 enable = false;
203
204         moveUpPB->setEnabled(enable);
205         moveDownPB->setEnabled(enable);
206         moveInPB->setEnabled(enable);
207         moveOutPB->setEnabled(enable);
208 }
209
210
211 void TocWidget::update()
212 {
213         lyxerr[Debug::GUI] << "In TocWidget::update()" << endl;
214         select(form_->getCurrentIndex(typeCO->currentIndex()));
215         QWidget::update();
216 }
217
218
219 void TocWidget::updateGui()
220 {
221         QStringListModel * type_model = form_->typeModel();
222         if (type_model->stringList().isEmpty()) {
223                 enableButtons(false);
224                 typeCO->setModel(type_model);
225                 tocTV->setModel(new QStandardItemModel);
226                 tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
227                 depthSL->setEnabled(false);
228                 return;
229         }
230
231         QString current_text = typeCO->currentText();
232         typeCO->setModel(type_model);
233         int const current_type = typeCO->findText(current_text);
234         if (current_type != -1)
235                 typeCO->setCurrentIndex(current_type);
236         else
237                 typeCO->setCurrentIndex(form_->selectedType());
238
239         setTocModel(typeCO->currentIndex());
240 }
241
242
243 void TocWidget::setTocModel(size_t type)
244 {
245         bool buttons_enabled = false;
246         QStandardItemModel * toc_model = form_->tocModel(type);
247         if (toc_model) {
248                 buttons_enabled = toc_model->rowCount() > 0;
249                 tocTV->setModel(toc_model);
250                 tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
251         }
252
253         enableButtons(buttons_enabled);
254
255         reconnectSelectionModel();
256         depthSL->setEnabled(true);
257         depthSL->setMaximum(form_->getTocDepth(type));
258         depthSL->setValue(depth_);
259
260         lyxerr[Debug::GUI] << "In TocWidget::updateGui()" << endl;
261
262         select(form_->getCurrentIndex(typeCO->currentIndex()));
263
264         if (toc_model) {
265                 lyxerr[Debug::GUI]
266                 << "form_->tocModel()->rowCount " 
267                         << toc_model->rowCount()
268                         << "\nform_->tocModel()->columnCount "
269                         << toc_model->columnCount()
270                         << endl;
271         }
272 }
273
274
275 void TocWidget::reconnectSelectionModel()
276 {
277         connect(tocTV->selectionModel(),
278                 SIGNAL(currentChanged(const QModelIndex &,
279                         const QModelIndex &)),
280                 this, SLOT(selectionChanged(const QModelIndex &,
281                         const QModelIndex &)));
282 }
283
284 } // namespace frontend
285 } // namespace lyx
286
287 #include "TocWidget_moc.cpp"