]> git.lyx.org Git - lyx.git/commitdiff
patch from dekel
authorLars Gullik Bjønnes <larsbj@gullik.org>
Fri, 19 May 2000 16:46:01 +0000 (16:46 +0000)
committerLars Gullik Bjønnes <larsbj@gullik.org>
Fri, 19 May 2000 16:46:01 +0000 (16:46 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@744 a592a061-630c-0410-9148-cb99ea01b6c8

27 files changed:
ChangeLog
forms/lyx.fd
lib/bind/menus.bind
src/BufferView.C
src/BufferView.h
src/BufferView2.C
src/LaTeXFeatures.C
src/LaTeXFeatures.h
src/buffer.C
src/buffer.h
src/insets/insetinclude.C
src/insets/insetinclude.h
src/insets/insetlabel.C
src/insets/insetlabel.h
src/insets/insetref.C
src/insets/insetref.h
src/insets/lyxinset.h
src/lyx.C
src/lyx.h
src/lyx_cb.C
src/lyxfunc.C
src/lyxparagraph.h
src/mathed/formula.C
src/mathed/formula.h
src/menus.C
src/menus.h
src/paragraph.C

index 2cb9984de58d8d3730dc2fca8c810b078f5fa1d3..782bccc51d9a721f7c4ff243823042e96e2e2bb6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,48 @@
+2000-05-10  Dekel Tsur  <dekel@math.tau.ac.il>
+
+       * forms/lyx.fd: Redesign of form_ref
+
+       * src/LaTeXFeatures.[Ch]
+       * src/buffer.C
+       * src/lyx_cb.C
+       * src/menus.C   
+       * src/insets/insetref.[Ch]: Added support for varioref and prettyref.
+
+       * src/buffer.h
+       * src/lyxparagraph.h: Added new classes: LyXParagraph::inset_iterator
+       and Buffer::inset_iterator.
+
+       * src/menus.C: Added new menus: TOC and Refs.
+
+       * src/insets/insetlabel.C (Edit) Made InsetLabel editable.
+
+       * src/buffer.C (getTocList): New method.
+
+       * src/BufferView2.C (ChangeRefs): New method.
+
+       * src/buffer.C (getLabelList): New method. It replaces the old
+       getReferenceList. The return type is vector<string> instead of 
+       string.
+
+       * src/insets/insetinclude.C (getLabelList): New method. Replaces
+       the old getLabel() and GetNumberOfLabels() methods.
+       * src/insets/insetlabel.C (getLabelList): ditto
+       * src/mathed/formula.C (getLabelList): ditto
+       
+       * src/paragraph.C (String): New method.
+
+       * src/lyx_cb.C (TocSelectCB,TocUpdateCB): Rewritten.
+       Uses the new getTocList() method. 
+       TocSelectCB() now calls to TocUpdateCB() before moving the cursor, 
+       which automatically updates the contents of the browser.
+       (RefUpdateCB): Use the new getLabelList method.
+
+       * src/lyxfunc.C (Dispatch): Give an error if the label is not found.
+       
+       * src/BufferView2.C (gotoLabel) Use the new getLabelList method.
+
+       * src/spellchecker.C: Added using std::reverse;
+
 2000-05-19  Juergen Vigna  <jug@sad.it>
 
        * src/tabular.C (Validate): fixed/added validating of LaTeXFeatures.
index 5ea55ba0aeabb5e7e1824263cc6187d26af4e891..f783f0021394223d513199870c8c23c586b84d3b 100644 (file)
@@ -8,14 +8,14 @@ Unit of measure: FL_COORD_PIXEL
 
 =============== FORM ===============
 Name: form_title
-Width: 425
+Width: 420
 Height: 290
 Number of Objects: 2
 
 --------------------
 class: FL_BOX
 type: UP_BOX
-box: 0 0 425 290
+box: 0 0 420 290
 boxtype: FL_UP_BOX
 colors: FL_BLACK FL_TOP_BCOL
 alignment: FL_ALIGN_CENTER
@@ -93,7 +93,7 @@ argument:
 --------------------
 class: FL_BEGIN_GROUP
 type: 0
-box: 0 10 10 0
+box: 0 0 0
 boxtype: FL_NO_BOX
 colors: FL_COL1 FL_MCOL
 alignment: FL_ALIGN_CENTER
@@ -482,14 +482,14 @@ argument: 0
 
 =============== FORM ===============
 Name: form_ref
-Width: 290
-Height: 330
-Number of Objects: 8
+Width: 590
+Height: 400
+Number of Objects: 12
 
 --------------------
 class: FL_BOX
 type: UP_BOX
-box: 0 0 290 330
+box: 0 0 590 400
 boxtype: FL_UP_BOX
 colors: FL_COL1 FL_COL1
 alignment: FL_ALIGN_CENTER
@@ -507,7 +507,7 @@ argument:
 --------------------
 class: FL_BROWSER
 type: HOLD_BROWSER
-box: 10 10 270 140
+box: 10 10 280 380
 boxtype: FL_DOWN_BOX
 colors: FL_COL1 FL_YELLOW
 alignment: FL_ALIGN_BOTTOM
@@ -525,7 +525,7 @@ argument: 0
 --------------------
 class: FL_BUTTON
 type: NORMAL_BUTTON
-box: 180 200 100 30
+box: 480 60 100 30
 boxtype: FL_UP_BOX
 colors: FL_COL1 FL_COL1
 alignment: FL_ALIGN_CENTER
@@ -543,7 +543,7 @@ argument: 0
 --------------------
 class: FL_BUTTON
 type: NORMAL_BUTTON
-box: 180 240 100 30
+box: 480 100 100 30
 boxtype: FL_UP_BOX
 colors: FL_COL1 FL_COL1
 alignment: FL_ALIGN_CENTER
@@ -561,7 +561,7 @@ argument: 0
 --------------------
 class: FL_BUTTON
 type: NORMAL_BUTTON
-box: 10 240 160 30
+box: 310 60 160 30
 boxtype: FL_UP_BOX
 colors: FL_COL1 FL_COL1
 alignment: FL_ALIGN_CENTER
@@ -579,7 +579,7 @@ argument: 0
 --------------------
 class: FL_BUTTON
 type: NORMAL_BUTTON
-box: 10 200 160 30
+box: 310 100 160 30
 boxtype: FL_UP_BOX
 colors: FL_COL1 FL_COL1
 alignment: FL_ALIGN_CENTER
@@ -597,7 +597,7 @@ argument: 1
 --------------------
 class: FL_BUTTON
 type: NORMAL_BUTTON
-box: 10 280 160 30
+box: 310 280 160 30
 boxtype: FL_UP_BOX
 colors: FL_COL1 FL_COL1
 alignment: FL_ALIGN_CENTER
@@ -610,12 +610,12 @@ resize: FL_RESIZE_NONE
 gravity: FL_SouthWest FL_SouthWest
 name: 
 callback: RefSelectCB
-argument: 2
+argument: 5
 
 --------------------
 class: FL_INPUT
 type: NORMAL_INPUT
-box: 80 160 200 30
+box: 380 20 200 30
 boxtype: FL_DOWN_BOX
 colors: FL_COL1 FL_MCOL
 alignment: FL_ALIGN_LEFT
@@ -630,5 +630,78 @@ name: ref_name
 callback: 
 argument: 
 
+--------------------
+class: FL_CHECKBUTTON
+type: PUSH_BUTTON
+box: 310 360 110 30
+boxtype: FL_NO_BOX
+colors: FL_COL1 FL_YELLOW
+alignment: FL_ALIGN_CENTER
+style: FL_NORMAL_STYLE
+size: FL_NORMAL_SIZE
+lcol: FL_BLACK
+label: Sort keys|#S
+shortcut: 
+resize: FL_RESIZE_ALL
+gravity: FL_NoGravity FL_NoGravity
+name: sort
+callback: RefUpdateCB
+argument: 0
+       value: 1
+
+--------------------
+class: FL_BUTTON
+type: NORMAL_BUTTON
+box: 310 140 160 30
+boxtype: FL_UP_BOX
+colors: FL_COL1 FL_COL1
+alignment: FL_ALIGN_CENTER
+style: FL_NORMAL_STYLE
+size: FL_NORMAL_SIZE
+lcol: FL_BLACK
+label: Insert vReference|#V
+shortcut: 
+resize: FL_RESIZE_NONE
+gravity: FL_SouthWest FL_SouthWest
+name: vref
+callback: RefSelectCB
+argument: 2
+
+--------------------
+class: FL_BUTTON
+type: NORMAL_BUTTON
+box: 310 180 160 30
+boxtype: FL_UP_BOX
+colors: FL_COL1 FL_COL1
+alignment: FL_ALIGN_CENTER
+style: FL_NORMAL_STYLE
+size: FL_NORMAL_SIZE
+lcol: FL_BLACK
+label: Insert vPage Number|#N
+shortcut: 
+resize: FL_RESIZE_NONE
+gravity: FL_SouthWest FL_SouthWest
+name: vpageref
+callback: RefSelectCB
+argument: 3
+
+--------------------
+class: FL_BUTTON
+type: NORMAL_BUTTON
+box: 310 220 160 30
+boxtype: FL_UP_BOX
+colors: FL_COL1 FL_COL1
+alignment: FL_ALIGN_CENTER
+style: FL_NORMAL_STYLE
+size: FL_NORMAL_SIZE
+lcol: FL_BLACK
+label: Insert Pretty Ref|#T
+shortcut: 
+resize: FL_RESIZE_NONE
+gravity: FL_SouthWest FL_SouthWest
+name: prettyref
+callback: RefSelectCB
+argument: 4
+
 ==============================
 create_the_forms
index a6fe6a531094e19e7c0052f8f53084e4898d1544..2f5e7b57263dbc060bbbe8dfaf4903f29e9984f8 100644 (file)
 \bind "M-e w"                  "latex-view-log"
 \bind "M-e space"              "menu-open Edit" 
 
+#
+# TOC menu
+#
+
+\bind "M-t"                    "menu-open TOC" 
+
+#
+# Refs menu
+#
+
+\bind "M-r"                    "menu-open Refs" 
+
+
 #
 # Layout menu
 #
index 22ae6295a897b39fbf26bc7698df8b4833321f1c..2425f7ce1593d5e0f0c65b47095641241cdf482a 100644 (file)
@@ -154,9 +154,6 @@ void BufferView::workAreaMotionNotify(int x, int y, unsigned int state)
 }
 
 
