]> git.lyx.org Git - lyx.git/blobdiff - src/Paragraph.cpp
Fix for bug 3650. Made changes to the Paragraph::checkBiblio() routine,
[lyx.git] / src / Paragraph.cpp
index c34ac65297dedcf7b75fb0cdd834bc971dac8b99..7afacfabce96b64b855ba92f54d04de59914c0b4 100644 (file)
@@ -194,7 +194,7 @@ public:
                                   Font & basefont,
                                   Font const & outerfont,
                                   bool & open_font,
-                                  Change::Type & running_change,
+                                  Change & running_change,
                                   Layout const & style,
                                   pos_type & i,
                                   unsigned int & column, value_type const c);
@@ -665,7 +665,7 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                                             Font & basefont,
                                             Font const & outerfont,
                                             bool & open_font,
-                                            Change::Type & running_change,
+                                            Change & running_change,
                                             Layout const & style,
                                             pos_type & i,
                                             unsigned int & column,
@@ -702,7 +702,8 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                        } else {
                                if (open_font) {
                                        column += running_font.latexWriteEndChanges(
-                                               os, basefont, basefont);
+                                               os, bparams, runparams,
+                                               basefont, basefont);
                                        open_font = false;
                                }
 
@@ -723,18 +724,10 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                        break;
                }
 
-               // output change tracking marks only if desired,
-               // if dvipost is installed,
-               // and with dvi/ps (other formats don't work)
-               LaTeXFeatures features(buf, bparams, runparams);
-               bool const output = bparams.outputChanges
-                       && runparams.flavor == OutputParams::LATEX
-                       && features.isAvailable("dvipost");
-
                if (inset->canTrackChanges()) {
-                       column += Changes::latexMarkChange(os, running_change,
-                               Change::UNCHANGED, output);
-                       running_change = Change::UNCHANGED;
+                       column += Changes::latexMarkChange(os, bparams, running_change,
+                               Change(Change::UNCHANGED));
+                       running_change = Change(Change::UNCHANGED);
                }
 
                bool close = false;
@@ -757,7 +750,8 @@ void Paragraph::Pimpl::simpleTeXSpecialChars(Buffer const & buf,
                // some insets cannot be inside a font change command
                if (open_font && inset->noFontChange()) {
                        column += running_font.latexWriteEndChanges(
-                                       os, basefont, basefont);
+                                       os, bparams, runparams,
+                                               basefont, basefont);
                        open_font = false;
                        basefont = owner_->getLayoutFont(bparams, outerfont);
                        running_font = basefont;
@@ -991,7 +985,7 @@ void Paragraph::Pimpl::validate(LaTeXFeatures & features,
                {
                        features.useLanguage(language);
                        LYXERR(Debug::LATEX) << "Found language "
-                                            << language->babel() << endl;
+                                            << language->lang() << endl;
                }
        }
 
@@ -1326,7 +1320,7 @@ Font const Paragraph::getFirstFontSettings(BufferParams const & bparams) const
 
 
 // Gets the fully instantiated font at a given position in a paragraph
-// This is basically the same function as LyXText::GetFont() in text2.cpp.
+// This is basically the same function as Text::GetFont() in text2.cpp.
 // The difference is that this one is used for generating the LaTeX file,
 // and thus cosmetic "improvements" are disallowed: This has to deliver
 // the true picture of the buffer. (Asger)
@@ -1928,13 +1922,6 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        // of the body.
        Font basefont;
 
-       // output change tracking marks only if desired,
-       // if dvipost is installed,
-       // and with dvi/ps (other formats don't work)
-       bool const output = bparams.outputChanges
-               && runparams.flavor == OutputParams::LATEX
-               && LaTeXFeatures::isAvailable("dvipost");
-
        // Maybe we have to create a optional argument.
        pos_type body_pos = beginOfBody();
        unsigned int column = 0;
@@ -1954,7 +1941,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
        // Do we have an open font change?
        bool open_font = false;
 
-       Change::Type runningChangeType = Change::UNCHANGED;
+       Change runningChange = Change(Change::UNCHANGED);
 
        texrow.start(id(), 0);
 
@@ -1975,15 +1962,16 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                        if (body_pos > 0) {
                                if (open_font) {
                                        column += running_font.latexWriteEndChanges(
-                                               os, basefont, basefont);
+                                               os, bparams, runparams,
+                                               basefont, basefont);
                                        open_font = false;
                                }
                                basefont = getLayoutFont(bparams, outerfont);
                                running_font = basefont;
 
-                               column += Changes::latexMarkChange(os,
-                                               runningChangeType, Change::UNCHANGED, output);
-                               runningChangeType = Change::UNCHANGED;
+                               column += Changes::latexMarkChange(os, bparams,
+                                               runningChange, Change(Change::UNCHANGED));
+                               runningChange = Change(Change::UNCHANGED);
 
                                os << "}] ";
                                column +=3;
@@ -1999,21 +1987,29 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                                                            runparams.moving_arg);
                }
 
