]> git.lyx.org Git - lyx.git/blobdiff - src/Text.cpp
Do not scale statusbar icons
[lyx.git] / src / Text.cpp
index 575eea62b01c7fc96b5d6e71ad3fc6cf7469ad8d..8f30f4eb7c151f0c6a9d8c1986252949445d3c24 100644 (file)
 
 #include "Author.h"
 #include "Buffer.h"
-#include "buffer_funcs.h"
 #include "BufferParams.h"
 #include "BufferView.h"
 #include "Changes.h"
 #include "CompletionList.h"
 #include "Cursor.h"
+#include "CursorSlice.h"
 #include "CutAndPaste.h"
-#include "DispatchResult.h"
 #include "Encoding.h"
 #include "ErrorList.h"
-#include "FuncRequest.h"
 #include "factory.h"
-#include "InsetList.h"
+#include "Font.h"
+#include "FuncRequest.h"
 #include "Language.h"
 #include "Layout.h"
 #include "Lexer.h"
 #include "LyXRC.h"
 #include "Paragraph.h"
 #include "ParagraphParameters.h"
-#include "ParIterator.h"
 #include "TextClass.h"
 #include "TextMetrics.h"
-#include "WordLangTuple.h"
 #include "WordList.h"
 
+#include "insets/Inset.h"
 #include "insets/InsetText.h"
-#include "insets/InsetBibitem.h"
 #include "insets/InsetCaption.h"
-#include "insets/InsetNewline.h"
-#include "insets/InsetNewpage.h"
-#include "insets/InsetArgument.h"
 #include "insets/InsetIPAMacro.h"
-#include "insets/InsetSpace.h"
 #include "insets/InsetSpecialChar.h"
 #include "insets/InsetTabular.h"
 
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/docstream.h"
+#include "support/docstring.h"
 #include "support/gettext.h"
 #include "support/lassert.h"
-#include "support/Length.h"
 #include "support/lstrings.h"
-#include "support/lyxalgo.h"
 #include "support/lyxtime.h"
 #include "support/textutils.h"
 #include "support/unique_ptr.h"
@@ -641,14 +633,14 @@ public:
        virtual ~TextCompletionList() {}
 
        ///
-       virtual bool sorted() const { return true; }
+       bool sorted() const override { return true; }
        ///
-       virtual size_t size() const
+       size_t size() const override
        {
                return list_.size();
        }
        ///
-       virtual docstring const & data(size_t idx) const
+       docstring const & data(size_t idx) const override
        {
                return list_.word(idx);
        }
@@ -867,11 +859,12 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str,
        pos_type pos = cur.pos();
 
        // The special chars we handle
-       map<wchar_t, InsetSpecialChar::Kind> specialchars;
-       specialchars[0x200c] = InsetSpecialChar::LIGATURE_BREAK;
-       specialchars[0x200b] = InsetSpecialChar::ALLOWBREAK;
-       specialchars[0x2026] = InsetSpecialChar::LDOTS;
-       specialchars[0x2011] = InsetSpecialChar::NOBREAKDASH;
+       static map<wchar_t, InsetSpecialChar::Kind> specialchars = {
+               { 0x200c, InsetSpecialChar::LIGATURE_BREAK },
+               { 0x200b, InsetSpecialChar::ALLOWBREAK },
+               { 0x2026, InsetSpecialChar::LDOTS },
+               { 0x2011, InsetSpecialChar::NOBREAKDASH }
+       };
 
        // insert the string, don't insert doublespace
        bool space_inserted = true;
@@ -902,11 +895,11 @@ void Text::insertStringAsLines(Cursor & cur, docstring const & str,
                                ++pos;
                                space_inserted = true;
                        }
