]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/TocWidget.cpp
fix problem reported by Uwe
[lyx.git] / src / frontends / qt4 / TocWidget.cpp
1 /**
2  * \file TocWidget.cpp
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         enableControls(false);
133         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
134         if (!list.isEmpty()) {
135                 enableControls(false);
136                 form_->goTo(typeCO->currentIndex(), list[0]);
137                 form_->outlineUp();
138                 enableControls(true);
139         }
140 }
141
142
143 void TocWidget::on_moveDownPB_clicked()
144 {
145         enableControls(false);
146         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
147         if (!list.isEmpty()) {
148                 enableControls(false);
149                 form_->goTo(typeCO->currentIndex(), list[0]);
150                 form_->outlineDown();
151                 enableControls(true);
152         }
153 }
154
155
156 void TocWidget::on_moveInPB_clicked()
157 {
158         enableControls(false);
159         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
160         if (!list.isEmpty()) {
161                 enableControls(false);
162                 form_->goTo(typeCO->currentIndex(), list[0]);
163                 form_->outlineIn();
164                 enableControls(true);
165         }
166 }
167
168
169 void TocWidget::on_moveOutPB_clicked()
170 {
171         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
172         if (!list.isEmpty()) {
173                 enableControls(false);
174                 form_->goTo(typeCO->currentIndex(), list[0]);
175                 form_->outlineOut();
176                 enableControls(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::enableControls(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         depthSL->setEnabled(enable);
210 }
211
212
213 void TocWidget::update()
214 {
215         LYXERR(Debug::GUI) << "In TocWidget::update()" << endl;
216         select(form_->getCurrentIndex(typeCO->currentIndex()));
217         QWidget::update();
218 }
219
220
221 void TocWidget::updateGui()
222 {
223         QStringListModel * type_model = form_->typeModel();
224         if (type_model->stringList().isEmpty()) {
225                 enableControls(false);
226                 typeCO->setModel(type_model);
227                 tocTV->setModel(new QStandardItemModel);
228                 tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
229                 return;
230         }
231
232         QString current_text = typeCO->currentText();
233         typeCO->setModel(type_model);
234         int const current_type = typeCO->findText(current_text);
235         if (current_type != -1)
236                 typeCO->setCurrentIndex(current_type);
237         else
238                 typeCO->setCurrentIndex(form_->selectedType());
239
240         setTocModel(typeCO->currentIndex());
241 }
242
243
244 void TocWidget::setTocModel(size_t type)
245 {
246         bool controls_enabled = false;
247         QStandardItemModel * toc_model = form_->tocModel(type);
248         if (toc_model) {
249                 controls_enabled = toc_model->rowCount() > 0;
250                 tocTV->setModel(toc_model);
251                 tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
252         }
253
254         enableControls(controls_enabled);
255
256         reconnectSelectionModel();
257
258         if (controls_enabled) {
259                 depthSL->setMaximum(form_->getTocDepth(type));
260                 depthSL->setValue(depth_);
261         }
262
263         LYXERR(Debug::GUI) << "In TocWidget::updateGui()" << endl;
264
265         select(form_->getCurrentIndex(typeCO->currentIndex()));
266
267         if (toc_model) {
268                 LYXERR(Debug::GUI)
269                 << "form_->tocModel()->rowCount " 
270                         << toc_model->rowCount()
271                         << "\nform_->tocModel()->columnCount "
272                         << toc_model->columnCount()
273                         << endl;
274         }
275 }
276
277
278 void TocWidget::reconnectSelectionModel()
279 {
280         connect(tocTV->selectionModel(),
281                 SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)),
282                 this, SLOT(selectionChanged(const QModelIndex &, const QModelIndex &)));
283 }
284
285 } // namespace frontend
286 } // namespace lyx
287
288 #include "TocWidget_moc.cpp"