Previews for \input insets.

Refactor code common to InsetInclude and InsetFormula into a new
PreviewedInset class.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4830 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Angus Leeming 2002-08-01 17:28:59 +00:00
parent bec8a7b65c
commit d91ffd8d78
14 changed files with 413 additions and 119 deletions

View File

@ -1,3 +1,18 @@
2002-08-01 Angus Leeming <leeming@lyx.org>
* PreviewedInset.[Ch]: new files. An abstract base class that can help
insets to generate previews.
The daughter class must instantiate three small methods.
The Inset would own an instance of this daughter class and invoke it
as necessary. For example, mathd/formula.C gets previews at the cost
of 15 or so lines of code.
* Makefile.am: add PreviewedInset.[Ch].
* PreviewLoader.C (add): add debug message.
* Previews.C (generateBufferPreviews): remove if-block from loop.
2002-07-29 Lars Gullik Bjønnes <larsbj@gullik.net>
* PreviewLoader.C (setFontScalingFactor): strip,frontStrip ->

View File

@ -31,5 +31,7 @@ libgraphics_la_SOURCES = \
PreviewLoader.h \
PreviewLoader.C \
Previews.h \
Previews.C
Previews.C \
PreviewedInset.h \
PreviewedInset.C

View File

@ -383,6 +383,8 @@ void PreviewLoader::Impl::add(string const & latex_snippet)
if (!pconverter_ || status(latex_snippet) != NotFound)
return;
lyxerr[Debug::GRAPHICS] << "adding snippet:\n" << latex_snippet << endl;
pending_.push_back(latex_snippet);
}

View File

@ -0,0 +1,106 @@
// -*- C++ -*-
/**
* \file PreviewedInset.C
* Copyright 2002 the LyX Team
* Read the file COPYING
*
* \author Angus Leeming <leeming@lyx.org>
*/
#ifdef __GNUG__
#pragma implementation
#endif
#include <config.h>
#include "PreviewedInset.h"
#include "BufferView.h"
#include "GraphicsImage.h"
#include "PreviewLoader.h"
#include "PreviewImage.h"
#include "Previews.h"
#include <boost/bind.hpp>
namespace grfx {
bool PreviewedInset::activated()
{
return Previews::activated();
}
void PreviewedInset::generatePreview() const
{
if (!Previews::activated() || !previewWanted() ||
!view() || !view()->buffer())
return;
grfx::Previews & previews = grfx::Previews::get();
grfx::PreviewLoader & loader = previews.loader(view()->buffer());
addPreview(loader);
loader.startLoading();
}
void PreviewedInset::addPreview(grfx::PreviewLoader & ploader) const
{
if (!Previews::activated() || !previewWanted())
return;
// Generate the LaTeX snippet.
string const snippet = latexString();
pimage_ = ploader.preview(snippet);
if (pimage_)
return;
// If this is the first time of calling, connect to the
// grfx::PreviewLoader signal that'll inform us when the preview image
// is ready for loading.
if (!connection_.connected()) {
connection_ = ploader.connect(
boost::bind(&PreviewedInset::imageReady, this, _1));
}
ploader.add(snippet);
}
bool PreviewedInset::previewReady() const
{
if (!grfx::Previews::activated() || !previewWanted() ||
!view() || !view()->buffer())
return false;
// If the cached grfx::PreviewImage is invalid, update it.
string const snippet = latexString();
if (!pimage_ || snippet != pimage_->snippet()) {
grfx::PreviewLoader & ploader =
grfx::Previews::get().loader(view()->buffer());
pimage_ = ploader.preview(snippet);
}
if (!pimage_)
return false;
return pimage_->image(inset_, *view());
}
void PreviewedInset::imageReady(grfx::PreviewImage const & pimage) const
{
// Check snippet against the Inset's current contents
if (latexString() != pimage.snippet())
return;
pimage_ = &pimage;
if (view())
view()->updateInset(&inset_, false);
}
} // namespace grfx

View File

