]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/TocWidget.cpp
rename buffer parameter math_number_before to math_numbering_side
[lyx.git] / src / frontends / qt4 / TocWidget.cpp
index 0822c8bd70dc3c1948d4d67a4fa8f4bbc2a32c78..b96a7c644cfc97e657066f6823c51f02e4ddc852 100644 (file)
@@ -35,7 +35,6 @@
 
 #include <QHeaderView>
 #include <QMenu>
-#include <QTimer>
 
 #include <vector>
 
@@ -45,15 +44,23 @@ 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),
+         timer_(new QTimer(this))
 {
        setupUi(this);
 
-       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")));
+       moveOutTB->setIcon(QIcon(getPixmap("images/", "outline-out", "svgz,png")));
+       moveInTB->setIcon(QIcon(getPixmap("images/", "outline-in", "svgz,png")));
+       moveUpTB->setIcon(QIcon(getPixmap("images/", "outline-up", "svgz,png")));
+       moveDownTB->setIcon(QIcon(getPixmap("images/", "outline-down", "svgz,png")));
+       updateTB->setIcon(QIcon(getPixmap("images/", "reload", "svgz,png")));
+
+       QSize icon_size = gui_view.iconSize();
+       moveOutTB->setIconSize(icon_size);
+       moveInTB->setIconSize(icon_size);
+       moveUpTB->setIconSize(icon_size);
+       moveDownTB->setIconSize(icon_size);
+       updateTB->setIconSize(icon_size);
 
        // avoid flickering
        tocTV->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
@@ -68,6 +75,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,9 +90,13 @@ 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)), 
+       connect(filterLE, SIGNAL(textEdited(QString)),
                this, SLOT(filterContents()));
 
+       // setting the update timer
+       timer_->setSingleShot(true);
+       connect(timer_, SIGNAL(timeout()), this, SLOT(finishUpdateView()));
+
        init(QString());
 }
 
@@ -94,7 +106,7 @@ 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; 
+               return;
        menu->exec(mapToGlobal(pos));
 }
 
@@ -105,9 +117,9 @@ Inset * TocWidget::itemInset() const
        TocItem const & item =
                gui_view_.tocModels().currentItem(current_type_, index);
        DocIterator const & dit = item.dit();
-       
+
        Inset * inset = 0;
-       if (current_type_ == "label" 
+       if (current_type_ == "label"
                  || current_type_ == "graphics"
                  || current_type_ == "citation"
                  || current_type_ == "child")
@@ -115,16 +127,12 @@ Inset * TocWidget::itemInset() const
 
        else if (current_type_ == "branch"
                         || current_type_ == "index"
-                        || current_type_ == "change")
+                        || current_type_ == "change"
+                        || current_type_ == "table"
+                    || current_type_ == "listing"
+                    || current_type_ == "figure")
                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;
 }
 
