]> git.lyx.org Git - lyx.git/blobdiff - src/insets/insetgraphics.C
Don't remove cell selections after fontchange.
[lyx.git] / src / insets / insetgraphics.C
index 8640ca9a234a3dd8f9125183030e742771cb8d3e..1dc04a8530c0eea9948d5443e3762bdede8630ab 100644 (file)
@@ -37,10 +37,6 @@ Known BUGS:
                its original size and color, resizing is done in the final output,
                but not in the LyX window.
 
-       * EPS figures are not fully detected, they may have a lot of possible
-               suffixes so we need to read the file and detect if it's EPS or not.
-               [Implemented, need testing]
-               
 TODO Before initial production release:
     * Replace insetfig everywhere
         * Search for comments of the form
@@ -95,38 +91,47 @@ TODO Before initial production release:
 
 #include "insets/insetgraphics.h"
 #include "insets/insetgraphicsParams.h"
+
 #include "graphics/GraphicsCache.h"
 #include "graphics/GraphicsCacheItem.h"
 
-#include "frontends/Dialogs.h"
 #include "LyXView.h"
 #include "buffer.h"
 #include "BufferView.h"
 #include "converter.h"
-#include "frontends/support/LyXImage.h"
 #include "Painter.h"
 #include "lyx_gui_misc.h"
-#include "support/FileInfo.h"
-#include "support/filetools.h"
-#include "frontends/controllers/helper_funcs.h"
-#include "support/lyxlib.h"
 #include "lyxtext.h"
 #include "lyxrc.h"
-#include "font.h" // For the lyxfont class.
-#include "fstream" // for ifstream in isEPS
-#include <algorithm> // For the std::max
-#include "support/lyxmanip.h"
+#include "font.h"
 #include "debug.h"
 #include "gettext.h"
 
+#include "frontends/Dialogs.h"
+#include "frontends/Alert.h"
+#include "frontends/controllers/helper_funcs.h"
+#include "frontends/support/LyXImage.h"
+
+#include "support/FileInfo.h"
+#include "support/filetools.h"
+#include "support/lyxlib.h"
+#include "support/lyxmanip.h"
+#include "support/lyxalgo.h"
+
+#include <fstream>
+#include <algorithm>
+
 extern string system_tempdir;
 
 using std::ifstream;
 using std::ostream;
 using std::endl;
+using std::max;
+using std::vector;
+
 
 ///////////////////////////////////////////////////////////////////////////
-int VersionNumber = 1;
+int const VersionNumber = 1;
 ///////////////////////////////////////////////////////////////////////////
 
 // This function is a utility function
@@ -138,9 +143,25 @@ string const RemoveExtension(string const & filename)
 }
 
 
+namespace {
+
+string const unique_id()
+{
+       static unsigned int seed = 1000;
+
+       ostringstream ost;
+       ost << "graph" << ++seed;
+
+       // Needed if we use lyxstring.
+       return ost.str().c_str();
+}
+
+} // namespace anon
+
+
 // Initialize only those variables that do not have a constructor.
 InsetGraphics::InsetGraphics()
-       : cacheHandle(0), imageLoaded(false)
+       : cacheHandle(0), imageLoaded(false), graphic_label(unique_id())
 {}
 
 
@@ -148,6 +169,7 @@ InsetGraphics::InsetGraphics(InsetGraphics const & ig, bool same_id)
        : Inset(), SigC::Object()
        , cacheHandle(ig.cacheHandle)
        , imageLoaded(ig.imageLoaded)
+       , graphic_label(unique_id())
 {
        setParams(ig.getParams());
        if (same_id)
@@ -230,10 +252,10 @@ int InsetGraphics::width(BufferView *, LyXFont const & font) const
                if (!msg.empty()) {
                        msgFont.setSize(LyXFont::SIZE_TINY);
                        int const msg_width = lyxfont::width(msg, msgFont);
-                       font_width = std::max(font_width, msg_width);
+                       font_width = max(font_width, msg_width);
                }
                
-               return std::max(50, font_width + 15);
+               return max(50, font_width + 15);
        }
 }
 
@@ -342,7 +364,7 @@ void InsetGraphics::readInsetGraphics(Buffer const * buf, LyXLex & lex)
 
                string const token = lex.getString();
                lyxerr[Debug::INFO] << "Token: '" << token << '\'' 
-                                   << std::endl;
+                                   << endl;
 
                if (token.empty()) {
                        continue;
@@ -356,13 +378,13 @@ void InsetGraphics::readInsetGraphics(Buffer const * buf, LyXLex & lex)
                                << "This document was created with a newer Graphics widget"
                                ", You should use a newer version of LyX to read this"
                                " file."
-                               << std::endl;
+                               << endl;
                        // TODO: Possibly open up a dialog?
                }
                else {
                        if (! params.Read(buf, lex, token))
                                lyxerr << "Unknown token, " << token << ", skipping." 
-                                       << std::endl;
+                                       << endl;
                }
        }
 }