@ -0,0 +1,85 @@
// -*- C++ -*-
/**
* \file PreviewedInset.h
* Copyright 2002 the LyX Team
* Read the file COPYING
*
* \author Angus Leeming <leeming@lyx.org>
*
* grfx::PreviewedInset is an abstract base class that can help insets to
* generate previews. The daughter class must instantiate three small
* methods. The Inset would own an instance of this daughter class.
*/
#ifndef PREVIEWEDINSET_H
#define PREVIEWEDINSET_H
#ifdef __GNUG__
#pragma interface
#endif
#include "LString.h"
#include <boost/signals/trackable.hpp>
#include <boost/signals/connection.hpp>
class Inset;
class BufferView;
namespace grfx {
class PreviewImage;
class PreviewLoader;
class PreviewedInset : public boost::signals::trackable {
public:
/// a wrapper for Previews::activated()
static bool activated();
///
PreviewedInset(Inset & inset) : inset_(inset), pimage_(0) {}
/** Find the PreviewLoader, add a LaTeX snippet to it and
* start the loading process.
*/
void generatePreview() const;
/** Add a LaTeX snippet to the PreviewLoader but do not start the
* loading process.
*/
void addPreview(PreviewLoader & ploader) const;
/// The preview has been generated and is ready to use.
bool previewReady() const;
/// If !previewReady() returns 0.
PreviewImage const * pimage() const { return pimage_; }
protected:
/// Allow the daughter classes to cast up to the parent inset.
Inset * inset() const { return &inset_; }
private:
/** This method is connected to the grfx::PreviewLoader::imageReady
* signal.
*/
void imageReady(PreviewImage const &) const;
/// Does the owning inset want a preview?
virtual bool previewWanted() const = 0;
///
virtual BufferView * view() const = 0;
/// a wrapper to Inset::latex
virtual string const latexString() const = 0;
///
Inset & inset_;
/// We don't own this
mutable PreviewImage const * pimage_;
///
mutable boost::signals::connection connection_;
};
} // namespace grfx
#endif // PREVIEWEDINSET_H

View File

@ -94,9 +94,7 @@ void Previews::generateBufferPreviews(Buffer const & buffer) const
Buffer::inset_iterator end = buffer.inset_const_iterator_end();
for (; it != end; ++it) {
if ((*it)->lyxCode() == Inset::MATH_CODE) {
(*it)->generatePreview(ploader);
}
(*it)->addPreview(ploader);
}
ploader.startLoading();

View File

@ -1,3 +1,12 @@
2002-08-01 Angus Leeming <leeming@lyx.org>
* inset.h (generatePreview): renamed as addPreview.
(generatePreview): new method. Allows code to be moved out of
math_nestinset.C and into the new PreviewedInset class.
* insetinclude.[Ch] (ascent, descent, width, draw, addPreview):
add previews to the inset when \input-ing LaTeX.
2002-07-29 Lars Gullik Bjønnes <larsbj@gullik.net>
* several files: strip,frontStrip -> trim,ltrim,rtrim

View File

@ -332,14 +332,20 @@ public:
virtual int latexTextWidth(BufferView *) const;
/** Adds a LaTeX snippet to the Preview Loader for transformation
* into a bitmap image. Also connects to PreviewLoader::imageReady
* so that the inset is informed when the image has been generated
* in order to initiate its loading into LyX.
* into a bitmap image. Does not start the laoding process.
*
* Most insets have no interest in this capability, so the method
* defaults to empty.
*/
virtual void generatePreview(grfx::PreviewLoader &) const {}
virtual void addPreview(grfx::PreviewLoader &) const {}
/** Find the PreviewLoader, add a LaTeX snippet to it and
* start the loading process.
*
* Most insets have no interest in this capability, so the method
* defaults to empty.
*/
virtual void generatePreview() const {}
protected:
///

View File

