]> git.lyx.org Git - lyx.git/blobdiff - src/paragraph.C
partial fix for cut and paste
[lyx.git] / src / paragraph.C
index 1dec5968edb708a13aa3997c57942645e511ab28..5a7131ab3cc6e8f4553aba5def966d9690410ba7 100644 (file)
@@ -32,6 +32,7 @@
 #include "lyxrow.h"
 #include "outputparams.h"
 #include "paragraph_funcs.h"
+#include "ParagraphList_fwd.h"
 #include "sgml.h"
 #include "texrow.h"
 #include "vspace.h"
@@ -55,6 +56,7 @@ using lyx::pos_type;
 using lyx::support::contains;
 using lyx::support::subst;
 
+using std::distance;
 using std::endl;
 using std::list;
 using std::stack;
@@ -63,26 +65,28 @@ using std::ostream;
 using std::ostringstream;
 
 
+ParagraphList::ParagraphList()
+{}
+
+
 Paragraph::Paragraph()
        : y(0), height(0), begin_of_body_(0),
          pimpl_(new Paragraph::Pimpl(this))
 {
+       //lyxerr << "sizeof Paragraph::Pimpl: " << sizeof(Paragraph::Pimpl) << endl;
        itemdepth = 0;
        params().clear();
 }
 
 
 Paragraph::Paragraph(Paragraph const & par)
-       : y(0), height(0), text_(par.text_), begin_of_body_(par.begin_of_body_),
+       :       itemdepth(par.itemdepth), insetlist(par.insetlist),
+               rows(par.rows), y(par.y), height(par.height),
+               width(par.width), layout_(par.layout_),
+               text_(par.text_), begin_of_body_(par.begin_of_body_),
          pimpl_(new Paragraph::Pimpl(*par.pimpl_, this))
 {
-       itemdepth = 0;
-       // this is because of the dummy layout of the paragraphs that
-       // follow footnotes
-       layout_ = par.layout();
-
-       // copy everything behind the break-position to the new paragraph
-       insetlist = par.insetlist;
+       //lyxerr << "Paragraph::Paragraph(Paragraph const&)" << endl;
        InsetList::iterator it = insetlist.begin();
        InsetList::iterator end = insetlist.end();
        for (; it != end; ++it)
@@ -90,30 +94,30 @@ Paragraph::Paragraph(Paragraph const & par)
 }
 
 
-void Paragraph::operator=(Paragraph const & par)
+Paragraph & Paragraph::operator=(Paragraph const & par)
 {
        // needed as we will destroy the pimpl_ before copying it
-       if (&par != this)
-               return;
-
-       lyxerr << "Paragraph::operator=()" << endl;
-
-       text_ = par.text_;
-
-       delete pimpl_;
-       pimpl_ = new Pimpl(*par.pimpl_, this);
-
-       itemdepth = par.itemdepth;
-       // this is because of the dummy layout of the paragraphs that
-       // follow footnotes
-       layout_ = par.layout();
-
-       // copy everything behind the break-position to the new paragraph
-       insetlist = par.insetlist;
-       InsetList::iterator it = insetlist.begin();
-       InsetList::iterator end = insetlist.end();
-       for (; it != end; ++it)
-               it->inset = it->inset->clone().release();
+       if (&par != this) {
+               itemdepth = par.itemdepth;
+
+               insetlist = par.insetlist;
+               InsetList::iterator it = insetlist.begin();
+               InsetList::iterator end = insetlist.end();
+               for (; it != end; ++it)
+                       it->inset = it->inset->clone().release();
+
+               rows = par.rows;
+               y = par.y;
+               height = par.height;
+               width = par.width;
+               layout_ = par.layout();
+               text_ = par.text_;
+               begin_of_body_ = par.begin_of_body_;
+
+               delete pimpl_;
+               pimpl_ = new Pimpl(*par.pimpl_, this);
+       }
+       return *this;
 }
 
 
@@ -302,10 +306,7 @@ void Paragraph::insertInset(pos_type pos, InsetBase * inset,
 
 bool Paragraph::insetAllowed(InsetOld_code code)
 {
-       //lyxerr << "Paragraph::InsertInsetAllowed" << endl;
-       if (pimpl_->inset_owner)
-               return pimpl_->inset_owner->insetAllowed(code);
-       return true;
+       return !pimpl_->inset_owner || pimpl_->inset_owner->insetAllowed(code);
 }
 
 
@@ -327,7 +328,10 @@ InsetBase const * Paragraph::getInset(pos_type pos) const
 LyXFont const Paragraph::getFontSettings(BufferParams const & bparams,
                                         pos_type pos) const
 {
-       BOOST_ASSERT(pos <= size());
+       if (pos > size()) {
+               lyxerr << " pos: " << pos << " size: " << size() << endl;
+               BOOST_ASSERT(pos <= size());
+       }
 
        Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
        Pimpl::FontList::const_iterator end = pimpl_->fontlist.end();
@@ -518,7 +522,7 @@ void Paragraph::setFont(pos_type pos, LyXFont const & font)
                if (it->pos() >= pos)
                        break;
        }
-       unsigned int i = std::distance(beg, it);
+       unsigned int i = distance(beg, it);
        bool notfound = (it == endit);
 
        if (!notfound && pimpl_->fontlist[i].font() == font)
@@ -644,7 +648,7 @@ void Paragraph::applyLayout(LyXLayout_ptr const & new_layout)
 }
 
 
