On Mon, Apr 24, 2006 at 10:07:43AM +0200, Jean-Marc Lasgouttes wrote:
> >>>>> "Martin" == Martin Vermeer <[EMAIL PROTECTED]> writes:
> 
> Martin> No it isn't. I suppose you can take all outline-related
> Martin> patches with my name on it, plus lower-case some occurrences
> Martin> of Outline.
> 
> Martin> BTW It's Jean-Marc's call. He may want to wait for this to
> Martin> stabilize a bit (remember the crash with a section header
> Martin> inside an inset?)
> 
> My take on it is that I prefer a version which is 100% stable without
> the bells and whistles (reverse synchronisation, toc backend) over one
> which is more complete but not sure. I was interested by Martin's
> patch at the time because it was very simple and did not interefere
> with the rest of the code. I am less interested in 1.4 by a rewrite of
> the toc code.

Then you want this patch. Has the inside-inset crash fixed and outlining
buttons disabled for non-ToC. Abdel claims that there should still be a
crash in this (related to "illegal" counters like 1.0.5).
 
- Martin
Index: LyXAction.C
===================================================================
--- LyXAction.C (revision 13690)
+++ LyXAction.C (working copy)
@@ -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 },
Index: BufferView_pimpl.C
===================================================================
--- BufferView_pimpl.C  (revision 13690)
+++ BufferView_pimpl.C  (working copy)
@@ -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(
        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:
@@ -1196,6 +1198,16 @@ bool BufferView::Pimpl::dispatch(FuncReq
                break;
        }
 
+       case LFUN_OUTLINE: {
+               lyx::toc::OutlineOp const op =
+                   
static_cast<lyx::toc::OutlineOp>(convert<int>(cmd.argument));
+               lyx::toc::outline(op, buffer_, cursor_.pit());
+               cursor_.text()->setCursor(cursor_, cursor_.pit(), 0);
+               buffer_->markDirty();
+               updateCounters(*buffer_);
+               update();
+       }
+                                 
        case LFUN_GOTOERROR:
                bv_funcs::gotoInset(bv_, InsetBase::ERROR_CODE, false);
                break;
Index: frontends/qt2/QTocDialog.C
===================================================================
--- frontends/qt2/QTocDialog.C  (revision 13690)
+++ frontends/qt2/QTocDialog.C  (working copy)
@@ -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()));
 }
 
 
@@ -60,12 +63,50 @@ void QTocDialog::select_adaptor(QListVie
 }
 
 
+void QTocDialog::enableButtons(bool enable)
+{
+       updatePB->setEnabled(enable);
+
+       if (!form_->canOutline())
+               enable = false;
+
+       moveupPB->setEnabled(enable);
+       movednPB->setEnabled(enable);
+       moveinPB->setEnabled(enable);
+       moveoutPB->setEnabled(enable);
+}
+
+
 void QTocDialog::update_adaptor()
 {
        form_->update();
 }
 
 
+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();
Index: frontends/qt2/ui/QTocDialogBase.ui
===================================================================
--- frontends/qt2/ui/QTocDialogBase.ui  (revision 13690)
+++ frontends/qt2/ui/QTocDialogBase.ui  (working copy)
@@ -168,7 +168,51 @@
                     </property>
                     <property stdset="1">
                         <name>text</name>
-                        <string>&amp;Update</string>
+                        <string>U&amp;pdate</string>
+                    </property>
+                </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>moveupPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;Up</string>
+                    </property>
+               </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>movednPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;Down</string>
+                    </property>
+                </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>moveinPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;In</string>
+                    </property>
+                </widget>
+               <widget>
+                    <class>QPushButton</class>
+                    <property stdset="1">
+                        <name>name</name>
+                        <cstring>moveoutPB</cstring>
+                    </property>
+                    <property stdset="1">
+                        <name>text</name>
+                        <string>&amp;Out</string>
                     </property>
                 </widget>
                 <spacer>
Index: frontends/qt2/QTocDialog.h
===================================================================
--- frontends/qt2/QTocDialog.h  (revision 13690)
+++ frontends/qt2/QTocDialog.h  (working copy)
@@ -24,11 +24,17 @@ class QTocDialog : public QTocDialogBase
 public:
        QTocDialog(QToc * form);
        ~QTocDialog();
+       ///
+       void enableButtons(bool enable = true);
 public slots:
        void activate_adaptor(int);
        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:
Index: frontends/qt2/QToc.C
===================================================================
--- frontends/qt2/QToc.C        (revision 13690)
+++ frontends/qt2/QToc.C        (working copy)
@@ -48,6 +48,8 @@ void QToc::build_dialog()
 
        // Manage the cancel/close button
        bcview().setCancel(dialog_->closePB);
