The attached patch fixes some real problems with the output of change tracked documents and implements a possibility to check whether a (required) package is installed.
The problems, which always occur when a user is in change tracking mode (also cf. bug 1031): - If dvipost is not installed, export to dvi/ps is broken (because dvipost is needed). This is annoying since dvipost is far from being a standard package. - pdflatex gives strange (and IMO wrong) output, even if dvipost is installed. Since dvipost does not handle pdflatex output, all text (unchanged, deleted, and added) occurs in the output (unmarked). IMHO only the actual text (unchanged and added, *not* deleted) should be there. The patch implements the following: - a buffer param "output_changes". If this is false, the change tracking marks (and the deleted text) will not appear in the output. It will just appear as it would look like with all changes accepted. output_changes is always false if flavor is not LATEX (e.g. for pdflatex) and if dvipost is not installed (see below). This needs a file format change. - an LFUN_OUTPUT_CHANGES, which lets the user select if he wants to see the changes in the dvi/ps output or not. The Changes menu now has a toggle "Show changes in output" (apart from the bugfix this is a useful feature anyway; AFAIR OOo's and winword's change tracking mechanism has this also). - The "Show changes in output" menu item is grayed out if dvipost is not installed; also, output_changes is set to false in this case. For this, I had to implement a list which holds the contents of packages.lst and a method isAvailable, which returns whether one of the required packages is installed or not. I was surprised that this method didn't exist yet and I think it will be useful for other cases too (indicate the user if he can actually use a certain feature). However, this was the most tricky part for me and I'd appreciate if you'd review that part critically. I think these changes should go in to get the change tracker into a usable state. The new feature can be considered a nifty side-effect <grin/>. Regards, Jürgen
Index: BufferView_pimpl.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView_pimpl.C,v retrieving revision 1.567 diff -u -r1.567 BufferView_pimpl.C --- BufferView_pimpl.C 10 Jan 2005 19:17:38 -0000 1.567 +++ BufferView_pimpl.C 23 Jan 2005 17:03:23 -0000 @@ -34,6 +34,7 @@ #include "gettext.h" #include "intl.h" #include "insetiterator.h" +#include "LaTeXFeatures.h" #include "lyx_cb.h" // added for Dispatch functions #include "lyx_main.h" #include "lyxfind.h" @@ -972,6 +973,16 @@ flag.setOnOff(buf->params().tracking_changes); break; + case LFUN_OUTPUT_CHANGES: { + LaTeXFeatures features(*buf, buf->params(), false); + if (!features.isAvailable("dvipost")) + buf->params().output_changes = false; + flag.enabled(buf && buf->params().tracking_changes + && features.isAvailable("dvipost")); + flag.setOnOff(buf->params().output_changes); + break; + } + case LFUN_MERGE_CHANGES: case LFUN_ACCEPT_CHANGE: // what about these two case LFUN_REJECT_CHANGE: // what about these two @@ -1070,6 +1081,17 @@ case LFUN_TRACK_CHANGES: trackChanges(); break; + + case LFUN_OUTPUT_CHANGES: { + Buffer * buf = bv_->buffer(); + if (!buf->params().tracking_changes) + break; + else { + bool const state = buf->params().output_changes; + buf->params().output_changes = !state; + } + break; + } case LFUN_MERGE_CHANGES: owner_->getDialogs().show("changes"); Index: LaTeXFeatures.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/LaTeXFeatures.C,v retrieving revision 1.115 diff -u -r1.115 LaTeXFeatures.C --- LaTeXFeatures.C 19 Jan 2005 11:44:29 -0000 1.115 +++ LaTeXFeatures.C 23 Jan 2005 17:03:24 -0000 @@ -22,6 +22,7 @@ #include "Floating.h" #include "FloatList.h" #include "language.h" +#include "lyxlex.h" #include "lyx_sty.h" #include "lyxrc.h" @@ -30,6 +31,7 @@ #include <sstream> using lyx::support::IsSGMLFilename; +using lyx::support::LibFileSearch; using lyx::support::MakeRelPath; using lyx::support::OnlyPath; @@ -66,6 +68,39 @@ } +void LaTeXFeatures::getAvailable() +{ + LyXLex lex(0, 0); + string real_file = LibFileSearch("", "packages.lst"); + + if (real_file.empty()) + return; + + lex.setFile(real_file); + + if (!lex.isOK()) + return; + + bool finished = false; + // Parse config-file + while (lex.isOK() && !finished) { + switch (lex.lex()) { + case LyXLex::LEX_FEOF: + finished = true; + break; + default: + string const name = lex.getString(); + PackagesList::const_iterator begin = packages_.begin(); + PackagesList::const_iterator end = packages_.end(); + if (find(begin, end, name) == end) + packages_.push_back(name); + } + } + + return; +} + + void LaTeXFeatures::useLayout(string const & layoutname) { // Some code to avoid loops in dependency definition @@ -108,6 +143,14 @@ bool LaTeXFeatures::isRequired(string const & name) const { return find(features_.begin(), features_.end(), name) != features_.end(); +} + + +bool LaTeXFeatures::isAvailable(string const & name) +{ + if (packages_.empty()) + getAvailable(); + return find(packages_.begin(), packages_.end(), name) != packages_.end(); } Index: LaTeXFeatures.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/LaTeXFeatures.h,v retrieving revision 1.58 diff -u -r1.58 LaTeXFeatures.h --- LaTeXFeatures.h 19 Jan 2005 15:03:27 -0000 1.58 +++ LaTeXFeatures.h 23 Jan 2005 17:03:24 -0000 @@ -62,8 +62,12 @@ void addExternalPreamble(std::string const &); /// Provide a string name-space to the requirements void require(std::string const & name); + /// Which of the required packages are installed? + void getAvailable(); /// Is the package required? bool isRequired(std::string const & name) const; + /// Is the (required) package available? + bool isAvailable(std::string const & name); /// void useFloat(std::string const & name); /// @@ -96,6 +100,10 @@ FeaturesList features_; /// FeaturesList preamble_snippets_; + /// The available (required) packages + typedef std::list<std::string> PackagesList; + /// + PackagesList packages_; /// typedef std::set<Language const *> LanguageList; /// Index: LyXAction.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/LyXAction.C,v retrieving revision 1.203 diff -u -r1.203 LyXAction.C --- LyXAction.C 27 Dec 2004 16:30:27 -0000 1.203 +++ LyXAction.C 23 Jan 2005 17:03:25 -0000 @@ -305,6 +305,7 @@ { LFUN_ESCAPE, "escape", ReadOnly }, { LFUN_TOOLTIPS_TOGGLE, "toggle-tooltips", NoBuffer }, { LFUN_TRACK_CHANGES, "track-changes", Noop }, + { LFUN_OUTPUT_CHANGES, "output-changes", Noop }, { LFUN_MERGE_CHANGES, "merge-changes", Noop }, { LFUN_ACCEPT_CHANGE, "accept-change", Noop }, { LFUN_REJECT_CHANGE, "reject-change", Noop }, Index: buffer.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/buffer.C,v retrieving revision 1.606 diff -u -r1.606 buffer.C --- buffer.C 20 Jan 2005 21:34:22 -0000 1.606 +++ buffer.C 23 Jan 2005 17:03:28 -0000 @@ -1185,7 +1185,7 @@ { LyXTextClass const & tclass = params().getLyXTextClass(); - if (params().tracking_changes) { + if (params().tracking_changes && params().output_changes) { features.require("dvipost"); features.require("color"); } Index: bufferparams.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/bufferparams.C,v retrieving revision 1.96 diff -u -r1.96 bufferparams.C --- bufferparams.C 19 Jan 2005 15:03:29 -0000 1.96 +++ bufferparams.C 23 Jan 2005 17:03:30 -0000 @@ -341,6 +341,7 @@ cite_engine = biblio::ENGINE_BASIC; use_bibtopic = false; tracking_changes = false; + output_changes = false; secnumdepth = 3; tocdepth = 3; language = default_language; @@ -508,6 +509,8 @@ lex >> use_bibtopic; } else if (token == "\\tracking_changes") { lex >> tracking_changes; + } else if (token == "\\output_changes") { + lex >> output_changes; } else if (token == "\\branch") { lex.next(); string branch = lex.getString(); @@ -711,6 +714,7 @@ } os << "\\tracking_changes " << convert<string>(tracking_changes) << "\n"; + os << "\\output_changes " << convert<string>(output_changes) << "\n"; if (tracking_changes) { AuthorList::Authors::const_iterator it = pimpl_->authorlist.begin(); @@ -1100,7 +1104,7 @@ lyxpreamble += "\\makeatother\n"; // dvipost settings come after everything else - if (tracking_changes) { + if (tracking_changes && output_changes) { lyxpreamble += "\\dvipostlayout\n" "\\dvipost{osstart color push Red}\n" Index: bufferparams.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/bufferparams.h,v retrieving revision 1.53 diff -u -r1.53 bufferparams.h --- bufferparams.h 19 Jan 2005 15:03:29 -0000 1.53 +++ bufferparams.h 23 Jan 2005 17:03:30 -0000 @@ -209,6 +209,8 @@ bool use_bibtopic; /// revision tracking for this buffer ? bool tracking_changes; + /// output changes to dvi? + bool output_changes; /// Time ago we agreed that this was a buffer property [ale990407] std::string parentname; /// Index: changes.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/changes.C,v retrieving revision 1.10 diff -u -r1.10 changes.C --- changes.C 5 Jan 2005 20:21:24 -0000 1.10 +++ changes.C 23 Jan 2005 17:03:31 -0000 @@ -495,11 +495,12 @@ int Changes::latexMarkChange(std::ostream & os, - Change::Type const old, Change::Type const change) + Change::Type const old, Change::Type const change, + bool const & output) { - if (old == change) + if (!output || old == change) return 0; - + string const start("\\changestart{}"); string const end("\\changeend{}"); string const son("\\overstrikeon{}"); Index: changes.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/changes.h,v retrieving revision 1.5 diff -u -r1.5 changes.h --- changes.h 19 Jan 2005 15:03:29 -0000 1.5 +++ changes.h 23 Jan 2005 17:03:31 -0000 @@ -89,7 +89,8 @@ /// output latex to mark a transition between two changetypes /// returns length of text outputted - static int latexMarkChange(std::ostream & os, Change::Type old, Change::Type change); + static int latexMarkChange(std::ostream & os, Change::Type old, + Change::Type change, bool const & output); /// output .lyx file format for transitions between changes static void lyxMarkChange(std::ostream & os, int & column, Index: lfuns.h =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lfuns.h,v retrieving revision 1.39 diff -u -r1.39 lfuns.h --- lfuns.h 27 Dec 2004 16:30:27 -0000 1.39 +++ lfuns.h 23 Jan 2005 17:03:32 -0000 @@ -354,6 +354,7 @@ LFUN_PREVIOUSBUFFER, // 270 LFUN_WORDS_COUNT, + LFUN_OUTPUT_CHANGES, // jspitzm 20050121 LFUN_LASTACTION // end of the table }; Index: paragraph.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.C,v retrieving revision 1.399 diff -u -r1.399 paragraph.C --- paragraph.C 6 Jan 2005 16:52:08 -0000 1.399 +++ paragraph.C 23 Jan 2005 17:03:35 -0000 @@ -1009,24 +1009,34 @@ } Change::Type change = pimpl_->lookupChange(i); - - column += Changes::latexMarkChange(os, running_change, change); + + // output change tracking marks only if desired + // and with dvi/ps (other formats don't work) + bool const output = bparams.output_changes + && runparams.flavor == OutputParams::LATEX; + + column += Changes::latexMarkChange(os, running_change, + change, output); running_change = change; - OutputParams rp = runparams; - rp.free_spacing = style->free_spacing; - rp.local_language = font.language()->babel(); - rp.intitle = style->intitle; - pimpl_->simpleTeXSpecialChars(buf, bparams, - os, texrow, rp, - font, running_font, - basefont, outerfont, open_font, - running_change, - *style, i, column, c); + // do not output text which is marked deleted + // if change tracking output is not desired + if (output || running_change != Change::DELETED) { + OutputParams rp = runparams; + rp.free_spacing = style->free_spacing; + rp.local_language = font.language()->babel(); + rp.intitle = style->intitle; + pimpl_->simpleTeXSpecialChars(buf, bparams, + os, texrow, rp, + font, running_font, + basefont, outerfont, open_font, + running_change, + *style, i, column, c); + } } column += Changes::latexMarkChange(os, - running_change, Change::UNCHANGED); + running_change, Change::UNCHANGED, bparams.output_changes); // If we have an open font definition, we have to close it if (open_font) { Index: paragraph_pimpl.C =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph_pimpl.C,v retrieving revision 1.98 diff -u -r1.98 paragraph_pimpl.C --- paragraph_pimpl.C 26 Sep 2004 08:24:08 -0000 1.98 +++ paragraph_pimpl.C 23 Jan 2005 17:03:36 -0000 @@ -505,7 +505,7 @@ if (inset->isTextInset()) { column += Changes::latexMarkChange(os, running_change, - Change::UNCHANGED); + Change::UNCHANGED, bparams.output_changes); running_change = Change::UNCHANGED; }
Index: stdmenus.ui =================================================================== RCS file: /usr/local/lyx/cvsroot/lyx-devel/lib/ui/stdmenus.ui,v retrieving revision 1.38 diff -u -r1.38 stdmenus.ui --- stdmenus.ui 15 Jan 2005 18:36:02 -0000 1.38 +++ stdmenus.ui 23 Jan 2005 17:04:33 -0000 @@ -372,6 +372,7 @@ Item "Merge Changes...|M" "merge-changes" Item "Accept All Changes|A" "accept-all-changes" Item "Reject All Changes|R" "reject-all-changes" + Item "Show changes in output|S" "output-changes" End #