-int Paragraph::beginOfBody() const
+pos_type Paragraph::beginOfBody() const
 {
        return begin_of_body_;
 }
@@ -709,19 +713,26 @@ InsetBibitem * Paragraph::bibitem() const
 }
 
 
+bool Paragraph::forceDefaultParagraphs() const
+{
+       return inInset() && inInset()->forceDefaultParagraphs(inInset());
+}
+
+
+bool Paragraph::autoBreakRows() const
+{
+       return inInset() && static_cast<InsetText *>(inInset())->getAutoBreakRows();
+}
+
+
 namespace {
 
 // paragraphs inside floats need different alignment tags to avoid
-// unwanted space 
+// unwanted space
 
-bool noTrivlistCentering(UpdatableInset const * inset)
+bool noTrivlistCentering(InsetBase::Code code)
 {
-       if (inset && inset->owner()) {
-               InsetBase::Code const code = inset->owner()->lyxCode();
-               return code == InsetBase::FLOAT_CODE ||
-                       code == InsetBase::WRAP_CODE;
-       }
-       return false;
+       return code == InsetBase::FLOAT_CODE || code == InsetBase::WRAP_CODE;
 }
 
 
@@ -738,10 +749,10 @@ string correction(string const & orig)
 
 
 string const corrected_env(string const & suffix, string const & env,
-                          UpdatableInset const * inset)
+       InsetBase::Code code)
 {
        string output = suffix + "{";
-       if (noTrivlistCentering(inset))
+       if (noTrivlistCentering(code))
                output += correction(env);
        else
                output += env;
@@ -786,27 +797,25 @@ int Paragraph::startTeXParParams(BufferParams const & bparams,
                break;
        case LYX_ALIGN_LEFT: {
                string output;
-               UpdatableInset const * const inset = pimpl_->inset_owner;
                if (getParLanguage(bparams)->babel() != "hebrew")
-                       output = corrected_env("\\begin", "flushleft", inset);
+                       output = corrected_env("\\begin", "flushleft", ownerCode());
                else
-                       output = corrected_env("\\begin", "flushright", inset);
+                       output = corrected_env("\\begin", "flushright", ownerCode());
                os << output;
                column += output.size();
                break;
        } case LYX_ALIGN_RIGHT: {
                string output;
-               UpdatableInset const * const inset = pimpl_->inset_owner;
                if (getParLanguage(bparams)->babel() != "hebrew")
-                       output = corrected_env("\\begin", "flushright", inset);
+                       output = corrected_env("\\begin", "flushright", ownerCode());
                else
-                       output = corrected_env("\\begin", "flushleft", inset);
+                       output = corrected_env("\\begin", "flushleft", ownerCode());
                os << output;
                column += output.size();
                break;
        } case LYX_ALIGN_CENTER: {
                string output;
-               output = corrected_env("\\begin", "center", pimpl_->inset_owner);
+               output = corrected_env("\\begin", "center", ownerCode());
                os << output;
                column += output.size();
                break;
@@ -847,27 +856,25 @@ int Paragraph::endTeXParParams(BufferParams const & bparams,
                break;
        case LYX_ALIGN_LEFT: {
                string output;
-               UpdatableInset const * const inset = pimpl_->inset_owner;
                if (getParLanguage(bparams)->babel() != "hebrew")
-                       output = corrected_env("\\par\\end", "flushleft", inset);
+                       output = corrected_env("\\par\\end", "flushleft", ownerCode());
                else
-                       output = corrected_env("\\par\\end", "flushright", inset);
+                       output = corrected_env("\\par\\end", "flushright", ownerCode());
                os << output;
                column += output.size();
                break;
        } case LYX_ALIGN_RIGHT: {
                string output;
-               UpdatableInset const * const inset = pimpl_->inset_owner;
                if (getParLanguage(bparams)->babel() != "hebrew")
-                       output = corrected_env("\\par\\end", "flushright", inset);
+                       output = corrected_env("\\par\\end", "flushright", ownerCode());
                else
-                       output = corrected_env("\\par\\end", "flushleft", inset);
+                       output = corrected_env("\\par\\end", "flushleft", ownerCode());
                os << output;
                column += output.size();
                break;
        } case LYX_ALIGN_CENTER: {
                string output;
-               output = corrected_env("\\par\\end", "center", pimpl_->inset_owner);
+               output = corrected_env("\\par\\end", "center", ownerCode());
                os << output;
                column += output.size();
                break;
@@ -895,8 +902,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        // length (all in one row) if that is true then we don't allow
        // any special options in the paragraph and also we don't allow
        // any environment other then "Standard" to be valid!
-       bool asdefault =
-               (inInset() && inInset()->forceDefaultParagraphs(inInset()));
+       bool asdefault = forceDefaultParagraphs();
 
        if (asdefault) {
                style = bparams.getLyXTextClass().defaultLayout();
@@ -1338,7 +1344,7 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
        int char_line_count = depth;
        bool label_closed = true;
        bool para_closed = true;
-       
+
        if (style->latextype == LATEX_ITEM_ENVIRONMENT) {
                string ls = "";
                Counters & counters = buf.params().getLyXTextClass().counters();
@@ -1351,11 +1357,11 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
                        if (!defaultstyle->latexparam().empty()) {
                                counters.step("para");
                                ls = tostr(counters.value("para"));
-                               ls = " id=\"" 
+                               ls = " id=\""
                                        + subst(defaultstyle->latexparam(), "#", ls) + '"';
                        }
-                       os << "<" << style->itemtag() << ">\n" 
-                          << string(depth, ' ') << "<" 
+                       os << "<" << style->itemtag() << ">\n"
+                          << string(depth, ' ') << "<"
                           << defaultstyle->latexname() << ls << ">\n";
                        para_closed = false;
                }
@@ -1384,7 +1390,6 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
                        }
                }
 
-
                if (isInset(i)) {
                        InsetBase const * inset = getInset(i);
                        // don't print the inset in position 0 if desc_on == 3 (label)
@@ -1408,8 +1413,8 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
                                        os << str;
                        } else if (!style->labeltag().empty() && !label_closed) {
                                ++char_line_count;
-                               os << "\n</" << style->labeltag() << "><" 
-                                  << style->itemtag() << "><" 
+                               os << "\n</" << style->labeltag() << "><"
+                                  << style->itemtag() << "><"
                                   << defaultstyle->latexname() << ">";
                                label_closed = true;
                                para_closed = false;
@@ -1431,12 +1436,12 @@ void Paragraph::simpleDocBookOnePar(Buffer const & buf,
        // resets description flag correctly
        if (!label_closed) {
                // <term> not closed...
-               os << "</" << style->labeltag() << ">\n<" 
-                  << style->itemtag() << "><" 
+               os << "</" << style->labeltag() << ">\n<"
+                  << style->itemtag() << "><"
                   << defaultstyle->latexname() << ">&nbsp;";
        }
        if (!para_closed) {
-               os << "\n" << string(depth, ' ') << "</" 
+               os << "\n" << string(depth, ' ') << "</"
                   << defaultstyle->latexname() << ">\n";
        }
        if (style->free_spacing)
@@ -1459,21 +1464,15 @@ bool IsInsetChar(char c)
 
 bool Paragraph::isHfill(pos_type pos) const
 {
-       return IsInsetChar(getChar(pos))
-              && getInset(pos)->lyxCode() == InsetBase::HFILL_CODE;
-}
-
-
-bool Paragraph::isInset(pos_type pos) const
-{
-       return IsInsetChar(getChar(pos));
+       return
+               isInset(pos) && getInset(pos)->lyxCode() == InsetBase::HFILL_CODE;
 }
 
 
 bool Paragraph::isNewline(pos_type pos) const
 {
-       return IsInsetChar(getChar(pos))
-              && getInset(pos)->lyxCode() == InsetBase::NEWLINE_CODE;
+       return
+               isInset(pos) && getInset(pos)->lyxCode() == InsetBase::NEWLINE_CODE;
 }
 
 
@@ -1526,7 +1525,9 @@ Paragraph::getParLanguage(BufferParams const & bparams) const
 {
        if (!empty())
                return getFirstFontSettings().language();
+#ifdef WITH_WARNINGS
 #warning FIXME we should check the prev par as well (Lgb)
+#endif
        return bparams.language;
 }
 
@@ -1535,8 +1536,7 @@ bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const
 {
        return lyxrc.rtl_support
                && getParLanguage(bparams)->RightToLeft()
-               && !(inInset() && inInset()->owner() &&
-                    inInset()->owner()->lyxCode() == InsetBase::ERT_CODE);
+               && ownerCode() != InsetBase::ERT_CODE;
 }
 
 
@@ -1553,7 +1553,7 @@ void Paragraph::changeLanguage(BufferParams const & bparams,
 }
 
 
-bool Paragraph::isMultiLingual(BufferParams const & bparams)
+bool Paragraph::isMultiLingual(BufferParams const & bparams) const
 {
        Language const * doc_language = bparams.language;
        Pimpl::FontList::const_iterator cit = pimpl_->fontlist.begin();
@@ -1570,8 +1570,7 @@ bool Paragraph::isMultiLingual(BufferParams const & bparams)
 
 // Convert the paragraph to a string.
 // Used for building the table of contents
-string const Paragraph::asString(Buffer const & buffer,
-                                bool label) const
+string const Paragraph::asString(Buffer const & buffer, bool label) const
 {
        OutputParams runparams;
        return asString(buffer, runparams, label);
@@ -1641,11 +1640,6 @@ string const Paragraph::asString(Buffer const & buffer,
 void Paragraph::setInsetOwner(UpdatableInset * inset)
 {
        pimpl_->inset_owner = inset;
-       InsetList::iterator it = insetlist.begin();
-       InsetList::iterator end = insetlist.end();
-       for (; it != end; ++it)
-               if (it->inset)
-                       it->inset->setOwner(inset);
 }
 
 
@@ -1675,14 +1669,14 @@ void Paragraph::cleanChanges()
 
 Change::Type Paragraph::lookupChange(lyx::pos_type pos) const
 {
-       BOOST_ASSERT(!size() || pos < size());
+       BOOST_ASSERT(empty() || pos < size());
        return pimpl_->lookupChange(pos);
 }
 
 
 Change const Paragraph::lookupChangeFull(lyx::pos_type pos) const
 {
-       BOOST_ASSERT(!size() || pos < size());
+       BOOST_ASSERT(empty() || pos < size());
        return pimpl_->lookupChangeFull(pos);
 }
 
@@ -1702,7 +1696,6 @@ bool Paragraph::isChangeEdited(pos_type start, pos_type end) const
 void Paragraph::setChange(lyx::pos_type pos, Change::Type type)
 {
        pimpl_->setChange(pos, type);
-
 }
 
 
@@ -1737,7 +1730,6 @@ Paragraph::value_type Paragraph::getChar(pos_type pos) const
                       << id() << " of size " << siz
                       << "  is a bit silly !" << endl;
                BOOST_ASSERT(false);
-               return '\0';
        }
 
        return text_[pos];
@@ -1752,11 +1744,6 @@ int Paragraph::id() const
 
 LyXLayout_ptr const & Paragraph::layout() const
 {
-/*
-       InsetBase * inset = inInset();
-       if (inset && inset->lyxCode() == InsetBase::ENVIRONMENT_CODE)
-               return static_cast<InsetEnvironment*>(inset)->layout();
-*/
        return layout_;
 }
 
@@ -1773,6 +1760,13 @@ UpdatableInset * Paragraph::inInset() const
 }
 
 
+InsetBase::Code Paragraph::ownerCode() const
+{
+       return pimpl_->inset_owner
+               ? pimpl_->inset_owner->lyxCode() : InsetBase::NO_CODE;
+}
+
+
 void Paragraph::clearContents()
 {
        text_.clear();
@@ -1804,9 +1798,7 @@ bool Paragraph::isFreeSpacing() const
 
        // for now we just need this, later should we need this in some
        // other way we can always add a function to InsetBase too.
-       if (pimpl_->inset_owner && pimpl_->inset_owner->owner())
-               return pimpl_->inset_owner->owner()->lyxCode() == InsetBase::ERT_CODE;
-       return false;
+       return ownerCode() == InsetBase::ERT_CODE;
 }
 
 
@@ -1814,9 +1806,7 @@ bool Paragraph::allowEmpty() const
 {
        if (layout()->keepempty)
                return true;
-       if (pimpl_->inset_owner && pimpl_->inset_owner->owner())
-               return pimpl_->inset_owner->owner()->lyxCode() == InsetBase::ERT_CODE;
-       return false;
+       return ownerCode() == InsetBase::ERT_CODE;
 }
 
 
@@ -1832,6 +1822,30 @@ RowList::iterator Paragraph::getRow(pos_type pos)
 }
 
 
+RowList::const_iterator Paragraph::getRow(pos_type pos) const
+{
+       RowList::const_iterator rit = rows.end();
+       RowList::const_iterator const begin = rows.begin();
+
+       for (--rit; rit != begin && rit->pos() > pos; --rit)
+               ;
+
+       return rit;
+}
+
+
+size_t Paragraph::row(pos_type pos) const
+{
+       RowList::const_iterator rit = rows.end();
+       RowList::const_iterator const begin = rows.begin();
+
+       for (--rit; rit != begin && rit->pos() > pos; --rit)
+               ;
+
+       return rit - begin;
+}
+
+
 unsigned char Paragraph::transformChar(unsigned char c, pos_type pos) const
 {
        if (!Encodings::is_arabic(c))