]> git.lyx.org Git - lyx.git/blobdiff - src/Text.cpp
1.) some white spaces removed
[lyx.git] / src / Text.cpp
index c149ad7973a26214e48aaf9f34bc8e2feab9addb..91b8a5f02a456ad58c5df78fd1736cfc0c0e8030 100644 (file)
@@ -4,14 +4,14 @@
  * Licence details can be found in the file COPYING.
  *
  * \author Asger Alstrup
- * \author Lars Gullik Bjønnes
+ * \author Lars Gullik Bjønnes
  * \author Dov Feldstern
  * \author Jean-Marc Lasgouttes
  * \author John Levon
- * \author André Pönitz
+ * \author André Pönitz
  * \author Stefan Schimanski
  * \author Dekel Tsur
- * \author Jürgen Vigna
+ * \author Jürgen Vigna
  *
  * Full author contact details are available in file CREDITS.
  */
 #include "insets/InsetSpecialChar.h"
 #include "insets/InsetTabular.h"
 
-#include "support/lassert.h"
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstream.h"
 #include "support/gettext.h"
+#include "support/lassert.h"
 #include "support/lstrings.h"
 #include "support/textutils.h"
 
@@ -293,7 +293,8 @@ class TextCompletionList : public CompletionList
 public:
        ///
        TextCompletionList(Cursor const & cur)
-       : buf_(cur.buffer()), pos_(0) {}
+               : buffer_(cur.buffer()), pos_(0)
+       {}
        ///
        virtual ~TextCompletionList() {}
        
@@ -312,7 +313,7 @@ public:
        
 private:
        ///
-       Buffer const & buf_;
+       Buffer const * buffer_;
        ///
        size_t pos_;
 };
@@ -341,7 +342,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
        Paragraph & cpar = cur.paragraph();
        pit_type cpit = cur.pit();
 
-       DocumentClass const & tclass = cur.buffer().params().documentClass();
+       DocumentClass const & tclass = cur.buffer()->params().documentClass();
        Layout const & layout = cpar.layout();
 
        // this is only allowed, if the current paragraph is not empty
@@ -356,7 +357,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
        // Always break behind a space
        // It is better to erase the space (Dekel)
        if (cur.pos() != cur.lastpos() && cpar.isLineSeparator(cur.pos()))
-               cpar.eraseChar(cur.pos(), cur.buffer().params().trackChanges);
+               cpar.eraseChar(cur.pos(), cur.buffer()->params().trackChanges);
 
        // What should the layout for the new paragraph be?
        bool keep_layout = inverse_logic ? 
@@ -370,7 +371,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
        // we need to set this before we insert the paragraph.
        bool const isempty = cpar.allowEmpty() && cpar.empty();
 
-       lyx::breakParagraph(cur.buffer().params(), paragraphs(), cpit,
+       lyx::breakParagraph(cur.buffer()->params(), paragraphs(), cpit,
                         cur.pos(), keep_layout);
 
        // After this, neither paragraph contains any rows!
@@ -391,11 +392,11 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
        }
 
        while (!pars_[next_par].empty() && pars_[next_par].isNewline(0)) {
-               if (!pars_[next_par].eraseChar(0, cur.buffer().params().trackChanges))
+               if (!pars_[next_par].eraseChar(0, cur.buffer()->params().trackChanges))
                        break; // the character couldn't be deleted physically due to change tracking
        }
 
-       updateLabels(cur.buffer());
+       cur.buffer()->updateLabels();
 
        // A singlePar update is not enough in this case.
        cur.updateFlags(Update::Force);
@@ -418,7 +419,7 @@ void Text::insertChar(Cursor & cur, char_type c)
        cur.recordUndo(INSERT_UNDO);
 
        TextMetrics const & tm = cur.bv().textMetrics(this);
-       Buffer const & buffer = cur.buffer();
+       Buffer const & buffer = *cur.buffer();
        Paragraph & par = cur.paragraph();
        // try to remove this
        pit_type const pit = cur.pit();
@@ -538,7 +539,8 @@ void Text::insertChar(Cursor & cur, char_type c)
                }
        }
 
-       par.insertChar(cur.pos(), c, cur.current_font, cur.buffer().params().trackChanges);
+       par.insertChar(cur.pos(), c, cur.current_font,
+               cur.buffer()->params().trackChanges);
        cur.checkBufferStructure();
 
 //             cur.updateFlags(Update::Force);
