diff --git a/src/mathed/formula.C b/src/mathed/formula.C index 01c3f227e3..9dc7b582c3 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -61,24 +61,13 @@ using std::getline; InsetFormula::InsetFormula() - : par_(MathAtom(new MathHullInset)) -{ - init(); -} - - -InsetFormula::InsetFormula(InsetFormula const & f) - : InsetFormulaBase(f), par_(f.par_), loader_(f.loader_.filename()) -{ - init(); -} + : par_(MathAtom(new MathHullInset)), loader_(0) +{} InsetFormula::InsetFormula(MathInsetTypes t) - : par_(MathAtom(new MathHullInset(t))) -{ - init(); -} + : par_(MathAtom(new MathHullInset(t))), loader_(0) +{} InsetFormula::InsetFormula(string const & s) @@ -94,8 +83,8 @@ InsetFormula::InsetFormula(string const & s) par_ = MathAtom(new MathHullInset(LM_OT_SIMPLE)); } } - init(); metrics(); + updatePreview(); } @@ -167,6 +156,7 @@ void InsetFormula::read(Buffer const *, LyXLex & lex) { mathed_parse_normal(par_, lex); metrics(); + updatePreview(); } @@ -189,7 +179,7 @@ void InsetFormula::draw(BufferView * bv, LyXFont const & font, MathPainterInfo pi(bv->painter()); if (canPreview()) { - pi.pain.image(x + 1, y - a + 1, w - 2, h - 2, *(loader_.image())); + pi.pain.image(x + 1, y - a + 1, w - 2, h - 2, *(loader_->image())); } else { pi.base.style = display() ? LM_ST_DISPLAY : LM_ST_TEXT; pi.base.font = font; @@ -354,6 +344,8 @@ InsetFormula::localDispatch(BufferView * bv, kb_action action, result = InsetFormulaBase::localDispatch(bv, action, arg); } + //updatePreview(); + return result; } @@ -404,7 +396,7 @@ int InsetFormula::ascent(BufferView *, LyXFont const &) const const int a = par_->ascent(); if (!canPreview()) return a + 1; - return a + 1 - (par_->height() - loader_.image()->getHeight()) / 2; + return a + 1 - (par_->height() - loader_->image()->getHeight()) / 2; } @@ -413,14 +405,14 @@ int InsetFormula::descent(BufferView *, LyXFont const &) const const int d = par_->descent(); if (!canPreview()) return d + 1; - return d + 1 - (par_->height() - loader_.image()->getHeight()) / 2; + return d + 1 - (par_->height() - loader_->image()->getHeight()) / 2; } int InsetFormula::width(BufferView * bv, LyXFont const & font) const { metrics(bv, font); - return canPreview() ? loader_.image()->getWidth() : par_->width(); + return canPreview() ? loader_->image()->getWidth() : par_->width(); } @@ -436,85 +428,78 @@ MathInsetTypes InsetFormula::getType() const bool InsetFormula::canPreview() const { - return lyxrc.preview && !par_->asNestInset()->editing() - && loader_.status() == grfx::Ready; + return lyxrc.preview && loader_ && !par_->asNestInset()->editing() + && loader_->status() == grfx::Ready; } void InsetFormula::statusChanged() { - //lyxerr << "### InsetFormula::statusChanged called!, status: " - // << loader_.status() << "\n"; - if (loader_.status() == grfx::Ready) + lyxerr << "### InsetFormula::statusChanged called!, status: " + << loader_->status() << "\n"; + if (loader_->status() == grfx::Ready) view()->updateInset(this, false); - else if (loader_.status() == grfx::WaitingToLoad) - loader_.startLoading(); + else if (loader_->status() == grfx::WaitingToLoad) + loader_->startLoading(); } -void InsetFormula::init() -{ - if (lyxrc.preview) - loader_.statusChanged.connect - (boost::bind(&InsetFormula::statusChanged, this)); -} - - -// built some unique filename -string constructFileName(string const & data) -{ - typedef std::map cache_type; - static cache_type theCache; - static int theCounter = 0; - - int number; - cache_type::const_iterator it = theCache.find(data); - if (it == theCache.end()) - number = theCache[data] = theCounter++; - else - number = it->second; - - ostringstream os; - os << number; - return os.str(); -} - - -void InsetFormula::updatePreview() const +void InsetFormula::updatePreview() { // nothing to be done if no preview requested + lyxerr << "### updatePreview() called\n"; if (!lyxrc.preview) return; - //lyxerr << "### updatePreview() called\n"; // get LaTeX ostringstream ls; WriteStream wi(ls, false, false); par_->write(wi); string const data = ls.str(); - string const base = constructFileName(data); - string const dir = OnlyPath(lyx::tempName()); - string const file = dir + base + ".lyxpreview"; - // everything is fine already - if (loader_.filename() == file) + // the preview cache, maps contents to image loaders + typedef std::map > cache_type; + static cache_type theCache; + static int theCounter = 0; + + // set our loader corresponding to our current data + cache_type::const_iterator it = theCache.find(data); + + // is this old data? + if (it != theCache.end()) { + // we have already a loader, connect to it anyway + lyxerr << "### updatePreview(), old loader: " << loader_ << "\n"; + loader_ = it->second.get(); + loader_->statusChanged.connect + (boost::bind(&InsetFormula::statusChanged, this)); return; + } + + // construct new file name + static string const dir = OnlyPath(lyx::tempName()); + ostringstream os; + os << dir << theCounter++ << ".lyxpreview"; + string file = os.str(); // the real work starts - //lyxerr << "### updatePreview() called for " << file << "\n"; + lyxerr << "### updatePreview(), new file " << file << "\n"; std::ofstream of(file.c_str()); of << "\\batchmode" - << "\\documentclass{article}" - << "\\usepackage{amssymb}" - << "\\thispagestyle{empty}" - << "\\pdfoutput=0" - << "\\begin{document}" - << data - << "\\end{document}\n"; + << "\\documentclass{article}" + << "\\usepackage{amssymb}" + << "\\thispagestyle{empty}" + << "\\pdfoutput=0" + << "\\begin{document}" + << data + << "\\end{document}\n"; of.close(); // now we are done, start actual loading we will get called back via // InsetFormula::statusChanged() if this is finished - loader_.reset(file); + lyxerr << "### updatePreview(), new loader: " << loader_ << "\n"; + theCache[data].reset(new grfx::Loader(file)); + loader_ = theCache.find(data)->second.get(); + loader_->startLoading(); + loader_->statusChanged.connect(boost::bind(&InsetFormula::statusChanged, this)); } diff --git a/src/mathed/formula.h b/src/mathed/formula.h index 12e94a5203..7ee57310c2 100644 --- a/src/mathed/formula.h +++ b/src/mathed/formula.h @@ -39,8 +39,6 @@ public: /// explicit InsetFormula(string const &); /// - InsetFormula(InsetFormula const &); - /// int ascent(BufferView *, LyXFont const &) const; /// int descent(BufferView *, LyXFont const &) const; @@ -95,15 +93,13 @@ private: /// void statusChanged(); /// - void init(); - /// - void updatePreview() const; + void updatePreview(); /// bool canPreview() const; /// contents MathAtom par_; - /// LaTeX preview - mutable grfx::Loader loader_; + /// non owning pointer + mutable grfx::Loader * loader_; }; #endif diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C index c8e5f0f608..5961993563 100644 --- a/src/mathed/formulabase.C +++ b/src/mathed/formulabase.C @@ -158,8 +158,6 @@ void InsetFormulaBase::metrics(BufferView * bv) const mi.base.font = font_; mi.base.font.setColor(LColor::math); par()->metrics(mi); - if (lyxrc.preview) - updatePreview(); } diff --git a/src/mathed/formulabase.h b/src/mathed/formulabase.h index d72e3fdb79..6732fe54f9 100644 --- a/src/mathed/formulabase.h +++ b/src/mathed/formulabase.h @@ -118,6 +118,8 @@ public: virtual void revealCodes(BufferView *) const; /// virtual Inset::EDITABLE editable() const { return HIGHLY_EDITABLE; } + /// + virtual void updatePreview() {} private: @@ -138,8 +140,6 @@ protected: void metrics(BufferView * bv = 0) const; /// void handleFont(BufferView * bv, string const & arg, string const & font); - /// - virtual void updatePreview() const {} /// mutable int xo_; diff --git a/src/mathed/math_cursor.C b/src/mathed/math_cursor.C index 32d6876b65..31dbb201a2 100644 --- a/src/mathed/math_cursor.C +++ b/src/mathed/math_cursor.C @@ -77,6 +77,14 @@ MathCursor::MathCursor(InsetFormulaBase * formula, bool front) } +MathCursor::~MathCursor() +{ + // ensure that 'notifyCursorLeave' is called + while (popLeft()) + ; +} + + void MathCursor::push(MathAtom & t) { Cursor_.push_back(MathCursorPos(t.nucleus())); @@ -103,8 +111,12 @@ void MathCursor::pushRight(MathAtom & t) bool MathCursor::popLeft() { //cerr << "Leaving atom to the left\n"; - if (depth() <= 1) + if (depth() <= 1) { + if (depth() == 1) + par()->notifyCursorLeaves(); return false; + } + par()->notifyCursorLeaves(); Cursor_.pop_back(); return true; } @@ -113,8 +125,12 @@ bool MathCursor::popLeft() bool MathCursor::popRight() { //cerr << "Leaving atom "; par()->write(cerr, false); cerr << " right\n"; - if (depth() <= 1) + if (depth() <= 1) { + if (depth() == 1) + par()->notifyCursorLeaves(); return false; + } + par()->notifyCursorLeaves(); Cursor_.pop_back(); posRight(); return true; diff --git a/src/mathed/math_cursor.h b/src/mathed/math_cursor.h index aa9a15554d..f250c4975b 100644 --- a/src/mathed/math_cursor.h +++ b/src/mathed/math_cursor.h @@ -60,6 +60,8 @@ public: /// explicit MathCursor(InsetFormulaBase *, bool left); /// + ~MathCursor(); + /// void insert(MathAtom const &); /// void insert(MathArray const &); diff --git a/src/mathed/math_inset.h b/src/mathed/math_inset.h index 47f9b8bb9e..0c6fd08548 100644 --- a/src/mathed/math_inset.h +++ b/src/mathed/math_inset.h @@ -244,6 +244,8 @@ public: virtual bool lock() const { return false; } /// access to the lock (only nest array have one) virtual void lock(bool) {} + /// get notification when the cursor leaves this inset + virtual void notifyCursorLeaves() {} /// write LaTeX and Lyx code virtual void write(WriteStream & os) const; diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index c67666853e..e724c37a94 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -5,6 +5,7 @@ #include "math_nestinset.h" #include "math_cursor.h" #include "math_mathmlstream.h" +#include "formulabase.h" #include "debug.h" #include "frontends/Painter.h" @@ -234,3 +235,11 @@ MathArray MathNestInset::glue() const ar.push_back(cell(i)); return ar; } + + +void MathNestInset::notifyCursorLeaves() +{ + //lyxerr << "leaving " << *this << "\n"; + if (mathcursor) + mathcursor->formula()->updatePreview(); +} diff --git a/src/mathed/math_nestinset.h b/src/mathed/math_nestinset.h index 64caa87a8e..e20cd31c9a 100644 --- a/src/mathed/math_nestinset.h +++ b/src/mathed/math_nestinset.h @@ -57,6 +57,8 @@ public: bool lock() const; /// access to the lock void lock(bool); + /// get notification when the cursor leaves this inset + void notifyCursorLeaves(); /// direct access to the cell MathArray & cell(idx_type);