]> git.lyx.org Git - lyx.git/blobdiff - src/Text2.cpp
Comment: add matching parenthesis
[lyx.git] / src / Text2.cpp
index 8eb70f8e328c5e455c27935774f62788d135dce8..6ce41a6d52fcf41b523b9c9668a8a2fb7e48d4e0 100644 (file)
@@ -347,6 +347,8 @@ void Text::setFont(Cursor & cur, Font const & font, bool toggleall)
                        newfi.setNoun(oldfi.noun() == FONT_OFF ? FONT_ON : FONT_OFF);
                if (newfi.number() == FONT_TOGGLE)
                        newfi.setNumber(oldfi.number() == FONT_OFF ? FONT_ON : FONT_OFF);
+               if (newfi.nospellcheck() == FONT_TOGGLE)
+                       newfi.setNoSpellcheck(oldfi.nospellcheck() == FONT_OFF ? FONT_ON : FONT_OFF);
        }
 
        setFont(cur.bv(), cur.selectionBegin().top(),
@@ -432,7 +434,7 @@ void Text::toggleFree(Cursor & cur, Font const & font, bool toggleall)
 }
 
 
-docstring Text::getStringToIndex(Cursor const & cur)
+docstring Text::getStringForDialog(Cursor & cur)
 {
        LBUFERR(this == cur.text());
 
@@ -442,17 +444,10 @@ docstring Text::getStringToIndex(Cursor const & cur)
        // Try implicit word selection. If there is a change
        // in the language the implicit word selection is
        // disabled.
-       Cursor tmpcur = cur;
-       selectWord(tmpcur, PREVIOUS_WORD);
-
-       if (!tmpcur.selection())
-               cur.message(_("Nothing to index!"));
-       else if (tmpcur.selBegin().pit() != tmpcur.selEnd().pit())
-               cur.message(_("Cannot index more than one paragraph!"));
-       else
-               return tmpcur.selectionAsString(false);
-
-       return docstring();
+       selectWordWhenUnderCursor(cur, WHOLE_WORD);
+       docstring const & retval = cur.selectionAsString(false);
+       cur.clearSelection();
+       return retval;
 }
 
 
@@ -784,24 +779,35 @@ bool Text::cursorDownParagraph(Cursor & cur)
        return updated;
 }
 
+namespace {
 
-// fix the cursor `cur' after a characters has been deleted at `where'
-// position. Called by deleteEmptyParagraphMechanism
-void Text::fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where)
+/** delete num_spaces characters between from and to. Return the
+ * number of spaces that got physically deleted (not marked as
+ * deleted) */
+int deleteSpaces(Paragraph & par, pos_type const from, pos_type to,
+                                 int num_spaces, bool const trackChanges)
 {
-       // Do nothing if cursor is not in the paragraph where the
-       // deletion occurred,
-       if (cur.pit() != where.pit())
-               return;
+       if (num_spaces <= 0)
+               return 0;
 
-       // If cursor position is after the deletion place update it
-       if (cur.pos() > where.pos())
-               --cur.pos();
+       // First, delete spaces marked as inserted
+       int pos = from;
+       while (pos < to && num_spaces > 0) {
+               Change const & change = par.lookupChange(pos);
+               if (change.inserted() && change.currentAuthor()) {
+                       par.eraseChar(pos, trackChanges);
+                       --num_spaces;
+                       --to;
+               } else
+                       ++pos;
+       }
+
+       // Then remove remaining spaces
+       int const psize = par.size();
+       par.eraseChars(from, from + num_spaces, trackChanges);
+       return psize - par.size();
+}
 
-       // Check also if we don't want to set the cursor on a spot behind the
-       // pagragraph because we erased the last character.
-       if (cur.pos() > cur.lastpos())
-               cur.pos() = cur.lastpos();
 }
 
 