-               Change::Type changeType = pimpl_->lookupChange(i).type;
+               Change const & change = pimpl_->lookupChange(i);
+
+               if (bparams.outputChanges && runningChange != change) {
+                       if (open_font) {
+                               column += running_font.latexWriteEndChanges(
+                                               os, bparams, runparams, basefont, basefont);
+                               open_font = false;
+                       }
+                       basefont = getLayoutFont(bparams, outerfont);
+                       running_font = basefont;
+
+                       column += Changes::latexMarkChange(os, bparams, runningChange, change);
+                       runningChange = change;
+               }
 
                // do not output text which is marked deleted
                // if change tracking output is disabled
-               if (!output && changeType == Change::DELETED) {
-                       runningChangeType = changeType;
+               if (!bparams.outputChanges && change.type == Change::DELETED) {
                        continue;
                }
 
                ++column;
                
-               column += Changes::latexMarkChange(os, runningChangeType,
-                       changeType, output);
-               runningChangeType = changeType;
-
                value_type const c = getChar(i);
 
                // Fully instantiated font
@@ -2027,19 +2023,22 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                     font.language() != running_font.language()))
                {
                        column += running_font.latexWriteEndChanges(
-                                       os, basefont,
+                                       os, bparams, runparams, basefont,
                                        (i == body_pos-1) ? basefont : font);
                        running_font = basefont;
                        open_font = false;
                }
 
                // Switch file encoding if necessary
-               int const count = switchEncoding(os, bparams,
-                               runparams.moving_arg, *(runparams.encoding),
-                               *(font.language()->encoding()));
-               if (count > 0) {
-                       column += count;
-                       runparams.encoding = font.language()->encoding();
+               if (runparams.encoding->package() == Encoding::inputenc &&
+                   font.language()->encoding()->package() == Encoding::inputenc) {
+                       int const count = switchEncoding(os, bparams,
+                                       runparams.moving_arg, *(runparams.encoding),
+                                       *(font.language()->encoding()));
+                       if (count > 0) {
+                               column += count;
+                               runparams.encoding = font.language()->encoding();
+                       }
                }
 
                // Do we need to change font?
@@ -2047,7 +2046,8 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                     font.language() != running_font.language()) &&
                        i != body_pos - 1)
                {
-                       column += font.latexWriteStartChanges(os, basefont,
+                       column += font.latexWriteStartChanges(os, bparams,
+                                                             runparams, basefont,
                                                              last_font);
                        running_font = font;
                        open_font = true;
@@ -2079,7 +2079,7 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
                pimpl_->simpleTeXSpecialChars(buf, bparams, os,
                                        texrow, rp, running_font,
                                        basefont, outerfont, open_font,
-                                       runningChangeType, *style, i, column, c);
+                                       runningChange, *style, i, column, c);
        }
 
        // If we have an open font definition, we have to close it