-extern int bibitemMaxWidth(Painter &, LyXFont const &);
-
-
 ///  Single-click on work area
 void BufferView::workAreaButtonPress(int xpos, int ypos, unsigned int button)
 {
index 766f48f737c083e7e5c614d179f4232be68611d1..1584f02f8eb777ad65f0b40da6904e7d8693585b 100644 (file)
@@ -218,6 +218,8 @@ public:
        void leaveView();
        ///
        void workAreaSelectionNotify(Window win, XEvent * event);
+       ///
+       bool ChangeRefs(string const & from, string const & to);
 private:
        struct Pimpl;
        Pimpl * pimpl_;
index a34e2cb210eeaa46dbd29b58017f8b13ce56160c..656b598f36d9100ccf6c637067956f994bbabe97 100644 (file)
@@ -12,6 +12,7 @@
 #include <config.h>
 
 #include <fstream>
+#include <algorithm>
 
 #include "BufferView.h"
 #include "buffer.h"
 #include "lyx_gui_misc.h"
 #include "LaTeX.h"
 #include "BufferView_pimpl.h"
+#include "insets/insetcommand.h" //ChangeRefs
 
 extern BufferList bufferlist;
 
 using std::pair;
 using std::endl;
 using std::ifstream;
+using std::vector;
+using std::find;
 
 // Inserts a file into current document
 bool BufferView::insertLyXFile(string const & filen)
@@ -283,24 +287,17 @@ void BufferView::open_new_inset(UpdatableInset * new_inset)
 bool BufferView::gotoLabel(string const & label)
 
 {
-        LyXParagraph * par = buffer()->paragraph;
-        LyXParagraph::size_type pos;
-        Inset * inset;
-        while (par) {
-                pos = -1;
-                while ((inset = par->ReturnNextInsetPointer(pos))){     
-                        for (int i = 0; i < inset->GetNumberOfLabels(); ++i) {
-                               if (label == inset->getLabel(i)) {
-                                       beforeChange();
-                                       text->SetCursor(par, pos);
-                                       text->sel_cursor = text->cursor;
-                                       update(0);
-                                       return true;
-                               }
-                       }
-                        ++pos;
-                } 
-                par = par->next;
+       for (Buffer::inset_iterator it = buffer()->inset_iterator_begin();
+            it != buffer()->inset_iterator_end(); ++it) {
+               vector<string> labels = (*it)->getLabelList();
+               if ( find(labels.begin(),labels.end(),label)
+                    != labels.end()) {
+                       beforeChange();
+                       text->SetCursor(it.getPar(), it.getPos());
+                       text->sel_cursor = text->cursor;
+                       update(0);
+                       return true;
+               }
        }
        return false;
 }
@@ -844,3 +841,41 @@ void BufferView::updateInset(Inset * inset, bool mark_dirty)
                }
        }
 }
+
+bool BufferView::ChangeRefs(string const & from, string const & to)
+{
+       bool flag = false;
+       LyXParagraph * par = buffer()->paragraph;
+       LyXCursor cursor = text->cursor;
+       LyXCursor tmpcursor = cursor;
+       cursor.par = tmpcursor.par->ParFromPos(tmpcursor.pos);
+       cursor.pos = tmpcursor.par->PositionInParFromPos(tmpcursor.pos);
+
+       while (par) {
+               bool flag2 = false;
+               for (LyXParagraph::inset_iterator it = par->inset_iterator_begin();
+                    it != par->inset_iterator_end(); ++it) {
+                       if ((*it)->LyxCode() == Inset::REF_CODE) {
+                               InsetCommand * inset = static_cast<InsetCommand *>(*it);
+                               if (inset->getContents() == from) {
+                                       inset->setContents(to);
+                                       flag2 = true;
+                               }
+                       }
+               }
+               if (flag2) {
+                       flag = true;
+                       if (par->footnoteflag != LyXParagraph::CLOSED_FOOTNOTE){
+                               // this is possible now, since SetCursor takes
+                               // care about footnotes
+                               text->SetCursorIntern(par, 0);
+                               text->RedoParagraphs(text->cursor,
+                                                    text->cursor.par->Next());
+                               text->FullRebreak();
+                       }
+               }
+               par = par->next;
+       }
+       text->SetCursorIntern(cursor.par, cursor.pos);
+       return flag;
+}
index 72a0ea97371a750323d92b34de61f9174375dfad..cac7a883585e53848201e725289480aaab29258b 100644 (file)
@@ -43,6 +43,8 @@ LaTeXFeatures::LaTeXFeatures(BufferParams const & p, int n)
        subfigure = false;
        floatflt = false;
        url = false;
+       varioref = false;
+       prettyref = false;
        
        // commands
        lyx = false;
@@ -181,7 +183,15 @@ string LaTeXFeatures::getPackages()
        if (url && ! tclass.provides(LyXTextClass::url))
                packages += "\\IfFileExists{url.sty}{\\usepackage{url}}\n"
                            "                      {\\newcommand{\\url}{\\texttt}}\n";
-       
+
+       // varioref.sty
+       if (varioref)
+               packages += "\\usepackage{varioref}\n";
+
+       // prettyref.sty
+       if (prettyref)
+               packages += "\\usepackage{prettyref}\n";
+
        return packages;
 }
 
