X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FTocWidget.cpp;h=80c9db97d952a6ab773ca96eca3f0675fbc5f7a8;hb=59e0cb8f85f0d2f985b31532dd3308315659c662;hp=d9ea2d79671733d6be569b48b1b29eb50c52f54c;hpb=184345e4e76c2190efbba69d673968feb22a085e;p=lyx.git diff --git a/src/frontends/qt4/TocWidget.cpp b/src/frontends/qt4/TocWidget.cpp index d9ea2d7967..80c9db97d9 100644 --- a/src/frontends/qt4/TocWidget.cpp +++ b/src/frontends/qt4/TocWidget.cpp @@ -23,7 +23,7 @@ #include "CutAndPaste.h" #include "FuncRequest.h" #include "FuncStatus.h" -#include "LyXFunc.h" +#include "LyX.h" #include "Menus.h" #include "TocBackend.h" @@ -39,13 +39,16 @@ #include +#define DELAY_UPDATE_VIEW + using namespace std; namespace lyx { namespace frontend { TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) - : QWidget(parent), depth_(0), persistent_(false), gui_view_(gui_view) + : QWidget(parent), depth_(0), persistent_(false), gui_view_(gui_view), update_delay_(0) + { setupUi(this); @@ -68,6 +71,7 @@ TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) // Only one item selected at a time. tocTV->setSelectionMode(QAbstractItemView::SingleSelection); + setFocusProxy(tocTV); // The toc types combo won't change its model. typeCO->setModel(gui_view_.tocModels().nameModel()); @@ -82,6 +86,8 @@ TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) this, SLOT(showContextMenu(const QPoint &))); connect(tocTV, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(showContextMenu(const QPoint &))); + connect(filterLE, SIGNAL(textEdited(QString)), + this, SLOT(filterContents())); init(QString()); } @@ -137,7 +143,7 @@ bool TocWidget::getStatus(Cursor & cur, FuncRequest const & cmd, TocItem const & item = gui_view_.tocModels().currentItem(current_type_, index); - switch (cmd.action) + switch (cmd.action()) { case LFUN_CHANGE_ACCEPT: case LFUN_CHANGE_REJECT: @@ -174,7 +180,10 @@ void TocWidget::doDispatch(Cursor & cur, FuncRequest const & cmd) TocItem const & item = gui_view_.tocModels().currentItem(current_type_, index); - switch (cmd.action) + // Start an undo group. + cur.beginUndoGroup(); + + switch (cmd.action()) { case LFUN_CHANGE_ACCEPT: case LFUN_CHANGE_REJECT: @@ -195,13 +204,14 @@ void TocWidget::doDispatch(Cursor & cur, FuncRequest const & cmd) case LFUN_OUTLINE_DOWN: case LFUN_OUTLINE_IN: case LFUN_OUTLINE_OUT: - outline(cmd.action); + outline(cmd.action()); break; default: if (inset) inset->dispatch(cur, tmpcmd); } + cur.endUndoGroup(); } @@ -235,14 +245,14 @@ void TocWidget::on_updateTB_clicked() // The backend update can take some time so we disable // the controls while waiting. enableControls(false); - gui_view_.tocModels().updateBackend(); + gui_view_.currentBufferView()->buffer().updateBuffer(); } void TocWidget::on_sortCB_stateChanged(int state) { gui_view_.tocModels().sort(current_type_, state == Qt::Checked); - updateView(); + updateViewForce(); } @@ -307,21 +317,23 @@ void TocWidget::setTreeDepth(int depth) void TocWidget::on_typeCO_currentIndexChanged(int index) { + if (index == -1) + return; current_type_ = typeCO->itemData(index).toString(); - updateView(); - gui_view_.setFocus(); + updateViewForce(); + if (typeCO->hasFocus()) + gui_view_.setFocus(); } -void TocWidget::outline(int func_code) +void TocWidget::outline(FuncCode func_code) { - enableControls(false); QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes(); if (list.isEmpty()) return; enableControls(false); goTo(list[0]); - dispatch(FuncRequest(static_cast(func_code))); + dispatch(FuncRequest(func_code)); enableControls(true); gui_view_.setFocus(); } @@ -364,18 +376,11 @@ void TocWidget::select(QModelIndex const & index) } -/// Test whether outlining operation is possible -static bool canOutline(QString const & type) -{ - return type == "tableofcontents"; -} - - void TocWidget::enableControls(bool enable) { updateTB->setEnabled(enable); - if (!canOutline(current_type_)) + if (!canOutline()) enable = false; moveUpTB->setEnabled(enable); @@ -385,45 +390,45 @@ void TocWidget::enableControls(bool enable) } -/// Test whether synchronized navigation is possible -static bool canNavigate(QString const & type) -{ - // It is not possible to have synchronous navigation in a correct - // and efficient way with the label and change type because Toc::item() - // does a linear search. Even when fixed, it might even not be desirable - // to do so if we want to support drag&drop of labels and references. - return type != "label" && type != "change"; -} - - -/// Test whether sorting is possible -static bool isSortable(QString const & type) +void TocWidget::updateView() { - return type != "tableofcontents"; +// Enable if you dont want the delaying business, cf #7138. +#ifndef DELAY_UPDATE_VIEW + updateViewForce(); + return; +#endif + // already scheduled? + if (update_delay_ == -1) + return; + QTimer::singleShot(update_delay_, this, SLOT(updateViewForce())); + // Subtler optimization for having the delay more UI invisible. + // We trigger update immediately for sparse editation actions, + // i.e. there was no editation/cursor movement in last 2 sec. + // At worst there will be +1 redraw after 2s in a such "calm" mode. + if (update_delay_ != 0) + updateViewForce(); + update_delay_ = -1; } - -void TocWidget::updateView() +void TocWidget::updateViewForce() { - if (!gui_view_.currentBufferView()) { - enableControls(false); - typeCO->setEnabled(false); + update_delay_ = 2000; + if (!gui_view_.documentBufferView()) { tocTV->setModel(0); - tocTV->setEnabled(false); depthSL->setMaximum(0); depthSL->setValue(0); - persistentCB->setEnabled(false); - sortCB->setEnabled(false); - depthSL->setEnabled(false); + setEnabled(false); return; } - sortCB->setEnabled(isSortable(current_type_)); - depthSL->setEnabled(true); - typeCO->setEnabled(true); + setEnabled(true); + bool const is_sortable = isSortable(); + sortCB->setEnabled(is_sortable); + bool focus_ = tocTV->hasFocus(); tocTV->setEnabled(false); tocTV->setUpdatesEnabled(false); - QAbstractItemModel * toc_model = gui_view_.tocModels().model(current_type_); + QAbstractItemModel * toc_model = + gui_view_.tocModels().model(current_type_); if (tocTV->model() != toc_model) { tocTV->setModel(toc_model); tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers); @@ -432,12 +437,11 @@ void TocWidget::updateView() } sortCB->blockSignals(true); - sortCB->setChecked(isSortable(current_type_) + sortCB->setChecked(is_sortable && gui_view_.tocModels().isSorted(current_type_)); sortCB->blockSignals(false); - - bool const can_navigate_ = canNavigate(current_type_); + bool const can_navigate_ = canNavigate(); persistentCB->setEnabled(can_navigate_); bool controls_enabled = toc_model && toc_model->rowCount() > 0 @@ -452,8 +456,40 @@ void TocWidget::updateView() persistentCB->setChecked(persistent_); select(gui_view_.tocModels().currentIndex(current_type_)); } + filterContents(); tocTV->setEnabled(true); tocTV->setUpdatesEnabled(true); + if (focus_) + tocTV->setFocus(); +} + + +void TocWidget::filterContents() +{ + if (!tocTV->model()) + return; + + QModelIndexList indices = tocTV->model()->match( + tocTV->model()->index(0, 0), + Qt::DisplayRole, "*", -1, + Qt::MatchFlags(Qt::MatchWildcard|Qt::MatchRecursive)); + + int size = indices.size(); + for (int i = 0; i < size; i++) { + QModelIndex index = indices[i]; + bool const matches = + index.data().toString().contains( + filterLE->text(), Qt::CaseInsensitive); + tocTV->setRowHidden(index.row(), index.parent(), !matches); + } + // recursively unhide parents of unhidden children + for (int i = size - 1; i >= 0; i--) { + QModelIndex index = indices[i]; + if (!tocTV->isRowHidden(index.row(), index.parent()) + && index.parent() != QModelIndex()) + tocTV->setRowHidden(index.parent().row(), + index.parent().parent(), false); + } } @@ -483,7 +519,7 @@ void TocWidget::init(QString const & str) new_index = typeCO->findData(decodeType(str)); // If everything else fails, settle on the table of contents which is - // guaranted to exist. + // guaranteed to exist. if (new_index == -1) { current_type_ = "tableofcontents"; new_index = typeCO->findData(current_type_); @@ -494,6 +530,9 @@ void TocWidget::init(QString const & str) typeCO->blockSignals(true); typeCO->setCurrentIndex(new_index); typeCO->blockSignals(false); + + // no delay when the whole outliner is reseted. + update_delay_ = 0; } } // namespace frontend