@@ -689,11 +691,9 @@ bool Text::cursorVisLeftOneWord(Cursor & cur)
                // we should stop when we have an LTR word on our right or an RTL word
                // on our left
                if ((left_is_letter && temp_cur.paragraph().getFontSettings(
-                               temp_cur.bv().buffer().params(), 
-                               left_pos).isRightToLeft())
+                               temp_cur.buffer()->params(), left_pos).isRightToLeft())
                        || (right_is_letter && !temp_cur.paragraph().getFontSettings(
-                               temp_cur.bv().buffer().params(), 
-                               right_pos).isRightToLeft()))
+                               temp_cur.buffer()->params(), right_pos).isRightToLeft()))
                        break;
        }
 
@@ -728,10 +728,10 @@ bool Text::cursorVisRightOneWord(Cursor & cur)
                // we should stop when we have an LTR word on our right or an RTL word
                // on our left
                if ((left_is_letter && temp_cur.paragraph().getFontSettings(
-                               temp_cur.bv().buffer().params(), 
+                               temp_cur.buffer()->params(), 
                                left_pos).isRightToLeft())
                        || (right_is_letter && !temp_cur.paragraph().getFontSettings(
-                               temp_cur.bv().buffer().params(), 
+                               temp_cur.buffer()->params(), 
                                right_pos).isRightToLeft()))
                        break;
        }
@@ -757,6 +757,25 @@ void Text::selectWord(Cursor & cur, word_location loc)
 }
 
 
+void Text::selectAll(Cursor & cur)
+{
+       LASSERT(this == cur.text(), /**/);
+       if (cur.lastpos() == 0 && cur.lastpit() == 0)
+               return;
+       // If the cursor is at the beginning, make sure the cursor ends there
+       if (cur.pit() == 0 && cur.pos() == 0) {
+               setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size());
+               cur.resetAnchor();
+               setCursor(cur, 0, 0);           
+       } else {
+               setCursor(cur, 0, 0);
+               cur.resetAnchor();
+               setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size());
+       }
+       cur.setSelection();
+}
+
+
 // Select the word currently under the cursor when no
 // selection is currently set
 bool Text::selectWordWhenUnderCursor(Cursor & cur, word_location loc)
@@ -809,9 +828,9 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
                pos_type right = (pit == endPit ? endPos : parSize);
 
                if (op == ACCEPT) {
-                       pars_[pit].acceptChanges(cur.buffer().params(), left, right);
+                       pars_[pit].acceptChanges(cur.buffer()->params(), left, right);
                } else {
-                       pars_[pit].rejectChanges(cur.buffer().params(), left, right);
+                       pars_[pit].rejectChanges(cur.buffer()->params(), left, right);
                }
        }
 
@@ -838,7 +857,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
                                        // instead, we mark it unchanged
                                        pars_[pit].setChange(pos, Change(Change::UNCHANGED));
                                } else {
-                                       mergeParagraph(cur.buffer().params(), pars_, pit);
+                                       mergeParagraph(cur.buffer()->params(), pars_, pit);
                                        --endPit;
                                        --pit;
                                }
@@ -851,7 +870,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
                                        // we mark the par break at the end of the last paragraph unchanged
                                        pars_[pit].setChange(pos, Change(Change::UNCHANGED));
                                } else {
-                                       mergeParagraph(cur.buffer().params(), pars_, pit);
+                                       mergeParagraph(cur.buffer()->params(), pars_, pit);
                                        --endPit;
                                        --pit;
                                }
@@ -861,7 +880,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
 
        // finally, invoke the DEPM
 
-       deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer().params().trackChanges);
+       deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer()->params().trackChanges);
 
        //
 
@@ -869,7 +888,7 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
        cur.clearSelection();
        setCursorIntern(cur, begPit, begPos);
        cur.updateFlags(Update::Force);
-       updateLabels(cur.buffer());
+       cur.buffer()->updateLabels();
 }
 
 
