]> git.lyx.org Git - lyx.git/blob - src/frontends/qt4/TocWidget.cpp
use "real" resources
[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 "GuiToc.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
27 using std::endl;
28 using std::vector;
29
30
31 namespace lyx {
32 namespace frontend {
33
34 TocWidget::TocWidget(GuiToc & form, QWidget * parent)
35         : QWidget(parent), depth_(0), form_(form)
36 {
37         setupUi(this);
38         setWindowTitle(qt_("Outline"));
39
40         connect(&form_, SIGNAL(modelReset()), SLOT(updateGui()));
41
42         moveOutTB->setIcon(QIcon(":/images/promote.png"));
43         moveInTB->setIcon(QIcon(":/images/demote.png"));
44         moveUpTB->setIcon(QIcon(":/images/up.png"));
45         moveDownTB->setIcon(QIcon(":/images/down.png"));
46         updateTB->setIcon(QIcon(":/images/reload.png"));
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         // Only one item selected at a time.
60         tocTV->setSelectionMode(QAbstractItemView::SingleSelection);
61 }
62
63
64 void TocWidget::selectionChanged(const QModelIndex & current,
65                                   const QModelIndex & /*previous*/)
66 {
67         LYXERR(Debug::GUI)
68                 << "selectionChanged index " << current.row()
69                 << ", " << current.column()
70                 << endl;
71
72         form_.goTo(typeCO->currentIndex(), current);
73 }
74
75
76 void TocWidget::on_updateTB_clicked()
77 {
78         // The backend update can take some time so we disable
79         // the controls while waiting.
80         enableControls(false);
81         form_.updateBackend();
82 }
83
84 /* FIXME (Ugras 17/11/06):
85 I have implemented a getIndexDepth function to get the model indices. In my
86 opinion, somebody should derive a new qvariant class for tocModelItem
87 which saves the string data and depth information. that will save the
88 depth calculation.
89 */
90 int TocWidget::getIndexDepth(QModelIndex const & index, int depth)
91 {
92         ++depth;
93         return (index.parent() == QModelIndex())
94                 ? depth : getIndexDepth(index.parent(),depth);
95 }
96
97
98 void TocWidget::on_depthSL_valueChanged(int depth)
99 {
100         if (depth == depth_)
101                 return;
102         setTreeDepth(depth);
103 }
104
105
106 void TocWidget::setTreeDepth(int depth)
107 {
108         depth_ = depth;
109
110         // expanding and then collapsing is probably better,
111         // but my qt 4.1.2 doesn't have expandAll()..
112         //tocTV->expandAll();
113         QModelIndexList indices = tocTV->model()->match(
114                 tocTV->model()->index(0,0),
115                 Qt::DisplayRole, "*", -1,
116                 Qt::MatchFlags(Qt::MatchWildcard|Qt::MatchRecursive));
117
118         int size = indices.size();
119         for (int i = 0; i < size; i++) {
120                 QModelIndex index = indices[i];
121                 if (getIndexDepth(index) < depth_)
122                         tocTV->expand(index);
123                 else
124                         tocTV->collapse(index);
125         }
126 }
127
128 void TocWidget::on_typeCO_currentIndexChanged(int value)
129 {
130         setTocModel(value);
131 }
132
133
134 void TocWidget::on_moveUpTB_clicked()
135 {
136         enableControls(false);
137         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
138         if (!list.isEmpty()) {
139                 enableControls(false);
140                 form_.goTo(typeCO->currentIndex(), list[0]);
141                 form_.outlineUp();
142                 enableControls(true);
143         }
144 }
145
146
147 void TocWidget::on_moveDownTB_clicked()
148 {
149         enableControls(false);
150         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
151         if (!list.isEmpty()) {
152                 enableControls(false);
153                 form_.goTo(typeCO->currentIndex(), list[0]);
154                 form_.outlineDown();
155                 enableControls(true);
156         }
157 }
158
159
160 void TocWidget::on_moveInTB_clicked()
161 {
162         enableControls(false);
163         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
164         if (!list.isEmpty()) {
165                 enableControls(false);
166                 form_.goTo(typeCO->currentIndex(), list[0]);
167                 form_.outlineIn();
168                 enableControls(true);
169         }
170 }
171
172
173 void TocWidget::on_moveOutTB_clicked()
174 {
175         QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
176         if (!list.isEmpty()) {
177                 enableControls(false);
178                 form_.goTo(typeCO->currentIndex(), list[0]);
179                 form_.outlineOut();
180                 enableControls(true);
181         }
182 }
183
184
185 void TocWidget::select(QModelIndex const & index)
186 {
187         if (!index.isValid()) {
188                 LYXERR(Debug::GUI)
189                         << "TocWidget::select(): QModelIndex is invalid!" << endl;
190                 return;
191         }
192
193         disconnectSelectionModel();
194         tocTV->setCurrentIndex(index);
195         tocTV->scrollTo(index);
196         reconnectSelectionModel();
197 }
198
199
200 void TocWidget::enableControls(bool enable)
201 {
202         updateTB->setEnabled(enable);
203
204         if (!form_.canOutline(typeCO->currentIndex()))
205                 enable = false;
206
207         moveUpTB->setEnabled(enable);
208         moveDownTB->setEnabled(enable);
209         moveInTB->setEnabled(enable);
210         moveOutTB->setEnabled(enable);
211
212         depthSL->setEnabled(enable);
213 }
214
215
216 void TocWidget::updateView()
217 {
218         LYXERR(Debug::GUI) << "In TocWidget::updateView()" << endl;
219         select(form_.currentIndex(typeCO->currentIndex()));
220 }
221
222
223 void TocWidget::updateGui()
224 {
225         vector<docstring> const & type_names = form_.typeNames();
226         if (type_names.empty()) {
227                 enableControls(false);
228                 typeCO->clear();
229                 tocTV->setModel(new QStandardItemModel);
230                 tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
231                 return;
232         }
233
234         QString current_text = typeCO->currentText();
235         //lyxerr << "current_text " << fromqstr(current_text) << endl;
236         typeCO->blockSignals(true);
237         typeCO->clear();
238         int current_type = -1;
239         for (size_t i = 0; i != type_names.size(); ++i) {
240                 QString item = toqstr(type_names[i]);
241                 typeCO->addItem(item);
242                 if (item == current_text)
243                         current_type = i;
244         }
245         if (current_type != -1)
246                 typeCO->setCurrentIndex(current_type);
247         else
248                 typeCO->setCurrentIndex(form_.selectedType());
249         typeCO->blockSignals(false);
250
251         setTocModel(typeCO->currentIndex());
252 }
253
254
255 void TocWidget::setTocModel(size_t type)
256 {
257         bool controls_enabled = false;
258         QStandardItemModel * toc_model = form_.tocModel(type);
259         if (toc_model) {
260                 controls_enabled = toc_model->rowCount() > 0;
261                 tocTV->setModel(toc_model);
262                 tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
263         }
264
265         enableControls(controls_enabled);
266
267         reconnectSelectionModel();
268
269         if (controls_enabled) {
270                 depthSL->setMaximum(form_.getTocDepth(type));
271                 depthSL->setValue(depth_);
272         }
273
274         LYXERR(Debug::GUI) << "In TocWidget::updateGui()" << endl;
275
276         select(form_.currentIndex(typeCO->currentIndex()));
277
278         if (toc_model) {
279                 LYXERR(Debug::GUI)
280                 << "tocModel()->rowCount "
281                         << toc_model->rowCount()
282                         << "\nform_->tocModel()->columnCount "
283                         << toc_model->columnCount()
284                         << endl;
285         }
286 }
287
288
289 void TocWidget::reconnectSelectionModel()
290 {
291         connect(tocTV->selectionModel(),
292                 SIGNAL(currentChanged(const QModelIndex &,
293                        const QModelIndex &)),
294                 this,
295                 SLOT(selectionChanged(const QModelIndex &,
296                      const QModelIndex &)));
297 }
298
299 void TocWidget::disconnectSelectionModel()
300 {
301         disconnect(tocTV->selectionModel(),
302                 SIGNAL(currentChanged(QModelIndex, QModelIndex)),
303                 this, SLOT(selectionChanged(QModelIndex, QModelIndex)));
304 }
305
306 } // namespace frontend
307 } // namespace lyx
308
309 #include "TocWidget_moc.cpp"