@ -15,11 +15,15 @@
#include "gettext.h"
#include "frontends/Dialogs.h"
#include "frontends/Painter.h"
#include "support/filetools.h"
#include "support/FileInfo.h"
#include "support/lstrings.h"
#include "graphics/PreviewedInset.h"
#include "graphics/PreviewImage.h"
#include <cstdlib>
@ -29,6 +33,26 @@ using std::vector;
using std::pair;
extern BufferList bufferlist;
extern BufferView * current_view;
class InsetInclude::PreviewImpl : public grfx::PreviewedInset {
public:
///
PreviewImpl(InsetInclude & p) : PreviewedInset(p) {}
///
bool previewWanted() const;
///
string const latexString() const;
///
BufferView * view() const { return current_view; }
///
InsetInclude & parent() const {
return *static_cast<InsetInclude*>(inset());
}
};
namespace {
@ -47,12 +71,14 @@ string const uniqueID()
InsetInclude::InsetInclude(Params const & p)
: params_(p), include_label(uniqueID())
: params_(p), include_label(uniqueID()),
preview_(new PreviewImpl(*this))
{}
InsetInclude::InsetInclude(InsetCommandParams const & p, Buffer const & b)
: include_label(uniqueID())
: include_label(uniqueID()),
preview_(new PreviewImpl(*this))
{
params_.cparams = p;
params_.masterFilename_ = b.fileName();
@ -110,6 +136,9 @@ void InsetInclude::set(Params const & p)
}
params_.cparams.setCmdName(command);
if (grfx::PreviewedInset::activated() && params_.flag == INPUT)
preview_->generatePreview();
}
@ -445,3 +474,88 @@ vector<pair<string,string> > const InsetInclude::getKeys() const
return keys;
}
int InsetInclude::ascent(BufferView * bv, LyXFont const & font) const
{
return preview_->previewReady() ?
preview_->pimage()->ascent() : InsetButton::ascent(bv, font);
}
int InsetInclude::descent(BufferView * bv, LyXFont const & font) const
{
return preview_->previewReady() ?
preview_->pimage()->descent() : InsetButton::descent(bv, font);
}
int InsetInclude::width(BufferView * bv, LyXFont const & font) const
{
return preview_->previewReady() ?
preview_->pimage()->width() : InsetButton::width(bv, font);
}
void InsetInclude::draw(BufferView * bv, LyXFont const & font, int y,
float & xx, bool b) const
{
if (!preview_->previewReady()) {
InsetButton::draw(bv, font, y, xx, b);
return;
}
int const x = int(xx);
int const w = width(bv, font);
int const d = descent(bv, font);
int const a = ascent(bv, font);
int const h = a + d;
bv->painter().image(x, y - a, w, h,
*(preview_->pimage()->image(*this, *bv)));
xx += w;
}
//
// preview stuff
//
void InsetInclude::addPreview(grfx::PreviewLoader & ploader) const
{
lyxerr << "InsetInclude::addPreview" << endl;
preview_->addPreview(ploader);
}
bool InsetInclude::PreviewImpl::previewWanted() const
{
return parent().params_.flag == InsetInclude::INPUT;
}
string const InsetInclude::PreviewImpl::latexString() const
{
if (!view() || !view()->buffer())
return string();
ostringstream os;
parent().latex(view()->buffer(), os, false, false);
// This fails if the file has a relative path.
// return os.str().c_str();
// I would /really/ like not to do this...
// HELP!
string command;
string file = rtrim(split(os.str().c_str(), command, '{'), "}");
if (!AbsolutePath(file))
file = MakeAbsPath(file, view()->buffer()->filePath());
ostringstream out;
out << command << '{' << file << '}' << endl;
return out.str().c_str();
}

View File

@ -18,6 +18,7 @@
#include "insetcommand.h"
#include <boost/signals/signal0.hpp>
#include <boost/scoped_ptr.hpp>
class Buffer;
struct LaTeXFeatures;
@ -65,6 +66,15 @@ public:
///
~InsetInclude();
/// Override these InsetButton methods if Previewing
int ascent(BufferView *, LyXFont const &) const;
///
int descent(BufferView *, LyXFont const &) const;
///
int width(BufferView *, LyXFont const &) const;
///
void draw(BufferView *, LyXFont const &, int, float &, bool) const;
/// get the parameters
Params const & params(void) const;
/// set the parameters
@ -117,6 +127,9 @@ public:
/// return true if the file is or got loaded.
bool loadIfNeeded() const;
///
void addPreview(grfx::PreviewLoader &) const;
/// hide a dialog if about
boost::signal0<void> hideDialog;
private:
@ -133,6 +146,12 @@ private:
Params params_;
/// holds the entity name that defines the file location (SGML)
string const include_label;
/// Use the Pimpl idiom to hide the internals of the previewer.
class PreviewImpl;
friend class PreviewImpl;
/// The pointer never changes although *preview_'s contents may.
boost::scoped_ptr<PreviewImpl> const preview_;
};