@@ -2087,11 +2087,12 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
 #ifdef FIXED_LANGUAGE_END_DETECTION
                if (next_) {
                        running_font
-                               .latexWriteEndChanges(os, basefont,
+                               .latexWriteEndChanges(os, bparams, runparams,
+                                       basefont,
                                        next_->getFont(bparams, 0, outerfont));
                } else {
-                       running_font.latexWriteEndChanges(os, basefont,
-                                                         basefont);
+                       running_font.latexWriteEndChanges(os, bparams,
+                                       runparams, basefont, basefont);
                }
 #else
 #ifdef WITH_WARNINGS
@@ -2099,12 +2100,12 @@ bool Paragraph::simpleTeXOnePar(Buffer const & buf,
 //#warning there as we start another \selectlanguage with the next paragraph if
 //#warning we are in need of this. This should be fixed sometime (Jug)
 #endif
-               running_font.latexWriteEndChanges(os, basefont, basefont);
+               running_font.latexWriteEndChanges(os, bparams, runparams,
+                               basefont, basefont);
 #endif
        }
 
-       column += Changes::latexMarkChange(os,
-                       runningChangeType, Change::UNCHANGED, output);
+       column += Changes::latexMarkChange(os, bparams, runningChange, Change(Change::UNCHANGED));
 
        // Needed if there is an optional argument but no contents.
        if (body_pos > 0 && body_pos == size()) {
@@ -2175,6 +2176,7 @@ bool Paragraph::emptyTag() const
                            lyx_code != Inset::INCLUDE_CODE &&
                            lyx_code != Inset::GRAPHICS_CODE &&
                            lyx_code != Inset::ERT_CODE &&
+                           lyx_code != Inset::LISTINGS_CODE &&
                            lyx_code != Inset::FLOAT_CODE &&
                            lyx_code != Inset::TABULAR_CODE) {
                                return false;
@@ -2340,7 +2342,8 @@ bool Paragraph::isRightToLeftPar(BufferParams const & bparams) const
 {
        return lyxrc.rtl_support
                && getParLanguage(bparams)->rightToLeft()
-               && ownerCode() != Inset::ERT_CODE;
+               && ownerCode() != Inset::ERT_CODE
+               && ownerCode() != Inset::LISTINGS_CODE;
 }
 
 
@@ -2391,7 +2394,7 @@ docstring const Paragraph::asString(Buffer const & buffer,
                os << params().labelString() << ' ';
 
        for (pos_type i = beg; i < end; ++i) {
-               value_type const c = getUChar(buffer.params(), i);
+               value_type const c = getChar(i);
                if (isPrintable(c))
                        os.put(c);
                else if (c == META_INSET)
@@ -2501,7 +2504,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 Inset too.
-       return ownerCode() == Inset::ERT_CODE;
+       return ownerCode() == Inset::ERT_CODE || ownerCode() == Inset::LISTINGS_CODE;
 }
 
 
@@ -2509,7 +2512,7 @@ bool Paragraph::allowEmpty() const
 {
        if (layout()->keepempty)
                return true;
-       return ownerCode() == Inset::ERT_CODE;
+       return ownerCode() == Inset::ERT_CODE || ownerCode() == Inset::LISTINGS_CODE;
 }
 
 
@@ -2589,25 +2592,70 @@ bool Paragraph::hfillExpansion(Row const & row, pos_type pos) const
 }
 
 
-bool Paragraph::checkBiblio(bool track_changes)
+int Paragraph::checkBiblio(bool track_changes)
 {
+       //FIXME From JS:
+       //This is getting more and more a mess. ...We really should clean 
+       //up this bibitem issue for 1.6. See also bug 2743.
+
        // Add bibitem insets if necessary
        if (layout()->labeltype != LABEL_BIBLIO)
-               return false;
+               return 0;
 
        bool hasbibitem = !insetlist.empty()
                // Insist on it being in pos 0
                && getChar(0) == Paragraph::META_INSET
                && insetlist.begin()->inset->lyxCode() == Inset::BIBITEM_CODE;
 
-       if (hasbibitem)
-               return false;
+       docstring oldkey;
+       docstring oldlabel;
+
+       // remove a bibitem in pos != 0
+       // restore it later in pos 0 if necessary
+       // (e.g. if a user inserts contents _before_ the item)
+       // we're assuming there's only one of these, which there
+       // should be.
+       int erasedInsetPosition = -1;
+       InsetList::iterator it = insetlist.begin();
+       InsetList::iterator end = insetlist.end();
+       for (; it != end; ++it)
+               if (it->inset->lyxCode() == Inset::BIBITEM_CODE
+                   && it->pos > 0) {
+                       InsetBibitem * olditem = static_cast<InsetBibitem *>(it->inset);
+                       oldkey = olditem->getParam("key");
+                       oldlabel = olditem->getParam("label");
+                       erasedInsetPosition = it->pos;
+                       eraseChar(erasedInsetPosition, track_changes);
+                       break;
+       }
 
+       //There was an InsetBibitem at the beginning, and we didn't
+       //have to erase one.
+       if (hasbibitem && erasedInsetPosition < 0)
+                       return 0;
+       
+       //There was an InsetBibitem at the beginning and we did have to 
+       //erase one. So we give its properties to the beginning inset.
+       if (hasbibitem) {
+               InsetBibitem * inset = 
+                       static_cast<InsetBibitem *>(insetlist.begin()->inset);
+               if (!oldkey.empty())
+                       inset->setParam("key", oldkey);
+               inset->setParam("label", oldlabel);
+               return -erasedInsetPosition;
+       }
+       
+       //There was no inset at the beginning, so we need to create one with
+       //the key and label of the one we erased.
        InsetBibitem * inset(new InsetBibitem(InsetCommandParams("bibitem")));
+       // restore values of previously deleted item in this par.
+       if (!oldkey.empty())
+               inset->setParam("key", oldkey);
+       inset->setParam("label", oldlabel);
        insertInset(0, static_cast<Inset *>(inset),
-               Change(track_changes ? Change::INSERTED : Change::UNCHANGED));
+                   Change(track_changes ? Change::INSERTED : Change::UNCHANGED));
 
-       return true;
+       return 1;
 }
 
 } // namespace lyx