From e5706b107da902bc6a28cba0de3ccd6f75d9fee7 Mon Sep 17 00:00:00 2001 From: Angus Leeming Date: Tue, 26 Oct 2004 18:39:13 +0000 Subject: [PATCH] The Movers patch. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@9130 a592a061-630c-0410-9148-cb99ea01b6c8 --- lib/ChangeLog | 26 +- lib/configure.m4 | 6 +- lib/scripts/fig_copy.sh | 82 +++++ src/ChangeLog | 25 +- src/Makefile.am | 2 + src/converter.C | 26 +- src/converter.h | 4 +- src/frontends/controllers/ChangeLog | 4 + src/frontends/controllers/ControlPrefs.C | 3 + src/frontends/controllers/ControlPrefs.h | 7 + src/frontends/qt2/ChangeLog | 10 +- src/frontends/qt2/Makefile.dialogs | 1 + src/frontends/qt2/QPrefs.C | 8 +- src/frontends/qt2/QPrefs.h | 2 + src/frontends/qt2/QPrefsDialog.C | 193 +++++++++++ src/frontends/qt2/QPrefsDialog.h | 10 +- src/frontends/qt2/ui/QPrefCopiersModule.ui | 296 +++++++++++++++++ src/frontends/xforms/ChangeLog | 6 + src/frontends/xforms/FormPreferences.C | 308 +++++++++++++++++- src/frontends/xforms/FormPreferences.h | 46 ++- .../xforms/forms/form_preferences.fd | 120 ++++++- src/insets/ChangeLog | 18 +- src/insets/ExternalSupport.C | 4 +- src/insets/insetgraphics.C | 10 +- src/lyx_main.C | 2 + src/lyxrc.C | 58 ++++ src/lyxrc.h | 1 + src/mover.C | 83 +++++ src/mover.h | 128 ++++++++ 29 files changed, 1435 insertions(+), 54 deletions(-) create mode 100644 lib/scripts/fig_copy.sh create mode 100644 src/frontends/qt2/ui/QPrefCopiersModule.ui create mode 100644 src/mover.C create mode 100644 src/mover.h diff --git a/lib/ChangeLog b/lib/ChangeLog index 803512a022..650441a4bf 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,11 @@ +2004-10-26 Angus Leeming + + * configure.m4: add an XFig 'copier'. + + * scripts/fig_copy.sh: a script to 'copy' an XFig data file. If this + involves a directory change, then any references to picture files are + changed from relative to absolute paths. + 2004-10-25 Bennett Helm * Makefile.am (dist_bind_DATA): add mac.bind @@ -17,9 +25,9 @@ 2004-10-19 Jean-Marc Lasgouttes - * bind/xemacs.bind: - * bind/emacs.bind: - * bind/mac.bind: + * bind/xemacs.bind: + * bind/emacs.bind: + * bind/mac.bind: * bind/cua.bind: add bindings for buffer-previous/next 2004-10-18 Andreas Vox @@ -84,7 +92,7 @@ be done because LyX is installed in a directory which name contains spaces. - * chkconfig.ltx: remove use of macro \srcdir + * chkconfig.ltx: remove use of macro \srcdir (\TestDocClass): change to take two arguments (\DeclareLaTeXClass, \DeclareLinuxDocClass, \DeclareDocBookClass): do not exit after execution @@ -99,12 +107,12 @@ 2004-08-14 Jean-Marc Lasgouttes - * ui/stdmenus.ui: + * ui/stdmenus.ui: * ui/classic.ui: add LyX menu 2004-08-14 Bennett Helm - * bind/mac.bind: new file. This is the Mac flavour bind file, based on + * bind/mac.bind: new file. This is the Mac flavour bind file, based on bindings found in the Mac world. 2004-08-13 LyX Guy @@ -114,7 +122,7 @@ 2004-08-13 José Matos * layouts/elsart.layout: fixed its permission settings and readded layouts. Added optional itens as already present in 1.3 version. - + 2004-08-13 José Matos * layouts/elsart.layout: removed temporarily to correct the permission settings of the file. @@ -161,12 +169,12 @@ * encodings: * languages: implement iso-8859-13 (latin-7) for Latvian and - Lithuanian. Also include Icelandic. + Lithuanian. Also include Icelandic. 2004-06-09 Lars Gullik Bjonnes * Makefile.am (dist_*): Use the dist annotation to clean up the - Makefile slightly. + Makefile slightly. 2004-06-02 Lars Gullik Bjonnes diff --git a/lib/configure.m4 b/lib/configure.m4 index 3676c5c6df..232b829bfb 100644 --- a/lib/configure.m4 +++ b/lib/configure.m4 @@ -479,11 +479,11 @@ EOF for file in ./layouts/*.layout "${srcdir}"/layouts/*.layout ; do case $file in */\*.layout) ;; - *) if test -r "$file" ; then + *) if test -r "$file" ; then class=`echo $file | sed -e 's%^.*layouts/\(.*\)\.layout$%\1%'` # Generate the proper TestDocClass command for this layout grep '\\Declare\(LaTeX\|DocBook\|LinuxDoc\)Class' "$file" \ - | sed -e 's/^\# *\(.*\)$/\\TestDocClass{'${class}'}{\1}/' + | sed -e 's/^\# *\(.*\)$/\\TestDocClass{'${class}'}{\1}/' fi ;; esac done > chklayouts.tex @@ -587,6 +587,8 @@ cat >$outfile < + +# This script will copy an XFIG .fig file "$1" to "$2". In the process, +# it will modify the contents of the .fig file so that the names of any +# picture files that are stored as relative paths are replaced +# with the absolute path. + +test $# -eq 2 || { + echo "Usage: fig_copy.sh " >&2 + exit 1 +} + + +test -r "$1" || { + echo "Unable to read $1" >&2 + exit 1 +} + + +# The work is trivial if "to" and "from" are in the same directory. +PRESENT_DIR=$PWD + +cd `dirname "$1"` || exit $? +FROM_DIR=$PWD +cd "$PRESENT_DIR" || exit $? + +cd `dirname "$2"` || exit $? +TO_DIR=$PWD +cd "$PRESENT_DIR" || exit $? + +test "$FROM_DIR" = "$TO_DIR" && { + 'cp' -f "$1" "$2" + exit $? +} + + +# Ok, they're in different directories. The .fig file must be modified. + +# WS is a space and a tab character. +WS=' ' + +TRANSFORMATION=" +# We're looking for a line of text that defines an entry of +# type '2' (a polyline), subtype '5' (an external picture file). +# The line has 14 other data fields. +/^[${WS}]*2[${WS}]\{1,\}5\([${WS}]\{1,\}[^${WS}]\{1,\}\)\{14\}/{ + +:loop +# If we're not on the last line, get the next line. +# It's this that defines the file itself. +$!{ +N + +# Does the new line contain any data? +# If not, loop +/\n[${WS}]*$/bloop + +# Does the new line contain only a comment? +# If so, loop +/\n[${WS}]*#[^\n]*$/bloop + +# The contents of the final line containing the file name +# are ' X ', where X = 0 or 1. +# If the file name does not begin with '/', then insert the absolute path. +# Note that this test will work even if the file name contains spaces. +s@\(.*\n[${WS}]*[01][${WS}]\{1,\}\)\([^/]\)@\1${FROM_DIR}/\2@ +} +}" + +sed "${TRANSFORMATION}" "$1" > "$2" +exit $? diff --git a/src/ChangeLog b/src/ChangeLog index 45a12a1ea3..dc6b2254d7 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,20 @@ +2004-10-26 Angus Leeming + + * Makefile.am: add mover.[Ch]. + + * converter.C (convert, move): use the new Movers to move external + files to the temp directory. + + * lyx_main.C (init): ensure that the global system_movers data + is initialised. + + * lyxrc.[Ch]: code to read and write 'copiers' from/to the + preferences file. + + * mover.[Ch]: new files, defining a Mover as a utility to move an + external file between directories and, if necessary, manipulate this + file using a helper script. + 2004-10-25 José Matos * output_docbook.C (makeCommand): merge two if's that tested the same condition. @@ -28,7 +45,7 @@ * output_docbook.C (makeParagraph, makeEnvironment, makeCommand): use the new functions to fix cleanly the support for descriptions. - + 2004-10-24 José Matos * buffer.C (makeLinuxDocFile, makeDocBookFile): @@ -73,7 +90,7 @@ * bufferlist.C (previous, next): new methods - * lfuns.h: + * lfuns.h: * LyXAction.C (init): add LFUN_NEXTBUFFER and LFUN_PREVIOUSBUFFER 2004-10-18 Andreas Vox @@ -93,13 +110,13 @@ 2004-10-13 José Matos * output_docbook.C (docbookParagraphs): fix closing tags in the - end of the document. + end of the document. 2004-10-09 José Matos * buffer.C: format up to 237. * bufferparams.C (write): use tostr to convert booleans to strings. - + 2004-10-08 Martin Vermeer * lyxrc.C: add to tooltip about using xindy to prefs (xforms) diff --git a/src/Makefile.am b/src/Makefile.am index 19a9819b1f..3f71e765f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -226,6 +226,8 @@ lyx_SOURCES = \ messages.h \ metricsinfo.C \ metricsinfo.h \ + mover.C \ + mover.h \ output.C \ output.h \ outputparams.C \ diff --git a/src/converter.C b/src/converter.C index 6591c65152..7ce839105a 100644 --- a/src/converter.C +++ b/src/converter.C @@ -20,6 +20,7 @@ #include "gettext.h" #include "language.h" #include "LaTeX.h" +#include "mover.h" #include "frontends/Alert.h" @@ -42,7 +43,6 @@ using lyx::support::OnlyPath; using lyx::support::Path; using lyx::support::prefixIs; using lyx::support::QuoteName; -using lyx::support::rename; using lyx::support::split; using lyx::support::subst; using lyx::support::Systemcall; @@ -283,7 +283,7 @@ bool Converters::convert(Buffer const * buffer, formats.extension(to_format)); if (from_format == to_format) - return move(from_file, to_file, false); + return move(from_format, from_file, to_file, false); Graph::EdgePath edgepath = getPath(from_format, to_format); if (edgepath.empty()) { @@ -374,7 +374,8 @@ bool Converters::convert(Buffer const * buffer, res = one.startscript(type, command); if (!real_outfile.empty()) { - if (!rename(outfile, real_outfile)) + Mover const & mover = movers(conv.to); + if (!mover.rename(outfile, real_outfile)) res = -1; else lyxerr[Debug::FILES] @@ -414,7 +415,6 @@ bool Converters::convert(Buffer const * buffer, if (conv.To->dummy()) return true; - if (!conv.result_dir.empty()) { to_file = AddName(subst(conv.result_dir, token_base, to_base), subst(conv.result_file, @@ -424,7 +424,8 @@ bool Converters::convert(Buffer const * buffer, token_base, from_base); string to = subst(conv.result_dir, token_base, to_base); - if (!rename(from, to)) { + Mover const & mover = movers(conv.from); + if (!mover.rename(from, to)) { Alert::error(_("Cannot convert file"), bformat(_("Could not move a temporary file from %1$s to %2$s."), from, to)); @@ -433,13 +434,14 @@ bool Converters::convert(Buffer const * buffer, } return true; } else - return move(outfile, to_file, conv.latex); + return move(conv.to, outfile, to_file, conv.latex); } // If from = /path/file.ext and to = /path2/file2.ext2 then this method // moves each /path/file*.ext file to /path2/file2*.ext2' -bool Converters::move(string const & from, string const & to, bool copy) +bool Converters::move(string const & fmt, + string const & from, string const & to, bool copy) { if (from == to) return true; @@ -459,9 +461,11 @@ bool Converters::move(string const & from, string const & to, bool copy) to2 = ChangeExtension(to2, to_extension); lyxerr[Debug::FILES] << "moving " << from2 << " to " << to2 << endl; - bool const moved = (copy) - ? lyx::support::copy(from2, to2) - : rename(from2, to2); + + Mover const & mover = movers(fmt); + bool const moved = copy + ? mover.copy(from2, to2) + : mover.rename(from2, to2); if (!moved && no_errors) { Alert::error(_("Cannot convert file"), bformat(_("Could not move a temporary file from %1$s to %2$s."), @@ -531,7 +535,7 @@ bool Converters::runLaTeX(Buffer const & buffer, string const & command, { buffer.busy(true); buffer.message(_("Running LaTeX...")); - + runparams.document_language = buffer.params().language->babel(); // do the LaTeX run(s) diff --git a/src/converter.h b/src/converter.h index 3945dd5c3b..ce290766fc 100644 --- a/src/converter.h +++ b/src/converter.h @@ -142,7 +142,9 @@ private: /// std::string latex_command_; /// - bool move(std::string const & from, std::string const & to, bool copy); + bool move(std::string const & fmt, + std::string const & from, std::string const & to, + bool copy); /// Graph G_; }; diff --git a/src/frontends/controllers/ChangeLog b/src/frontends/controllers/ChangeLog index e885e41678..2e044193e9 100644 --- a/src/frontends/controllers/ChangeLog +++ b/src/frontends/controllers/ChangeLog @@ -1,3 +1,7 @@ +2004-10-26 Angus Leeming + + * ControlPrefs.[Ch]: add code to interface with the Movers. + 2004-09-14 Jean-Marc Lasgouttes * ControlSpellchecker.C (check): do not set the selection diff --git a/src/frontends/controllers/ControlPrefs.C b/src/frontends/controllers/ControlPrefs.C index 8f1a3775ca..67f0dc910e 100644 --- a/src/frontends/controllers/ControlPrefs.C +++ b/src/frontends/controllers/ControlPrefs.C @@ -52,6 +52,7 @@ bool ControlPrefs::initialiseParams(std::string const &) formats_ = ::formats; converters_ = ::converters; converters_.update(formats_); + movers_ = ::movers; colors_.clear(); redraw_gui_ = false; update_screen_font_ = false; @@ -75,6 +76,8 @@ void ControlPrefs::dispatchParams() ::converters.update(::formats); ::converters.buildGraph(); + ::movers = movers_; + vector::const_iterator it = colors_.begin(); vector::const_iterator const end = colors_.end(); for (; it != end; ++it) diff --git a/src/frontends/controllers/ControlPrefs.h b/src/frontends/controllers/ControlPrefs.h index 8093de5634..f06bbd6ebd 100644 --- a/src/frontends/controllers/ControlPrefs.h +++ b/src/frontends/controllers/ControlPrefs.h @@ -16,6 +16,7 @@ #include "converter.h" #include "format.h" #include "lyxrc.h" +#include "mover.h" #include #include @@ -46,6 +47,9 @@ public: Formats & formats() { return formats_; } Formats const & formats() const { return formats_; } + Movers & movers() { return movers_; } + Movers const & movers() const { return movers_; } + /// various file pickers std::string const browsebind(std::string const & file) const; std::string const browseUI(std::string const & file) const; @@ -79,6 +83,9 @@ private: /// temporary formats Formats formats_; + /// temporary movers + Movers movers_; + /// A list of colors to be dispatched std::vector colors_; diff --git a/src/frontends/qt2/ChangeLog b/src/frontends/qt2/ChangeLog index e3a7d595fd..99635acecb 100644 --- a/src/frontends/qt2/ChangeLog +++ b/src/frontends/qt2/ChangeLog @@ -1,3 +1,11 @@ +2004-10-26 Angus Leeming + + * Makefile.dialogs: + * QPrefs.[Ch]: + * QPrefsDialog.[Ch]: + * ui/QPrefCopierModule.ui: enable the Movers to be modified from the + preferences dialog. + 2004-10-18 Georg Baum * ui/QPrefConvertersModule.ui: Add translation context to "To:" @@ -6,7 +14,7 @@ 2004-10-11 Andreas Vox * qfont_loader.C (initFontPath, addToFontPath): two new static - member functions that replace addFontPath + member functions that replace addFontPath (available): remove special MacOSX code; use addToFontPath * lyx_gui.C (parse_init): add call to qfont_loader::initFontPath() diff --git a/src/frontends/qt2/Makefile.dialogs b/src/frontends/qt2/Makefile.dialogs index 1b1ada508d..d16c829f6b 100644 --- a/src/frontends/qt2/Makefile.dialogs +++ b/src/frontends/qt2/Makefile.dialogs @@ -40,6 +40,7 @@ UIFILES = \ QPrefAsciiModule.ui \ QPrefColorsModule.ui \ QPrefConvertersModule.ui \ + QPrefCopiersModule.ui \ QPrefDateModule.ui \ QPrefDisplayModule.ui \ QPrefFileformatsModule.ui \ diff --git a/src/frontends/qt2/QPrefs.C b/src/frontends/qt2/QPrefs.C index 0c6f78c2a4..20d5a4ac09 100644 --- a/src/frontends/qt2/QPrefs.C +++ b/src/frontends/qt2/QPrefs.C @@ -93,6 +93,12 @@ Formats & QPrefs::formats() } +Movers & QPrefs::movers() +{ + return controller().movers(); +} + + void QPrefs::build_dialog() { dialog_.reset(new QPrefsDialog(this)); @@ -626,8 +632,8 @@ void QPrefs::update_contents() fontmod->screenHugerED->setText(toqstr(tostr(rc.font_sizes[LyXFont::SIZE_HUGER]))); dialog_->updateFormats(); - dialog_->updateConverters(); + dialog_->updateCopiers(); } } // namespace frontend diff --git a/src/frontends/qt2/QPrefs.h b/src/frontends/qt2/QPrefs.h index f27076e608..4b5dfa3f40 100644 --- a/src/frontends/qt2/QPrefs.h +++ b/src/frontends/qt2/QPrefs.h @@ -17,6 +17,7 @@ class Converters; class Formats; +class Movers; namespace lyx { namespace frontend { @@ -45,6 +46,7 @@ private: Converters & converters(); Formats & formats(); + Movers & movers(); /// languages std::vector lang_; diff --git a/src/frontends/qt2/QPrefsDialog.C b/src/frontends/qt2/QPrefsDialog.C index 3444fd1938..cb1423e343 100644 --- a/src/frontends/qt2/QPrefsDialog.C +++ b/src/frontends/qt2/QPrefsDialog.C @@ -9,6 +9,7 @@ */ #include +#include "debug.h" #include "qt_helpers.h" #include "QPrefsDialog.h" @@ -28,6 +29,7 @@ #include "ui/QPrefPathsModule.h" #include "ui/QPrefSpellcheckerModule.h" #include "ui/QPrefConvertersModule.h" +#include "ui/QPrefCopiersModule.h" #include "ui/QPrefFileformatsModule.h" #include "ui/QPrefLanguageModule.h" #include "ui/QPrefPrinterModule.h" @@ -74,6 +76,7 @@ QPrefsDialog::QPrefsDialog(QPrefs * form) pathsModule = new QPrefPathsModule(this); spellcheckerModule = new QPrefSpellcheckerModule(this); convertersModule = new QPrefConvertersModule(this); + copiersModule = new QPrefCopiersModule(this); fileformatsModule = new QPrefFileformatsModule(this); languageModule = new QPrefLanguageModule(this); printerModule = new QPrefPrinterModule(this); @@ -104,6 +107,7 @@ QPrefsDialog::QPrefsDialog(QPrefs * form) prefsPS->addPanel(pathsModule, _("Paths")); prefsPS->addPanel(fileformatsModule, _("File formats")); prefsPS->addPanel(convertersModule, _("Converters")); + prefsPS->addPanel(copiersModule, _("Copiers")); prefsPS->setCurrentPanel(_("User interface")); @@ -176,6 +180,16 @@ QPrefsDialog::QPrefsDialog(QPrefs * form) connect(convertersModule->converterNewPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(convertersModule->converterRemovePB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(convertersModule->converterModifyPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); + + connect(copiersModule->copierNewPB, SIGNAL(clicked()), this, SLOT(new_copier())); + connect(copiersModule->copierRemovePB, SIGNAL(clicked()), this, SLOT(remove_copier())); + connect(copiersModule->copierModifyPB, SIGNAL(clicked()), this, SLOT(modify_copier())); + connect(copiersModule->AllCopiersLB, SIGNAL(highlighted(int)), this, SLOT(switch_copierLB(int))); + connect(copiersModule->copierFormatCO, SIGNAL(activated(int)), this, SLOT(switch_copierCO(int))); + connect(copiersModule->copierNewPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); + connect(copiersModule->copierRemovePB, SIGNAL(clicked()), this, SLOT(change_adaptor())); + connect(copiersModule->copierModifyPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); + connect(fileformatsModule->formatNewPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(fileformatsModule->formatRemovePB, SIGNAL(clicked()), this, SLOT(change_adaptor())); connect(fileformatsModule->formatModifyPB, SIGNAL(clicked()), this, SLOT(change_adaptor())); @@ -359,6 +373,185 @@ void QPrefsDialog::remove_converter() } +void QPrefsDialog::updateCopiers() +{ + // The choice widget + copiersModule->copierFormatCO->clear(); + + for (Formats::const_iterator it = form_->formats().begin(), + end = form_->formats().end(); + it != end; ++it) { + copiersModule->copierFormatCO->insertItem(toqstr(it->prettyname())); + } + + // The browser widget + copiersModule->AllCopiersLB->clear(); + + for (Movers::iterator it = form_->movers().begin(), + end = form_->movers().end(); + it != end; ++it) { + std::string const & command = it->second.command(); + if (command.empty()) + continue; + std::string const & fmt = it->first; + std::string const & pretty = form_->formats().prettyName(fmt); + + copiersModule->AllCopiersLB->insertItem(toqstr(pretty)); + } + + if (copiersModule->AllCopiersLB->currentItem() == -1) + copiersModule->AllCopiersLB->setCurrentItem(0); +} + + +namespace { + +struct SamePrettyName { + SamePrettyName(string const & n) : pretty_name_(n) {} + + bool operator()(::Format const & fmt) const { + return fmt.prettyname() == pretty_name_; + } + +private: + string const pretty_name_; +}; + + +Format const * getFormat(std::string const & prettyname) +{ + Formats::const_iterator it = ::formats.begin(); + Formats::const_iterator const end = ::formats.end(); + it = std::find_if(it, end, SamePrettyName(prettyname)); + return it == end ? 0 : &*it; +} + +} // namespace anon + + +void QPrefsDialog::switch_copierLB(int nr) +{ + std::string const browser_text = + fromqstr(copiersModule->AllCopiersLB->currentText()); + lyxerr << "switch_copierLB(" << nr << ")\n" + << "browser_text " << browser_text << std::endl; + Format const * fmt = getFormat(browser_text); + if (fmt == 0) + return; + + string const & fmt_name = fmt->name(); + string const & gui_name = fmt->prettyname(); + string const & command = form_->movers().command(fmt_name); + + lyxerr << "switch_copierLB(" << nr << ")\n" + << "fmt_name " << fmt_name << '\n' + << "gui_name " << gui_name << '\n' + << "command " << command << std::endl; + + copiersModule->copierED->clear(); + int const combo_size = copiersModule->copierFormatCO->count(); + for (int i = 0; i < combo_size; ++i) { + QString const qtext = copiersModule->copierFormatCO->text(i); + std::string const text = fromqstr(qtext); + if (text == gui_name) { + copiersModule->copierFormatCO->setCurrentItem(i); + copiersModule->copierED->setText(toqstr(command)); + lyxerr << "found combo item " << i << std::endl; + break; + } + } +} + + +void QPrefsDialog::switch_copierCO(int nr) +{ + std::string const combo_text = + fromqstr(copiersModule->copierFormatCO->currentText()); + lyxerr << "switch_copierCO(" << nr << ")\n" + << "combo_text " << combo_text << std::endl; + Format const * fmt = getFormat(combo_text); + if (fmt == 0) + return; + + string const & fmt_name = fmt->name(); + string const & gui_name = fmt->prettyname(); + string const & command = form_->movers().command(fmt_name); + + lyxerr << "switch_copierCO(" << nr << ")\n" + << "fmt_name " << fmt_name << '\n' + << "gui_name " << gui_name << '\n' + << "command " << command << std::endl; + + copiersModule->copierED->setText(toqstr(command)); + + int const index = copiersModule->AllCopiersLB->currentItem(); + if (index >= 0) + copiersModule->AllCopiersLB->setSelected(index, false); + + int const browser_size = copiersModule->AllCopiersLB->count(); + for (int i = 0; i < browser_size; ++i) { + QString const qtext = copiersModule->AllCopiersLB->text(i); + std::string const text = fromqstr(qtext); + if (text == gui_name) { + copiersModule->AllCopiersLB->setSelected(i, true); + int top = std::max(i - 5, 0); + copiersModule->AllCopiersLB->setTopItem(top); + break; + } + } +} + + +void QPrefsDialog::new_copier() +{ + std::string const combo_text = + fromqstr(copiersModule->copierFormatCO->currentText()); + Format const * fmt = getFormat(combo_text); + if (fmt == 0) + return; + + string const command = fromqstr(copiersModule->copierED->text()); + if (command.empty()) + return; + + form_->movers().set(fmt->name(), command); + + updateCopiers(); + int const last = copiersModule->AllCopiersLB->count() - 1; + copiersModule->AllCopiersLB->setCurrentItem(last); +} + + +void QPrefsDialog::modify_copier() +{ + std::string const combo_text = + fromqstr(copiersModule->copierFormatCO->currentText()); + Format const * fmt = getFormat(combo_text); + if (fmt == 0) + return; + + string const command = fromqstr(copiersModule->copierED->text()); + form_->movers().set(fmt->name(), command); + + updateCopiers(); +} + + +void QPrefsDialog::remove_copier() +{ + std::string const combo_text = + fromqstr(copiersModule->copierFormatCO->currentText()); + Format const * fmt = getFormat(combo_text); + if (fmt == 0) + return; + + string const & fmt_name = fmt->name(); + form_->movers().set(fmt_name, string()); + + updateCopiers(); +} + + void QPrefsDialog::updateFormats() { QPrefFileformatsModule * formatmod(fileformatsModule); diff --git a/src/frontends/qt2/QPrefsDialog.h b/src/frontends/qt2/QPrefsDialog.h index bfee667962..67bafd0477 100644 --- a/src/frontends/qt2/QPrefsDialog.h +++ b/src/frontends/qt2/QPrefsDialog.h @@ -27,6 +27,7 @@ class QPrefDisplayModule; class QPrefPathsModule; class QPrefSpellcheckerModule; class QPrefConvertersModule; +class QPrefCopiersModule; class QPrefFileformatsModule; class QPrefLanguageModule; class QPrefPrinterModule; @@ -48,7 +49,7 @@ public: ~QPrefsDialog(); void updateConverters(); - + void updateCopiers(); void updateFormats(); public slots: @@ -64,6 +65,12 @@ public slots: void modify_converter(); void remove_converter(); + void switch_copierLB(int nr); + void switch_copierCO(int nr); + void new_copier(); + void modify_copier(); + void remove_copier(); + void change_color(); void select_ui(); @@ -98,6 +105,7 @@ private: QPrefPathsModule * pathsModule; QPrefSpellcheckerModule * spellcheckerModule; QPrefConvertersModule * convertersModule; + QPrefCopiersModule * copiersModule; QPrefFileformatsModule * fileformatsModule; QPrefLanguageModule * languageModule; QPrefPrinterModule * printerModule; diff --git a/src/frontends/qt2/ui/QPrefCopiersModule.ui b/src/frontends/qt2/ui/QPrefCopiersModule.ui new file mode 100644 index 0000000000..e446ec5d0b --- /dev/null +++ b/src/frontends/qt2/ui/QPrefCopiersModule.ui @@ -0,0 +1,296 @@ + +QPrefCopiersModule +config.h +qt_helpers.h + + QWidget + + name + QPrefCopiersModule + + + geometry + + 0 + 0 + 547 + 261 + + + + caption + File Conversion + + + + margin + 11 + + + spacing + 6 + + + QLayoutWidget + + name + Layout4 + + + + margin + 0 + + + spacing + 6 + + + QLabel + + name + AllCopiersLA + + + text + C&opiers + + + buddy + AllCopiersLB + + + + QLayoutWidget + + name + Layout1 + + + + margin + 0 + + + spacing + 6 + + + QListBox + + + text + New Item + + + + name + AllCopiersLB + + + sizePolicy + + 3 + 7 + + + + vScrollBarMode + AlwaysOn + + + hScrollBarMode + AlwaysOff + + + + QPushButton + + name + copierNewPB + + + text + &New + + + + QPushButton + + name + copierRemovePB + + + text + &Remove + + + + + + + + QLayoutWidget + + name + Layout6 + + + + margin + 0 + + + spacing + 6 + + + QLayoutWidget + + name + Layout2 + + + + margin + 0 + + + spacing + 6 + + + QComboBox + + name + copierFormatCO + + + sizePolicy + + 3 + 0 + + + + + QLabel + + name + copierLA + + + text + &Copier: + + + buddy + copierED + + + + QLabel + + name + copierFormatLA + + + text + &Format: + + + buddy + copierFormatCO + + + + QLineEdit + + name + copierED + + + + + + QLayoutWidget + + name + Layout5 + + + + margin + 0 + + + spacing + 6 + + + QPushButton + + name + copierModifyPB + + + text + &Modify + + + + + name + Spacer2 + + + orientation + Horizontal + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + + + name + Spacer28 + + + orientation + Vertical + + + sizeType + Expanding + + + sizeHint + + 20 + 20 + + + + + + + + + AllCopiersLB + copierFormatCO + copierED + copierNewPB + copierRemovePB + + diff --git a/src/frontends/xforms/ChangeLog b/src/frontends/xforms/ChangeLog index afe504e25f..73c733db99 100644 --- a/src/frontends/xforms/ChangeLog +++ b/src/frontends/xforms/ChangeLog @@ -1,3 +1,9 @@ +2004-10-26 Angus Leeming + + * FormPreferences.[Ch]: + * forms/form_preferences.fd: enable the Movers to be modified from the + preferences dialog. + 2004-10-18 Georg Baum * forms/form_preferences.fd: Add translation context to "To:" diff --git a/src/frontends/xforms/FormPreferences.C b/src/frontends/xforms/FormPreferences.C index a4eaeea4e0..df41505316 100644 --- a/src/frontends/xforms/FormPreferences.C +++ b/src/frontends/xforms/FormPreferences.C @@ -93,13 +93,12 @@ typedef FormController > base_class; FormPreferences::FormPreferences(Dialog & parent) : base_class(parent, _("Preferences"), scalableTabfolders), - colors_(*this), converters_(*this), inputs_misc_(*this), - formats_(*this), interface_(*this), language_(*this), - lnf_misc_(*this), identity_(*this), outputs_misc_(*this), - paths_(*this), printer_(*this), screen_fonts_(*this), - spelloptions_(*this) -{ -} + colors_(*this), converters_(*this), copiers_(*this), + formats_(*this), identity_(*this), inputs_misc_(*this), + interface_(*this), language_(*this), lnf_misc_(*this), + outputs_misc_(*this), paths_(*this), printer_(*this), + screen_fonts_(*this), spelloptions_(*this) +{} void FormPreferences::redraw() @@ -169,6 +168,7 @@ void FormPreferences::build() // these will become nested tabfolders colors_.build(); converters_.build(); + copiers_.build(); formats_.build(); inputs_misc_.build(); interface_.build(); @@ -245,6 +245,9 @@ void FormPreferences::build() fl_addto_tabfolder(converters_tab_->tabfolder_inner, _("Converters").c_str(), converters_.dialog()->form); + fl_addto_tabfolder(converters_tab_->tabfolder_inner, + _("Copiers").c_str(), + copiers_.dialog()->form); // then build inputs // Paths should probably go in a few inner_tab called Files @@ -317,6 +320,8 @@ string const FormPreferences::getFeedback(FL_OBJECT * ob) return colors_.feedback(ob); if (ob->form->fdui == converters_.dialog()) return converters_.feedback(ob); + if (ob->form->fdui == copiers_.dialog()) + return copiers_.feedback(ob); if (ob->form->fdui == formats_.dialog()) return formats_.feedback(ob); if (ob->form->fdui == inputs_misc_.dialog()) @@ -356,6 +361,8 @@ ButtonPolicy::SMInput FormPreferences::input(FL_OBJECT * ob, long) colors_.input(ob); } else if (ob->form->fdui == converters_.dialog()) { valid = converters_.input(ob); + } else if (ob->form->fdui == copiers_.dialog()) { + valid = copiers_.input(ob); } else if (ob->form->fdui == formats_.dialog()) { valid = formats_.input(ob); } else if (ob->form->fdui == interface_.dialog()) { @@ -384,6 +391,7 @@ void FormPreferences::update() colors_.update(); formats_.update(); // Must be before converters_.update() converters_.update(); + copiers_.update(); inputs_misc_.update(rc); interface_.update(rc); language_.update(rc); @@ -971,6 +979,292 @@ void FormPreferences::Converters::UpdateChoices() } +FormPreferences::Copiers::Copiers(FormPreferences & p) + : parent_(p) +{} + + +FD_preferences_copiers const * FormPreferences::Copiers::dialog() +{ + return dialog_.get(); +} + + +::Movers & FormPreferences::Copiers::movers() +{ + return parent_.controller().movers(); +} + + +void FormPreferences::Copiers::build() +{ + dialog_.reset(build_preferences_copiers(&parent_)); + + fl_set_input_return(dialog_->input_copier, FL_RETURN_CHANGED); + + // set up the feedback mechanism + setPrehandler(dialog_->browser_all); + setPrehandler(dialog_->button_delete); + setPrehandler(dialog_->button_add); + setPrehandler(dialog_->choice_format); + setPrehandler(dialog_->input_copier); +} + + +string const +FormPreferences::Copiers::feedback(FL_OBJECT const * const ob) const +{ + if (ob == dialog_->browser_all) + return _("All explicitly defined copiers for LyX"); + + if (ob == dialog_->choice_format) + return _("Copier for this format"); + + if (ob == dialog_->input_copier) + + return _("The command used to copy the file. " + "$$i is the \"from\" file name and " + "$$o is the \"to\" file name.\n" + "$$s can be used as path to " + "LyX's own collection of scripts."); + + if (ob == dialog_->button_delete) + return _("Remove the current copier from the list of available " + "copiers. Note: you must then \"Apply\" the change."); + + if (ob == dialog_->button_add) { + if (string(ob->label) == _("Add")) + return _("Add the current copier to the list of available " + "copiers. Note: you must then \"Apply\" the change."); + else + return _("Modify the contents of the current copier. " + "Note: you must then \"Apply\" the change."); + } + + return string(); +} + + +bool FormPreferences::Copiers::input(FL_OBJECT const * const ob) +{ + if (ob == dialog_->browser_all) + return Browser(); + + if (ob == dialog_->choice_format + || ob == dialog_->input_copier) + return Input(); + + if (ob == dialog_->button_add) + return Add(); + + if (ob == dialog_->button_delete) + return Erase(); + + return true; +} + + +void FormPreferences::Copiers::update() +{ + // Build data for the browser widget + Movers::iterator const begin = movers().begin(); + Movers::iterator const end = movers().end(); + + vector fmts; + fmts.reserve(std::distance(begin, end)); + for (Movers::iterator it = begin; it != end; ++it) { + std::string const & command = it->second.command(); + if (command.empty()) + continue; + std::string const & fmt = it->first; + fmts.push_back(::formats.prettyName(fmt)); + } + + std::sort(fmts.begin(), fmts.end()); + + // Build data for the choice widget + string choice; + for (::Formats::const_iterator it = ::formats.begin(); + it != ::formats.end(); ++it) { + if (!choice.empty()) + choice += " | "; + else + choice += ' '; + choice += it->prettyname(); + } + choice += ' '; + + // The input widget + fl_freeze_form(dialog_->form); + fl_set_input(dialog_->input_copier, ""); + + // The browser widget + fl_clear_browser(dialog_->browser_all); + + vector::const_iterator it = fmts.begin(); + vector::const_iterator const fmts_end = fmts.end(); + for (; it != fmts_end; ++it) + fl_addto_browser(dialog_->browser_all, it->c_str()); + + // The choice widget + fl_clear_choice(dialog_->choice_format); + fl_addto_choice(dialog_->choice_format, choice.c_str()); + fl_set_choice(dialog_->choice_format, 1); + + Input(); + fl_unfreeze_form(dialog_->form); +} + + +namespace { + +struct SamePrettyName { + SamePrettyName(string const & n) : pretty_name_(n) {} + + bool operator()(::Format const & fmt) const { + return fmt.prettyname() == pretty_name_; + } + +private: + string const pretty_name_; +}; + + +::Format const * getFormat(std::string const & prettyname) +{ + ::Formats::const_iterator it = ::formats.begin(); + ::Formats::const_iterator const end = ::formats.end(); + it = std::find_if(it, end, SamePrettyName(prettyname)); + return it == end ? 0 : &*it; +} + +} // namespace anon + + +bool FormPreferences::Copiers::Add() +{ + ::Format const * fmt = getFormat(getString(dialog_->choice_format)); + if (fmt == 0) + return false; + + string const command = getString(dialog_->input_copier); + if (command.empty()) + return false; + + fl_freeze_form(dialog_->form); + + movers().set(fmt->name(), command); + update(); + setEnabled(dialog_->button_add, false); + + fl_unfreeze_form(dialog_->form); + return true; +} + + +bool FormPreferences::Copiers::Browser() +{ + int const i = fl_get_browser(dialog_->browser_all); + if (i <= 0) return false; + + ::Format const * fmt = getFormat(getString(dialog_->browser_all, i)); + if (fmt == 0) + return false; + + string const & fmt_name = fmt->name(); + string const & gui_name = fmt->prettyname(); + string const & command = movers().command(fmt_name); + + fl_freeze_form(dialog_->form); + + int const choice_size = fl_get_choice_maxitems(dialog_->choice_format); + for (int i = 1; i <= choice_size; ++i) { + char const * const c_str = + fl_get_choice_item_text(dialog_->choice_format, i); + string const line = c_str ? trim(c_str) : string(); + if (line == gui_name) { + fl_set_choice(dialog_->choice_format, i); + break; + } + } + + fl_set_input(dialog_->input_copier, command.c_str()); + + fl_set_object_label(dialog_->button_add, idex(_("Modify|#M")).c_str()); + fl_set_button_shortcut(dialog_->button_add, + scex(_("Modify|#M")).c_str(), 1); + + setEnabled(dialog_->button_add, false); + setEnabled(dialog_->button_delete, true); + + fl_unfreeze_form(dialog_->form); + return false; +} + + +bool FormPreferences::Copiers::Erase() +{ + ::Format const * fmt = getFormat(getString(dialog_->choice_format)); + if (fmt == 0) + return false; + + string const & fmt_name = fmt->name(); + + movers().set(fmt_name, string()); + update(); + return true; +} + + +bool FormPreferences::Copiers::Input() +{ + ::Format const * fmt = getFormat(getString(dialog_->choice_format)); + if (fmt == 0) + return false; + + string const & gui_name = fmt->prettyname(); + string const command = getString(dialog_->input_copier); + + fl_freeze_form(dialog_->form); + fl_deselect_browser(dialog_->browser_all); + bool found_line = false; + int const browser_size = fl_get_browser_maxline(dialog_->browser_all); + for (int i = 1; i <= browser_size; ++i) { + char const * const c_str = + fl_get_browser_line(dialog_->browser_all, i); + string const line = c_str ? trim(c_str) : string(); + if (line == gui_name) { + fl_select_browser_line(dialog_->browser_all, i); + int top = max(i-5, 1); + fl_set_browser_topline(dialog_->browser_all, top); + found_line = true; + break; + } + } + + if (!found_line) { + fl_set_object_label(dialog_->button_add, + idex(_("Add|#A")).c_str()); + fl_set_button_shortcut(dialog_->button_add, + scex(_("Add|#A")).c_str(), 1); + + setEnabled(dialog_->button_delete, false); + } else { + fl_set_object_label(dialog_->button_add, + idex(_("Modify|#M")).c_str()); + fl_set_button_shortcut(dialog_->button_add, + scex(_("Modify|#M")).c_str(), 1); + + setEnabled(dialog_->button_delete, true); + } + + setEnabled(dialog_->button_add, !command.empty()); + + fl_unfreeze_form(dialog_->form); + return false; +} + + FormPreferences::Formats::Formats(FormPreferences & p) : parent_(p) {} diff --git a/src/frontends/xforms/FormPreferences.h b/src/frontends/xforms/FormPreferences.h index e7f4a0cb02..8adb810ddc 100644 --- a/src/frontends/xforms/FormPreferences.h +++ b/src/frontends/xforms/FormPreferences.h @@ -21,6 +21,7 @@ class Converters; class Formats; +class Movers; class Dialogs; class LyXRC; @@ -33,6 +34,7 @@ class ControlPrefs; struct FD_preferences; struct FD_preferences_colors; struct FD_preferences_converters; +struct FD_preferences_copiers; struct FD_preferences_formats; struct FD_preferences_inputs_misc; struct FD_preferences_interface; @@ -185,6 +187,42 @@ private: /// friend class Converters; + /// + class Copiers { + public: + /// + Copiers(FormPreferences & p); + /// + FD_preferences_copiers const * dialog(); + /// + void build(); + /// + std::string const feedback(FL_OBJECT const * const) const; + /// + bool input(FL_OBJECT const * const); + /// + void update(); + + private: + /// + bool Add(); + /// + bool Browser(); + /// + bool Erase(); + /// + bool Input(); + /// + ::Movers & movers(); + + /// + FormPreferences & parent_; + /// + boost::scoped_ptr dialog_; + }; + /// + friend class Copiers; + /// class Formats { public: @@ -492,18 +530,20 @@ private: /// Converters converters_; /// - InputsMisc inputs_misc_; + Copiers copiers_; /// Formats formats_; /// + Identity identity_; + /// + InputsMisc inputs_misc_; + /// Interface interface_; /// Language language_; /// LnFmisc lnf_misc_; /// - Identity identity_; - /// OutputsMisc outputs_misc_; /// Paths paths_; diff --git a/src/frontends/xforms/forms/form_preferences.fd b/src/frontends/xforms/forms/form_preferences.fd index e76675ae86..5bd7a3eb32 100644 --- a/src/frontends/xforms/forms/form_preferences.fd +++ b/src/frontends/xforms/forms/form_preferences.fd @@ -3,7 +3,7 @@ Magic: 13000 Internal Form Definition File (do not change) -Number of forms: 15 +Number of forms: 16 Unit of measure: FL_COORD_PIXEL SnapGrid: 5 @@ -1937,7 +1937,7 @@ boxtype: FL_FRAME_BOX colors: FL_COL1 FL_BLACK alignment: FL_ALIGN_LEFT style: FL_NORMAL_STYLE -size: FL_DEFAULT_SIZE +size: FL_NORMAL_SIZE lcol: FL_BLACK label: From:|#F shortcut: @@ -1955,7 +1955,7 @@ boxtype: FL_FRAME_BOX colors: FL_COL1 FL_BLACK alignment: FL_ALIGN_LEFT style: FL_NORMAL_STYLE -size: FL_DEFAULT_SIZE +size: FL_NORMAL_SIZE lcol: FL_BLACK label: To:|#T[[as in 'From format x to format y']] shortcut: @@ -2037,6 +2037,120 @@ name: button_delete callback: C_FormDialogView_InputCB argument: 0 +=============== FORM =============== +Name: form_preferences_copiers +Width: 450 +Height: 360 +Number of Objects: 6 + +-------------------- +class: FL_BOX +type: FLAT_BOX +box: 0 0 450 360 +boxtype: FL_FLAT_BOX +colors: FL_COL1 FL_COL1 +alignment: FL_ALIGN_CENTER +style: FL_NORMAL_STYLE +size: FL_DEFAULT_SIZE +lcol: FL_BLACK +label: +shortcut: +resize: FL_RESIZE_ALL +gravity: FL_NoGravity FL_NoGravity +name: +callback: +argument: + +-------------------- +class: FL_BROWSER +type: HOLD_BROWSER +box: 30 30 160 270 +boxtype: FL_DOWN_BOX +colors: FL_COL1 FL_YELLOW +alignment: FL_ALIGN_TOP +style: FL_NORMAL_STYLE +size: FL_NORMAL_SIZE +lcol: FL_BLACK +label: All copiers:|#l +shortcut: +resize: FL_RESIZE_ALL +gravity: FL_NoGravity FL_NoGravity +name: browser_all +callback: C_FormDialogView_InputCB +argument: 0 + +-------------------- +class: FL_CHOICE +type: NORMAL_CHOICE +box: 280 30 150 30 +boxtype: FL_FRAME_BOX +colors: FL_COL1 FL_BLACK +alignment: FL_ALIGN_LEFT +style: FL_NORMAL_STYLE +size: FL_NORMAL_SIZE +lcol: FL_BLACK +label: Format:|#F +shortcut: +resize: FL_RESIZE_ALL +gravity: FL_NoGravity FL_NoGravity +name: choice_format +callback: C_FormDialogView_InputCB +argument: 0 + +-------------------- +class: FL_INPUT +type: NORMAL_INPUT +box: 280 70 150 30 +boxtype: FL_DOWN_BOX +colors: FL_COL1 FL_MCOL +alignment: FL_ALIGN_LEFT +style: FL_NORMAL_STYLE +size: FL_NORMAL_SIZE +lcol: FL_BLACK +label: Copier:|#C +shortcut: +resize: FL_RESIZE_ALL +gravity: FL_NoGravity FL_NoGravity +name: input_copier +callback: C_FormDialogView_InputCB +argument: 0 + +-------------------- +class: FL_BUTTON +type: NORMAL_BUTTON +box: 240 270 90 30 +boxtype: FL_UP_BOX +colors: FL_COL1 FL_COL1 +alignment: FL_ALIGN_CENTER +style: FL_NORMAL_STYLE +size: FL_NORMAL_SIZE +lcol: FL_BLACK +label: Add|#A +shortcut: +resize: FL_RESIZE_ALL +gravity: FL_NoGravity FL_NoGravity +name: button_add +callback: C_FormDialogView_InputCB +argument: 0 + +-------------------- +class: FL_BUTTON +type: NORMAL_BUTTON +box: 340 270 90 30 +boxtype: FL_UP_BOX +colors: FL_COL1 FL_COL1 +alignment: FL_ALIGN_CENTER +style: FL_NORMAL_STYLE +size: FL_NORMAL_SIZE +lcol: FL_BLACK +label: Delete|#D +shortcut: +resize: FL_RESIZE_ALL +gravity: FL_NoGravity FL_NoGravity +name: button_delete +callback: C_FormDialogView_InputCB +argument: 0 + =============== FORM =============== Name: form_preferences_paths Width: 450 diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index 6626f7beee..f1487497eb 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,7 +1,13 @@ +2004-10-26 Angus Leeming + + * ExternalSupport.C (updateExternal): + * insetgraphics.C (copyFileIfNeeded): use the new Movers to move external + files to the temp directory. + 2004-10-25 Jürgen Spitzmüller - * insetfoot.C (latex): use \thanks instead of \footnote on titlepage - layouts. This fixes problems with the memoir class (which does not + * insetfoot.C (latex): use \thanks instead of \footnote on titlepage + layouts. This fixes problems with the memoir class (which does not allow \footnote) [bug 1677] 2004-10-24 Andreas Vox @@ -44,16 +50,16 @@ 2004-09-29 Andreas Vox - * insetgraphics.C (createDocBookAttribute, docbook) : + * insetgraphics.C (createDocBookAttribute, docbook) : convert scale, width, height and keepaspectratio to Docbook standards) - + * insetgraphics.[hC] (toDocbookLength): new method to convert TeX units to Docbook units where possible. 2004-09-29 Andreas Vox - * insetgraphics.C (docbook): create inlinegraphic instead of graphic. - + * insetgraphics.C (docbook): create inlinegraphic instead of graphic. + * insetgraphics.[hC] (createDocBookAttributes): Export parameters as attributes with new method for docbook. diff --git a/src/insets/ExternalSupport.C b/src/insets/ExternalSupport.C index b96abfd07c..c12ebaaa15 100644 --- a/src/insets/ExternalSupport.C +++ b/src/insets/ExternalSupport.C @@ -21,6 +21,7 @@ #include "debug.h" #include "exporter.h" #include "format.h" +#include "mover.h" #include "support/filetools.h" #include "support/forkedcall.h" @@ -204,7 +205,8 @@ void updateExternal(InsetExternalParams const & params, unsigned long const temp_checksum = support::sum(temp_file); if (from_checksum != temp_checksum) { - if (!support::copy(abs_from_file, temp_file)) { + Mover const & mover = movers(from_format); + if (!mover.copy(abs_from_file, temp_file)) { lyxerr[Debug::EXTERNAL] << "external::updateExternal. " << "Unable to copy " diff --git a/src/insets/insetgraphics.C b/src/insets/insetgraphics.C index 1d0de8708c..ec239f1b45 100644 --- a/src/insets/insetgraphics.C +++ b/src/insets/insetgraphics.C @@ -67,6 +67,7 @@ TODO #include "lyxlength.h" #include "lyxlex.h" #include "metricsinfo.h" +#include "mover.h" #include "outputparams.h" #include "frontends/Alert.h" @@ -454,7 +455,8 @@ copyFileIfNeeded(string const & file_in, string const & file_out) // Nothing to do... return std::make_pair(IDENTICAL_CONTENTS, file_out); - bool const success = support::copy(file_in, file_out); + Mover const & mover = movers(getExtFromContents(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" @@ -796,7 +798,7 @@ int writeImageObject(char * format, ostream& os, OutputParams const & runparams, if (runparams.flavor != OutputParams::XML) { os << "" ; @@ -831,14 +833,14 @@ int InsetGraphics::docbook(Buffer const &, ostream & os, params().filename.absFilename()); } os << ""; - + 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 << ""; return r; } diff --git a/src/lyx_main.C b/src/lyx_main.C index 7b4b8ce795..879e9c2df6 100644 --- a/src/lyx_main.C +++ b/src/lyx_main.C @@ -36,6 +36,7 @@ #include "lyxtextclasslist.h" #include "lyxserver.h" #include "MenuBackend.h" +#include "mover.h" #include "ToolbarBackend.h" #include "mathed/math_inset.h" @@ -373,6 +374,7 @@ void LyX::init(bool gui) system_lyxrc = lyxrc; system_formats = formats; system_converters = converters; + system_movers = movers; system_lcolor = lcolor; string prefsfile = "preferences"; diff --git a/src/lyxrc.C b/src/lyxrc.C index 1129afb870..ea6f37b002 100644 --- a/src/lyxrc.C +++ b/src/lyxrc.C @@ -29,6 +29,7 @@ #include "LColor.h" #include "lyxlex.h" #include "lyxfont.h" +#include "mover.h" #include "graphics/GraphicsTypes.h" @@ -71,6 +72,7 @@ keyword_item lyxrcTags[] = { { "\\check_lastfiles", LyXRC::RC_CHECKLASTFILES }, { "\\chktex_command", LyXRC::RC_CHKTEX_COMMAND }, { "\\converter", LyXRC::RC_CONVERTER }, + { "\\copier", LyXRC::RC_COPIER }, { "\\cursor_follows_scrollbar", LyXRC::RC_CURSOR_FOLLOWS_SCROLLBAR }, { "\\custom_export_command", LyXRC::RC_CUSTOM_EXPORT_COMMAND }, { "\\custom_export_format", LyXRC::RC_CUSTOM_EXPORT_FORMAT }, @@ -964,6 +966,18 @@ int LyXRC::read(LyXLex & lexrc) } break; + case RC_COPIER: { + string fmt, command; + if (lexrc.next()) { + fmt = lexrc.getString(); + } + if (lexrc.next()) { + command = lexrc.getString(); + } + movers.set(fmt, command); + break; + } + case RC_CONVERTER: { string from, to, command, flags; if (lexrc.next()) { @@ -1136,6 +1150,23 @@ void LyXRC::print() const } +struct SameMover { + typedef std::pair Data; + + SameMover(Data const & comparison) + : comparison_(comparison) {} + + bool operator()(Data const & data) const + { + return data.first == comparison_.first && + data.second.command() == comparison_.second.command(); + } + +private: + Data comparison_; +}; + + void LyXRC::write(ostream & os, bool ignore_system_lyxrc) const { os << "### This file is part of\n" @@ -1915,7 +1946,34 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc) const os << "\\converter \"" << cit->from << "\" \"" << cit->to << "\" \"\" \"\"\n"; + case RC_COPIER: + os << "\n#\n" + << "# COPIERS SECTION ##########################\n" + << "#\n\n"; + + // Look for new movers + Movers::iterator const sysbegin = system_movers.begin(); + Movers::iterator const sysend = system_movers.end(); + + for (Movers::iterator it = movers.begin(), end = movers.end(); + it != end; ++it) { + Movers::iterator const sysit = + std::find_if(sysbegin, sysend, SameMover(*it)); + if (sysit == sysend) { + std::string const & fmt = it->first; + std::string const & command = + it->second.command(); + + os << "\\copier " << fmt + << " \"" << command << "\"\n"; + } + } + + // We don't actually delete SpecialisedMover(s) from the + // map, just clear their 'command', so there's no need + // to test for anything else. } + os.flush(); } diff --git a/src/lyxrc.h b/src/lyxrc.h index 05b6a32fa2..5cd5bc34b6 100644 --- a/src/lyxrc.h +++ b/src/lyxrc.h @@ -120,6 +120,7 @@ enum LyXRCTags { RC_SHOW_BANNER, RC_WHEEL_JUMP, RC_CONVERTER, + RC_COPIER, RC_VIEWER, RC_FORMAT, RC_DEFAULT_LANGUAGE, diff --git a/src/mover.C b/src/mover.C new file mode 100644 index 0000000000..a646f49478 --- /dev/null +++ b/src/mover.C @@ -0,0 +1,83 @@ +/** + * \file mover.C + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + +#include "mover.h" + +#include "support/filetools.h" +#include "support/lstrings.h" +#include "support/lyxlib.h" +#include "support/systemcall.h" + +#include + +using std::ostringstream; +using std::string; + +namespace support = lyx::support; + +Movers movers; +Movers system_movers; + + +bool Mover::do_copy(string const & from, string const & to) const +{ + return support::copy(from, to); +} + + +bool Mover::do_rename(string const & from, string const & to) const +{ + return support::rename(from, to); +} + + +bool SpecialisedMover::do_copy(string const & from, string const & to) const +{ + if (command_.empty()) + return Mover::do_copy(from, to); + + string command = support::LibScriptSearch(command_); + command = support::subst(command, "$$i", from); + command = support::subst(command, "$$o", to); + + support::Systemcall one; + return one.startscript(support::Systemcall::Wait, command) == 0; +} + + +bool SpecialisedMover::do_rename(string const & from, string const & to) const +{ + if (command_.empty()) + return Mover::do_rename(from, to); + + if (!do_copy(from, to)) + return false; + return support::unlink(from) == 0; +} + + +void Movers::set(string const & fmt, string const & command) +{ + specials_[fmt] = SpecialisedMover(command); +} + + +Mover const & Movers::operator()(string const & fmt) const +{ + SpecialsMap::const_iterator const it = specials_.find(fmt); + return (it == specials_.end()) ? default_ : it->second; +} + + +string const Movers::command(string const & fmt) const +{ + SpecialsMap::const_iterator const it = specials_.find(fmt); + return (it == specials_.end()) ? string() : it->second.command(); +} diff --git a/src/mover.h b/src/mover.h new file mode 100644 index 0000000000..3e80753601 --- /dev/null +++ b/src/mover.h @@ -0,0 +1,128 @@ +// -*- C++ -*- +/** + * \file mover.h + * This file is part of LyX, the document processor. + * Licence details can be found in the file COPYING. + * + * \author Angus Leeming + * + * Full author contact details are available in file CREDITS. + */ + +#ifndef MOVER_H +#define MOVER_H + +#include +#include + +/** + * Utility to copy a file of a specified format from one place to another. + * This base class simply invokes the command support::copy(). + */ +class Mover +{ +public: + virtual ~Mover() {} + + /** Copy file @c from to @c to. + * \returns true if successful. + */ + bool + copy(std::string const & from, std::string const & to) const + { + return do_copy(from, to); + } + + /** Rename file @c from as @c to. + * \returns true if successful. + */ + bool + rename(std::string const & from, std::string const & to) const + { + return do_rename(from, to); + } + +protected: + virtual bool + do_copy(std::string const & from, std::string const & to) const; + + virtual bool + do_rename(std::string const & from, std::string const & to) const; +}; + + +/** + * Specialisation of the Mover concept that uses an external command + * to copy a file. + * + * For example, an XFig .fig file can contain references to external + * picture files. If such a reference has a relative path, then the + * copied .fig file will require a transformation of the picture file + * reference if it is to be found by XFig. + */ +struct SpecialisedMover : public Mover +{ + SpecialisedMover() {} + + /** @c command should be of the form + * + * sh $$s/copy_fig.sh $$i $$o + * + * where $$s is a placeholder for the lyx script directory, + * $$i is a placeholder for the name of the file to be moved, + * $$o is a placeholder for the name of the file after moving. + */ + SpecialisedMover(std::string const & command) + : command_(command) {} + + /// The template used to launch the external command. + std::string const & command() const { return command_; } + +private: + virtual bool + do_copy(std::string const & from, std::string const & to) const; + + virtual bool + do_rename(std::string const & from, std::string const & to) const; + + std::string command_; +}; + + +/** + * Manage the store of (Mover)s. + */ +class Movers +{ +public: + /** Register a specialised @c command to be used to copy a file + * of format @c fmt. + */ + void set(std::string const & fmt, std::string const & command); + + /// @c returns the Mover registered for format @c fmt. + Mover const & operator()(std::string const & fmt) const; + + /** @returns the command template if @c fmt 'finds' a + * SpecialisedMover. Otherwise, returns an empty string. + */ + std::string const command(std::string const & fmt) const; + +private: + typedef std::map SpecialsMap; + +public: + typedef SpecialsMap::const_iterator iterator; + iterator begin() const { return specials_.begin(); } + iterator end() const { return specials_.end(); } + +private: + Mover default_; + SpecialsMap specials_; +}; + + +extern Movers movers; +extern Movers system_movers; + +#endif // MOVER_H -- 2.39.2