]> git.lyx.org Git - lyx.git/blobdiff - src/insets/InsetListings.cpp
Implement ForceLtR; cleanup of collapsable insets
[lyx.git] / src / insets / InsetListings.cpp
index 3e5100b89ee47fbf188e7d44d488b59c2cbc38d7..b52e9fb9afa9b09b51ea23e7976bc20a88d4c060 100644 (file)
 #include "InsetListings.h"
 #include "InsetCaption.h"
 
-#include "Language.h"
-#include "gettext.h"
+#include "Buffer.h"
+#include "BufferParams.h"
+#include "Counters.h"
+#include "Cursor.h"
 #include "DispatchResult.h"
 #include "FuncRequest.h"
 #include "FuncStatus.h"
+#include "gettext.h"
+#include "InsetList.h"
+#include "Language.h"
 #include "MetricsInfo.h"
-#include "Cursor.h"
+
 #include "support/lstrings.h"
 
 #include <sstream>
 namespace lyx {
 
 using support::token;
+using support::contains;
+using support::subst;
 
-using std::auto_ptr;
 using std::istringstream;
 using std::ostream;
 using std::ostringstream;
 using std::string;
 
+char const lstinline_delimiters[] =
+       "!*()-=+|;:'\"`,<.>/?QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";
 
 void InsetListings::init()
 {
        setButtonLabel();
-       Font font(Font::ALL_SANE);
+       FontInfo font = sane_font;
        font.decSize();
        font.decSize();
-       font.setColor(Color::none);
+       font.setColor(Color_none);
        setLabelFont(font);
-       text_.current_font.setLanguage(latex_language);
-       text_.real_current_font.setLanguage(latex_language);
+       // FIXME: what to do with those?
+       //text_.current_font.setLanguage(latex_language);
+       //text_.real_current_font.setLanguage(latex_language);
 }
 
 
 InsetListings::InsetListings(BufferParams const & bp, InsetListingsParams const & par)
-       : InsetERT(bp, par.status())
+       : InsetCollapsable(bp, par.status())
 {
+       setLayout(bp);
        init();
 }
 
 
 InsetListings::InsetListings(InsetListings const & in)
-       : InsetERT(in), params_(in.params_)
+       : InsetCollapsable(in), params_(in.params_)
 {
        init();
 }
 
 
-auto_ptr<Inset> InsetListings::doClone() const
+Inset * InsetListings::clone() const
 {
-       return auto_ptr<Inset>(new InsetListings(*this));
+       return new InsetListings(*this);
 }
 
 
@@ -81,6 +91,21 @@ Inset::DisplayType InsetListings::display() const
 }
 
 
+void InsetListings::updateLabels(Buffer const & buf, ParIterator const & it)
+{
+       Counters & cnts = buf.params().getTextClass().counters();
+       string const saveflt = cnts.current_float();
+
+       // Tell to captions what the current float is
+       cnts.current_float("listing");
+
+       InsetCollapsable::updateLabels(buf, it);
+
+       //reset afterwards
+       cnts.current_float(saveflt);
+}
+
+
 void InsetListings::write(Buffer const & buf, ostream & os) const
 {
        os << "listings" << "\n";
@@ -115,44 +140,27 @@ void InsetListings::read(Buffer const & buf, Lexer & lex)
                        break;
                }
        }