@@ -370,7 +392,7 @@ void InsetGraphics::readInsetGraphics(Buffer const * buf, LyXLex & lex)
 // FormatVersion < 1.0  (LyX < 1.2)
 void InsetGraphics::readFigInset(Buffer const * buf, LyXLex & lex)
 {
-       std::vector<string> const oldUnits =
+       vector<string> const oldUnits =
                getVectorFromString("pt,cm,in,p%,c%");
        bool finished = false;
        // set the display default      
@@ -410,6 +432,7 @@ void InsetGraphics::readFigInset(Buffer const * buf, LyXLex & lex)
                        // kept for backwards compability. Delete in 0.13.x
                } else if (token == "angle") {
                        if (lex.next())
+                               params.rotate = true;
                                params.rotateAngle = lex.getFloat();
                } else if (token == "size") {
                        if (lex.next())
@@ -460,43 +483,41 @@ string const InsetGraphics::createLatexOptions() const
        // before writing it to the output stream.
        ostringstream options;
        if (!params.bb.empty())
-           options << "bb=" << strip(params.bb) << ',';
+           options << "  bb=" << strip(params.bb) << ",\n";
        if (params.draft)
-           options << "%\n  draft,";
+           options << "  draft,\n";
        if (params.clip)
-           options << "%\n  clip,";
+           options << "  clip,\n";
        if (params.size_type == InsetGraphicsParams::WH) {
            if (!params.width.zero())
-               options << "%\n  width=" << params.width.asLatexString() << ',';
+               options << "  width=" << params.width.asLatexString() << ",\n";
            if (!params.height.zero())
-               options << "%\n  height=" << params.height.asLatexString() << ',';
+               options << "  height=" << params.height.asLatexString() << ",\n";
        } else if (params.size_type == InsetGraphicsParams::SCALE) {
            if (params.scale > 0)
-               options << "%\n  scale=" << double(params.scale)/100.0 << ',';
+               options << "  scale=" << double(params.scale)/100.0 << ",\n";
        }
        if (params.keepAspectRatio)
-           options << "%\n  keepaspectratio,";
+           options << "  keepaspectratio,\n";
        // Make sure it's not very close to zero, a float can be effectively
        // zero but not exactly zero.
-       if (!lyx::float_equal(params.rotateAngle, 0, 0.001)) {
-           options << "%\n  angle=" << params.rotateAngle << ',';
+       if (!lyx::float_equal(params.rotateAngle, 0, 0.001) && params.rotate) {
+           options << "  angle=" << params.rotateAngle << ",\n";
            if (!params.rotateOrigin.empty()) {
-               options << "%\n  origin=";
-               options << params.rotateOrigin[0];
+               options << "  origin=" << params.rotateOrigin[0];
                if (contains(params.rotateOrigin,"Top"))
                    options << 't';
                else if (contains(params.rotateOrigin,"Bottom"))
                    options << 'b';
                else if (contains(params.rotateOrigin,"Baseline"))
                    options << 'B';
-               options << ',';
+               options << ",\n";
            }
        }
        if (!params.special.empty())
-           options << params.special << ',';
+           options << params.special << ",\n";
        string opts = options.str().c_str();
-       opts = strip(opts, ',');
-       return opts;
+       return opts.substr(0,opts.size()-2);    // delete last ",\n"
 }
 
 namespace {
@@ -505,7 +526,7 @@ string decideOutputImageFormat(string const & suffix)
        // lyxrc.pdf_mode means:
        // Are we creating a PDF or a PS file?
        // (Should actually mean, are we using latex or pdflatex).      
-       lyxerr << "decideOutput::lyxrc.pdf_mode = " << lyxrc.pdf_mode << "\n";
+       lyxerr[Debug::INFO] << "decideOutput::lyxrc.pdf_mode = " << lyxrc.pdf_mode << "\n";
        if (lyxrc.pdf_mode) {
                if (contains(suffix,"ps") || suffix == "pdf")
                        return "pdf";
@@ -515,7 +536,7 @@ string decideOutputImageFormat(string const & suffix)
                        return "png";
        }
        // If it's postscript, we always do eps.
-       lyxerr << "decideOutput: we have PostScript mode\n";
+       lyxerr[Debug::INFO] << "decideOutput: we have PostScript mode\n";
        if (suffix != "ps")
            return "eps";
        else
@@ -538,33 +559,38 @@ string const InsetGraphics::prepareFile(Buffer const *buf) const
        //   convert_place = original file directory
        //   return original filename without the extension
        //
+       // if it's a zipped one, than let LaTeX do the rest!!!
+       if ((zippedFile(params.filename) && params.noUnzip) || buf->niceFile) {
+           lyxerr[Debug::INFO] << "don't unzip file or export latex" 
+                   << params.filename << endl;
+           return params.filename;
+       }
+       string filename_ = params.filename;
+       if (zippedFile(filename_))
+           filename_ = unzipFile(filename_);
+       // now we have unzipped files
        // Get the extension (format) of the original file.
        // we handle it like a virtual one, so we can have
        // different extensions with the same type.
-       // if it's a zipped one, than let LaTeX do the rest!!!
-       //if (zippedFile(params.filename))      
-       //    return params.filename;
-       // now we have unzipped files
-       string const extension = getExtFromContents(params.filename);
-       // Are we creating a PDF or a PS file?
-       // (Should actually mean, are we usind latex or pdflatex).
+       string const extension = getExtFromContents(filename_);
+       // are we usind latex ((e)ps) or pdflatex (pdf,jpg,png)
        string const image_target = decideOutputImageFormat(extension);
-       if (extension == image_target)
-               return params.filename;
+       if (extension == image_target)          // :-)
+               return filename_;
+//     commented out to check if the "not exist"bug is fixed.
+//     if (!IsFileReadable(filename_)) {       // :-(
+//             Alert::alert(_("File") + params.filename,
+//                        _("isn't readable or doesn't exists!"));
+//             return filename_;
+//     }
        string outfile;
-       if (!buf->niceFile) {
-               string const temp = AddName(buf->tmppath, params.filename);
-               lyxerr << "temp = " << temp << "\n";
-               outfile = RemoveExtension(temp);
-       } else {
-               string const path = buf->filePath();
-               string const relname = MakeRelPath(params.filename, path);
-               outfile = RemoveExtension(relname);
-       }
-       lyxerr << "buf::tmppath = " << buf->tmppath << "\n";
-       lyxerr << "filename = " << params.filename << "\n";
-       lyxerr << "outfile = " << outfile << endl;
-       converters.convert(buf, params.filename, outfile, extension, image_target);
+       string const temp = AddName(buf->tmppath, filename_);
+       outfile = RemoveExtension(temp);
+       lyxerr[Debug::INFO] << "tempname = " << temp << "\n";
+       lyxerr[Debug::INFO] << "buf::tmppath = " << buf->tmppath << "\n";
+       lyxerr[Debug::INFO] << "filename_ = " << filename_ << "\n";
+       lyxerr[Debug::INFO] << "outfile = " << outfile << endl;
+       converters.convert(buf, filename_, outfile, extension, image_target);
        return outfile;
 }
 
@@ -579,30 +605,32 @@ int InsetGraphics::latex(Buffer const *buf, ostream & os,
                        << _("empty figure path") << "}\n";
                return 1; // One end of line marker added to the stream.
        }
-       // Keep count of newlines that we issued.
-       int newlines = 0;
-       // This variables collect all the latex code that should be before and
+       // These variables collect all the latex code that should be before and
        // after the actual includegraphics command.
        string before;
        string after;
        // Do we want subcaptions?
        if (params.subcaption) {
                before += "\\subfigure[" + params.subcaptionText + "]{";
-               after = '}' + after;
+               after = '}';
        }
        // We never use the starred form, we use the "clip" option instead.
-       os << before << "\\includegraphics";
+       before += "\\includegraphics";
        // Write the options if there are any.
        string const opts = createLatexOptions();
        if (!opts.empty()) {
-               os << "[%\n  " << opts << ']';
+               before += ("[%\n" + opts +']');
        }
        // Make the filename relative to the lyx file
        // and remove the extension so the LaTeX will use whatever is
        // appropriate (when there are several versions in different formats)
-       string const filename = prepareFile(buf);
-       os << '{' << filename << '}' << after;
+       string const latex_str = before + '{' + prepareFile(buf) + '}' + after;
+       os << latex_str;
        // Return how many newlines we issued.
+       int const newlines =
+               int(lyx::count(latex_str.begin(), latex_str.end(),'\n') + 1);
+       // lyxerr << "includegraphics: " << newlines << " lines of text"
+       //        << endl; 
        return newlines;
 }
 