@@ -922,7 +941,7 @@ void Text::deleteWordForward(Cursor & cur)
                cursorForward(cur);
        else {
                cur.resetAnchor();
-               cur.selection() = true;
+               cur.setSelection(true);
                cursorForwardOneWord(cur);
                cur.setSelection();
                cutSelection(cur, true, false);
@@ -938,7 +957,7 @@ void Text::deleteWordBackward(Cursor & cur)
                cursorBackward(cur);
        else {
                cur.resetAnchor();
-               cur.selection() = true;
+               cur.setSelection(true);
                cursorBackwardOneWord(cur);
                cur.setSelection();
                cutSelection(cur, true, false);
@@ -979,7 +998,7 @@ void Text::changeCase(Cursor & cur, TextCase action)
                Paragraph & par = pars_[pit];
                pos_type const pos = (pit == begPit ? begPos : 0);
                right = (pit == endPit ? endPos : par.size());
-               par.changeCase(cur.buffer().params(), pos, right, action);
+               par.changeCase(cur.buffer()->params(), pos, right, action);
        }
 
        // the selection may have changed due to logically-only deleted chars
@@ -1003,7 +1022,7 @@ bool Text::handleBibitems(Cursor & cur)
        if (cur.pos() != 0)
                return false;
 
-       BufferParams const & bufparams = cur.buffer().params();
+       BufferParams const & bufparams = cur.buffer()->params();
        Paragraph const & par = cur.paragraph();
        Cursor prevcur = cur;
        if (cur.pit() > 0) {
@@ -1018,7 +1037,7 @@ bool Text::handleBibitems(Cursor & cur)
                cur.recordUndo(ATOMIC_UNDO, prevcur.pit());
                mergeParagraph(bufparams, cur.text()->paragraphs(),
                                                        prevcur.pit());
-               updateLabels(cur.buffer());
+               cur.buffer()->updateLabels();
                setCursorIntern(cur, prevcur.pit(), prevcur.pos());
                cur.updateFlags(Update::Force);
                return true;
@@ -1032,7 +1051,7 @@ bool Text::handleBibitems(Cursor & cur)
 
 bool Text::erase(Cursor & cur)
 {
-       LASSERT(this == cur.text(), /**/);
+       LASSERT(this == cur.text(), return false);
        bool needsUpdate = false;
        Paragraph & par = cur.paragraph();
 
@@ -1041,12 +1060,12 @@ bool Text::erase(Cursor & cur)
                // any paragraphs
                cur.recordUndo(DELETE_UNDO);
                bool const was_inset = cur.paragraph().isInset(cur.pos());
-               if(!par.eraseChar(cur.pos(), cur.buffer().params().trackChanges))
+               if(!par.eraseChar(cur.pos(), cur.buffer()->params().trackChanges))
                        // the character has been logically deleted only => skip it
                        cur.top().forwardPos();
 
                if (was_inset)
-                       updateLabels(cur.buffer());
+                       cur.buffer()->updateLabels();
                else
                        cur.checkBufferStructure();
                needsUpdate = true;
@@ -1054,7 +1073,7 @@ bool Text::erase(Cursor & cur)
                if (cur.pit() == cur.lastpit())
                        return dissolveInset(cur);
 
-               if (!par.isMergedOnEndOfParDeletion(cur.buffer().params().trackChanges)) {
+               if (!par.isMergedOnEndOfParDeletion(cur.buffer()->params().trackChanges)) {
                        par.setChange(cur.pos(), Change(Change::DELETED));
                        cur.forwardPos();
                        needsUpdate = true;
@@ -1085,7 +1104,7 @@ bool Text::backspacePos0(Cursor & cur)
 
        bool needsUpdate = false;
 
-       BufferParams const & bufparams = cur.buffer().params();
+       BufferParams const & bufparams = cur.buffer()->params();
        DocumentClass const & tclass = bufparams.documentClass();
        ParagraphList & plist = cur.text()->paragraphs();
        Paragraph const & par = cur.paragraph();
@@ -1122,7 +1141,7 @@ bool Text::backspacePos0(Cursor & cur)
        }
 
        if (needsUpdate) {
-               updateLabels(cur.buffer());
+               cur.buffer()->updateLabels();
                setCursorIntern(cur, prevcur.pit(), prevcur.pos());
        }
 
@@ -1140,7 +1159,7 @@ bool Text::backspace(Cursor & cur)
 
                Paragraph & prev_par = pars_[cur.pit() - 1];
 
-               if (!prev_par.isMergedOnEndOfParDeletion(cur.buffer().params().trackChanges)) {
+               if (!prev_par.isMergedOnEndOfParDeletion(cur.buffer()->params().trackChanges)) {
                        prev_par.setChange(prev_par.size(), Change(Change::DELETED));
                        setCursorIntern(cur, cur.pit() - 1, prev_par.size());
                        return true;
@@ -1160,9 +1179,9 @@ bool Text::backspace(Cursor & cur)
                setCursorIntern(cur, cur.pit(), cur.pos() - 1,
                                false, cur.boundary());
                bool const was_inset = cur.paragraph().isInset(cur.pos());
-               cur.paragraph().eraseChar(cur.pos(), cur.buffer().params().trackChanges);
+               cur.paragraph().eraseChar(cur.pos(), cur.buffer()->params().trackChanges);
                if (was_inset)
-                       updateLabels(cur.buffer());
+                       cur.buffer()->updateLabels();
                else
                        cur.checkBufferStructure();
        }
@@ -1180,14 +1199,15 @@ bool Text::backspace(Cursor & cur)
 }
 
 
-bool Text::dissolveInset(Cursor & cur) {
-       LASSERT(this == cur.text(), /**/);
+bool Text::dissolveInset(Cursor & cur)
+{
+       LASSERT(this == cur.text(), return false);
 
        if (isMainText(cur.bv().buffer()) || cur.inset().nargs() != 1)
                return false;
 
        cur.recordUndoInset();
-       cur.mark() = false;
+       cur.setMark(false);
        cur.selHandle(false);
        // save position
        pos_type spos = cur.pos();
@@ -1200,7 +1220,7 @@ bool Text::dissolveInset(Cursor & cur) {
        if (spit == 0)
                spos += cur.pos();
        spit += cur.pit();
-       Buffer & b = cur.buffer();
+       Buffer & b = *cur.buffer();
        cur.paragraph().eraseChar(cur.pos(), b.params().trackChanges);
        if (!plist.empty()) {
                // ERT paragraphs have the Language latex_language.
@@ -1280,6 +1300,7 @@ bool Text::read(Buffer const & buf, Lexer & lex,
                ErrorList & errorList, InsetText * insetPtr)
 {
        depth_type depth = 0;
+       bool res = true;
 
        while (lex.isOK()) {
                lex.nextToken();
@@ -1297,16 +1318,18 @@ bool Text::read(Buffer const & buf, Lexer & lex,
                if (token == "\\begin_body")
                        continue;
 
-               if (token == "\\end_document")
-                       return false;
+               if (token == "\\end_document") {
+                       res = false;
+                       break;
+               }
 
                if (token == "\\begin_layout") {
                        lex.pushToken(token);
 
                        Paragraph par;
+                       par.setInsetOwner(insetPtr);
                        par.params().depth(depth);
                        par.setFont(0, Font(inherit_font, buf.params().language));
-                       par.setInsetOwner(insetPtr);
                        pars_.push_back(par);
 
                        // FIXME: goddamn InsetTabular makes us pass a Buffer
@@ -1328,14 +1351,26 @@ bool Text::read(Buffer const & buf, Lexer & lex,
                        LYXERR0("Handling unknown body token: `" << token << '\'');
                }
        }
-       return true;
+
+       // avoid a crash on weird documents (bug 4859)
+       if (pars_.empty()) {
+               Paragraph par;
+               par.setInsetOwner(insetPtr);
+               par.params().depth(depth);
+               par.setFont(0, Font(inherit_font, 
+                                   buf.params().language));
+               par.setPlainOrDefaultLayout(buf.params().documentClass());
+               pars_.push_back(par);
+       }
+       
+       return res;
 }
 
 // Returns the current font and depth as a message.
-docstring Text::currentState(Cursor & cur)
+docstring Text::currentState(Cursor const & cur) const
 {
        LASSERT(this == cur.text(), /**/);
-       Buffer & buf = cur.buffer();
+       Buffer & buf = *cur.buffer();
        Paragraph const & par = cur.paragraph();
        odocstringstream os;
 
@@ -1411,7 +1446,7 @@ docstring Text::currentState(Cursor & cur)
 }
 
 
-docstring Text::getPossibleLabel(Cursor & cur) const
+docstring Text::getPossibleLabel(Cursor const & cur) const
 {
        pit_type pit = cur.pit();
 
@@ -1488,6 +1523,25 @@ docstring Text::getPossibleLabel(Cursor & cur) const
 }
 
 
+docstring Text::asString(int options) const
+{
+       return asString(0, pars_.size(), options);
+}
+
+
+docstring Text::asString(pit_type beg, pit_type end, int options) const
+{
+       size_t i = size_t(beg);
+       docstring str = pars_[i].asString(options);
+       for (++i; i != size_t(end); ++i) {
+               str += '\n';
+               str += pars_[i].asString(options);
+       }
+       return str;
+}
+
+
+
 void Text::charsTranspose(Cursor & cur)
 {
        LASSERT(this == cur.text(), /**/);
@@ -1520,17 +1574,17 @@ void Text::charsTranspose(Cursor & cur)
                return;
 
        // Store the characters to be transposed (including font information).
-       char_type char1 = par.getChar(pos1);
+       char_type const char1 = par.getChar(pos1);
        Font const font1 =
-               par.getFontSettings(cur.buffer().params(), pos1);
+               par.getFontSettings(cur.buffer()->params(), pos1);
 
-       char_type char2 = par.getChar(pos2);
+       char_type const char2 = par.getChar(pos2);
        Font const font2 =
-               par.getFontSettings(cur.buffer().params(), pos2);
+               par.getFontSettings(cur.buffer()->params(), pos2);
 
        // And finally, we are ready to perform the transposition.
        // Track the changes if Change Tracking is enabled.
-       bool const trackChanges = cur.buffer().params().trackChanges;
+       bool const trackChanges = cur.buffer()->params().trackChanges;
 
        cur.recordUndo();