From b4f97b61cf0b257e31bcf512668ad458523d7f5a Mon Sep 17 00:00:00 2001 From: Tommaso Cucinotta Date: Mon, 19 Sep 2011 00:12:09 +0000 Subject: [PATCH] Added support for natively zipped file formats that do not need decompression for being handled by converters (e.g., compressed dia, odg, sxd, ...). These need to be marked via the "zipped=native" flag in the RC file. The old 'dia' configuration is automatically updated (it used to be hardcoded in the code, now it is handled via the flag). See also http://www.mail-archive.com/lyx-devel@lists.lyx.org/msg170974.html git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@39705 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/configure.py | 4 ++-- lib/scripts/prefs2prefs_prefs.py | 18 +++++++++++++++++ src/Format.cpp | 31 +++++++++++++++++++++++++++++- src/Format.h | 24 +++++++++++++++++++++-- src/LyXRC.cpp | 6 +++++- src/graphics/GraphicsCacheItem.cpp | 2 +- src/insets/InsetGraphics.cpp | 4 ++-- src/support/FileName.cpp | 4 ---- 8 files changed, 80 insertions(+), 13 deletions(-) diff --git a/lib/configure.py b/lib/configure.py index b4ca005bf1..2d0fae5cc7 100644 --- a/lib/configure.py +++ b/lib/configure.py @@ -486,7 +486,7 @@ def checkFormatEntries(dtl_tools): rc_entry = [r'\Format fig fig FIG "" "%%" "%%" "vector"']) # checkViewerEditor('a Dia viewer and editor', ['dia'], - rc_entry = [r'\Format dia dia DIA "" "%%" "%%" "vector"']) + rc_entry = [r'\Format dia dia DIA "" "%%" "%%" "vector,zipped=native"']) # checkViewerEditor('a Grace viewer and editor', ['xmgrace'], rc_entry = [r'\Format agr agr Grace "" "%%" "%%" "vector"']) @@ -1301,7 +1301,7 @@ def removeTempFiles(): if __name__ == '__main__': lyx_check_config = True outfile = 'lyxrc.defaults' - lyxrc_fileformat = 2 + lyxrc_fileformat = 3 rc_entries = '' lyx_keep_temps = False version_suffix = '' diff --git a/lib/scripts/prefs2prefs_prefs.py b/lib/scripts/prefs2prefs_prefs.py index 73846524f7..ff44763280 100644 --- a/lib/scripts/prefs2prefs_prefs.py +++ b/lib/scripts/prefs2prefs_prefs.py @@ -20,6 +20,11 @@ # Support for multiple file extensions per format. # No conversion necessary. +# Incremented to format 3, r39705 by tommaso +# Support for file formats that are natively (g)zipped. +# We must add the flag zipped=native to formats that +# were previously hardcoded in the C++ source: dia. + import re @@ -101,6 +106,18 @@ def export_menu(line): return (True, "\\Format %s \"%s,menu=export\"" % (fmat, opts)) +zipre = re.compile(r'^\\[Ff]ormat\s+("?dia"?\s+.*)\s+"([^"]*?)"') +def zipped_native(line): + if not line.lower().startswith("\\format"): + return no_match + m = zipre.match(line) + if not m: + return no_match + fmat = m.group(1) + opts = m.group(2) + return (True, + "\\Format %s \"%s,zipped=native\"" % (fmat, opts)) + ######################## @@ -113,4 +130,5 @@ conversions = [ language_package ]], [ 2, []], + [ 3, [ zipped_native ]], ] diff --git a/src/Format.cpp b/src/Format.cpp index 4219174df7..22ee7ee014 100644 --- a/src/Format.cpp +++ b/src/Format.cpp @@ -95,6 +95,7 @@ Format::Format(string const & n, string const & e, string const & p, editor_(ed), flags_(flags) { extension_list_ = getVectorFromString(e, ","); + LYXERR(Debug::GRAPHICS, "New Format: n=" << n << ", flags=" << flags); } @@ -152,11 +153,26 @@ string Formats::getFormatFromFile(FileName const & filename) const return string(); string const format = filename.guessFormatFromContents(); + string const ext = getExtension(filename.absFileName()); + if ((format == "gzip" || format == "zip" || format == "compress") + && !ext.empty()) { + string const & fmt_name = formats.getFormatFromExtension(ext); + if (!fmt_name.empty()) { + Format const * p_format = formats.getFormat(fmt_name); + if (p_format && p_format->zippedNative()) + return p_format->name(); + } + } if (!format.empty()) return format; // try to find a format from the file extension. - string const ext = getExtension(filename.absFileName()); + return getFormatFromExtension(ext); +} + + +string Formats::getFormatFromExtension(string const & ext) const +{ if (!ext.empty()) { // this is ambigous if two formats have the same extension, // but better than nothing @@ -173,6 +189,19 @@ string Formats::getFormatFromFile(FileName const & filename) const } +bool Formats::isZippedFile(support::FileName const & filename) const { + string const & fname = filename.absFileName(); + time_t timestamp = filename.lastModified(); + map::iterator it = zipped_.find(fname); + if (it != zipped_.end() && it->second.timestamp == timestamp) + return it->second.zipped; + string const & format = getFormatFromFile(filename); + bool zipped = (format == "gzip" || format == "zip"); + zipped_.insert(pair(fname, ZippedInfo(zipped, timestamp))); + return zipped; +} + + static string fixCommand(string const & cmd, string const & ext, os::auto_open_mode mode) { diff --git a/src/Format.h b/src/Format.h index 623ed26f7d..21721fa8e6 100644 --- a/src/Format.h +++ b/src/Format.h @@ -17,7 +17,8 @@ #include "OutputParams.h" #include - +#include +#include namespace lyx { @@ -37,7 +38,9 @@ public: /// Set if this format can contain vector graphics. vector = 2, /// This format should appear in the File > Export menu - export_menu = 4 + export_menu = 4, + /// This may be a compressed file but doesn't need decompression + zipped_native = 8 }; /// Format(std::string const & n, std::string const & e, std::string const & p, @@ -89,6 +92,8 @@ public: void setFlags(int v) { flags_ = v; } /// bool inExportMenu() const { return flags_ & export_menu; } + /// + bool zippedNative() const { return flags_ & zipped_native; } private: /// Internal name. Needs to be unique. std::string name_; @@ -138,6 +143,13 @@ public: * string. */ std::string getFormatFromFile(support::FileName const & filename) const; + /// Finds a format from a file extension. Returns string() if not found. + std::string getFormatFromExtension(std::string const & ext) const; + /** Returns true if the file referenced by \p filename is zipped and + ** needs to be unzipped for being handled + ** @note For natively zipped formats, such as dia/odg, this returns false. + **/ + bool isZippedFile(support::FileName const & filename) const; /// Set editor and/or viewer to "auto" for formats that can be /// opened by the OS. void setAutoOpen(); @@ -179,6 +191,14 @@ public: private: /// FormatList formatlist; + /// Used to store last timestamp of file and whether it is (was) zipped + struct ZippedInfo { + bool zipped; std::time_t timestamp; + ZippedInfo(bool zipped, std::time_t timestamp) + : zipped(zipped), timestamp(timestamp) { } + }; + /// + mutable std::map zipped_; }; /// diff --git a/src/LyXRC.cpp b/src/LyXRC.cpp index ffe1aff2d9..d5b62eb7b8 100644 --- a/src/LyXRC.cpp +++ b/src/LyXRC.cpp @@ -55,7 +55,7 @@ namespace os = support::os; namespace { -static unsigned int const LYXRC_FILEFORMAT = 2; +static unsigned int const LYXRC_FILEFORMAT = 3; // when adding something to this array keep it sorted! LexerKeyword lyxrcTags[] = { @@ -1118,6 +1118,8 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format) flgs |= Format::document; else if (flag == "vector") flgs |= Format::vector; + else if (flag == "zipped=native") + flgs |= Format::zipped_native; else if (flag == "menu=export") flgs |= Format::export_menu; else @@ -2750,6 +2752,8 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c flags.push_back("document"); if (cit->vectorFormat()) flags.push_back("vector"); + if (cit->zippedNative()) + flags.push_back("zipped=native"); if (cit->inExportMenu()) flags.push_back("menu=export"); diff --git a/src/graphics/GraphicsCacheItem.cpp b/src/graphics/GraphicsCacheItem.cpp index 21f3aee31b..e4bfb019f9 100644 --- a/src/graphics/GraphicsCacheItem.cpp +++ b/src/graphics/GraphicsCacheItem.cpp @@ -359,7 +359,7 @@ bool CacheItem::Impl::tryDisplayFormat(FileName & filename, string & from) return false; } - zipped_ = filename_.isZippedFile(); + zipped_ = formats.isZippedFile(filename); if (zipped_) { unzipped_filename_ = FileName::tempName( filename_.toFilesystemEncoding()); diff --git a/src/insets/InsetGraphics.cpp b/src/insets/InsetGraphics.cpp index f0eb88663c..48155fc109 100644 --- a/src/insets/InsetGraphics.cpp +++ b/src/insets/InsetGraphics.cpp @@ -490,7 +490,7 @@ copyToDirIfNeeded(DocFileName const & file, string const & dir) return make_pair(IDENTICAL_PATHS, file_in); string mangled = file.mangledFileName(); - if (file.isZipped()) { + if (formats.isZippedFile(file)) { // We need to change _eps.gz to .eps.gz. The mangled name is // still unique because of the counter in mangledFileName(). // We can't just call mangledFileName() with the zip @@ -616,7 +616,7 @@ string InsetGraphics::prepareFile(OutputParams const & runparams) const // If the file is compressed and we have specified that it // should not be uncompressed, then just return its name and // let LaTeX do the rest! - if (params().filename.isZipped()) { + if (formats.isZippedFile(params().filename)) { if (params().noUnzip) { // We don't know whether latex can actually handle // this file, but we can't check, because that would diff --git a/src/support/FileName.cpp b/src/support/FileName.cpp index a16278fce4..9edbe619f3 100644 --- a/src/support/FileName.cpp +++ b/src/support/FileName.cpp @@ -933,10 +933,6 @@ string FileName::guessFormatFromContents() const format = "fits"; } - // Dia knows also compressed form - if ((format == "gzip") && (!compare_ascii_no_case(extension(), "dia"))) - format="dia"; - if (!format.empty()) { LYXERR(Debug::GRAPHICS, "Recognised Fileformat: " << format); return format;