@@ -139,7 +147,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:
@@ -148,14 +156,15 @@ bool TocWidget::getStatus(Cursor & cur, FuncRequest const & cmd,
        case LFUN_OUTLINE_IN:
        case LFUN_OUTLINE_OUT:
        case LFUN_SECTION_SELECT:
-               status.setEnabled(true);
+               status.setEnabled((bool)item.dit());
                return true;
 
-       case LFUN_LABEL_COPY_AS_REF: {
+       case LFUN_LABEL_COPY_AS_REFERENCE: {
                // For labels in math, we need to supply the label as a string
-               FuncRequest label_copy(LFUN_LABEL_COPY_AS_REF, item.asString());
+               FuncRequest label_copy(LFUN_LABEL_COPY_AS_REFERENCE, item.str());
                if (inset)
                        return inset->getStatus(cur, label_copy, status);
+               break;
        }
 
        default:
@@ -179,28 +188,35 @@ void TocWidget::doDispatch(Cursor & cur, FuncRequest const & cmd)
        // Start an undo group.
        cur.beginUndoGroup();
 
-       switch (cmd.action)
+       switch (cmd.action())
        {
        case LFUN_CHANGE_ACCEPT:
        case LFUN_CHANGE_REJECT:
+               dispatch(item.action());
+               cur.dispatch(tmpcmd);
+               break;
+
        case LFUN_SECTION_SELECT:
                dispatch(item.action());
                cur.dispatch(tmpcmd);
+               // necessary to get the selection drawn.
+               cur.buffer()->changed(true);
+               gui_view_.setFocus();
                break;
 
-       case LFUN_LABEL_COPY_AS_REF: {
+       case LFUN_LABEL_COPY_AS_REFERENCE: {
                // For labels in math, we need to supply the label as a string
-               FuncRequest label_copy(LFUN_LABEL_COPY_AS_REF, item.asString());
+               FuncRequest label_copy(LFUN_LABEL_COPY_AS_REFERENCE, item.str());
                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);
+               outline(cmd.action());
                break;
 
        default:
@@ -223,6 +239,7 @@ void TocWidget::on_tocTV_pressed(QModelIndex const & index)
        if (button & Qt::LeftButton) {
                goTo(index);
                gui_view_.setFocus();
+               gui_view_.activateWindow();
        }
 }
 
@@ -241,14 +258,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();
+       updateViewNow();
 }
 
 
@@ -258,6 +275,7 @@ void TocWidget::on_persistentCB_stateChanged(int state)
 }
 
 
+#if 0
 /* 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
@@ -270,7 +288,7 @@ static int indexDepth(QModelIndex const & index, int depth = -1)
        return index.parent() == QModelIndex()
                ? depth : indexDepth(index.parent(), depth);
 }
-
+#endif
 
 void TocWidget::on_depthSL_valueChanged(int depth)
 {
@@ -287,47 +305,32 @@ 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),
-               Qt::DisplayRole, "*", -1,
-               Qt::MatchFlags(Qt::MatchWildcard|Qt::MatchRecursive));
-
-       int size = indices.size();
-       for (int i = 0; i < size; i++) {
-               QModelIndex index = indices[i];
-               tocTV->setExpanded(index, indexDepth(index) < depth_);
-       }
-#endif
 }
 
 
 void TocWidget::on_typeCO_currentIndexChanged(int index)
 {
+       if (index == -1)
+               return;
        current_type_ = typeCO->itemData(index).toString();
-       updateView();
-       gui_view_.setFocus();
+       updateViewNow();
+       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<FuncCode>(func_code)));
+       dispatch(FuncRequest(func_code));
        enableControls(true);
        gui_view_.setFocus();
 }
@@ -387,25 +390,21 @@ void TocWidget::enableControls(bool enable)
 void TocWidget::updateView()
 {
        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);
+               setEnabled(false);
                return;
        }
+       setEnabled(true);
        bool const is_sortable = isSortable();
        sortCB->setEnabled(is_sortable);
-       depthSL->setEnabled(true);
-       typeCO->setEnabled(true);
+       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);
@@ -418,8 +417,7 @@ void TocWidget::updateView()
                && gui_view_.tocModels().isSorted(current_type_));
        sortCB->blockSignals(false);
 
-       bool const can_navigate_ = canNavigate();
-       persistentCB->setEnabled(can_navigate_);
+       persistentCB->setEnabled(canNavigate());
 
        bool controls_enabled = toc_model && toc_model->rowCount() > 0
                && !gui_view_.documentBufferView()->buffer().isReadonly();
@@ -427,20 +425,52 @@ void TocWidget::updateView()
 
        depthSL->setMaximum(gui_view_.tocModels().depth(current_type_));
        depthSL->setValue(depth_);
-       if (!persistent_ && can_navigate_)
-               setTreeDepth(depth_);
-       if (can_navigate_) {
+       tocTV->setEnabled(true);
+       tocTV->setUpdatesEnabled(true);
+       if (focus)
+               tocTV->setFocus();
+
+       // Expensive operations are on a timer.  We finish the update immediately
+       // for sparse edition actions, i.e. there was no edition/cursor movement
+       // recently, then every 300ms.
+       if (!timer_->isActive()) {
+               finishUpdateView();
+               timer_->start(300);
+       }
+}
+
+
+void TocWidget::updateViewNow()
+{
+       timer_->stop();
+       updateView();
+}
+
+
+void TocWidget::finishUpdateView()
+{
+       // Profiling shows that this is the expensive stuff in the context of typing
+       // text and moving with arrows. For bigger operations, this is negligible,
+       // and outweighted by TocModels::reset() anyway.
+       if (canNavigate()) {
+               if (!persistent_)
+                       setTreeDepth(depth_);
                persistentCB->setChecked(persistent_);
-               select(gui_view_.tocModels().currentIndex(current_type_));
+               // select the item at current cursor location
+               if (gui_view_.documentBufferView()) {
+                       DocIterator const & dit = gui_view_.documentBufferView()->cursor();
+                       select(gui_view_.tocModels().currentIndex(current_type_, dit));
+               }
        }
        filterContents();
-       tocTV->setEnabled(true);
-       tocTV->setUpdatesEnabled(true);
 }
 
 
 void TocWidget::filterContents()
 {
+       if (!tocTV->model())
+               return;
+
        QModelIndexList indices = tocTV->model()->match(
                tocTV->model()->index(0, 0),
                Qt::DisplayRole, "*", -1,
@@ -451,10 +481,10 @@ void TocWidget::filterContents()
                QModelIndex index = indices[i];
                bool const matches =
                        index.data().toString().contains(
-                               filterLE->text(), Qt::CaseSensitive);
+                               filterLE->text(), Qt::CaseInsensitive);
                tocTV->setRowHidden(index.row(), index.parent(), !matches);
        }
-       // recursively unhide parents of unhidden children 
+       // 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())
@@ -468,9 +498,11 @@ void TocWidget::filterContents()
 static QString decodeType(QString const & str)
 {
        QString type = str;
-       if (type.contains("tableofcontents")) {
+       if (type.contains("tableofcontents"))
                type = "tableofcontents";
-       } else if (type.contains("floatlist")) {
+       else if (type.contains("lstlistoflistings"))
+               type = "listing";
+       else if (type.contains("floatlist")) {
                if (type.contains("\"figure"))
                        type = "figure";
                else if (type.contains("\"table"))
@@ -491,7 +523,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_);
@@ -502,6 +534,7 @@ void TocWidget::init(QString const & str)
        typeCO->blockSignals(true);
        typeCO->setCurrentIndex(new_index);
        typeCO->blockSignals(false);
+       updateViewNow();
 }
 
 } // namespace frontend