#include "exporter.h"
#include "format.h"
#include "funcrequest.h"
+#include "FuncStatus.h"
#include "gettext.h"
#include "LaTeXFeatures.h"
#include "lyx_main.h"
#include "lyxlength.h"
#include "lyxlex.h"
#include "metricsinfo.h"
+#include "mover.h"
#include "outputparams.h"
+#include "sgml.h"
#include "frontends/Alert.h"
#include "frontends/LyXView.h"
+#include "support/convert.h"
#include "support/filetools.h"
#include "support/lyxalgo.h" // lyx::count
-#include "support/lyxlib.h" // float_equal
+#include "support/lyxlib.h" // lyx::sum
+#include "support/lstrings.h"
#include "support/os.h"
#include "support/systemcall.h"
-#include "support/tostr.h"
#include <boost/bind.hpp>
#include <boost/tuple/tuple.hpp>
using lyx::support::FileName;
using lyx::support::float_equal;
using lyx::support::GetExtension;
-using lyx::support::getExtFromContents;
using lyx::support::IsFileReadable;
-using lyx::support::LibFileSearch;
+using lyx::support::latex_path;
using lyx::support::OnlyFilename;
using lyx::support::rtrim;
using lyx::support::subst;
}
-string const uniqueID()
+string findTargetFormat(string const & format, OutputParams const & runparams)
{
- static unsigned int seed = 1000;
- return "graph" + tostr(++seed);
-}
-
-
-string findTargetFormat(string const & suffix, OutputParams const & runparams)
-{
- // Are we using latex or pdflatex).
+ // Are we using latex or pdflatex?
if (runparams.flavor == OutputParams::PDFLATEX) {
lyxerr[Debug::GRAPHICS] << "findTargetFormat: PDF mode" << endl;
- if (contains(suffix, "ps") || suffix == "pdf")
+ // Convert postscript to pdf
+ if (format == "eps" || format == "ps")
return "pdf";
- if (suffix == "jpg") // pdflatex can use jpeg
- return suffix;
- return "png"; // and also png
+ // pdflatex can use jpeg, png and pdf directly
+ if (format == "jpg" || format == "pdf")
+ return format;
+ // Convert everything else to png
+ return "png";
}
// If it's postscript, we always do eps.
lyxerr[Debug::GRAPHICS] << "findTargetFormat: PostScript mode" << endl;
- if (suffix != "ps") // any other than ps
- return "eps"; // is changed to eps
- return suffix; // let ps untouched
+ if (format != "ps")
+ // any other than ps is changed to eps
+ return "eps";
+ // let ps untouched
+ return format;
}
} // namespace anon
InsetGraphics::InsetGraphics()
- : graphic_label(uniqueID()),
+ : graphic_label(sgml::uniqueID("graph")),
graphic_(new RenderGraphic(this))
{}
InsetGraphics::InsetGraphics(InsetGraphics const & ig)
: InsetOld(ig),
boost::signals::trackable(),
- graphic_label(uniqueID()),
+ graphic_label(sgml::uniqueID("graph")),
graphic_(new RenderGraphic(*ig.graphic_, this))
{
setParams(ig.params());
}
-auto_ptr<InsetBase> InsetGraphics::clone() const
+auto_ptr<InsetBase> InsetGraphics::doClone() const
{
return auto_ptr<InsetBase>(new InsetGraphics(*this));
}
}
-void InsetGraphics::priv_dispatch(LCursor & cur, FuncRequest & cmd)
+void InsetGraphics::doDispatch(LCursor & cur, FuncRequest & cmd)
{
switch (cmd.action) {
case LFUN_GRAPHICS_EDIT: {
Buffer const & buffer = cur.buffer();
InsetGraphicsParams p;
InsetGraphicsMailer::string2params(cmd.argument, buffer, p);
- if (!p.filename.empty()) {
+ if (!p.filename.empty())
setParams(p);
- cur.bv().update();
- }
+ else
+ cur.noUpdate();
break;
}
break;
default:
- InsetOld::priv_dispatch(cur, cmd);
+ InsetBase::doDispatch(cur, cmd);
break;
}
}
+bool InsetGraphics::getStatus(LCursor & cur, FuncRequest const & cmd,
+ FuncStatus & flag) const
+{
+ switch (cmd.action) {
+ case LFUN_GRAPHICS_EDIT:
+ case LFUN_INSET_MODIFY:
+ case LFUN_INSET_DIALOG_UPDATE:
+ flag.enabled(true);
+ return true;
+
+ default:
+ return InsetBase::getStatus(cur, cmd, flag);
+ }
+}
+
+
void InsetGraphics::edit(LCursor & cur, bool)
{
InsetGraphicsMailer(*this).showDialog(&cur.bv());
}
-InsetOld::EDITABLE InsetGraphics::editable() const
+InsetBase::EDITABLE InsetGraphics::editable() const
{
return IS_EDITABLE;
}
// before writing it to the output stream.
ostringstream options;
if (!params().bb.empty())
- options << " bb=" << rtrim(params().bb) << ",\n";
+ options << "bb=" << rtrim(params().bb) << ',';
if (params().draft)
- options << " draft,\n";
+ options << "draft,";
if (params().clip)
- options << " clip,\n";
- if (!float_equal(params().scale, 0.0, 0.05)) {
- if (!float_equal(params().scale, 100.0, 0.05))
- options << " scale=" << params().scale / 100.0
- << ",\n";
+ options << "clip,";
+ double const scl = convert<double>(params().scale);
+ if (!params().scale.empty() && !float_equal(scl, 0.0, 0.05)) {
+ if (!float_equal(scl, 100.0, 0.05))
+ options << "scale=" << scl / 100.0 << ',';
} else {
if (!params().width.zero())
- options << " width=" << params().width.asLatexString() << ",\n";
+ options << "width=" << params().width.asLatexString() << ',';
if (!params().height.zero())
- options << " height=" << params().height.asLatexString() << ",\n";
+ options << "height=" << params().height.asLatexString() << ',';
if (params().keepAspectRatio)
- options << " keepaspectratio,\n";
+ options << "keepaspectratio,";
}
// Make sure rotation angle is not very close to zero;
// a float can be effectively zero but not exactly zero.
- if (!float_equal(params().rotateAngle, 0, 0.001)) {
- options << " angle=" << params().rotateAngle << ",\n";
+ if (!params().rotateAngle.empty()
+ && !float_equal(convert<double>(params().rotateAngle), 0.0, 0.001)) {
+ options << "angle=" << params().rotateAngle << ',';
if (!params().rotateOrigin.empty()) {
- options << " origin=" << 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 << ",\n";
+ options << ',';
}
}
if (!params().special.empty())
- options << params().special << ",\n";
+ options << params().special << ',';
string opts = options.str();
- // delete last ",\n"
- return opts.substr(0, opts.size() - 2);
+ // delete last ','
+ return opts.substr(0, opts.size() - 1);
}
string const InsetGraphics::toDocbookLength(LyXLength const & len) const
{
ostringstream result;
- switch (len.unit() ) {
- case LyXLength::SP: //< Scaled point (65536sp = 1pt) TeX's smallest unit.
+ switch (len.unit()) {
+ case LyXLength::SP: // Scaled point (65536sp = 1pt) TeX's smallest unit.
result << len.value() * 65536.0 * 72 / 72.27 << "pt";
break;
- case LyXLength::PT: //< Point = 1/72.27in = 0.351mm
+ case LyXLength::PT: // Point = 1/72.27in = 0.351mm
result << len.value() * 72 / 72.27 << "pt";
break;
- case LyXLength::BP: //< Big point (72bp = 1in), also PostScript point
+ case LyXLength::BP: // Big point (72bp = 1in), also PostScript point
result << len.value() << "pt";
break;
- case LyXLength::DD: //< Didot point = 1/72 of a French inch, = 0.376mm
+ case LyXLength::DD: // Didot point = 1/72 of a French inch, = 0.376mm
result << len.value() * 0.376 << "mm";
break;
- case LyXLength::MM: //< Millimeter = 2.845pt
+ case LyXLength::MM: // Millimeter = 2.845pt
result << len.value() << "mm";
break;
- case LyXLength::PC: //< Pica = 12pt = 4.218mm
+ case LyXLength::PC: // Pica = 12pt = 4.218mm
result << len.value() << "pc";
break;
- case LyXLength::CC: //< Cicero = 12dd = 4.531mm
+ case LyXLength::CC: // Cicero = 12dd = 4.531mm
result << len.value() * 4.531 << "mm";
break;
- case LyXLength::CM: //< Centimeter = 10mm = 2.371pc
+ case LyXLength::CM: // Centimeter = 10mm = 2.371pc
result << len.value() << "cm";
break;
- case LyXLength::IN: //< Inch = 25.4mm = 72.27pt = 6.022pc
+ case LyXLength::IN: // Inch = 25.4mm = 72.27pt = 6.022pc
result << len.value() << "in";
break;
- case LyXLength::EX: //< Height of a small "x" for the current font.
+ case LyXLength::EX: // Height of a small "x" for the current font.
// Obviously we have to compromise here. Any better ratio than 1.5 ?
result << len.value() / 1.5 << "em";
break;
- case LyXLength::EM: //< Width of capital "M" in current font.
+ case LyXLength::EM: // Width of capital "M" in current font.
result << len.value() << "em";
break;
- case LyXLength::MU: //< Math unit (18mu = 1em) for positioning in math mode
+ case LyXLength::MU: // Math unit (18mu = 1em) for positioning in math mode
result << len.value() * 18 << "em";
break;
- case LyXLength::PTW: //< Percent of TextWidth
- case LyXLength::PCW: //< Percent of ColumnWidth
- case LyXLength::PPW: //< Percent of PageWidth
- case LyXLength::PLW: //< Percent of LineWidth
- case LyXLength::PTH: //< Percent of TextHeight
- case LyXLength::PPH: //< Percent of Paper
+ case LyXLength::PTW: // Percent of TextWidth
+ case LyXLength::PCW: // Percent of ColumnWidth
+ case LyXLength::PPW: // Percent of PageWidth
+ case LyXLength::PLW: // Percent of LineWidth
+ case LyXLength::PTH: // Percent of TextHeight
+ case LyXLength::PPH: // Percent of Paper
// Sigh, this will go wrong.
result << len.value() << "%";
break;
// Right now it only works with my version of db2latex :-)
ostringstream options;
- if (!float_equal(params().scale, 0.0, 0.05)) {
- if (!float_equal(params().scale, 100.0, 0.05))
- options << " scale=\"" << static_cast<int>( (params().scale) + 0.5 )
+ double const scl = convert<double>(params().scale);
+ if (!params().scale.empty() && !float_equal(scl, 0.0, 0.05)) {
+ if (!float_equal(scl, 100.0, 0.05))
+ options << " scale=\""
+ << static_cast<int>( (scl) + 0.5 )
<< "\" ";
} else {
- if ( ! params().width.zero()) {
+ if (!params().width.zero()) {
options << " width=\"" << toDocbookLength(params().width) << "\" ";
}
- if ( ! params().height.zero()) {
+ if (!params().height.zero()) {
options << " depth=\"" << toDocbookLength(params().height) << "\" ";
}
- if ( params().keepAspectRatio ) {
+ if (params().keepAspectRatio) {
// This will be irrelevant unless both width and height are set
options << "scalefit=\"1\" ";
}
// Nothing to do...
return std::make_pair(IDENTICAL_CONTENTS, file_out);
- bool const success = support::copy(file_in, file_out);
+ Mover const & mover = movers(formats.getFormatFromFile(file_in));
+ bool const success = mover.copy(file_in, file_out);
if (!success) {
lyxerr[Debug::GRAPHICS]
<< support::bformat(_("Could not copy the file\n%1$s\n"
}
-string const stripExtension(string const & file)
+string const stripExtensionIfPossible(string const & file)
{
// Remove the extension so the LaTeX will use whatever
// is appropriate (when there are several versions in
// This works only if the filename contains no dots besides
// the just removed one. We can fool here by replacing all
// dots with a macro whose definition is just a dot ;-)
- return subst(RemoveExtension(file), ".", "\\lyxdot ");
+ // The automatic format selection does not work if the file
+ // name is escaped.
+ string const latex_name = latex_path(file,
+ lyx::support::EXCLUDE_EXTENSION);
+ if (contains(latex_name, '"'))
+ return latex_name;
+ return latex_path(RemoveExtension(file),
+ lyx::support::PROTECT_EXTENSION,
+ lyx::support::ESCAPE_DOTS);
}
if (to_format == file_format ||
(to_format == "eps" && file_format == "ps") ||
(to_format == "ps" && file_format == "eps"))
- return stripExtension(file);
- return file;
+ return stripExtensionIfPossible(file);
+ return latex_path(file, lyx::support::EXCLUDE_EXTENSION);
}
} // namespace anon
string const InsetGraphics::prepareFile(Buffer const & buf,
OutputParams const & runparams) const
{
- // We assume that the file exists (the caller checks this)
+ // The following code depends on non-empty filenames
+ if (params().filename.empty())
+ return string();
+
string const orig_file = params().filename.absFilename();
string const rel_file = params().filename.relFilename(buf.filePath());
// of include files
Buffer const * m_buffer = buf.getMasterBuffer();
+ // Return the output name if the file does not exist.
+ // We are not going to change the extension or using the name of the
+ // temporary file, the code is already complicated enough.
+ if (!IsFileReadable(orig_file))
+ return params().filename.outputFilename(m_buffer->filePath());
+
// We place all temporary files in the master buffer's temp dir.
// This is possible because we use mangled file names.
// This is necessary for DVI export.
source_file, output_file);
// We can't strip the extension, because we don't know
// the unzipped file format
- return output_file;
+ return latex_path(output_file,
+ lyx::support::EXCLUDE_EXTENSION);
}
string const unzipped_temp_file = unzippedFileName(temp_file);
}
}
- string const from = getExtFromContents(temp_file);
+ string const from = formats.getFormatFromFile(temp_file);
+ if (from.empty()) {
+ lyxerr[Debug::GRAPHICS]
+ << "\tCould not get file format." << endl;
+ return orig_file;
+ }
string const to = findTargetFormat(from, runparams);
+ string const ext = formats.extension(to);
lyxerr[Debug::GRAPHICS]
<< "\t we have: from " << from << " to " << to << '\n';
<< "\tthe orig file is: " << orig_file << endl;
if (from == to) {
- // The extension of temp_file might be != to!
+ // The extension of temp_file might be != ext!
runparams.exportdata->addExternalFile("latex", source_file,
output_file);
runparams.exportdata->addExternalFile("dvi", source_file,
return stripExtensionIfPossible(output_file, to);
}
- string const to_file = ChangeExtension(temp_file, to);
- string const output_to_file = ChangeExtension(output_file, to);
+ string const to_file = ChangeExtension(temp_file, ext);
+ string const output_to_file = ChangeExtension(output_file, ext);
// Do we need to perform the conversion?
// Yes if to_file does not exist or if temp_file is newer than to_file
output_to_file);
runparams.exportdata->addExternalFile("dvi", to_file,
output_to_file);
- return stripExtension(output_file);
+ return stripExtensionIfPossible(output_file);
}
lyxerr[Debug::GRAPHICS]
<< "\tfile to convert = " << temp_file << '\n'
<< "\t from " << from << " to " << to << '\n';
- // if no special converter defined, then we take the default one
- // from ImageMagic: convert from:inname.from to:outname.to
- if (!converters.convert(&buf, temp_file, temp_file, from, to)) {
- string const command =
- "sh " + LibFileSearch("scripts", "convertDefault.sh") +
- ' ' + from + ':' + temp_file + ' ' +
- to + ':' + to_file;
- lyxerr[Debug::GRAPHICS]
- << "No converter defined! I use convertDefault.sh:\n\t"
- << command << endl;
- Systemcall one;
- one.startscript(Systemcall::Wait, command);
- if (IsFileReadable(to_file)) {
- runparams.exportdata->addExternalFile("latex",
- to_file, output_to_file);
- runparams.exportdata->addExternalFile("dvi",
- to_file, output_to_file);
- } else {
- string str = bformat(_("No information for converting %1$s "
- "format files to %2$s.\n"
- "Try defining a convertor in the preferences."), from, to);
- Alert::error(_("Could not convert image"), str);
- }
+ if (converters.convert(&buf, temp_file, temp_file, from, to, true)) {
+ runparams.exportdata->addExternalFile("latex",
+ to_file, output_to_file);
+ runparams.exportdata->addExternalFile("dvi",
+ to_file, output_to_file);
}
- return stripExtension(output_file);
+ return stripExtensionIfPossible(output_file);
}
lyxerr[Debug::GRAPHICS] << "\tOpts = " << opts << endl;
if (!opts.empty() && !message.empty())
- before += ("[%\n" + opts + ',' + message + ']');
+ before += ('[' + opts + ',' + message + ']');
else if (!opts.empty() || !message.empty())
- before += ("[%\n" + opts + message + ']');
+ before += ('[' + opts + message + ']');
lyxerr[Debug::GRAPHICS]
<< "\tBefore = " << before
<< "\n\tafter = " << after << endl;
-
string latex_str = before + '{';
- if (file_exists)
- // Convert the file if necessary.
- // Remove the extension so the LaTeX will use whatever
- // is appropriate (when there are several versions in
- // different formats)
- latex_str += prepareFile(buf, runparams);
- else
- latex_str += relative_file + " not found!";
-
+ // Convert the file if necessary.
+ // Remove the extension so LaTeX will use whatever is appropriate
+ // (when there are several versions in different formats)
+ latex_str += prepareFile(buf, runparams);
latex_str += '}' + after;
os << latex_str;
lyxerr[Debug::GRAPHICS] << "InsetGraphics::latex outputting:\n"
<< latex_str << endl;
// Return how many newlines we issued.
- return int(lyx::count(latex_str.begin(), latex_str.end(),'\n') + 1);
+ return int(lyx::count(latex_str.begin(), latex_str.end(),'\n'));
}
}
+namespace {
+
+int writeImageObject(char * format, ostream& os, OutputParams const & runparams,
+ string const graphic_label, string const attributes)
+{
+ if (runparams.flavor != OutputParams::XML) {
+ os << "<![ %output.print." << format << "; [" << std::endl;
+ }
+ os <<"<imageobject><imagedata fileref=\"&"
+ << graphic_label << ";." << format << "\" " << attributes ;
+ if (runparams.flavor == OutputParams::XML) {
+ os << " role=\"" << format << "\"/>" ;
+ }
+ else {
+ os << " format=\"" << format << "\">" ;
+ }
+ os << "</imageobject>";
+ if (runparams.flavor != OutputParams::XML) {
+ os << std::endl << "]]>" ;
+ }
+ return runparams.flavor == OutputParams::XML ? 0 : 2;
+}
+// end anonymous namespace
+}
+
+
// For explanation on inserting graphics into DocBook checkout:
// http://en.tldp.org/LDP/LDP-Author-Guide/html/inserting-pictures.html
// See also the docbook guide at http://www.docbook.org/
if (runparams.flavor == OutputParams::XML) {
runparams.exportdata->addExternalFile("docbook-xml",
params().filename.absFilename());
- os << "<inlinegraphic fileref=\"&" << graphic_label << ";\" " + createDocBookAttributes() + "/>";
} else {
runparams.exportdata->addExternalFile("docbook",
params().filename.absFilename());
- os << "<inlinegraphic fileref=\"&" << graphic_label << ";\" " + createDocBookAttributes() + "/>";
}
- return 0;
+ os << "<inlinemediaobject>";
+
+ int r = 0;
+ string attributes = createDocBookAttributes();
+ r += writeImageObject("png", os, runparams, graphic_label, attributes);
+ r += writeImageObject("pdf", os, runparams, graphic_label, attributes);
+ r += writeImageObject("eps", os, runparams, graphic_label, attributes);
+ r += writeImageObject("bmp", os, runparams, graphic_label, attributes);
+
+ os << "</inlinemediaobject>";
+ return r;
}
return;
features.includeFile(graphic_label,
- RemoveExtension(params().filename.absFilename()));
+ RemoveExtension(params().filename.absFilename()));
features.require("graphicx");
}
-void InsetGraphics::editGraphics(InsetGraphicsParams const & p, Buffer const & buffer) const
+void InsetGraphics::editGraphics(InsetGraphicsParams const & p,
+ Buffer const & buffer) const
{
string const file_with_path = p.filename.absFilename();
- formats.edit(buffer, file_with_path, getExtFromContents(file_with_path));
+ formats.edit(buffer, file_with_path,
+ formats.getFormatFromFile(file_with_path));
}