-               } else if (specialchars.find(ch) != specialchars.end()) {
-                       par.insertInset(pos, new InsetSpecialChar(specialchars.find(ch)->second),
-                                       font, bparams.track_changes ?
-                                               Change(Change::INSERTED)
-                                             : Change(Change::UNCHANGED));
+               } else if (specialchars.find(ch) != specialchars.end()
+                          && (par.insertInset(pos, new InsetSpecialChar(specialchars.find(ch)->second),
+                                              font, bparams.track_changes
+                                              ? Change(Change::INSERTED)
+                                              : Change(Change::UNCHANGED)))) {
                        ++pos;
                        space_inserted = false;
                } else if (!isPrintable(ch)) {
@@ -1134,7 +1127,7 @@ void Text::charInserted(Cursor & cur)
            && par.isWordSeparator(cur.pos() - 1)) {
                // get the word in front of cursor
                LBUFERR(this == cur.text());
-               cur.paragraph().updateWords();
+               par.updateWords();
        }
 }
 
@@ -1503,7 +1496,8 @@ void Text::acceptOrRejectChanges(Cursor & cur, ChangeOp op)
        }
 
        // finally, invoke the DEPM
-       deleteEmptyParagraphMechanism(begPit, endPit, cur.buffer()->params().track_changes);
+       deleteEmptyParagraphMechanism(begPit, endPit, begPos, endPos,
+                                     cur.buffer()->params().track_changes);
 
        cur.finishUndo();
        cur.clearSelection();
@@ -1778,7 +1772,7 @@ bool Text::backspace(Cursor & cur)
                Cursor prev_cur = cur;
                --prev_cur.pit();
 
-               if (cur.paragraph().size() > 0
+               if (!cur.paragraph().empty()
                    && !prev_cur.paragraph().isMergedOnEndOfParDeletion(cur.buffer()->params().track_changes)) {
                        cur.recordUndo(prev_cur.pit(), prev_cur.pit());
                        prev_cur.paragraph().setChange(prev_cur.lastpos(), Change(Change::DELETED));
@@ -1877,11 +1871,18 @@ bool Text::dissolveInset(Cursor & cur)
                 */
                DocumentClass const & tclass = cur.buffer()->params().documentClass();
                if (inset_it.lastpos() == 1
-                       && !tclass.isPlainLayout(plist[0].layout())
-                       && !tclass.isDefaultLayout(plist[0].layout()))
-                       cur.paragraph().makeSameLayout(plist[0]);
+                   && !tclass.isPlainLayout(plist[0].layout())
+                   && !tclass.isDefaultLayout(plist[0].layout())) {
+                       // Copy all parameters except depth.
+                       Paragraph & par = cur.paragraph();
+                       par.setLayout(plist[0].layout());
+                       depth_type const dpth = par.getDepth();
+                       par.params() = plist[0].params();
+                       par.params().depth(dpth);
+               }
 
                pasteParagraphList(cur, plist, b.params().documentClassPtr(),
+                                  b.params().authors(),
                                   b.errorList("Paste"));
        }
 
@@ -1901,6 +1902,88 @@ bool Text::dissolveInset(Cursor & cur)
 }
 
 
