3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Abdelrazak Younes
9 * Full author contact details are available in file CREDITS.
14 #include "TocWidget.h"
16 #include "GuiApplication.h"
18 #include "qt_helpers.h"
22 #include "FuncRequest.h"
25 #include "support/debug.h"
26 #include "support/lassert.h"
28 #include <QHeaderView>
38 TocWidget::TocWidget(GuiView & gui_view, QWidget * parent)
39 : QWidget(parent), depth_(0), persistent_(false), gui_view_(gui_view)
43 moveOutTB->setIcon(QIcon(getPixmap("images/", "promote", "png")));
44 moveInTB->setIcon(QIcon(getPixmap("images/", "demote", "png")));
45 moveUpTB->setIcon(QIcon(getPixmap("images/", "up", "png")));
46 moveDownTB->setIcon(QIcon(getPixmap("images/", "down", "png")));
47 updateTB->setIcon(QIcon(getPixmap("images/", "reload", "png")));
50 tocTV->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
54 // hide the pointless QHeader for now
55 // in the future, new columns may appear
56 // like labels, bookmarks, etc...
57 // tocTV->header()->hide();
58 tocTV->header()->setVisible(false);
60 // Only one item selected at a time.
61 tocTV->setSelectionMode(QAbstractItemView::SingleSelection);
63 // The toc types combo won't change its model.
64 typeCO->setModel(gui_view_.tocModels().nameModel());
66 // Make sure the buttons are disabled when first shown without a loaded
68 enableControls(false);
74 void TocWidget::on_tocTV_activated(QModelIndex const & index)
80 void TocWidget::on_tocTV_pressed(QModelIndex const & index)
82 Qt::MouseButtons const button = QApplication::mouseButtons();
83 if (button & Qt::LeftButton) {
90 void TocWidget::goTo(QModelIndex const & index)
92 LYXERR(Debug::GUI, "goto " << index.row()
93 << ", " << index.column());
95 gui_view_.tocModels().goTo(current_type_, index);
99 void TocWidget::on_updateTB_clicked()
101 // The backend update can take some time so we disable
102 // the controls while waiting.
103 enableControls(false);
104 gui_view_.tocModels().updateBackend();
108 void TocWidget::on_sortCB_stateChanged(int state)
110 gui_view_.tocModels().sort(current_type_, state == Qt::Checked);
114 void TocWidget::on_persistentCB_stateChanged(int state)
116 persistent_ = state == Qt::Checked;
120 /* FIXME (Ugras 17/11/06):
121 I have implemented a indexDepth function to get the model indices. In my
122 opinion, somebody should derive a new qvariant class for tocModelItem
123 which saves the string data and depth information. That will save the
124 depth calculation. */
126 static int indexDepth(QModelIndex const & index, int depth = -1)
129 return index.parent() == QModelIndex()
130 ? depth : indexDepth(index.parent(), depth);
134 void TocWidget::on_depthSL_valueChanged(int depth)
139 gui_view_.setFocus();
143 void TocWidget::setTreeDepth(int depth)
149 #if QT_VERSION >= 0x040300
150 // this should be faster than our own code below
152 tocTV->collapseAll();
154 tocTV->expandToDepth(depth - 1);
156 // expanding and then collapsing is probably better,
157 // but my qt 4.1.2 doesn't have expandAll()..
158 //tocTV->expandAll();
159 QModelIndexList indices = tocTV->model()->match(
160 tocTV->model()->index(0, 0),
161 Qt::DisplayRole, "*", -1,
162 Qt::MatchFlags(Qt::MatchWildcard|Qt::MatchRecursive));
164 int size = indices.size();
165 for (int i = 0; i < size; i++) {
166 QModelIndex index = indices[i];
167 tocTV->setExpanded(index, indexDepth(index) < depth_);
173 void TocWidget::on_typeCO_currentIndexChanged(int index)
175 current_type_ = typeCO->itemData(index).toString();
177 gui_view_.setFocus();
181 void TocWidget::outline(int func_code)
183 enableControls(false);
184 QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
187 enableControls(false);
189 dispatch(FuncRequest(static_cast<FuncCode>(func_code)));
190 enableControls(true);
191 gui_view_.setFocus();
195 void TocWidget::on_moveUpTB_clicked()
197 outline(LFUN_OUTLINE_UP);
201 void TocWidget::on_moveDownTB_clicked()
203 outline(LFUN_OUTLINE_DOWN);
207 void TocWidget::on_moveInTB_clicked()
209 outline(LFUN_OUTLINE_IN);
213 void TocWidget::on_moveOutTB_clicked()
215 outline(LFUN_OUTLINE_OUT);
219 void TocWidget::select(QModelIndex const & index)
221 if (!index.isValid()) {
222 LYXERR(Debug::GUI, "TocWidget::select(): QModelIndex is invalid!");
226 tocTV->scrollTo(index);
227 tocTV->clearSelection();
228 tocTV->setCurrentIndex(index);
232 /// Test if outlining operation is possible
233 static bool canOutline(QString const & type)
235 return type == "tableofcontents";
239 void TocWidget::enableControls(bool enable)
241 updateTB->setEnabled(enable);
243 if (!canOutline(current_type_))
246 moveUpTB->setEnabled(enable);
247 moveDownTB->setEnabled(enable);
248 moveInTB->setEnabled(enable);
249 moveOutTB->setEnabled(enable);
251 depthSL->setMaximum(0);
252 depthSL->setValue(0);
257 /// Test if synchronized navigation is possible
258 static bool canNavigate(QString const & type)
260 // It is not possible to have synchronous navigation in a correctl
261 // and efficient way with the label type because Toc::item() do a linear
262 // seatch. Even if fixed, it might even not be desirable to do so if we
263 // want to support drag&drop of labels and references.
264 return type != "label" && type != "change";
268 void TocWidget::updateView()
270 if (!gui_view_.view()) {
271 enableControls(false);
272 typeCO->setEnabled(false);
274 tocTV->setEnabled(false);
277 typeCO->setEnabled(true);
278 tocTV->setEnabled(false);
279 tocTV->setUpdatesEnabled(false);
281 QAbstractItemModel * toc_model = gui_view_.tocModels().model(current_type_);
282 if (tocTV->model() != toc_model) {
283 tocTV->setModel(toc_model);
284 tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers);
286 setTreeDepth(depth_);
289 sortCB->blockSignals(true);
290 sortCB->setChecked(gui_view_.tocModels().isSorted(current_type_));
291 sortCB->blockSignals(false);
293 persistentCB->setChecked(persistent_);
295 bool controls_enabled = toc_model && toc_model->rowCount() > 0
296 && !gui_view_.buffer()->isReadonly();
297 enableControls(controls_enabled);
299 depthSL->setMaximum(gui_view_.tocModels().depth(current_type_));
300 depthSL->setValue(depth_);
302 setTreeDepth(depth_);
303 if (canNavigate(current_type_))
304 select(gui_view_.tocModels().currentIndex(current_type_));
305 tocTV->setEnabled(true);
306 tocTV->setUpdatesEnabled(true);
310 static QString decodeType(QString const & str)
313 if (type.contains("tableofcontents")) {
314 type = "tableofcontents";
315 } else if (type.contains("floatlist")) {
316 if (type.contains("\"figure"))
318 else if (type.contains("\"table"))
320 else if (type.contains("\"algorithm"))
327 void TocWidget::init(QString const & str)
331 new_index = typeCO->findData(current_type_);
333 new_index = typeCO->findData(decodeType(str));
335 // If everything else fails, settle on the table of contents which is
336 // guaranted to exist.
337 if (new_index == -1) {
338 current_type_ = "tableofcontents";
339 new_index = typeCO->findData(current_type_);
341 current_type_ = typeCO->itemData(new_index).toString();
344 typeCO->blockSignals(true);
345 typeCO->setCurrentIndex(new_index);
346 typeCO->blockSignals(false);
349 } // namespace frontend
352 #include "moc_TocWidget.cpp"