View File

@ -1,3 +1,13 @@
2002-08-01 Angus Leeming <leeming@lyx.org>
* formula.C: move code into the new PreviewedInset class.
* formula.[Ch] (generatePreview): renamed as addPreview.
(generatePreview): new method invoking PreviewedInset::generatePreview.
* math_nestinset.C (notifyCursorLeaves): simplify. Now just calls
Inset::generatePreview.
2002-07-29 Lars Gullik Bjønnes <larsbj@gullik.net>
* formula.C (localDispatch): strip,frontStrip -> trim,ltrim,rtrim

View File

@ -47,16 +47,11 @@
#include "frontends/LyXView.h"
#include "frontends/Painter.h"
#include "graphics/GraphicsImage.h"
#include "graphics/PreviewLoader.h"
#include "graphics/PreviewedInset.h"
#include "graphics/PreviewImage.h"
#include "graphics/Previews.h"
#include <fstream>
#include <boost/bind.hpp>
#include <boost/signals/trackable.hpp>
#include <boost/signals/connection.hpp>
#include <boost/utility.hpp>
using std::ostream;
using std::ifstream;
@ -67,30 +62,26 @@ using std::vector;
using std::getline;
struct InsetFormula::PreviewImpl : public boost::signals::trackable {
class InsetFormula::PreviewImpl : public grfx::PreviewedInset {
public:
///
PreviewImpl(InsetFormula & p) : parent_(p), pimage_(0) {}
PreviewImpl(InsetFormula & p) : PreviewedInset(p) {}
private:
///
bool previewWanted() const;
///
void generatePreview(grfx::PreviewLoader & previewer);
/** This method is connected to the grfx::PreviewLoader::imageReady
* signal.
*/
void previewReady(grfx::PreviewImage const &);
/// A helper method.
string const latexString() const;
///
bool usePreview() const;
BufferView * view() const
{
return parent().view();
}
///
InsetFormula & parent_;
///
mutable grfx::PreviewImage const * pimage_;
///
boost::signals::connection connection_;
InsetFormula & parent() const
{
return *static_cast<InsetFormula*>(inset());
}
};
@ -216,7 +207,7 @@ void InsetFormula::draw(BufferView * bv, LyXFont const & font,
{
// This initiates the loading of the preview, so should come
// before the metrics are computed.
bool const use_preview = preview_->usePreview();
bool const use_preview = preview_->previewReady();
int const x = int(xx);
int const w = width(bv, font);
@ -228,7 +219,7 @@ void InsetFormula::draw(BufferView * bv, LyXFont const & font,
if (use_preview) {
pi.pain.image(x, y - a, w, h,
*(preview_->pimage_->image(*this, *bv)));
*(preview_->pimage()->image(*this, *bv)));
} else {
//pi.base.style = display() ? LM_ST_DISPLAY : LM_ST_TEXT;
pi.base.style = LM_ST_TEXT;
@ -441,17 +432,17 @@ bool InsetFormula::insetAllowed(Inset::Code code) const
int InsetFormula::ascent(BufferView *, LyXFont const &) const
{
return preview_->usePreview() ?
preview_->pimage_->ascent() : 1 + par_->ascent();
return preview_->previewReady() ?
preview_->pimage()->ascent() : 1 + par_->ascent();
}
int InsetFormula::descent(BufferView *, LyXFont const &) const
{
if (!preview_->usePreview())
if (!preview_->previewReady())
return 1 + par_->descent();
int const descent = preview_->pimage_->descent();
int const descent = preview_->pimage()->descent();
return display() ? descent + 12 : descent;
}
@ -459,8 +450,8 @@ int InsetFormula::descent(BufferView *, LyXFont const &) const
int InsetFormula::width(BufferView * bv, LyXFont const & font) const
{
metrics(bv, font);
return preview_->usePreview() ?
preview_->pimage_->width() : par_->width();
return preview_->previewReady() ?
preview_->pimage()->width() : par_->width();
}
@ -480,58 +471,21 @@ void InsetFormula::mutate(string const & type)
// preview stuff
//
void InsetFormula::generatePreview(grfx::PreviewLoader & ploader) const
void InsetFormula::addPreview(grfx::PreviewLoader & ploader) const
{
// Do nothing if no preview is desired.
if (!grfx::Previews::activated())
return;
preview_->generatePreview(ploader);
preview_->addPreview(ploader);
}
void InsetFormula::PreviewImpl::generatePreview(grfx::PreviewLoader & ploader)
void InsetFormula::generatePreview() const
{
// Generate the LaTeX snippet.
string const snippet = latexString();
pimage_ = ploader.preview(snippet);
if (pimage_)
return;
// If this is the first time of calling, connect to the
// grfx::PreviewLoader signal that'll inform us when the preview image
// is ready for loading.
if (!connection_.connected()) {
connection_ = ploader.connect(
boost::bind(&PreviewImpl::previewReady, this, _1));
}
ploader.add(snippet);
preview_->generatePreview();
}
bool InsetFormula::PreviewImpl::usePreview() const
bool InsetFormula::PreviewImpl::previewWanted() const
{
BufferView * view = parent_.view();
if (!grfx::Previews::activated() ||
parent_.par_->asNestInset()->editing() ||
!view || !view->buffer())
return false;
// If the cached grfx::PreviewImage is invalid, update it.
string const snippet = latexString();
if (!pimage_ || snippet != pimage_->snippet()) {
grfx::PreviewLoader & ploader =
grfx::Previews::get().loader(view->buffer());
pimage_ = ploader.preview(snippet);
}
if (!pimage_)
return false;
return pimage_->image(parent_, *view);
return !parent().par_->asNestInset()->editing();
}
@ -539,19 +493,6 @@ string const InsetFormula::PreviewImpl::latexString() const
{
ostringstream ls;
WriteStream wi(ls, false, false);
parent_.par_->write(wi);
parent().par_->write(wi);
return ls.str().c_str();
}
void InsetFormula::PreviewImpl::previewReady(grfx::PreviewImage const & pimage)
{
// Check snippet against the Inset's current contents
if (latexString() != pimage.snippet())
return;
pimage_ = &pimage;
BufferView * view = parent_.view();
if (view)
view->updateInset(&parent_, false);
}

View File

@ -82,7 +82,9 @@ public:
///
MathAtom & par() { return par_; }
///
void generatePreview(grfx::PreviewLoader &) const;
void generatePreview() const;
///
void addPreview(grfx::PreviewLoader &) const;
///
void mutate(string const & type);

View File

@ -6,11 +6,8 @@
#include "math_cursor.h"
#include "math_mathmlstream.h"
#include "formulabase.h"
#include "BufferView.h"
#include "debug.h"
#include "frontends/Painter.h"
#include "graphics/PreviewLoader.h"
#include "graphics/Previews.h"
using std::vector;
@ -323,22 +320,10 @@ void MathNestInset::normalize(NormalStream & os) const
void MathNestInset::notifyCursorLeaves()
{
// Generate a preview only if previews are active and we are leaving
// the InsetFormula itself
if (!grfx::Previews::activated() ||
!mathcursor || mathcursor->depth() != 1)
// Generate a preview only if we are leaving the InsetFormula itself
if (!mathcursor || mathcursor->depth() != 1)
return;
InsetFormulaBase * inset = mathcursor->formula();
BufferView * bufferview = inset->view();
// Paranoia check
if (!bufferview || !bufferview->buffer())
return;
grfx::Previews & previews = grfx::Previews::get();
grfx::PreviewLoader & loader = previews.loader(bufferview->buffer());
inset->generatePreview(loader);
loader.startLoading();
inset->generatePreview();
}