X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FTocWidget.cpp;h=538c04c177cb894dd2f4045301e7db29fb640087;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=3be6aeb220c1572214128ccec1d41784dde1c826;hpb=6ad1b1cd0968021c7aba0b3358a3e0e860c61ed7;p=lyx.git diff --git a/src/frontends/qt4/TocWidget.cpp b/src/frontends/qt4/TocWidget.cpp index 3be6aeb220..538c04c177 100644 --- a/src/frontends/qt4/TocWidget.cpp +++ b/src/frontends/qt4/TocWidget.cpp @@ -13,17 +13,28 @@ #include "TocWidget.h" +#include "GuiApplication.h" #include "GuiView.h" #include "qt_helpers.h" #include "TocModel.h" +#include "Buffer.h" +#include "BufferView.h" +#include "CutAndPaste.h" #include "FuncRequest.h" +#include "FuncStatus.h" #include "LyXFunc.h" +#include "Menus.h" +#include "TocBackend.h" + +#include "insets/InsetCommand.h" +#include "insets/InsetRef.h" #include "support/debug.h" #include "support/lassert.h" #include +#include #include #include @@ -34,15 +45,15 @@ namespace lyx { namespace frontend { TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) - : QWidget(parent), depth_(0), gui_view_(gui_view) + : QWidget(parent), depth_(0), persistent_(false), gui_view_(gui_view) { setupUi(this); - moveOutTB->setIcon(QIcon(":/images/promote.png")); - moveInTB->setIcon(QIcon(":/images/demote.png")); - moveUpTB->setIcon(QIcon(":/images/up.png")); - moveDownTB->setIcon(QIcon(":/images/down.png")); - updateTB->setIcon(QIcon(":/images/reload.png")); + moveOutTB->setIcon(QIcon(getPixmap("images/", "promote", "png"))); + moveInTB->setIcon(QIcon(getPixmap("images/", "demote", "png"))); + moveUpTB->setIcon(QIcon(getPixmap("images/", "up", "png"))); + moveDownTB->setIcon(QIcon(getPixmap("images/", "down", "png"))); + updateTB->setIcon(QIcon(getPixmap("images/", "reload", "png"))); // avoid flickering tocTV->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); @@ -60,6 +71,141 @@ TocWidget::TocWidget(GuiView & gui_view, QWidget * parent) // The toc types combo won't change its model. typeCO->setModel(gui_view_.tocModels().nameModel()); + + // Make sure the buttons are disabled when first shown without a loaded + // Buffer. + enableControls(false); + + // make us responsible for the context menu of the tabbar + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(showContextMenu(const QPoint &))); + connect(tocTV, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(showContextMenu(const QPoint &))); + + init(QString()); +} + + +void TocWidget::showContextMenu(const QPoint & pos) +{ + std::string name = "context-toc-" + fromqstr(current_type_); + QMenu * menu = guiApp->menus().menu(toqstr(name), gui_view_); + if (!menu) + return; + menu->exec(mapToGlobal(pos)); +} + + +Inset * TocWidget::itemInset() const +{ + QModelIndex const & index = tocTV->currentIndex(); + TocItem const & item = + gui_view_.tocModels().currentItem(current_type_, index); + DocIterator const & dit = item.dit(); + + Inset * inset = 0; + if (current_type_ == "label" + || current_type_ == "graphics" + || current_type_ == "citation" + || current_type_ == "child") + inset = dit.nextInset(); + + else if (current_type_ == "branch" + || current_type_ == "index" + || current_type_ == "change") + inset = &dit.inset(); + + else if (current_type_ == "table" + || current_type_ == "listing" + || current_type_ == "figure") { + DocIterator tmp_dit(dit); + tmp_dit.pop_back(); + inset = &tmp_dit.inset(); + } + return inset; +} + + +bool TocWidget::getStatus(Cursor & cur, FuncRequest const & cmd, + FuncStatus & status) const +{ + Inset * inset = itemInset(); + FuncRequest tmpcmd(cmd); + + QModelIndex const & index = tocTV->currentIndex(); + TocItem const & item = + gui_view_.tocModels().currentItem(current_type_, index); + + switch (cmd.action) + { + case LFUN_CHANGE_ACCEPT: + case LFUN_CHANGE_REJECT: + case LFUN_OUTLINE_UP: + case LFUN_OUTLINE_DOWN: + case LFUN_OUTLINE_IN: + case LFUN_OUTLINE_OUT: + case LFUN_SECTION_SELECT: + status.setEnabled(true); + return true; + + case LFUN_LABEL_COPY_AS_REF: { + // For labels in math, we need to supply the label as a string + FuncRequest label_copy(LFUN_LABEL_COPY_AS_REF, item.asString()); + if (inset) + return inset->getStatus(cur, label_copy, status); + } + + default: + if (inset) + return inset->getStatus(cur, tmpcmd, status); + } + + return false; +} + + +void TocWidget::doDispatch(Cursor & cur, FuncRequest const & cmd) +{ + Inset * inset = itemInset(); + FuncRequest tmpcmd(cmd); + + QModelIndex const & index = tocTV->currentIndex(); + TocItem const & item = + gui_view_.tocModels().currentItem(current_type_, index); + + // Start an undo group. + cur.beginUndoGroup(); + + switch (cmd.action) + { + case LFUN_CHANGE_ACCEPT: + case LFUN_CHANGE_REJECT: + case LFUN_SECTION_SELECT: + dispatch(item.action()); + cur.dispatch(tmpcmd); + break; + + case LFUN_LABEL_COPY_AS_REF: { + // For labels in math, we need to supply the label as a string + FuncRequest label_copy(LFUN_LABEL_COPY_AS_REF, item.asString()); + if (inset) + inset->dispatch(cur, label_copy); + break; + } + + case LFUN_OUTLINE_UP: + case LFUN_OUTLINE_DOWN: + case LFUN_OUTLINE_IN: + case LFUN_OUTLINE_OUT: + outline(cmd.action); + break; + + default: + if (inset) + inset->dispatch(cur, tmpcmd); + } + cur.endUndoGroup(); } @@ -69,10 +215,13 @@ void TocWidget::on_tocTV_activated(QModelIndex const & index) } -void TocWidget::on_tocTV_clicked(QModelIndex const & index) +void TocWidget::on_tocTV_pressed(QModelIndex const & index) { - goTo(index); - gui_view_.setFocus(); + Qt::MouseButtons const button = QApplication::mouseButtons(); + if (button & Qt::LeftButton) { + goTo(index); + gui_view_.setFocus(); + } } @@ -94,6 +243,19 @@ void TocWidget::on_updateTB_clicked() } +void TocWidget::on_sortCB_stateChanged(int state) +{ + gui_view_.tocModels().sort(current_type_, state == Qt::Checked); + updateView(); +} + + +void TocWidget::on_persistentCB_stateChanged(int state) +{ + persistent_ = state == Qt::Checked; +} + + /* FIXME (Ugras 17/11/06): I have implemented a indexDepth function to get the model indices. In my opinion, somebody should derive a new qvariant class for tocModelItem @@ -123,11 +285,18 @@ void TocWidget::setTreeDepth(int depth) if (!tocTV->model()) return; +#if QT_VERSION >= 0x040300 + // this should be faster than our own code below + if (depth == 0) + tocTV->collapseAll(); + else + tocTV->expandToDepth(depth - 1); +#else // expanding and then collapsing is probably better, // but my qt 4.1.2 doesn't have expandAll().. //tocTV->expandAll(); QModelIndexList indices = tocTV->model()->match( - tocTV->model()->index(0,0), + tocTV->model()->index(0, 0), Qt::DisplayRole, "*", -1, Qt::MatchFlags(Qt::MatchWildcard|Qt::MatchRecursive)); @@ -136,6 +305,7 @@ void TocWidget::setTreeDepth(int depth) QModelIndex index = indices[i]; tocTV->setExpanded(index, indexDepth(index) < depth_); } +#endif } @@ -198,7 +368,7 @@ void TocWidget::select(QModelIndex const & index) } -/// Test if outlining operation is possible +/// Test whether outlining operation is possible static bool canOutline(QString const & type) { return type == "tableofcontents"; @@ -216,17 +386,78 @@ void TocWidget::enableControls(bool enable) moveDownTB->setEnabled(enable); moveInTB->setEnabled(enable); moveOutTB->setEnabled(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"; +} - depthSL->setEnabled(enable); + +/// Test whether sorting is possible +static bool isSortable(QString const & type) +{ + return type != "tableofcontents"; } void TocWidget::updateView() { - LYXERR(Debug::GUI, "In TocWidget::updateView()"); - setTocModel(); - setTreeDepth(depth_); - select(gui_view_.tocModels().currentIndex(current_type_)); + if (!gui_view_.documentBufferView()) { + enableControls(false); + typeCO->setEnabled(false); + tocTV->setModel(0); + tocTV->setEnabled(false); + depthSL->setMaximum(0); + depthSL->setValue(0); + persistentCB->setEnabled(false); + sortCB->setEnabled(false); + depthSL->setEnabled(false); + return; + } + sortCB->setEnabled(isSortable(current_type_)); + depthSL->setEnabled(true); + typeCO->setEnabled(true); + tocTV->setEnabled(false); + tocTV->setUpdatesEnabled(false); + + QAbstractItemModel * toc_model = gui_view_.tocModels().model(current_type_); + if (tocTV->model() != toc_model) { + tocTV->setModel(toc_model); + tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers); + if (persistent_) + setTreeDepth(depth_); + } + + sortCB->blockSignals(true); + sortCB->setChecked(isSortable(current_type_) + && gui_view_.tocModels().isSorted(current_type_)); + sortCB->blockSignals(false); + + + bool const can_navigate_ = canNavigate(current_type_); + persistentCB->setEnabled(can_navigate_); + + bool controls_enabled = toc_model && toc_model->rowCount() > 0 + && !gui_view_.documentBufferView()->buffer().isReadonly(); + enableControls(controls_enabled); + + depthSL->setMaximum(gui_view_.tocModels().depth(current_type_)); + depthSL->setValue(depth_); + if (!persistent_ && can_navigate_) + setTreeDepth(depth_); + if (can_navigate_) { + persistentCB->setChecked(persistent_); + select(gui_view_.tocModels().currentIndex(current_type_)); + } + tocTV->setEnabled(true); + tocTV->setUpdatesEnabled(true); } @@ -249,19 +480,6 @@ static QString decodeType(QString const & str) void TocWidget::init(QString const & str) { - if (!gui_view_.view()) { - enableControls(false); - typeCO->setEnabled(false); - tocTV->setModel(0); - tocTV->setEnabled(false); - return; - } - - typeCO->setEnabled(true); - tocTV->setEnabled(true); - - typeCO->blockSignals(true); - int new_index; if (str.isEmpty()) new_index = typeCO->findData(current_type_); @@ -273,32 +491,16 @@ void TocWidget::init(QString const & str) if (new_index == -1) { current_type_ = "tableofcontents"; new_index = typeCO->findData(current_type_); + } else { + current_type_ = typeCO->itemData(new_index).toString(); } + typeCO->blockSignals(true); typeCO->setCurrentIndex(new_index); typeCO->blockSignals(false); } - -void TocWidget::setTocModel() -{ - QStandardItemModel * toc_model = gui_view_.tocModels().model(current_type_); - - if (tocTV->model() != toc_model) { - tocTV->setModel(toc_model); - tocTV->setEditTriggers(QAbstractItemView::NoEditTriggers); - } - - bool controls_enabled = toc_model && toc_model->rowCount() > 0;; - enableControls(controls_enabled); - - if (controls_enabled) { - depthSL->setMaximum(gui_view_.tocModels().depth(current_type_)); - depthSL->setValue(depth_); - } -} - } // namespace frontend } // namespace lyx -#include "TocWidget_moc.cpp" +#include "moc_TocWidget.cpp"