@@ -811,6 +817,7 @@ bool Text::deleteEmptyParagraphMechanism(Cursor & cur,
        //LYXERR(Debug::DEBUG, "DEPM: cur:\n" << cur << "old:\n" << old);
 
        Paragraph & oldpar = old.paragraph();
+       bool const trackChanges = cur.buffer()->params().track_changes;
 
        // We allow all kinds of "mumbo-jumbo" when freespacing.
        if (oldpar.isFreeSpacing())
@@ -820,8 +827,8 @@ bool Text::deleteEmptyParagraphMechanism(Cursor & cur,
           There are still some small problems that can lead to
           double spaces stored in the document file or space at
           the beginning of paragraphs(). This happens if you have
-          the cursor between to spaces and then save. Or if you
-          cut and paste and the selection have a space at the
+          the cursor between two spaces and then save. Or if you
+          cut and paste and the selection has a space at the
           beginning and then save right after the paste. (Lgb)
        */
 
@@ -841,34 +848,53 @@ bool Text::deleteEmptyParagraphMechanism(Cursor & cur,
 
        // Whether a common inset is found and whether the cursor is still in
        // the same paragraph (possibly nested).
-       bool const same_par = depth < cur.depth() && old.pit() == cur[depth].pit();
+       bool const same_par = depth < cur.depth() && old.idx() == cur[depth].idx()
+               && old.pit() == cur[depth].pit();
        bool const same_par_pos = depth == cur.depth() - 1 && same_par
                && old.pos() == cur[depth].pos();
 
-       // If the chars around the old cursor were spaces, delete one of them.
+       // If the chars around the old cursor were spaces, delete some of
+       // them, but only if the cursor has really moved.
        if (!same_par_pos) {
-               // Only if the cursor has really moved.
-               if (old.pos() > 0
-                   && old.pos() < oldpar.size()
-                   && oldpar.isLineSeparator(old.pos())
-                   && oldpar.isLineSeparator(old.pos() - 1)
-                   && !oldpar.isDeleted(old.pos() - 1)
-                   && !oldpar.isDeleted(old.pos())) {
-                       oldpar.eraseChar(old.pos() - 1, cur.buffer()->params().track_changes);
-// FIXME: This will not work anymore when we have multiple views of the same buffer
-// In this case, we will have to correct also the cursors held by
-// other bufferviews. It will probably be easier to do that in a more
-// automated way in CursorSlice code. (JMarc 26/09/2001)
-                       // correct all cursor parts
+               // find range of spaces around cursors
+               pos_type from = old.pos();
+               while (from > 0
+                      && oldpar.isLineSeparator(from - 1)
+                      && !oldpar.isDeleted(from - 1))
+                       --from;
+               pos_type to = old.pos();
+               while (to < old.lastpos()
+                      && oldpar.isLineSeparator(to)
+                      && !oldpar.isDeleted(to))
+                       ++to;
+
+               int num_spaces = to - from;
+               // If we are not at the start of the paragraph, keep one space
+               if (from != to && from > 0)
+                       --num_spaces;
+
+               // If cursor is inside range, keep one additional space
+               if (same_par && cur.pos() > from && cur.pos() < to)
+                       --num_spaces;
+
+               // Remove spaces and adapt cursor.
+               if (num_spaces > 0) {
+                       int const deleted =
+                               deleteSpaces(oldpar, from, to, num_spaces, trackChanges);
+                       // correct cur position
+                       // FIXME: there can be other cursors pointing there, we should update them
                        if (same_par) {
-                               fixCursorAfterDelete(cur[depth], old.top());
+                               if (cur[depth].pos() >= to)
+                                       cur[depth].pos() -= deleted;
+                               else if (cur[depth].pos() > from)
+                                       cur[depth].pos() = min(from + 1, old.lastpos());
                                need_anchor_change = true;
                        }
                        return true;
                }
        }
 
-       // only do our magic if we changed paragraph
+       // only do our other magic if we changed paragraph
        if (same_par)
                return false;
 
@@ -908,7 +934,7 @@ bool Text::deleteEmptyParagraphMechanism(Cursor & cur,
                return true;
        }
 
-       if (oldpar.stripLeadingSpaces(cur.buffer()->params().track_changes)) {
+       if (oldpar.stripLeadingSpaces(trackChanges)) {
                need_anchor_change = true;
                // We return true here because the Paragraph contents changed and
                // we need a redraw before further action is processed.
@@ -930,13 +956,30 @@ void Text::deleteEmptyParagraphMechanism(pit_type first, pit_type last, bool tra
                if (par.isFreeSpacing())
                        continue;
 
-               for (pos_type pos = 1; pos < par.size(); ++pos) {
-                       if (par.isLineSeparator(pos) && par.isLineSeparator(pos - 1)
-                           && !par.isDeleted(pos - 1)) {
-                               if (par.eraseChar(pos - 1, trackChanges)) {
-                                       --pos;
-                               }
-                       }
+               pos_type from = 0;
+               while (from < par.size()) {
+                       // skip non-spaces
+                       while (from < par.size()
+                              && (!par.isLineSeparator(from) || par.isDeleted(from)))
+                               ++from;
+                       // find string of spaces
+                       pos_type to = from;
+                       while (to < par.size()
+                              && par.isLineSeparator(to) && !par.isDeleted(to))
+                               ++to;
+                       // empty? We are done
+                       if (from == to)
+                               break;
+
+                       int num_spaces = to - from;
+
+                       // If we are not at the extremity of the paragraph, keep one space
+                       if (from != to && from > 0 && to < par.size())
+                               --num_spaces;
+
+                       // Remove spaces if needed
+                       int const deleted = deleteSpaces(par, from , to, num_spaces, trackChanges);
+                       from = to - deleted;
                }
 
                // don't delete anything if this is the only remaining paragraph