diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 2facee57d4..d75f1730bb 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -49,6 +49,7 @@ #include "ParagraphParameters.h" #include "pariterator.h" #include "rowpainter.h" +#include "toc.h" #include "undo.h" #include "vspace.h" @@ -1042,6 +1043,7 @@ FuncStatus BufferView::Pimpl::getStatus(FuncRequest const & cmd) case LFUN_INSERT_LABEL: case LFUN_BOOKMARK_SAVE: case LFUN_GOTO_PARAGRAPH: + case LFUN_OUTLINE: case LFUN_GOTOERROR: case LFUN_GOTONOTE: case LFUN_REFERENCE_GOTO: @@ -1197,6 +1199,16 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & cmd) break; } + case LFUN_OUTLINE: { + lyx::toc::OutlineOp const op = + static_cast(convert(cmd.argument)); + lyx::toc::Outline(op, buffer_, cursor_.pit()); + bv_->text()->setCursor(cursor_, cursor_.pit(), 0); + buffer_->markDirty(); + updateCounters(*buffer_); + update(); + } + case LFUN_GOTOERROR: bv_funcs::gotoInset(bv_, InsetBase::ERROR_CODE, false); break; diff --git a/src/LyXAction.C b/src/LyXAction.C index 911bef3d4c..8ef336aeee 100644 --- a/src/LyXAction.C +++ b/src/LyXAction.C @@ -240,6 +240,7 @@ void LyXAction::init() { LFUN_DOWN_PARAGRAPH, "paragraph-down", ReadOnly | NoUpdate}, { LFUN_DOWN_PARAGRAPHSEL, "paragraph-down-select", ReadOnly }, { LFUN_GOTO_PARAGRAPH, "paragraph-goto", ReadOnly }, + { LFUN_OUTLINE, "outline", ReadOnly }, { LFUN_PARAGRAPH_SPACING, "paragraph-spacing", Noop }, { LFUN_UP_PARAGRAPH, "paragraph-up", ReadOnly | NoUpdate}, { LFUN_UP_PARAGRAPHSEL, "paragraph-up-select", ReadOnly }, diff --git a/src/frontends/controllers/ControlToc.C b/src/frontends/controllers/ControlToc.C index f64cb4ad62..a931d66aba 100644 --- a/src/frontends/controllers/ControlToc.C +++ b/src/frontends/controllers/ControlToc.C @@ -8,9 +8,12 @@ * Full author contact details are available in file CREDITS. */ +#include + #include #include "ControlToc.h" +#include "funcrequest.h" #include "gettext.h" using std::vector; @@ -34,6 +37,14 @@ void ControlToc::goTo(toc::TocItem const & item) } +void ControlToc::outline(toc::OutlineOp op) +{ + std::ostringstream o; + o << op << std::flush; + kernel().dispatch(FuncRequest(LFUN_OUTLINE, o.str())); +} + + vector const ControlToc::getTypes() const { return toc::getTypes(kernel().buffer()); diff --git a/src/frontends/controllers/ControlToc.h b/src/frontends/controllers/ControlToc.h index f71751c2fe..d812d34e8c 100644 --- a/src/frontends/controllers/ControlToc.h +++ b/src/frontends/controllers/ControlToc.h @@ -38,6 +38,9 @@ public: /// Given a type, returns the contents toc::Toc const getContents(std::string const & type) const; + + /// Apply the selected outlining operation + void outline(toc::OutlineOp op); }; } // namespace frontend diff --git a/src/frontends/qt2/QToc.C b/src/frontends/qt2/QToc.C index b3c5f79827..5b0dc68f39 100644 --- a/src/frontends/qt2/QToc.C +++ b/src/frontends/qt2/QToc.C @@ -107,7 +107,9 @@ void QToc::updateToc(int newdepth) QListViewItem * last = 0; QListViewItem * parent = 0; QListViewItem * item; - + QListViewItem * selected_item = 0; + bool multiple = false; + // Yes, it is this ugly. Two reasons - root items must have // a QListView parent, rather than QListViewItem; and the // TOC can move in and out an arbitrary number of levels @@ -157,10 +159,24 @@ void QToc::updateToc(int newdepth) item->setOpen(iter->depth < depth_); curdepth = iter->depth; last = item; + + // Recognise part past the counter + if (iter->str.substr(iter->str.find(' ') + 1) == text_) { + if (selected_item == 0) + selected_item = item; + else + // more than one match + multiple = true; + } } dialog_->tocLV->setUpdatesEnabled(true); dialog_->tocLV->update(); + if (!multiple) { + dialog_->tocLV->ensureItemVisible(selected_item); + dialog_->tocLV->setSelected(selected_item, true); + dialog_->tocLV->scrollBy(0, dialog_->tocLV->height() / 2); + } setTitle(fromqstr(dialog_->typeCO->currentText())); } @@ -180,6 +196,8 @@ void QToc::select(string const & text) return; } + // Lop off counter part and save: + text_ = text.substr(text.find(' ') + 1); controller().goTo(*iter); } @@ -190,5 +208,34 @@ void QToc::set_depth(int depth) updateToc(depth); } + +void QToc::moveup() +{ + controller().outline(toc::UP); + update_contents(); +} + + +void QToc::movedn() +{ + controller().outline(toc::DOWN); + update_contents(); +} + + +void QToc::movein() +{ + controller().outline(toc::IN); + update_contents(); +} + + +void QToc::moveout() +{ + controller().outline(toc::OUT); + update_contents(); +} + + } // namespace frontend } // namespace lyx diff --git a/src/frontends/qt2/QToc.h b/src/frontends/qt2/QToc.h index 09c6b69a25..fe1c3a9100 100644 --- a/src/frontends/qt2/QToc.h +++ b/src/frontends/qt2/QToc.h @@ -42,6 +42,15 @@ private: /// set the depth void set_depth(int depth); + /// Move header up/down/in/out in list (outlining) + void moveup(); + /// + void movedn(); + /// + void movein(); + /// + void moveout(); + virtual void apply() {} /// update dialog @@ -55,6 +64,9 @@ private: /// depth of list shown int depth_; + + /// Store selected item's string + std::string text_; }; } // namespace frontend diff --git a/src/frontends/qt2/QTocDialog.C b/src/frontends/qt2/QTocDialog.C index 0e92d89378..d125e1bf94 100644 --- a/src/frontends/qt2/QTocDialog.C +++ b/src/frontends/qt2/QTocDialog.C @@ -32,8 +32,11 @@ QTocDialog::QTocDialog(QToc * form) if (w) w->hide(); - connect(closePB, SIGNAL(clicked()), - form, SLOT(slotClose())); + connect(closePB, SIGNAL(clicked()), form, SLOT(slotClose())); + connect(moveupPB, SIGNAL(clicked()), this, SLOT(moveup_adaptor())); + connect(movednPB, SIGNAL(clicked()), this, SLOT(movedn_adaptor())); + connect(moveinPB, SIGNAL(clicked()), this, SLOT(movein_adaptor())); + connect(moveoutPB, SIGNAL(clicked()), this, SLOT(moveout_adaptor())); } @@ -66,6 +69,30 @@ void QTocDialog::update_adaptor() } +void QTocDialog::moveup_adaptor() +{ + form_->moveup(); +} + + +void QTocDialog::movedn_adaptor() +{ + form_->movedn(); +} + + +void QTocDialog::movein_adaptor() +{ + form_->movein(); +} + + +void QTocDialog::moveout_adaptor() +{ + form_->moveout(); +} + + void QTocDialog::closeEvent(QCloseEvent * e) { form_->slotWMHide(); diff --git a/src/frontends/qt2/QTocDialog.h b/src/frontends/qt2/QTocDialog.h index d028d8131c..875a17db0b 100644 --- a/src/frontends/qt2/QTocDialog.h +++ b/src/frontends/qt2/QTocDialog.h @@ -29,6 +29,10 @@ public slots: void depth_adaptor(int); void select_adaptor(QListViewItem *); void update_adaptor(); + void moveup_adaptor(); + void movedn_adaptor(); + void movein_adaptor(); + void moveout_adaptor(); protected: void closeEvent(QCloseEvent * e); private: diff --git a/src/frontends/qt2/ui/QTocDialogBase.ui b/src/frontends/qt2/ui/QTocDialogBase.ui index 5eb58f606e..ec0719eebb 100644 --- a/src/frontends/qt2/ui/QTocDialogBase.ui +++ b/src/frontends/qt2/ui/QTocDialogBase.ui @@ -171,6 +171,50 @@ &Update + + QPushButton + + name + moveupPB + + + text + Up + + + + QPushButton + + name + movednPB + + + text + Dn + + + + QPushButton + + name + moveinPB + + + text + In + + + + QPushButton + + name + moveoutPB + + + text + Out + + name diff --git a/src/lfuns.h b/src/lfuns.h index 0c7633df5c..3f104040b3 100644 --- a/src/lfuns.h +++ b/src/lfuns.h @@ -357,6 +357,7 @@ enum kb_action { LFUN_BIBDB_ADD, LFUN_BIBDB_DEL, LFUN_INSERT_CITATION, + LFUN_OUTLINE, // Vermeer 20060323 LFUN_LASTACTION // end of the table }; diff --git a/src/toc.C b/src/toc.C index d90cab6e37..6a253472a3 100644 --- a/src/toc.C +++ b/src/toc.C @@ -19,7 +19,6 @@ #include "funcrequest.h" #include "LyXAction.h" #include "paragraph.h" -#include "pariterator.h" #include "frontends/LyXView.h" @@ -167,5 +166,106 @@ void asciiTocList(string const & type, Buffer const & buffer, ostream & os) } +void Outline(OutlineOp mode, Buffer * buf, pit_type & pit) +{ + ParagraphList & pars = buf->text().paragraphs(); + ParagraphList::iterator bgn = pars.begin(); + ParagraphList::iterator s = boost::next(bgn, pit); + ParagraphList::iterator p = s; + ParagraphList::iterator end = pars.end(); + + LyXTextClass::const_iterator lit = + buf->params().getLyXTextClass().begin(); + LyXTextClass::const_iterator const lend = + buf->params().getLyXTextClass().end(); + + int const thistoclevel = s->layout()->toclevel; + int toclevel; + switch (mode) { + case UP: { + if (p != end) + ++p; + for (; p != end; ++p) { + toclevel = p->layout()->toclevel; + if (toclevel != LyXLayout::NOT_IN_TOC + && toclevel <= thistoclevel) { + break; + } + } + ParagraphList::iterator q = s; + if (q != bgn) + --q; + else + break; + for (; q != bgn; --q) { + toclevel = q->layout()->toclevel; + if (toclevel != LyXLayout::NOT_IN_TOC + && toclevel <= thistoclevel) { + break; + } + } + pit_type const newpit = std::distance(pars.begin(), q); + pit_type const len = std::distance(s, p); + pit += len; + pars.insert(q, s, p); + s = boost::next(pars.begin(), pit); + ParagraphList::iterator t = boost::next(s, len); + pit = newpit; + pars.erase(s, t); + break; + } + case DOWN: { + if (p != end) + ++p; + for (; p != end; ++p) { + toclevel = p->layout()->toclevel; + if (toclevel != LyXLayout::NOT_IN_TOC + && toclevel <= thistoclevel) { + break; + } + } + ParagraphList::iterator q = p; + if (q != end) + ++q; + else + break; + for (; q != end; ++q) { + toclevel = q->layout()->toclevel; + if (toclevel != LyXLayout::NOT_IN_TOC + && toclevel <= thistoclevel) { + break; + } + } + pit_type const newpit = std::distance(pars.begin(), q); + pit_type const len = std::distance(s, p); + pars.insert(q, s, p); + s = boost::next(pars.begin(), pit); + ParagraphList::iterator t = boost::next(s, len); + pit = newpit - len; + pars.erase(s, t); + break; + } + case IN: + for (; lit != lend; ++lit) { + if ((*lit)->toclevel == thistoclevel + 1) { + s->layout((*lit)); + break; + } + } + break; + case OUT: + for (; lit != lend; ++lit) { + if ((*lit)->toclevel == thistoclevel - 1) { + s->layout((*lit)); + break; + } + } + break; + default: + break; + } +} + + } // namespace toc } // namespace lyx diff --git a/src/toc.h b/src/toc.h index f0f2f80262..96f6966de3 100644 --- a/src/toc.h +++ b/src/toc.h @@ -20,6 +20,8 @@ #include #include +#include "pariterator.h" + class Buffer; class LyXView; class Paragraph; @@ -84,6 +86,18 @@ bool operator!=(TocItem const & a, TocItem const & b) } +/// the type of outline operation +enum OutlineOp { + UP, // Move this header with text down + DOWN, // Move this header with text up + IN, // Make this header deeper + OUT // Make this header shallower +}; + + +void Outline(OutlineOp, Buffer *, pit_type &); + + } // namespace toc } // namespace lyx