-       InsetERT::read(buf, lex);
+       InsetCollapsable::read(buf, lex);
 }
 
 
 docstring const InsetListings::editMessage() const
 {
-       return _("Opened Listings Inset");
+       return _("Opened Listing Inset");
 }
 
 
 int InsetListings::latex(Buffer const & buf, odocstream & os,
                    OutputParams const & runparams) const
 {
-       string param_string = params().encodedString();
+       string param_string = params().params();
        // NOTE: I use {} to quote text, which is an experimental feature
        // of the listings package (see page 25 of the manual)
        int lines = 0;
-       bool lstinline = params().isInline();
-       if (lstinline) {
-               if (param_string.empty())
-                       os << "\\lstinline{";
-               else
-                       os << "\\lstinline[" << from_ascii(param_string) << "]{";
-       } else {
-               docstring const caption = getCaption(buf, runparams);
-               if (param_string.empty() && caption.empty())
-                       os << "\n\\begingroup\n\\inputencoding{latin1}\n\\begin{lstlisting}\n";
-               else {
-                       os << "\n\\begingroup\n\\inputencoding{latin1}\n\\begin{lstlisting}[";
-                       if (!caption.empty()) {
-                               os << "caption={" << caption << '}';
-                               if (!param_string.empty())
-                                       os << ',';
-                       }
-                       os << from_utf8(param_string) << "]\n";
-               }
-               lines += 4;
-       }
+       bool isInline = params().isInline();
+       // get the paragraphs. We can not output them directly to given odocstream
+       // because we can not yet determine the delimiter character of \lstinline
+       docstring code;
        ParagraphList::const_iterator par = paragraphs().begin();
        ParagraphList::const_iterator end = paragraphs().end();
 
@@ -165,20 +173,55 @@ int InsetListings::latex(Buffer const & buf, odocstream & os,
                        // ignore all struck out text and (caption) insets
                        if (par->isDeleted(i) || par->isInset(i))
                                continue;
-                       os.put(par->getChar(i));
+                       code += par->getChar(i);
                }
                ++par;
                // for the inline case, if there are multiple paragraphs
                // they are simply joined. Otherwise, expect latex errors.
-               if (par != end && !lstinline && !captionline) {
-                       os << "\n";
+               if (par != end && !isInline && !captionline) {
+                       code += "\n";
                        ++lines;
                }
        }
-       if (lstinline)
-               os << "}";              
-       else {
-               os << "\n\\end{lstlisting}\n\\endgroup\n";
+       if (isInline) {
+                char const * delimiter = lstinline_delimiters;
+               for (; delimiter != '\0'; ++delimiter)
+                       if (!contains(code, *delimiter))
+                               break;
+               // This code piece contains all possible special character? !!!
+               // Replace ! with a warning message and use ! as delimiter.
+               if (*delimiter == '\0') {
+                       code = subst(code, from_ascii("!"), from_ascii(" WARNING: no lstline delimiter can be used "));
+                       delimiter = lstinline_delimiters;
+               }
+               if (param_string.empty())
+                       os << "\\lstinline" << *delimiter;
+               else
+                       os << "\\lstinline[" << from_ascii(param_string) << "]" << *delimiter;
+                os << code
+                   << *delimiter;
+       } else {
+               OutputParams rp = runparams;
+               // FIXME: the line below would fix bug 4182,
+               // but real_current_font moved to cursor.
+               //rp.local_font = &text_.real_current_font;
+               rp.moving_arg = true;
+               docstring const caption = getCaption(buf, rp);
+               runparams.encoding = rp.encoding;
+               if (param_string.empty() && caption.empty())
+                       os << "\n\\begingroup\n\\inputencoding{latin1}\n\\begin{lstlisting}\n";
+               else {
+                       os << "\n\\begingroup\n\\inputencoding{latin1}\n\\begin{lstlisting}[";
+                       if (!caption.empty()) {
+                               os << "caption={" << caption << '}';
+                               if (!param_string.empty())
+                                       os << ',';
+                       }
+                       os << from_utf8(param_string) << "]\n";
+               }
+               lines += 4;
+                os << code
+                   << "\n\\end{lstlisting}\n\\endgroup\n";
                lines += 3;
        }
 
@@ -196,17 +239,17 @@ void InsetListings::doDispatch(Cursor & cur, FuncRequest & cmd)
        }
        case LFUN_INSET_DIALOG_UPDATE:
                InsetListingsMailer(*this).updateDialog(&cur.bv());
-               break;  
+               break;
        case LFUN_MOUSE_RELEASE: {
                if (cmd.button() == mouse_button::button3 && hitButton(cmd)) {
                        InsetListingsMailer(*this).showDialog(&cur.bv());
                        break;
                }
-               InsetERT::doDispatch(cur, cmd);
+               InsetCollapsable::doDispatch(cur, cmd);
                break;
        }
        default:
-               InsetERT::doDispatch(cur, cmd);
+               InsetCollapsable::doDispatch(cur, cmd);
                break;
        }
 }
@@ -223,7 +266,7 @@ bool InsetListings::getStatus(Cursor & cur, FuncRequest const & cmd,
                        status.enabled(!params().isInline());
                        return true;
                default:
-                       return InsetERT::getStatus(cur, cmd, status);
+                       return InsetCollapsable::getStatus(cur, cmd, status);
        }
 }
 
@@ -231,37 +274,17 @@ bool InsetListings::getStatus(Cursor & cur, FuncRequest const & cmd,
 void InsetListings::setButtonLabel()
 {
        // FIXME UNICODE
-       setLabel(isOpen() ?  _("Listings") : getNewLabel(_("Listings")));
-}
-
-
-bool InsetListings::metrics(MetricsInfo & mi, Dimension & dim) const
-{
-       Font tmpfont = mi.base.font;
-       getDrawFont(mi.base.font);
-       mi.base.font.realize(tmpfont);
-       InsetCollapsable::metrics(mi, dim);
-       mi.base.font = tmpfont;
-       bool const changed = dim_ != dim;
-       dim_ = dim;
-       return changed;
-}
-
-
-void InsetListings::draw(PainterInfo & pi, int x, int y) const
-{
-       Font tmpfont = pi.base.font;
-       getDrawFont(pi.base.font);
-       pi.base.font.realize(tmpfont);
-       InsetCollapsable::draw(pi, x, y);
-       pi.base.font = tmpfont;
+       if (decoration() == Classic)
+               setLabel(isOpen() ?  _("Listing") : getNewLabel(_("Listing")));
+       else
+               setLabel(getNewLabel(_("Listing")));
 }
 
 
 void InsetListings::validate(LaTeXFeatures & features) const
 {
        features.require("listings");
-       InsetERT::validate(features);
+       InsetCollapsable::validate(features);
 }
 
 
@@ -272,15 +295,6 @@ bool InsetListings::showInsetDialog(BufferView * bv) const
 }
 
 
-void InsetListings::getDrawFont(Font & font) const
-{
-       font = Font(Font::ALL_INHERIT, latex_language);
-       font.setFamily(Font::TYPEWRITER_FAMILY);
-       // FIXME: define Color::listing?
-       font.setColor(Color::foreground);
-}
-
-
 docstring InsetListings::getCaption(Buffer const & buf,
                    OutputParams const & runparams) const
 {
@@ -289,10 +303,10 @@ docstring InsetListings::getCaption(Buffer const & buf,
 
        ParagraphList::const_iterator pit = paragraphs().begin();
        for (; pit != paragraphs().end(); ++pit) {
-               InsetList::const_iterator it = pit->insetlist.begin();
-               for (; it != pit->insetlist.end(); ++it) {
+               InsetList::const_iterator it = pit->insetList().begin();
+               for (; it != pit->insetList().end(); ++it) {
                        Inset & inset = *it->inset;
-                       if (inset.lyxCode() == Inset::CAPTION_CODE) {
+                       if (inset.lyxCode() == CAPTION_CODE) {
                                odocstringstream ods;
                                InsetCaption * ins =
                                        static_cast<InsetCaption *>(it->inset);