index d3daa6e0e26e207346e070176e6d0d860d3e6f25..9b61f75132938edbe18a947abb50645de74ef42f 100644 (file)
@@ -79,6 +79,10 @@ struct LaTeXFeatures {
        bool floatflt;  // floatflt.sty
        ///
        bool url;       // url.sty
+       ///
+       bool varioref;  // varioref.sty
+       ///
+       bool prettyref; // prettyref.sty
        //@}
 
        
index b55da2e5e20dd963134a04ca8e907d8f37ec7132..fe29ec7faf4602977ff7ab6aaa10ad496b2db5cd 100644 (file)
@@ -31,6 +31,8 @@
 #include <sys/types.h>
 #include <utime.h>
 
+#include <algorithm>
+
 #ifdef __GNUG__
 #pragma implementation "buffer.h"
 #endif
@@ -95,7 +97,8 @@ using std::ios;
 using std::setw;
 using std::endl;
 using std::pair;
-
+using std::vector;
+using std::max;
 
 // all these externs should eventually be removed.
 extern BufferList bufferlist;
@@ -876,7 +879,10 @@ Buffer::parseSingleLyXformat2Token(LyXLex & lex, LyXParagraph *& par,
                                   || inscmd.getCmdName() == "htmlurl") {
                                inset = new InsetUrl(inscmd.getCommand());
                        } else if (inscmd.getCmdName() == "ref"
-                                  || inscmd.getCmdName() == "pageref") {
+                                  || inscmd.getCmdName() == "pageref"
+                                  || inscmd.getCmdName() == "vref"
+                                  || inscmd.getCmdName() == "vpageref"
+                                  || inscmd.getCmdName() == "prettyref") {
                                if (!inscmd.getOptions().empty() || !inscmd.getContents().empty()) {
                                        inset = new InsetRef(inscmd, this);
                                }
@@ -3736,33 +3742,25 @@ void Buffer::setPaperStuff()
 string Buffer::getIncludeonlyList(char delim)
 {
        string lst;
-       LyXParagraph * par = paragraph;
-       LyXParagraph::size_type pos;
-       Inset * inset;
-       while (par){
-               pos = -1;
-               while ((inset = par->ReturnNextInsetPointer(pos))){
-                       if (inset->LyxCode() == Inset::INCLUDE_CODE) {
-                               InsetInclude * insetinc = 
-                                       static_cast<InsetInclude*>(inset);
-                               if (insetinc->isInclude() 
-                                   && insetinc->isNoLoad()) {
-                                       if (!lst.empty())
-                                               lst += delim;
-                                       lst += OnlyFilename(ChangeExtension(insetinc->getContents(), string()));
-                               }
+       for (inset_iterator it = inset_iterator_begin();
+           it != inset_iterator_end(); ++it) {
+               if ((*it)->LyxCode() == Inset::INCLUDE_CODE) {
+                       InsetInclude * insetinc = 
+                               static_cast<InsetInclude *>(*it);
+                       if (insetinc->isInclude() 
+                           && insetinc->isNoLoad()) {
+                               if (!lst.empty())
+                                       lst += delim;
+                               lst += OnlyFilename(ChangeExtension(insetinc->getContents(), string()));
                        }
-                       ++pos;
-               } 
-               par = par->next;
+               }
        }
        lyxerr.debug() << "Includeonly(" << lst << ')' << endl;
        return lst;
 }
 
 
-// This is also a buffer property (ale)
-string Buffer::getReferenceList(char delim)
+vector<string> Buffer::getLabelList()
 {
        /// if this is a child document and the parent is already loaded
        /// Use the parent's list instead  [ale990407]
@@ -3770,30 +3768,70 @@ string Buffer::getReferenceList(char delim)
            && bufferlist.exists(params.parentname)) {
                Buffer * tmp = bufferlist.getBuffer(params.parentname);
                if (tmp)
-                       return tmp->getReferenceList(delim);
+                       return tmp->getLabelList();
        }
 
+       vector<string> label_list;
+       for (inset_iterator it = inset_iterator_begin();
+            it != inset_iterator_end(); ++it) {
+               vector<string> l = (*it)->getLabelList();
+               label_list.insert(label_list.end(), l.begin(), l.end());
+       }
+       return label_list;
+}
+
+
+vector<vector<Buffer::TocItem> > Buffer::getTocList()
+{
+       vector<vector<TocItem> > l(4);
        LyXParagraph * par = paragraph;
-       LyXParagraph::size_type pos;
-       Inset * inset;
-        string lst;
        while (par) {
-               pos = -1;
-               while ((inset = par->ReturnNextInsetPointer(pos))){     
-                       for (int i = 0; i < inset->GetNumberOfLabels(); ++i) {
-                               if (!lst.empty())
-                                       lst += delim;
-                               lst += inset->getLabel(i);
+               if (par->footnoteflag != LyXParagraph::NO_FOOTNOTE) {
+                       if (textclasslist.Style(params.textclass, 
+                                               par->GetLayout()).labeltype
+                           == LABEL_SENSITIVE) {
+                               TocItem tmp;
+                               tmp.par = par;
+                               tmp.depth = 0;
+                               tmp.str =  par->String(false);
+                               switch (par->footnotekind) {
+                               case LyXParagraph::FIG:
+                               case LyXParagraph::WIDE_FIG:
+                                       l[1].push_back(tmp);
+                                       break;
+                               case LyXParagraph::TAB:
+                               case LyXParagraph::WIDE_TAB:
+                                       l[2].push_back(tmp);
+                                       break;
+                               case LyXParagraph::ALGORITHM:
+                                       l[3].push_back(tmp);
+                                       break;
+                               case LyXParagraph::FOOTNOTE:
+                               case LyXParagraph::MARGIN:
+                                       break;
+                               }
+                       }
+               } else if (!par->IsDummy()) {
+                       char labeltype = textclasslist.Style(params.textclass, 
+                                                            par->GetLayout()).labeltype;
+      
+                       if (labeltype >= LABEL_COUNTER_CHAPTER
+                           && labeltype <= LABEL_COUNTER_CHAPTER + params.tocdepth) {
+                               // insert this into the table of contents
+                               TocItem tmp;
+                               tmp.par = par;
+                               tmp.depth = max(0,
+                                               labeltype - 
+                                               textclasslist.TextClass(params.textclass).maxcounter());
+                               tmp.str =  par->String(true);
+                               l[0].push_back(tmp);
                        }
-                       ++pos;
                }
                par = par->next;
        }
-       lyxerr.debug() << "References(" <<  lst << ")" << endl;
-       return lst;
+       return l;
 }
 
-
 // This is also a buffer property (ale)
 string Buffer::getBibkeyList(char delim)
 {
@@ -3818,28 +3856,21 @@ string Buffer::getBibkeyList(char delim)
 
        // Might be either using bibtex or a child has bibliography
        if (bibkeys.empty()) {
-               par = paragraph;
-               while (par) {
-                       Inset * inset;
-                       LyXParagraph::size_type pos = -1;
-
+               for (inset_iterator it = inset_iterator_begin();
+                    it != inset_iterator_end(); ++it) {
                        // Search for Bibtex or Include inset
-                       while ((inset = par->ReturnNextInsetPointer(pos))) {
-                               if (inset->LyxCode() == Inset::BIBTEX_CODE) {
+                       if ((*it)->LyxCode() == Inset::BIBTEX_CODE) {
+                               if (!bibkeys.empty())
+                                       bibkeys += delim;
+                               bibkeys += static_cast<InsetBibtex *>(*it)->getKeys(delim);
+                       } else if ((*it)->LyxCode() == Inset::INCLUDE_CODE) {
+                               string bk(static_cast<InsetInclude *>(*it)->getKeys(delim));
+                               if (!bk.empty()) {
                                        if (!bibkeys.empty())
                                                bibkeys += delim;
-                                       bibkeys += static_cast<InsetBibtex*>(inset)->getKeys(delim);
-                               } else if (inset->LyxCode() == Inset::INCLUDE_CODE) {
-                                       string bk = static_cast<InsetInclude*>(inset)->getKeys(delim);
-                                       if (!bk.empty()) {
-                                               if (!bibkeys.empty())
-                                                       bibkeys += delim;
-                                               bibkeys += bk;
-                                       }
+                                       bibkeys += bk;
                                }
-                               ++pos;
                        }
-                       par = par->next;
                }
        }
  
@@ -3928,3 +3959,25 @@ bool Buffer::isMultiLingual()
        }
        return false;
 }
+
+
+Buffer::inset_iterator::inset_iterator(LyXParagraph * paragraph,
+                                      LyXParagraph::size_type pos)
+       : par(paragraph) {
+       it = par->InsetIterator(pos);
+       if (it == par->inset_iterator_end()) {
+               par = par->next;
+               SetParagraph();
+       }
+}
+
+
+void Buffer::inset_iterator::SetParagraph() {
+       while (par) {
+               it = par->inset_iterator_begin();
+               if (it != par->inset_iterator_end())
+                       return;
+               par = par->next;
+       }
+       //it = 0;
+}
index 8cfa12ad98bd6ea0e8aac9130bdc82653a93fc26..52c692206540eb6970ffb11c49fa4ffca1c50a01 100644 (file)
@@ -291,9 +291,17 @@ public:
        ///
        string getIncludeonlyList(char delim = ',');
        ///
-       string getReferenceList(char delim = '|');
-       ///
        string getBibkeyList(char delim = '|');
+       ///
+       struct TocItem {
+               LyXParagraph *par;
+               int depth;
+               string str;
+       };
+       ///
+       std::vector<std::vector<TocItem> > getTocList();
+       ///
+       std::vector<string> getLabelList();
 
        /** This will clearly have to change later. Later we can have more
            than one user per buffer. */
@@ -411,6 +419,47 @@ private:
            of the buffers in the list of users to do a updateLayoutChoice.
        */
        BufferView * users;
+
+       class inset_iterator {
+       public:
+               inset_iterator() : par(0) /*, it(0)*/ {}
+               inset_iterator(LyXParagraph * paragraph) : par(paragraph) {
+                       SetParagraph();
+               }
+               inset_iterator(LyXParagraph * paragraph, LyXParagraph::size_type pos);
+               inset_iterator & operator++() {
+                       if (par) {
+                               ++it;
+                               if (it == par->inset_iterator_end()) {
+                                       par = par->next;
+                                       SetParagraph();
+                               }
+                       }
+                       return *this;
+               }
+               Inset * operator*() {return *it; }
+               LyXParagraph * getPar() { return par; }
+               LyXParagraph::size_type getPos() {return it.getPos(); }
+               bool operator==(inset_iterator const & iter) const {
+                       return it == iter.it && par == iter.par;
+               }
+               bool operator!=(inset_iterator const & iter) const {
+                       return it != iter.it || par != iter.par;
+               }
+       private:
+               void SetParagraph();
+               LyXParagraph * par;
+               LyXParagraph::inset_iterator it;
+       };
+public:
+       ///
+       inset_iterator inset_iterator_begin() {
+               return inset_iterator(paragraph);
+       }
+       ///
+       inset_iterator inset_iterator_end() {
+               return inset_iterator();
+       }
 };
 
 
@@ -420,4 +469,17 @@ void Buffer::setParentName(string const & name)
        params.parentname = name;    
 }
 
+inline
+bool operator==(Buffer::TocItem const & a, Buffer::TocItem const & b) {
+       return a.par == b.par && a.str == b.str;
+       // No need to compare depth.
+}
+
+
+inline
+bool operator!=(Buffer::TocItem const & a, Buffer::TocItem const & b) {
+       return !(a == b);
+       // No need to compare depth.
+}
+
 #endif
index edba5fac3caa0a4a23365201f27d6794ba811cc7..78f32359a9375b0c3a83533e9cd6dba484786030 100644 (file)
@@ -25,6 +25,7 @@
 
 using std::ostream;
 using std::endl;
+using std::vector;
 
 extern BufferView * current_view;
 
@@ -419,36 +420,19 @@ void InsetInclude::Validate(LaTeXFeatures & features) const
 }
 
 
-string InsetInclude::getLabel(int) const
+vector<string> InsetInclude::getLabelList() const
 {
-    string label;
+    vector<string> l;
     string parentname;
-       
-       
+
     if (loadIfNeeded()) {
        Buffer * tmp = bufferlist.getBuffer(getFileName());
        tmp->setParentName(""); 
-       label =  tmp->getReferenceList('\n');
+       l = tmp->getLabelList();
        tmp->setParentName(getMasterFilename());
     }
 
-    return label;
-}
-
-
-int InsetInclude::GetNumberOfLabels() const
-{
-    string label;
-
-    if (loadIfNeeded()) {
-       Buffer * tmp = bufferlist.getBuffer(getFileName());
-       tmp->setParentName("");    
-       label = tmp->getReferenceList('\n');
-       tmp->setParentName(getMasterFilename());
-    }
-    int nl = (label.empty())? 0: 1;
-       
-    return nl;
+    return l;
 }
 
 
index e713fb8f02d0fa6cd8fb57d29c01e089740fe2e5..b430c521d2ca751c6d827cbc8ed3100f7909e6ea 100644 (file)
@@ -40,10 +40,8 @@ public:
         Inset * Clone() const;
        ///
        Inset::Code LyxCode() const { return Inset::INCLUDE_CODE; }
-       /// This is 1 if the childs have labels, 0 otherwise
-       int GetNumberOfLabels() const;
        /// This returns the list of labels on the child buffer
-       string getLabel(int) const;
+       std::vector<string> getLabelList() const;
        /// This returns the list of bibkeys on the child buffer
        string getKeys(char delim) const;
        ///
index 0973ad239cd1b419a570cc4609693deaf86241a3..32e167cedad9c5cedbf824e56af4600db9180a59 100644 (file)
 
 #include "insetlabel.h"
 #include "support/LOstream.h"
+#include "lyx_gui_misc.h"     //askForText
+#include "support/lstrings.h" //frontStrip, strip
+#include "lyxtext.h"
+#include "buffer.h"
 
 using std::ostream;
+using std::vector;
+using std::pair;
 
 /* Label. Used to insert a label automatically */
 
@@ -34,17 +40,37 @@ Inset * InsetLabel::Clone() const
 }
 
 
-int InsetLabel::GetNumberOfLabels() const
+vector<string> InsetLabel::getLabelList() const
 {
-       return 1;
+       return vector<string>(1,contents);
 }
 
 
-string InsetLabel::getLabel(int) const
+void InsetLabel::Edit(BufferView * bv, int, int, unsigned int)
 {
-       return contents;
-}
+       if(bv->buffer()->isReadonly()) {
+               WarnReadonly(bv->buffer()->fileName());
+               return;
+       }
 
+       pair<bool, string> result = askForText(_("Enter label:"),
+                                              contents);
+       if (result.first) {
+               string new_contents = frontStrip(strip(result.second));
+               if (!new_contents.empty() &&
+                   contents != new_contents) {
+                       bool flag = bv->ChangeRefs(contents,new_contents);
+                       contents = new_contents;
+                       bv->text->RedoParagraph();
+                       if (flag) {
+                               bv->redraw();
+                               bv->fitCursor();
+                               //bv->updateScrollbar();
+                       } else
+                               bv->update(1);
+               }
+       }
+}
 
 int InsetLabel::Latex(ostream & os,
                      bool /*fragile*/, bool /*fs*/) const
index 62196b7d8014c01f28e986616a15847ae7db77c1..4730fd1d91405b0c9da1719004bd24f800a2bfbb 100644 (file)
@@ -32,13 +32,13 @@ public:
        ///
        Inset::Code LyxCode() const { return Inset::LABEL_CODE; }
        ///
-       int GetNumberOfLabels() const;
-       ///
-       string getLabel(int) const;
+       std::vector<string> getLabelList() const;
        ///
        string getScreenLabel() const { return getContents(); }
        ///
-       EDITABLE Editable() const { return NOT_EDITABLE; }
+       EDITABLE Editable() const { return IS_EDITABLE; }
+       ///
+       void Edit(BufferView *, int, int, unsigned int);
        ///
        int Latex(std::ostream &, bool fragile, bool free_spc) const;
        ///
index 0df28abc6d3d3b5dc56c5d2ee2aefedff12dae1e..38180c7ba130c3f33fb1598989f3984570ed9876 100644 (file)
 #include "lyxfunc.h"
 #include "commandtags.h"
 #include "gettext.h"
+#include "LaTeXFeatures.h"
 
 using std::ostream;
+using std::endl;
 
 extern BufferView * current_view;
 
@@ -25,10 +27,7 @@ InsetRef::InsetRef(string const & cmd, Buffer * bf)
        : master(bf)
 {
        scanCommand(cmd);
-       if (getCmdName() == "ref")
-               flag = InsetRef::REF;
-       else
-               flag = InsetRef::PAGE_REF;
+       GenerateFlag();
 }
 
 
@@ -38,10 +37,39 @@ InsetRef::InsetRef(InsetCommand const & inscmd, Buffer * bf)
        setCmdName(inscmd.getCmdName());
        setContents(inscmd.getContents());
        setOptions(inscmd.getOptions());
+       GenerateFlag();
+}
+
+
+void InsetRef::GenerateFlag()
+{
        if (getCmdName() == "ref")
-               flag = InsetRef::REF;
+               flag = REF;
+       else if (getCmdName() == "pageref")
+               flag = PAGE_REF;
+       else if (getCmdName() == "vref")
+               flag = VREF;
+       else if (getCmdName() == "vpageref")
+               flag = VPAGE_REF;
+       else if (getCmdName() == "prettyref")
+               flag = PRETTY_REF;
+       else {
+               lyxerr << "ERROR (InsetRef::GenerateFlag): Unknown command name "
+                      << getCmdName() << endl;
+               flag = REF;
+       }
+}
+
+
+void InsetRef::Toggle() {
+       static string const cmd_names[REF_LAST+1] 
+               = {"ref", "pageref", "vref", "vpageref", "prettyref"};
+       
+       if (flag == REF_LAST)
+               flag = REF_FIRST;
        else
-               flag = InsetRef::PAGE_REF;
+               flag = static_cast<Ref_Flags>(flag + 1);
+       setCmdName(cmd_names[flag]);
 }
 
 
@@ -54,12 +82,10 @@ void InsetRef::Edit(BufferView * bv, int, int, unsigned int)
 
 string InsetRef::getScreenLabel() const
 {
-       string temp;
-       if (flag == InsetRef::PAGE_REF)
-               temp += _("Page: ");
-       else 
-               temp += _("Ref: ");
-       temp += getContents();
+       static char const * labels[REF_LAST+1]
+               = { N_("Ref: "), N_("Page: "), N_("vRef: "), N_("vPage: "),
+                   N_("PrettyRef: ")};
+       string temp = _(labels[flag]) + getContents();
        if(!current_view->buffer()->isLatex()
           && !getOptions().empty()) {
                temp += "||";
@@ -126,3 +152,19 @@ string InsetRef::escape(string const & lab) const
        }
        return enc;
 }
+
+void InsetRef::Validate(LaTeXFeatures & features) const
+{
+       switch (flag) {
+       case VREF:
+       case VPAGE_REF: 
+               features.varioref = true;
+               break;
+       case PRETTY_REF:
+               features.prettyref = true;
+               break;
+       case REF:
+       case PAGE_REF:
+               break;
+       }
+}
index b9e63412de15d4f2f014d28051b573f678f8c85b..c1e12cc90b710bdfd5c575ec232186b4dda46fbd 100644 (file)
@@ -27,9 +27,19 @@ public:
         ///
         enum Ref_Flags {
                ///
-               REF,
+               REF = 0,
                ///
-               PAGE_REF
+               PAGE_REF,
+               ///
+               VREF,
+               ///
+               VPAGE_REF,
+               ///
+               PRETTY_REF,
+               ///
+               REF_LAST = PRETTY_REF,
+               ///
+               REF_FIRST = REF
        };
        
        ///
@@ -55,9 +65,7 @@ public:
        ///
        string getScreenLabel() const;
        ///
-       InsetRef::Ref_Flags getFlag() { return flag; }
-       ///
-       void setFlag(InsetRef::Ref_Flags f) { flag = f; }
+       void Toggle();
         ///
         void gotoLabel();
        ///
@@ -68,7 +76,11 @@ public:
        int Linuxdoc(std::ostream &) const;
        ///
        int DocBook(std::ostream &) const;
+       ///
+       void Validate(LaTeXFeatures & features) const;
 private:
+       ///
+       void GenerateFlag();
        /// This function escapes 8-bit characters
        string escape(string const &) const;
        ///
index 26dba9c5ee42b1824d513a9ff0d931a5cfb13f1d..ff08faa4685cd9fa744e307217577b41c106c2dd 100644 (file)
@@ -15,6 +15,8 @@
 #pragma interface
 #endif
 
+#include <vector>
+
 #include <X11/Xlib.h>
 
 #include "gettext.h"
@@ -156,9 +158,8 @@ public:
        /// returns LyX code associated with the inset. Used for TOC, ...)
        virtual Inset::Code LyxCode() const { return NO_CODE; }
   
-       /// Get the label that appears at screen
-       virtual string getLabel(int) const {
-               return string();
+       virtual std::vector<string> getLabelList() const {
+               return std::vector<string>();
        }
 
        ///
@@ -172,10 +173,6 @@ public:
        /// Changes the display state of the inset
        virtual void display(bool) {}  
        ///
-       virtual int GetNumberOfLabels() const {
-               return 0;
-       }
-       ///
        virtual bool InsertInsetAllowed(Inset *) const { return false; }
        ///
        virtual void setInsetName(const char * s) { name = s; }
index d8caa5d2dd9b3b26a9ae3d3332f7ab5a5184f21b..0799aa8862219f019b5f1f4037878b09a9853fd8 100644 (file)
--- a/src/lyx.C
+++ b/src/lyx.C
@@ -143,34 +143,50 @@ FD_form_ref *create_form_form_ref(void)
   FL_OBJECT *obj;
   FD_form_ref *fdui = (FD_form_ref *) fl_calloc(1, sizeof(FD_form_ref));
 
-  fdui->form_ref = fl_bgn_form(FL_NO_BOX, 290, 330);
-  obj = fl_add_box(FL_UP_BOX, 0, 0, 290, 330, "");
-  fdui->browser_ref = obj = fl_add_browser(FL_HOLD_BROWSER, 10, 10, 270, 140, "");
+  fdui->form_ref = fl_bgn_form(FL_NO_BOX, 590, 400);
+  obj = fl_add_box(FL_UP_BOX, 0, 0, 590, 400, "");
+  fdui->browser_ref = obj = fl_add_browser(FL_HOLD_BROWSER, 10, 10, 280, 380, "");
     fl_set_object_lsize(obj, FL_NORMAL_SIZE);
     fl_set_object_gravity(obj, FL_NorthWest, FL_SouthEast);
-  obj = fl_add_button(FL_NORMAL_BUTTON, 180, 200, 100, 30, idex(_("Update|#U")));fl_set_button_shortcut(obj, scex(_("Update|#U")), 1);
+  obj = fl_add_button(FL_NORMAL_BUTTON, 480, 60, 100, 30, idex(_("Update|#U")));fl_set_button_shortcut(obj, scex(_("Update|#U")), 1);
     fl_set_object_lsize(obj, FL_NORMAL_SIZE);
     fl_set_object_gravity(obj, FL_SouthEast, FL_SouthEast);
     fl_set_object_callback(obj, RefUpdateCB, 0);
-  obj = fl_add_button(FL_NORMAL_BUTTON, 180, 240, 100, 30, idex(_("Close|#C^[")));fl_set_button_shortcut(obj, scex(_("Close|#C^[")), 1);
+  obj = fl_add_button(FL_NORMAL_BUTTON, 480, 100, 100, 30, idex(_("Close|#C^[")));fl_set_button_shortcut(obj, scex(_("Close|#C^[")), 1);
     fl_set_object_lsize(obj, FL_NORMAL_SIZE);
     fl_set_object_gravity(obj, FL_SouthEast, FL_SouthEast);
     fl_set_object_callback(obj, RefHideCB, 0);
-  obj = fl_add_button(FL_NORMAL_BUTTON, 10, 240, 160, 30, idex(_("Insert Reference|#I^M")));fl_set_button_shortcut(obj, scex(_("Insert Reference|#I^M")), 1);
+  obj = fl_add_button(FL_NORMAL_BUTTON, 310, 60, 160, 30, idex(_("Insert Reference|#I^M")));fl_set_button_shortcut(obj, scex(_("Insert Reference|#I^M")), 1);
     fl_set_object_lsize(obj, FL_NORMAL_SIZE);
     fl_set_object_gravity(obj, FL_SouthWest, FL_SouthWest);
     fl_set_object_callback(obj, RefSelectCB, 0);
-  obj = fl_add_button(FL_NORMAL_BUTTON, 10, 200, 160, 30, idex(_("Insert Page Number|#P")));fl_set_button_shortcut(obj, scex(_("Insert Page Number|#P")), 1);
+  obj = fl_add_button(FL_NORMAL_BUTTON, 310, 100, 160, 30, idex(_("Insert Page Number|#P")));fl_set_button_shortcut(obj, scex(_("Insert Page Number|#P")), 1);
     fl_set_object_lsize(obj, FL_NORMAL_SIZE);
     fl_set_object_gravity(obj, FL_SouthWest, FL_SouthWest);
     fl_set_object_callback(obj, RefSelectCB, 1);
-  obj = fl_add_button(FL_NORMAL_BUTTON, 10, 280, 160, 30, idex(_("Go to Reference|#G")));fl_set_button_shortcut(obj, scex(_("Go to Reference|#G")), 1);
+  obj = fl_add_button(FL_NORMAL_BUTTON, 310, 280, 160, 30, idex(_("Go to Reference|#G")));fl_set_button_shortcut(obj, scex(_("Go to Reference|#G")), 1);
     fl_set_object_lsize(obj, FL_NORMAL_SIZE);
     fl_set_object_gravity(obj, FL_SouthWest, FL_SouthWest);
-    fl_set_object_callback(obj, RefSelectCB, 2);
-  fdui->ref_name = obj = fl_add_input(FL_NORMAL_INPUT, 80, 160, 200, 30, idex(_("Name|#N")));fl_set_button_shortcut(obj, scex(_("Name|#N")), 1);
+    fl_set_object_callback(obj, RefSelectCB, 5);
+  fdui->ref_name = obj = fl_add_input(FL_NORMAL_INPUT, 380, 20, 200, 30, idex(_("Name|#N")));fl_set_button_shortcut(obj, scex(_("Name|#N")), 1);
     fl_set_object_gravity(obj, FL_SouthWest, FL_SouthEast);
     fl_set_object_resize(obj, FL_RESIZE_X);
+  fdui->sort = obj = fl_add_checkbutton(FL_PUSH_BUTTON, 310, 360, 110, 30, idex(_("Sort keys|#S")));fl_set_button_shortcut(obj, scex(_("Sort keys|#S")), 1);
+    fl_set_object_lsize(obj, FL_NORMAL_SIZE);
+    fl_set_object_callback(obj, RefUpdateCB, 0);
+    fl_set_button(obj, 1);
+  fdui->vref = obj = fl_add_button(FL_NORMAL_BUTTON, 310, 140, 160, 30, idex(_("Insert vReference|#V")));fl_set_button_shortcut(obj, scex(_("Insert vReference|#V")), 1);
+    fl_set_object_lsize(obj, FL_NORMAL_SIZE);
+    fl_set_object_gravity(obj, FL_SouthWest, FL_SouthWest);
+    fl_set_object_callback(obj, RefSelectCB, 2);
+  fdui->vpageref = obj = fl_add_button(FL_NORMAL_BUTTON, 310, 180, 160, 30, idex(_("Insert vPage Number|#N")));fl_set_button_shortcut(obj, scex(_("Insert vPage Number|#N")), 1);
+    fl_set_object_lsize(obj, FL_NORMAL_SIZE);
+    fl_set_object_gravity(obj, FL_SouthWest, FL_SouthWest);
+    fl_set_object_callback(obj, RefSelectCB, 3);
+  fdui->prettyref = obj = fl_add_button(FL_NORMAL_BUTTON, 310, 220, 160, 30, idex(_("Insert Pretty Ref|#T")));fl_set_button_shortcut(obj, scex(_("Insert Pretty Ref|#T")), 1);
+    fl_set_object_lsize(obj, FL_NORMAL_SIZE);
+    fl_set_object_gravity(obj, FL_SouthWest, FL_SouthWest);
+    fl_set_object_callback(obj, RefSelectCB, 4);
   fl_end_form();
 
   //fdui->form_ref->fdui = fdui;
index 6677d3d37ac14e4614303f1c973e131cb79e464d..7426edf78c54d9ae7c0ddb815d9c3a1e80386ed6 100644 (file)
--- a/src/lyx.h
+++ b/src/lyx.h
@@ -73,6 +73,10 @@ typedef struct {
        long  ldata;
        FL_OBJECT *browser_ref;
        FL_OBJECT *ref_name;
+       FL_OBJECT *sort;
+       FL_OBJECT *vref;
+       FL_OBJECT *vpageref;
+       FL_OBJECT *prettyref;
 } FD_form_ref;
 
 extern FD_form_ref * create_form_form_ref(void);
index e11d0b9a992437711802aeca478034b89298b5fc..f51570f0fd8dd3e8d21ce1322e718c6159fc69e3 100644 (file)
@@ -55,7 +55,8 @@ using std::cout;
 using std::ios;
 using std::istream_iterator;
 using std::pair;
-using std::reverse;
+using std::vector;
+using std::sort;
 
 extern Combox * combo_language;
 extern Combox * combo_language2;
@@ -3100,14 +3101,7 @@ void Reconfigure(BufferView * bv)
 // Table of Contents
 //
 
-struct TocList {
-       int counter[6];
-       bool appendix;
-       TocList * next;
-};
-
-
-static TocList * toclist = 0;
+static vector<Buffer::TocItem> toclist;
 
 
 extern "C" void TocSelectCB(FL_OBJECT * ob, long)
@@ -3115,40 +3109,19 @@ extern "C" void TocSelectCB(FL_OBJECT * ob, long)
        if (!current_view->available())
                return;
    
-       TocList * tmptoclist = toclist;
-       int i = fl_get_browser(ob);
-       for (int a = 1; a < i && tmptoclist->next; ++a) {
-               tmptoclist = tmptoclist->next;
-       }
-
-       if (!tmptoclist)
-               return;
-     
-
-       LyXParagraph * par = current_view->buffer()->paragraph;
-       while (par && (par->GetFirstCounter(0) != tmptoclist->counter[0] ||
-                      par->GetFirstCounter(1) != tmptoclist->counter[1] ||
-                      par->GetFirstCounter(2) != tmptoclist->counter[2] ||
-                      par->GetFirstCounter(3) != tmptoclist->counter[3] ||
-                      par->GetFirstCounter(4) != tmptoclist->counter[4] ||
-                      par->GetFirstCounter(5) != tmptoclist->counter[5] ||
-                      par->appendix != tmptoclist->appendix)) {
-               par = par->LastPhysicalPar()->Next();
-       }
-   
-       if (par) {
-               current_view->beforeChange();
-               current_view->text->SetCursor(par, 0);
+       TocUpdateCB(0, 0);
+       unsigned int choice = fl_get_browser(ob);
+       if (0 < choice && choice - 1 < toclist.size()) {
+               current_view->beforeChange();
+               current_view->text->SetCursor(toclist[choice-1].par, 0);
                current_view->text->sel_cursor = 
                        current_view->text->cursor;
                current_view->update(0);
-       }
-       else {
+       } else {
                WriteAlert(_("Error"), 
                           _("Couldn't find this label"), 
                           _("in current document."));
        }
-         
 }
 
 
@@ -3160,108 +3133,40 @@ extern "C" void TocCancelCB(FL_OBJECT *, long)
 
 extern "C" void TocUpdateCB(FL_OBJECT *, long)
 {
-       static LyXParagraph * stapar = 0;
-       TocList * tmptoclist = 0;
-   
-       /* deleted the toclist */ 
-       if (toclist){
-               while (toclist){
-                       tmptoclist = toclist->next;
-                       delete toclist;
-                       toclist = tmptoclist;
-               }
-       }
-       toclist = 0;
-       tmptoclist = toclist;
-
-
-       fl_clear_browser(fd_form_toc->browser_toc);
        if (!current_view->available()) {
+               toclist.clear();
+               fl_clear_browser(fd_form_toc->browser_toc);
                fl_add_browser_line(fd_form_toc->browser_toc,
                                    _("*** No Document ***"));
                return;
        }
-       fl_hide_object(fd_form_toc->browser_toc);
-       /* get the table of contents */ 
-       LyXParagraph * par = current_view->buffer()->paragraph;
-       char labeltype;
-       char * line = new char[200];
-       int pos = 0;
-       unsigned char c;
+
+       vector<vector<Buffer::TocItem> > tmp =
+               current_view->buffer()->getTocList();
+       if (toclist == tmp[0])
+               return;
+       toclist = tmp[0];
+
+       static Buffer * buffer = 0;
        int topline = 0;
-   
-       if (stapar == par)
+       int line = 0;
+       if (buffer == current_view->buffer()) {
                topline = fl_get_browser_topline(fd_form_toc->browser_toc);
-       stapar = par;
-   
-       while (par) {
-               labeltype = textclasslist.Style(current_view->buffer()->params.textclass, 
-                                               par->GetLayout()).labeltype;
-      
-               if (labeltype >= LABEL_COUNTER_CHAPTER
-                   && labeltype <= LABEL_COUNTER_CHAPTER +
-                   current_view->buffer()->params.tocdepth) {
-                       /* insert this into the table of contents */ 
-                       /* first indent a little bit */ 
-                       
-                       for (pos = 0; 
-                            pos < (labeltype - 
-                                   textclasslist.TextClass(current_view->buffer()->
-                                                           params.textclass).maxcounter()) * 4 + 2;
-                            ++pos)
-                               line[pos] = ' ';
-                       
-                       // Then the labestring
-                       if (!par->labelstring.empty()) {
-                               string::size_type i = 0;
-                               while (pos < 199 && i < par->labelstring.length()) {
-                                       line[pos] = par->labelstring[i];
-                                       ++i;
-                                       ++pos;
-                               }
-                       }
-        
-                       line[pos] = ' ';
-                       ++pos;
-                       int pos0 = pos;
-                       
-                       /* now the contents */
-                       LyXParagraph::size_type i = 0;
-                       while (pos < 199 && i < par->size()) {
-                               c = par->GetChar(i);
-                               if (isprint(c) || c >= 128) {
-                                       line[pos] = c;
-                                       ++pos;
-                               }
-                               ++i;
-                       }
-                       if (par->isRightToLeftPar())
-                               reverse(line + pos0, line + pos);
-                       
-                       line[pos] = '\0';
-                       fl_add_browser_line(fd_form_toc->browser_toc, line);
-                       
-                       /* make a toclist entry */
-                       if (!tmptoclist){
-                               tmptoclist = new TocList;
-                               toclist = tmptoclist;
-                       } else {
-                               tmptoclist->next = new TocList;
-                               tmptoclist = tmptoclist->next;
-                       }
-                       
-                       tmptoclist->next = 0;
-                       int a = 0;
-                       for (a = 0; a < 6; ++a) {
-                               tmptoclist->counter[a] = par->GetFirstCounter(a);
-                       }
-                       tmptoclist->appendix = par->appendix;
-               }
-               par = par->LastPhysicalPar()->Next();
-               
-       }
-       delete[] line;
+               line = fl_get_browser(fd_form_toc->browser_toc);
+       } else
+               buffer = current_view->buffer();
+
+       fl_clear_browser(fd_form_toc->browser_toc);
+       fl_hide_object(fd_form_toc->browser_toc);
+
+       for (vector<Buffer::TocItem>::const_iterator it = toclist.begin();
+            it != toclist.end(); ++it)
+               fl_add_browser_line(fd_form_toc->browser_toc,
+                                   (string(4*(*it).depth,' ')+
+                                    (*it).str).c_str());
+
        fl_set_browser_topline(fd_form_toc->browser_toc, topline);
+       fl_select_browser_line(fd_form_toc->browser_toc, line);
        fl_show_object(fd_form_toc->browser_toc);
 }
 
@@ -3280,18 +3185,17 @@ extern "C" void RefSelectCB(FL_OBJECT *, long data)
        if (s.empty())
                return;
 
-        if (data == 2) {
+        if (data >= 5) {
                 current_view->owner()->getLyXFunc()->Dispatch(LFUN_REFGOTO, s.c_str());
                return;
        }
-           
-       string t;
-       if (data == 0)
-               t += "\\ref";
-       else
-               t += "\\pageref";
 
-       if(current_view->buffer()->isSGML())
+       static string const commands[5]
+               = { "\\ref", "\\pageref", "\\vref", "\\vpageref",
+                   "\\prettyref"};
+       string t = commands[data];
+
+       if (current_view->buffer()->isSGML())
                t += "[" + u + "]" + "{" + s + "}";
        else
                t += "{" + s + "}";
@@ -3317,11 +3221,16 @@ extern "C" void RefUpdateCB(FL_OBJECT *, long)
        string currentstr = btmp ? btmp : "";
 
        fl_clear_browser(brow);
+       fl_hide_object(brow);
 
-       string refs = current_view->buffer()->getReferenceList('\n');
-       int topline = 1;
+       vector<string> refs = current_view->buffer()->getLabelList();
+       if (fl_get_button(fd_form_ref->sort))
+               sort(refs.begin(),refs.end());
+       for (vector<string>::const_iterator it = refs.begin();
+            it != refs.end(); ++it)
+               fl_add_browser_line(brow, (*it).c_str());
 
-       fl_addto_browser_chars(brow, refs.c_str());
+       int topline = 1;
        int total_lines = fl_get_browser_maxline(brow);
        for (int i = 1; i <= total_lines ; ++i) {
                if (fl_get_browser_line(brow, i) == currentstr) {
@@ -3347,11 +3256,25 @@ extern "C" void RefUpdateCB(FL_OBJECT *, long)
        if (!current_view->buffer()->isSGML()) {
                fl_deactivate_object(fd_form_ref->ref_name);
                fl_set_object_lcol(fd_form_ref->ref_name, FL_INACTIVE);
-       }
-       else {
+
+               fl_activate_object(fd_form_ref->vref);
+               fl_set_object_lcol(fd_form_ref->vref, FL_BLACK);
+               fl_activate_object(fd_form_ref->vpageref);
+               fl_set_object_lcol(fd_form_ref->vpageref, FL_BLACK);
+               fl_activate_object(fd_form_ref->prettyref);
+               fl_set_object_lcol(fd_form_ref->prettyref, FL_BLACK);
+       } else {
                fl_activate_object(fd_form_ref->ref_name);
                fl_set_object_lcol(fd_form_ref->ref_name, FL_BLACK);
+
+               fl_deactivate_object(fd_form_ref->vref);
+               fl_set_object_lcol(fd_form_ref->vref, FL_INACTIVE);
+               fl_deactivate_object(fd_form_ref->vpageref);
+               fl_set_object_lcol(fd_form_ref->vpageref, FL_INACTIVE);
+               fl_deactivate_object(fd_form_ref->prettyref);
+               fl_set_object_lcol(fd_form_ref->prettyref, FL_INACTIVE);
        }
+       fl_show_object(brow);
 }
 
 
index e119a160d1f76a0bc44ebce7430c097d3060807d..ba13ea8b522f024b0201cdf0e62749546b459cc0 100644 (file)
@@ -1294,10 +1294,7 @@ string LyXFunc::Dispatch(int ac,
                InsetRef * inset = 
                        static_cast<InsetRef*>(getInsetByCode(Inset::REF_CODE));
                if (inset) {
-                       if (inset->getFlag() == InsetRef::REF)
-                               inset->setFlag(InsetRef::PAGE_REF);
-                       else
-                               inset->setFlag(InsetRef::REF);
+                       inset->Toggle();
                        owner->view()->updateInset(inset, true);
                } else {
                        setErrorMessage(N_("No cross-reference to toggle"));
@@ -1323,7 +1320,10 @@ string LyXFunc::Dispatch(int ac,
                
                if (!label.empty()) {
                        owner->view()->savePosition();
-                       owner->view()->gotoLabel(label.c_str());
+                       if (!owner->view()->gotoLabel(label))
+                               WriteAlert(_("Error"), 
+                                          _("Couldn't find this label"), 
+                                          _("in current document."));
                }
        }
        break;
@@ -3077,23 +3077,15 @@ void LyXFunc::CloseBuffer()
 
 Inset * LyXFunc::getInsetByCode(Inset::Code code)
 {
-       bool found = false;
-       Inset * inset = 0;
        LyXCursor cursor = owner->view()->text->cursor;
-       LyXParagraph::size_type pos = cursor.pos;
-       LyXParagraph * par = cursor.par;
-       
-       while (par && !found) {
-               while ((inset = par->ReturnNextInsetPointer(pos))){
-                       if (inset->LyxCode() == code) {
-                               found = true;
-                               break;
-                       }
-                       ++pos;
-               } 
-               par = par->next;
+       Buffer * buffer = owner->view()->buffer();
+       for (Buffer::inset_iterator it = Buffer::inset_iterator(cursor.par,
+                                                               cursor.pos);
+            it != buffer->inset_iterator_end(); ++it) {
+               if ((*it)->LyxCode() == code)
+                       return *it;
        }
-       return found ? inset : 0;
+       return 0;
 }
 
 
index f2aec60ef20434616a3b8a5c3a979150547c5413..7852ca9dd5f6a111617ec412af1f86b1d93a311f 100644 (file)
@@ -132,6 +132,8 @@ public:
        void ChangeLanguage(Language const * from, Language const * to);
        ///
        bool isMultiLingual();
+       ///
+       string String(bool label);
        
        ///
        void writeFile(std::ostream &, BufferParams const &, char, char) const;
@@ -415,8 +417,6 @@ public:
        ///
        Inset const * GetInset(size_type pos) const;
        ///
-       Inset * ReturnNextInsetPointer(size_type & pos);
-       ///
        void OpenFootnote(size_type pos);
        ///
        void CloseFootnote(size_type pos);
@@ -601,6 +601,37 @@ private:
        unsigned int id_;
        ///
        static unsigned int paragraph_id;
+public:
+       class inset_iterator {
+       public:
+               inset_iterator() {}
+               inset_iterator(InsetList::iterator const & iter) : it(iter) {};
+               inset_iterator & operator++() {
+                       ++it;
+                       return *this;
+               }
+               Inset * operator*() { return (*it).inset; }
+               size_type getPos() {return (*it).pos; }
+               bool operator==(inset_iterator const & iter) const {
+                       return it == iter.it;
+               }
+               bool operator!=(inset_iterator const & iter) const {
+                       return it != iter.it;
+               }
+       private:
+               InsetList::iterator it;
+       };
+       ///
+       inset_iterator inset_iterator_begin() {
+               return inset_iterator(insetlist.begin());
+       }
+       ///
+       inset_iterator inset_iterator_end() {
+               return inset_iterator(insetlist.end());
+       }
+       ///
+       inset_iterator InsetIterator(size_type pos);
+
 };
 
 #endif
index 8282d5475760f0a87337758e5c5836ca8d34185b..bfdd7a37ec057d54fdd169dac0c680710e2b5341 100644 (file)
@@ -47,6 +47,7 @@ using std::ostream;
 using std::istream;
 using std::pair;
 using std::endl;
+using std::vector;
 
 extern char * mathed_label;
 
@@ -602,48 +603,25 @@ void InsetFormula::display(bool dspf)
 }
 
 
-int InsetFormula::GetNumberOfLabels() const
+vector<string> InsetFormula::getLabelList() const
 {
-   // This is dirty, I know. I'll clean it at 0.13
-   if (par->GetType() == LM_OT_MPARN) {
-       MathMatrixInset * mt = static_cast<MathMatrixInset*>(par);
-       int nl = 0;
-       MathedRowSt const * crow = mt->getRowSt();
-       while (crow) {
-          if (crow->getLabel()) ++nl;
-          crow = crow->getNext();
-       }
-       return nl;
-   } else
-   if (!label.empty())
-       return 1;
-   else
-       return 0;
-}
+//#warning This is dirty, I know. Ill clean it at 0.11
+// Correction, the only way to clean this is with a new kernel: 0.13.
 
+       vector<string> label_list;
 
-string InsetFormula::getLabel(int il) const
-{
-//#warning This is dirty, I know. Ill clean it at 0.11
-       // Correction, the only way to clean this is with a new kernel: 0.13.
        if (par->GetType() == LM_OT_MPARN) {
-               string lab;
                MathMatrixInset * mt = static_cast<MathMatrixInset*>(par);
-               int nl = 0;
                MathedRowSt const * crow = mt->getRowSt();
                while (crow) {
-                       if (crow->getLabel()) {
-                               if (nl == il) {
-                                       lab = crow->getLabel();
-                                       break;
-                               }
-                               ++nl;
-                       }
+                       if (crow->getLabel())
+                               label_list.push_back(crow->getLabel());
                        crow = crow->getNext();
                }
-               return lab;
-       }
-       return label;
+       } else if (!label.empty())
+               label_list.push_back(label);
+
+       return label_list;
 }
 
 
index 6e6ffab61692498b5a42ba9036992fa8c3ae1f93..da8f6d69dc54494e7eabe1e0618cf94f5c17e50b 100644 (file)
@@ -110,9 +110,7 @@ public:
        ///
        bool SetNumber(bool);
        ///
-       int GetNumberOfLabels() const;
-       ///
-       string getLabel(int) const;
+       std::vector<string> getLabelList() const;
    
 protected:
        void UpdateLocal(BufferView * bv);
index 7e186f7f51e2f0de3420d73c515f8a256f4f0728..56032e79547b65109239a881a4245f354d0eaf3f 100644 (file)
@@ -26,6 +26,8 @@
 #pragma implementation
 #endif
 
+#include <algorithm>
+
 #include "menus.h"
 #include "version.h"
 #include "lyxfont.h"
 #include "layout.h"
 #include "lyx_cb.h"
 #include "bufferview_funcs.h"
+#include "insets/insetref.h"
 #include "insets/insettabular.h"
 #include "tabular.h"
 
 using std::vector;
 using std::endl;
+using std::max;
+using std::sort;
 
 extern FD_form_screen * fd_form_screen;
 extern BufferList bufferlist;
@@ -81,6 +86,16 @@ extern "C" void C_Menus_ShowEditMenu(FL_OBJECT * ob, long data)
        Menus::ShowEditMenu(ob, data);
 }
 
+extern "C" void C_Menus_ShowTocMenu(FL_OBJECT * ob, long data)
+{
+       Menus::ShowTocMenu(ob, data);
+}
+
+extern "C" void C_Menus_ShowRefsMenu(FL_OBJECT * ob, long data)
+{
+       Menus::ShowRefsMenu(ob, data);
+}
+
 extern "C" void C_Menus_ShowLayoutMenu(FL_OBJECT * ob, long data)
 {
        Menus::ShowLayoutMenu(ob, data);
@@ -120,6 +135,8 @@ Menus::Menus(LyXView * view, int air)
        fl_set_object_shortcut(menu_file, "", 1);
        fl_set_object_shortcut(menu_file2, "", 1);
        fl_set_object_shortcut(menu_edit, "", 1);
+       fl_set_object_shortcut(menu_toc, "", 1);
+       fl_set_object_shortcut(menu_refs, "", 1);
        fl_set_object_shortcut(menu_layout, "", 1);
        fl_set_object_shortcut(menu_math, "", 1);
        fl_set_object_shortcut(menu_insert, "", 1);
@@ -166,6 +183,10 @@ void Menus::openByName(string const & menuName)
                        ShowFileMenu(menu_file, 0);
                else if (menuName == _("Edit"))
                        ShowEditMenu(menu_edit, 0);
+               else if (menuName == _("TOC"))
+                       ShowTocMenu(menu_toc, 0);
+               else if (menuName == _("Refs"))
+                       ShowRefsMenu(menu_refs, 0);
                else if (menuName == _("Layout"))
                        ShowLayoutMenu(menu_layout, 0);
                else if (menuName == _("Insert"))
@@ -244,6 +265,34 @@ void Menus::create_menus(int air)
        fl_set_object_callback(obj, C_Menus_ShowEditMenu, 0);
        obj->u_vdata = this;
        
+       /// TOC menu button
+       menu_toc = obj = 
+               fl_add_button(FL_TOUCH_BUTTON,
+                             moffset, yloc,
+                             fl_get_string_width(FL_BOLD_STYLE,
+                                                 MENU_LABEL_SIZE,
+                                                 _("TOC"),
+                                                 strlen(_("TOC"))) + mbadd,
+                             mbheight, _("TOC"));
+       moffset += obj->w + air;
+       fl_set_object_shortcut(obj, scex(_("MB|#T")), 1);
+       fl_set_object_callback(obj, C_Menus_ShowTocMenu, 0);
+       obj->u_vdata = this;
+
+       /// Refs menu button
+       menu_refs = obj = 
+               fl_add_button(FL_TOUCH_BUTTON,
+                             moffset, yloc,
+                             fl_get_string_width(FL_BOLD_STYLE,
+                                                 MENU_LABEL_SIZE,
+                                                 _("Refs"),
+                                                 strlen(_("Refs"))) + mbadd,
+                             mbheight, _("Refs"));
+       moffset += obj->w + air;
+       fl_set_object_shortcut(obj, scex(_("MB|#R")), 1);
+       fl_set_object_callback(obj, C_Menus_ShowRefsMenu, 0);
+       obj->u_vdata = this;
+
        // Layout menu button
        menu_layout = obj = 
                fl_add_button(FL_TOUCH_BUTTON,
@@ -1225,6 +1274,201 @@ void Menus::ShowEditMenu(FL_OBJECT * ob, long)
 }
 
 
+void Add_to_toc_menu(vector<Buffer::TocItem> const & toclist, 
+                    unsigned int from, unsigned int to, int depth,
+                    int menu, vector<int> & menus, FL_OBJECT * ob)
+{
+       unsigned int const max_number_of_items = 25;
+       if (to - from <= max_number_of_items)
+               for (unsigned int i = from; i < to; ++i)
+                       fl_addtopup(menu,
+                                   (string(4*max(0,toclist[i].depth-depth),' ')
+                                    + toclist[i].str + "%x"
+                                    + tostr(i+1)).c_str());
+       else {
+               unsigned int pos = from;
+               while (pos < to) {
+                       unsigned int new_pos = pos+1;
+                       while (new_pos < to &&
+                              toclist[new_pos].depth > depth)
+                               ++new_pos;
+                       if (new_pos == pos+1) {
+                               fl_addtopup(menu,
+                                           (string(4*max(0,toclist[pos].depth-depth),' ')
+                                            + toclist[pos].str + "%x"
+                                            + tostr(pos+1)).c_str() );
+                       } else {
+                               int menu2 = fl_newpup(FL_ObjWin(ob));
+                               menus.push_back(menu2);
+                               Add_to_toc_menu(toclist, pos, new_pos,
+                                               depth+1, menu2, menus,ob);
+                               fl_addtopup(menu,
+                                           (string(4*max(0,toclist[pos].depth-depth),' ')
+                                            + toclist[pos].str+"%m").c_str(),
+                                           menu2);
+                       }
+                       pos = new_pos;
+               }
+       }
+}
+
+int const BIG_NUM = 1048576;
+
+void Menus::ShowTocMenu(FL_OBJECT * ob, long)
+{
+       Menus * men = static_cast<Menus*>(ob->u_vdata);
+       vector<int> menus;
+
+       // set the pseudo menu-button
+       fl_set_object_boxtype(ob, FL_UP_BOX);
+       fl_set_button(ob, 0);
+       fl_redraw_object(ob);
+   
+       int TocMenu = fl_newpup(FL_ObjWin(ob));
+       menus.push_back(TocMenu);
+       vector<vector<Buffer::TocItem> > toclist =
+               men->currentView()->buffer()->getTocList();
+
+       static char const * MenuNames[3] = { N_("List of Figures%m%l"),
+                                            N_("List of Tables%m%l"),
+                                            N_("List of Algorithms%m%l") };
+       for (int j = 1; j <= 3; ++j)
+               if (!toclist[j].empty()) {
+                       int menu2 = fl_newpup(FL_ObjWin(ob));
+                       menus.push_back(menu2);
+                       for (unsigned int i = 0; i < toclist[j].size(); ++i)
+                               fl_addtopup(menu2,
+                                           (toclist[j][i].str + "%x"
+                                            + tostr(i+1+j*BIG_NUM)).c_str());
+                       fl_addtopup(TocMenu, _(MenuNames[j-1]), menu2);
+               }
+
+       Add_to_toc_menu(toclist[0], 0, toclist[0].size(), 0,
+                       TocMenu, menus, ob);
+
+       fl_setpup_position(
+               men->_view->getForm()->x + ob->x,
+               men->_view->getForm()->y + ob->y + ob->h + 10);   
+       int choice = fl_dopup(TocMenu);
+       XFlush(fl_display);
+
+       // set the pseudo menu-button back
+       fl_set_object_boxtype(ob, FL_FLAT_BOX);
+       fl_redraw_object(ob);
+       if (choice == 0)
+               men->_view->getLyXFunc()->Dispatch(LFUN_TOCVIEW);
+       else if (choice > 0) {
+               int type = choice / BIG_NUM;
+               int num = (choice % BIG_NUM) - 1;
+               BufferView *bv = men->currentView();
+               bv->beforeChange();
+               bv->text->SetCursor(toclist[type][num].par, 0);
+               bv->text->sel_cursor = bv->text->cursor;
+               bv->update(0);
+       }
+       for (unsigned int i = 0; i < menus.size(); ++i)
+               fl_freepup(menus[i]);
+}
+
+void Add_to_refs_menu(vector<string> const & label_list, int offset,
+                    int menu, vector<int> & menus, FL_OBJECT * ob)
+{
+       unsigned int const max_number_of_items = 25;
+       unsigned int const max_number_of_items2 = 20;
+
+       if (label_list.size() <= max_number_of_items)
+               for (unsigned int i = 0; i < label_list.size(); ++i)
+                       fl_addtopup(menu,
+                                   (label_list[i] + "%x"
+                                    +tostr(i+offset)).c_str());
+       else
+               for (unsigned int i = 0; i < label_list.size();
+                    i += max_number_of_items2) {
+                       unsigned int j = std::min(label_list.size(),
+                                                 i+max_number_of_items2);
+                       int menu2 = fl_newpup(FL_ObjWin(ob));
+                       menus.push_back(menu2);
+                       for (unsigned int k = i;  k < j; ++k)
+                               fl_addtopup(menu2,
+                                           (label_list[k] + "%x"
+                                            + tostr(k+offset)).c_str());
+                       fl_addtopup(menu,
+                                   (label_list[i]+".."
+                                    +label_list[j-1]+"%m").c_str(),
+                                   menu2);
+               }
+
+
+}
+
+void Menus::ShowRefsMenu(FL_OBJECT * ob, long)
+{
+       vector<int> menus;
+
+       Menus * men = static_cast<Menus*>(ob->u_vdata);
+
+       // set the pseudo menu-button
+       fl_set_object_boxtype(ob, FL_UP_BOX);
+       fl_set_button(ob, 0);
+       fl_redraw_object(ob);
+   
+       int RefsMenu = fl_newpup(FL_ObjWin(ob));
+       menus.push_back(RefsMenu);
+       Buffer * buffer = men->currentView()->buffer();
+       vector<string> label_list = buffer->getLabelList();
+       sort(label_list.begin(), label_list.end());
+
+       static char const * MenuNames[5] = { N_("Insert Page Number%m"),
+                                            N_("Insert vref%m"),
+                                            N_("Insert vpageref%m"),
+                                            N_("Insert Pretty Ref%m"),
+                                            N_("Goto Reference%m%l") };
+
+       for (int j = 1; j <= 5; ++j) {
+               int menu2 = fl_newpup(FL_ObjWin(ob));
+               menus.push_back(menu2);
+               Add_to_refs_menu(label_list, 1+j*BIG_NUM, menu2, menus, ob);
+               fl_addtopup(RefsMenu, _(MenuNames[j-1]), menu2);
+       }
+
+       fl_addtopup(RefsMenu, _("Insert Reference:%d%x0"));
+       Add_to_refs_menu(label_list, 1, RefsMenu, menus, ob);
+
+       if (label_list.empty()) {
+               fl_setpup_mode(RefsMenu, 1, FL_PUP_GREY);
+               fl_setpup_mode(RefsMenu, 2, FL_PUP_GREY);
+       }
+
+       fl_setpup_position(
+               men->_view->getForm()->x + ob->x,
+               men->_view->getForm()->y + ob->y + ob->h + 10);   
+       int choice = fl_dopup(RefsMenu);
+       XFlush(fl_display);
+
+       // set the pseudo menu-button back
+       fl_set_object_boxtype(ob, FL_FLAT_BOX);
+       fl_redraw_object(ob);
+
+       if (choice > 0) {
+               int type = choice / BIG_NUM;
+               int num = (choice % BIG_NUM) - 1;
+               if (type >= 5)
+                       men->_view->getLyXFunc()->Dispatch(LFUN_REFGOTO,
+                                                          label_list[num].c_str());
+               else {
+                       static string const commands[5]
+                               = { "\\ref", "\\pageref", "\\vref", "\\vpageref",
+                                   "\\prettyref"};
+                       string t = commands[type] + "{" + label_list[num] + "}";
+                       men->currentView()->insertInset(new InsetRef(t, buffer));
+               }
+       }
+
+       for (unsigned int i = 0; i < menus.size(); ++i)
+               fl_freepup(menus[i]);
+}
+
+
 void Menus::ShowLayoutMenu(FL_OBJECT * ob, long)
 {
        Menus * men = static_cast<Menus*>(ob->u_vdata);
index 92350d6241334aa04848b5c67cc4448c471b60ca..46223efe930a89a73ef15ea71df6b90dda3d57e9 100644 (file)
@@ -42,6 +42,10 @@ public:
        ///
        static void ShowEditMenu(FL_OBJECT *ob, long data);
        ///
+       static void ShowTocMenu(FL_OBJECT *ob, long data);
+       ///
+       static void ShowRefsMenu(FL_OBJECT *ob, long data);
+       ///
        static void ShowLayoutMenu(FL_OBJECT *ob, long data);
        ///
        static void ShowInsertMenu(FL_OBJECT *ob, long data);
@@ -82,6 +86,10 @@ private:
        ///
        FL_OBJECT *menu_edit;
        ///
+       FL_OBJECT *menu_toc;
+       ///
+       FL_OBJECT *menu_refs;
+       ///
        FL_OBJECT *menu_layout;
        ///
        FL_OBJECT *menu_insert;
index 6cf88c4815038ba3e75b4e3629751cb94cd09876..6464dfe2d90a44c3e53e6ea998593981fba833e4 100644 (file)
@@ -1930,16 +1930,12 @@ int LyXParagraph::AutoDeleteInsets()
 }
 
 
-Inset * LyXParagraph::ReturnNextInsetPointer(LyXParagraph::size_type & pos)
+LyXParagraph::inset_iterator LyXParagraph::InsetIterator(LyXParagraph::size_type pos)
 {
        InsetList::iterator it = lower_bound(insetlist.begin(),
                                             insetlist.end(),
                                             pos, matchIT());
-       if (it != insetlist.end()) {
-               pos = (*it).pos;
-               return (*it).inset;
-       }
-       return 0;
+       return inset_iterator(it);
 }
 
 
@@ -4261,3 +4257,41 @@ bool LyXParagraph::isMultiLingual()
        }
        return false;
 }
+
+
+// Convert the paragraph to a string.
+// Used for building the table of contents
+string LyXParagraph::String(bool label)
+{
+       string s;
+       if (label && !IsDummy())
+               s += labelstring + ' ';
+       string::size_type len = s.size();
+
+       for (LyXParagraph::size_type i = 0;i < size(); ++i) {
+               unsigned char c = GetChar(i);
+               if (IsPrintable(c))
+                       s += c;
+               else if (c == META_INSET &&
+                        GetInset(i)->LyxCode() == Inset::MATH_CODE) {
+#ifdef HAVE_SSTREAM
+                       std::ostringstream ost;
+                       GetInset(i)->Ascii(ost);
+#else
+                       ostrstream ost;
+                       GetInset(i)->Ascii(ost);
+                       ost << '\0';
+#endif
+                       s += subst(ost.str(),'\n',' ');
+               }
+       }
+
+       if (next && next->footnoteflag != LyXParagraph::NO_FOOTNOTE)
+               s += NextAfterFootnote()->String(false);
+
+       if (!IsDummy()) {
+               if (isRightToLeftPar())
+                       reverse(s.begin() + len,s.end());
+       }
+       return s;
+}