@@ -629,20 +657,12 @@ int InsetGraphics::linuxdoc(Buffer const *, ostream &) const
 // For explanation on inserting graphics into DocBook checkout:
 // http://linuxdoc.org/LDP/LDP-Author-Guide/inserting-pictures.html
 // See also the docbook guide at http://www.docbook.org/
-int InsetGraphics::docbook(Buffer const * buf, ostream & os) const
+int InsetGraphics::docbook(Buffer const *, ostream & os) const
 {
-       // Change the path to be relative to the main file.
-       string const buffer_dir = buf->filePath();
-       string filename = RemoveExtension(
-               MakeRelPath(params.filename, buffer_dir));
-
-       if (suffixIs(filename, ".eps"))
-               filename.erase(filename.length() - 4);
-
        // In DocBook v5.0, the graphic tag will be eliminated from DocBook, will 
        // need to switch to MediaObject. However, for now this is sufficient and 
        // easier to use.
-       os << "<graphic fileref=\"" << filename << "\"></graphic>";
+       os << "<graphic fileref=\"&" << graphic_label << ";\">";
        return 0;
 }
 
@@ -653,6 +673,8 @@ void InsetGraphics::validate(LaTeXFeatures & features) const
        if (params.filename.empty())
                return ;
 
+       features.includeFile(graphic_label, RemoveExtension(params.filename));
+
        features.require("graphicx");
 
        if (params.subcaption)