+bool Text::splitInset(Cursor & cur)
+{
+       LASSERT(this == cur.text(), return false);
+
+       if (isMainText() || cur.inset().nargs() != 1)
+               return false;
+
+       cur.recordUndo();
+       if (cur.selection()) {
+               // start from selection begin
+               setCursor(cur, cur.selBegin().pit(), cur.selBegin().pos());
+               cur.clearSelection();
+       }
+       // save split position inside inset
+       // (we need to copy the whole inset first)
+       pos_type spos = cur.pos();
+       pit_type spit = cur.pit();
+       // some things only need to be done if the inset has content
+       bool const inset_non_empty = cur.lastpit() != 0 || cur.lastpos() != 0;
+
+       // move right before the inset
+       cur.popBackward();
+       cur.resetAnchor();
+       // remember position outside inset
+       pos_type ipos = cur.pos();
+       pit_type ipit = cur.pit();
+       // select inset ...
+       ++cur.pos();
+       cur.setSelection();
+       // ... and copy
+       cap::copySelectionToTemp(cur);
+       cur.clearSelection();
+       cur.resetAnchor();
+       // paste copied inset
+       cap::pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
+       cur.forceBufferUpdate();
+
+       // if the inset has text, cut after split position
+       // and paste to new inset
+       if (inset_non_empty) {
+               // go back to first inset
+               cur.text()->setCursor(cur, ipit, ipos);
+               cur.forwardPos();
+               setCursor(cur, spit, spos);
+               cur.resetAnchor();
+               setCursor(cur, cur.lastpit(), getPar(cur.lastpit()).size());
+               cur.setSelection();
+               cap::cutSelectionToTemp(cur);
+               cur.setMark(false);
+               cur.selHandle(false);
+               cur.resetAnchor();
+               bool atlastpos = false;
+               if (cur.pos() == 0 && cur.pit() > 0) {
+                       // if we are at par start, remove this par
+                       cur.text()->backspace(cur);
+                       cur.forceBufferUpdate();
+               } else if (cur.pos() == cur.lastpos())
+                       atlastpos = true;
+               // Move out of and jump over inset
+               cur.popBackward();
+               ++cur.pos();
+
+               // enter new inset
+               cur.forwardPos();
+               cur.setCursor(cur);
+               cur.resetAnchor();
+               cur.text()->selectAll(cur);
+               cutSelection(cur, false);
+               cap::pasteFromTemp(cur, cur.buffer()->errorList("Paste"));
+               cur.text()->setCursor(cur, 0, 0);
+               if (atlastpos && cur.paragraph().isFreeSpacing() && cur.paragraph().empty()) {
+                       // We started from par end, remove extra empty par in free spacing insets
+                       cur.text()->erase(cur);
+                       cur.forceBufferUpdate();
+               }
+       }
+
+       cur.finishUndo();
+       return true;
+}
+
+
 void Text::getWord(CursorSlice & from, CursorSlice & to,
        word_location const loc) const
 {
@@ -1991,7 +2074,7 @@ bool Text::read(Lexer & lex,
 }
 
 
-// Returns the current font and depth as a message.
+// Returns the current state (font, depth etc.) as a message for status bar.
 docstring Text::currentState(CursorData const & cur, bool devel_mode) const
 {
        LBUFERR(this == cur.text());
@@ -2021,7 +2104,7 @@ docstring Text::currentState(CursorData const & cur, bool devel_mode) const
        os << bformat(_("Font: %1$s"), font.stateText(&buf.params()));
 
        // The paragraph depth
-       int depth = cur.paragraph().getDepth();
+       int depth = par.getDepth();
        if (depth > 0)
                os << bformat(_(", Depth: %1$d"), depth);
 
@@ -2049,6 +2132,11 @@ docstring Text::currentState(CursorData const & cur, bool devel_mode) const
                }
        }
 
+       // Custom text style
+       InsetLayout const & layout = cur.inset().getLayout();
+       if (layout.lyxtype() == InsetLyXType::CHARSTYLE)
+               os << _(", Style: ") << translateIfPossible(layout.labelstring());
+
        if (devel_mode) {
                os << _(", Inset: ") << &cur.inset();
                if (cur.lastidx() > 0)
@@ -2273,19 +2361,6 @@ void Text::setMacrocontextPosition(DocIterator const & pos)
 }
 
 
-docstring Text::previousWord(CursorSlice const & sl) const
-{
-       CursorSlice from = sl;
-       CursorSlice to = sl;
-       getWord(from, to, PREVIOUS_WORD);
-       if (sl == from || to == from)
-               return docstring();
-
-       Paragraph const & par = sl.paragraph();
-       return par.asString(from.pos(), to.pos());
-}
-
-
 bool Text::completionSupported(Cursor const & cur) const
 {
        Paragraph const & par = cur.paragraph();
@@ -2316,7 +2391,11 @@ bool Text::insertCompletion(Cursor & cur, docstring const & s, bool /*finished*/
 
 docstring Text::completionPrefix(Cursor const & cur) const
 {
-       return previousWord(cur.top());
+       CursorSlice from = cur.top();
+       CursorSlice to = from;
+       getWord(from, to, PREVIOUS_WORD);
+
+       return cur.paragraph().asString(from.pos(), to.pos());
 }
 
 } // namespace lyx