+       type_ = toc::getType(controller().params().getCmdName());
+       dialog_->enableButtons();
 }
 
 
@@ -67,6 +69,8 @@ void QToc::updateType()
                        setTitle(guiname);
                }
        }
+       type_ = type;
+       dialog_->enableButtons();
 }
 
 
@@ -83,6 +87,8 @@ void QToc::updateToc(int newdepth)
        string type;
        if (!choice.empty())
                type = choice[dialog_->typeCO->currentItem()];
+       type_ = type;
+       dialog_->enableButtons();
 
        toc::Toc const & contents = controller().getContents(type);
 
@@ -107,7 +113,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,14 +165,34 @@ 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->scrollBy(0, selected_item->itemPos() 
+                       - dialog_->tocLV->height() / 2);
+               dialog_->tocLV->setSelected(selected_item, true);
+       }
        setTitle(fromqstr(dialog_->typeCO->currentText()));
 }
 
 
+bool QToc::canOutline()
+{
+       return controller().canOutline(type_);
+}
+
+
 void QToc::select(string const & text)
 {
        toc::Toc::const_iterator iter = toclist.begin();
@@ -180,6 +208,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 +220,34 @@ void QToc::set_depth(int depth)
                updateToc(depth);
 }
 
+
+void QToc::moveup()
+{
+       controller().outline(toc::Up);
+       updateToc(depth_);
+}
+
+
+void QToc::movedn()
+{
+       controller().outline(toc::Down);
+       updateToc(depth_);
+}
+
+
+void QToc::movein()
+{
+       controller().outline(toc::In);
+       updateToc(depth_);
+}
+
+
+void QToc::moveout()
+{
+       controller().outline(toc::Out);
+       updateToc(depth_);
+}
+
+
 } // namespace frontend
 } // namespace lyx
Index: frontends/qt2/QToc.h
===================================================================
--- frontends/qt2/QToc.h        (revision 13690)
+++ frontends/qt2/QToc.h        (working copy)
@@ -33,6 +33,9 @@ private:
        /// update the listview
        void updateToc(int newdepth);
 
+       ///
+       bool canOutline();
+
        /// update the float types
        void updateType();
 
@@ -42,6 +45,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 +67,12 @@ private:
 
        /// depth of list shown
        int depth_;
+
+       /// Store selected item's string
+       std::string text_;
+
+       /// Store ToC list type
+       std::string type_;
 };
 
 } // namespace frontend
Index: frontends/controllers/ControlToc.C
===================================================================
--- frontends/controllers/ControlToc.C  (revision 13690)
+++ frontends/controllers/ControlToc.C  (working copy)
@@ -8,9 +8,12 @@
  * Full author contact details are available in file CREDITS.
  */
 
+#include <sstream>
+
 #include <config.h>
 
 #include "ControlToc.h"
+#include "funcrequest.h"
 #include "gettext.h"
 
 using std::vector;
@@ -34,6 +37,20 @@ void ControlToc::goTo(toc::TocItem const
 }
 
 
+bool ControlToc::canOutline(string const & type)
+{
+       return type == "TOC";
+}
+
+
+void ControlToc::outline(toc::OutlineOp op)
+{
+       std::ostringstream o;
+       o << op << std::flush; 
+       kernel().dispatch(FuncRequest(LFUN_OUTLINE, o.str()));
+}
+
+
 vector<string> const ControlToc::getTypes() const
 {
        return toc::getTypes(kernel().buffer());
Index: frontends/controllers/ControlToc.h
===================================================================
--- frontends/controllers/ControlToc.h  (revision 13690)
+++ frontends/controllers/ControlToc.h  (working copy)
@@ -38,6 +38,12 @@ 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);
+
+       /// Test if outlining operation is possible
+       bool canOutline(std::string const & type);
 };
 
 } // namespace frontend
Index: lfuns.h
===================================================================
--- lfuns.h     (revision 13690)
+++ lfuns.h     (working copy)
@@ -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
 };
Index: toc.C
===================================================================
--- toc.C       (revision 13690)
+++ toc.C       (working copy)
@@ -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, B
 }
 
 
+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
Index: toc.h
===================================================================
--- toc.h       (revision 13690)
+++ toc.h       (working copy)
@@ -20,6 +20,8 @@
 #include <vector>
 #include <string>
 
+#include "pariterator.h"
+
 class Buffer;
 class LyXView;
 class Paragraph;
@@ -84,6 +86,18 @@ bool operator!=(TocItem const & a, TocIt
 }
 
 
+/// 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
 

Attachment: pgpHKx6Ot1W79.pgp
Description: PGP signature

Reply via email to