lyx_mirror/src/insets/Inset.h

516 lines
19 KiB
C
Raw Normal View History

// -*- C++ -*-
/**
* \file Inset.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Alejandro Aguilar Sierra
* \author J<EFBFBD>rgen Vigna
* \author Lars Gullik Bj<EFBFBD>nnes
* \author Matthias Ettrich
*
* Full author contact details are available in file CREDITS.
*/
#ifndef INSETBASE_H
#define INSETBASE_H
#include "ColorCode.h"
#include "InsetCode.h"
#include "support/strfwd.h"
#include <boost/shared_ptr.hpp>
#include <vector>
namespace lyx {
class BiblioInfo;
class Buffer;
class BufferParams;
class BufferView;
class Change;
class Cursor;
class CursorSlice;
class Dimension;
class DocIterator;
class FuncRequest;
class FuncStatus;
class InsetCollapsable;
class InsetIterator;
class InsetLayout;
class InsetList;
class InsetMath;
class InsetText;
class LaTeXFeatures;
class Lexer;
class MathAtom;
class MetricsInfo;
class OutputParams;
class PainterInfo;
class ParConstIterator;
class ParIterator;
class Text;
class TocList;
class EmbeddedFile;
class EmbeddedFileList;
namespace graphics { class PreviewLoader; }
/// Common base class to all insets
// Do not add _any_ (non-static) data members as this would inflate
// everything storing large quantities of insets. Mathed e.g. would
// suffer.
class Inset {
public:
///
enum EntryDirection {
ENTRY_DIRECTION_IGNORE,
ENTRY_DIRECTION_RIGHT,
ENTRY_DIRECTION_LEFT,
};
///
typedef ptrdiff_t difference_type;
/// short of anything else reasonable
typedef size_t size_type;
/// type for cell indices
typedef size_t idx_type;
/// type for cursor positions
typedef ptrdiff_t pos_type;
/// type for row numbers
typedef size_t row_type;
/// type for column numbers
typedef size_t col_type;
/// virtual base class destructor
virtual ~Inset() {}
/// change associated Buffer
virtual void setBuffer(Buffer * buffer) { buffer_ = buffer; }
virtual void setBufferRecursively(Buffer *) {}
/// retrieve associated Buffer
virtual Buffer * buffer() { return buffer_; }
virtual Buffer const * buffer() const { return buffer_; }
/// identification as math inset
virtual InsetMath * asInsetMath() { return 0; }
/// true for 'math' math inset, but not for e.g. mbox
virtual bool inMathed() const { return false; }
/// is this inset based on the InsetText class?
virtual InsetText * asInsetText() { return 0; }
/// is this inset based on the InsetText class?
virtual InsetText const * asInsetText() const { return 0; }
/// is this inset based on the InsetCollapsable class?
virtual InsetCollapsable * asInsetCollapsable() { return 0; }
/// is this inset based on the InsetCollapsable class?
virtual InsetCollapsable const * asInsetCollapsable() const { return 0; }
/// the real dispatcher
void dispatch(Cursor & cur, FuncRequest & cmd);
/**
* \returns true if this function made a definitive decision on
* whether the inset wants to handle the request \p cmd or not.
* The result of this decision is put into \p status.
*
* Every request that is enabled in this method needs to be handled
* in doDispatch(). Normally we have a 1:1 relationship between the
* requests handled in getStatus() and doDispatch(), but there are
* some exceptions:
* - A request that is disabled in getStatus() does not need to
* appear in doDispatch(). It is guaranteed that doDispatch()
* is never called with this request.
* - A few requests are en- or disabled in Inset::getStatus().
* These need to be handled in the doDispatch() methods of the
* derived insets, since Inset::doDispatch() has not enough
* information to handle them.
* - LFUN_MOUSE_* need not to be handled in getStatus(), because these
* are dispatched directly
*/
virtual bool getStatus(Cursor & cur, FuncRequest const & cmd,
FuncStatus & status) const;
/// cursor enters
virtual void edit(Cursor & cur, bool front,
EntryDirection entry_from = ENTRY_DIRECTION_IGNORE);
/// cursor enters
virtual Inset * editXY(Cursor & cur, int x, int y);
/// compute the size of the object returned in dim
/// \retval true if metrics changed.
virtual void metrics(MetricsInfo & mi, Dimension & dim) const = 0;
/// draw inset and update (xo, yo)-cache
virtual void draw(PainterInfo & pi, int x, int y) const = 0;
/// draw inset selection if necessary
virtual void drawSelection(PainterInfo &, int, int) const {}
///
virtual bool editing(BufferView const * bv) const;
///
virtual bool showInsetDialog(BufferView *) const { return false; }
/// draw inset decoration if necessary.
/// This can use \c drawMarkers() for example.
virtual void drawDecoration(PainterInfo &, int, int) const {}
/// draw four angular markers
void drawMarkers(PainterInfo & pi, int x, int y) const;
/// draw two angular markers
void drawMarkers2(PainterInfo & pi, int x, int y) const;
/// add space for markers
void metricsMarkers(Dimension & dim, int framesize = 1) const;
/// add space for markers
void metricsMarkers2(Dimension & dim, int framesize = 1) const;
/// last drawn position for 'important' insets
int xo(BufferView const & bv) const;
/// last drawn position for 'important' insets
int yo(BufferView const & bv) const;
/// set x/y drawing position cache if available
virtual void setPosCache(PainterInfo const &, int, int) const;
///
void setDimCache(MetricsInfo const &, Dimension const &) const;
/// do we cover screen position x/y?
virtual bool covers(BufferView const & bv, int x, int y) const;
/// get the screen positions of the cursor (see note in Cursor.cpp)
virtual void cursorPos(BufferView const & bv,
CursorSlice const & sl, bool boundary, int & x, int & y) const;
///
virtual bool isFreeSpacing() const { return false; }
///
virtual bool allowEmpty() const { return false; }
/// Force inset into LTR environment if surroundings are RTL?
virtual bool forceLTR() const { return false; }
/// is this an inset that can be moved into?
/// FIXME: merge with editable()
virtual bool isActive() const { return nargs() > 0; }
/// Where should we go when we press the up or down cursor key?
virtual bool idxUpDown(Cursor & cur, bool up) const;
/// Move one cell backwards
virtual bool idxBackward(Cursor &) const { return false; }
/// Move one cell forward
virtual bool idxForward(Cursor &) const { return false; }
/// Move to the next cell
virtual bool idxNext(Cursor &) const { return false; }
/// Move to the previous cell
virtual bool idxPrev(Cursor &) const { return false; }
/// Target pos when we enter the inset while moving forward
virtual bool idxFirst(Cursor &) const { return false; }
/// Target pos when we enter the inset while moving backwards
virtual bool idxLast(Cursor &) const { return false; }
/// Delete a cell and move cursor
virtual bool idxDelete(idx_type &) { return false; }
/// pulls cell after pressing erase
virtual void idxGlue(idx_type) {}
/// returns list of cell indices that are "between" from and to for
/// selection purposes
virtual bool idxBetween(idx_type idx, idx_type from, idx_type to) const;
/// to which column belongs a cell with a given index?
virtual col_type col(idx_type) const { return 0; }
/// to which row belongs a cell with a given index?
virtual row_type row(idx_type) const { return 0; }
/// cell idex corresponding to row and column;
virtual idx_type index(row_type row, col_type col) const;
/// any additional x-offset when drawing a cell?
virtual int cellXOffset(idx_type) const { return 0; }
/// any additional y-offset when drawing a cell?
virtual int cellYOffset(idx_type) const { return 0; }
/// number of embedded cells
virtual size_t nargs() const { return 0; }
/// number of rows in gridlike structures
virtual size_t nrows() const { return 0; }
/// number of columns in gridlike structures
virtual size_t ncols() const { return 0; }
/// Is called when the cursor leaves this inset.
/// Returns true if cursor is now invalid, e.g. if former
/// insets in higher cursor slices of \c old do not exist
/// anymore.
/// \c old is the old cursor, i.e. there is a slice pointing to this.
/// \c cur is the new cursor. Use the update flags to cause a redraw.
virtual bool notifyCursorLeaves(Cursor const & /*old*/, Cursor & /*cur*/)
{ return false; }
/// is called when the mouse enter or leave this inset
/// return true if this inset needs repaint
virtual bool setMouseHover(bool) { return false; }
/// return true if this inset is hovered (under mouse)
/// This is by now only used by mathed to draw corners
/// (Inset::drawMarkers() and Inset::drawMarkers2()).
/// Other insets do not have to redefine this function to
/// return the correct status of mouseHovered.
virtual bool mouseHovered() const { return false; }
/// request "external features"
virtual void validate(LaTeXFeatures &) const {}
/// Appends \c list with all labels found within this inset.
virtual void getLabelList(Buffer const &,
std::vector<docstring> & /* list */) const {}
/// describe content if cursor inside
virtual void infoize(odocstream &) const {}
/// describe content if cursor behind
virtual void infoize2(odocstream &) const {}
enum {
PLAINTEXT_NEWLINE = 10000
};
/// plain text output in ucs4 encoding
/// return the number of characters; in case of multiple lines of
/// output, add PLAINTEXT_NEWLINE to the number of chars in the last line
virtual int plaintext(Buffer const &, odocstream &,
OutputParams const &) const = 0;
/// docbook output
virtual int docbook(Buffer const &, odocstream & os,
OutputParams const &) const;
/// the string that is passed to the TOC
virtual void textString(Buffer const &, odocstream &) const {}
/** This enum indicates by which means the inset can be modified:
- NOT_EDITABLE: the inset's content cannot be modified at all
(e.g. printindex, insetspecialchar)
- IS_EDITABLE: content can be edited via dialog (e.g. bibtex, index, href)
- HIGHLY_EDITABLE: content can be edited on screen (normally means that
insettext is contained, e.g. collapsables, tabular) */
// FIXME: This has not yet been fully implemented to math insets
enum EDITABLE {
///
NOT_EDITABLE = 0,
///
IS_EDITABLE,
///
HIGHLY_EDITABLE
};
/// what appears in the minibuffer when opening
virtual docstring const editMessage() const;
///
virtual EDITABLE editable() const;
/// can we go further down on mouse click?
virtual bool descendable() const { return false; }
/// does this contain text that can be change track marked in DVI?
virtual bool canTrackChanges() const { return false; }
/// return true if the inset should be removed automatically
virtual bool autoDelete() const;
class CompletionList {
public:
///
virtual ~CompletionList() {}
///
virtual bool sorted() const =0;
///
virtual size_t size() const =0;
/// returns the string shown in the gui.
virtual docstring const & data(size_t idx) const = 0;
/// returns the resource string used to load an icon.
virtual std::string icon(size_t /*idx*/) const { return std::string(); }
};
/// Returns true if the inset supports completions.
virtual bool completionSupported(Cursor const &) const { return false; }
/// Returns true if the inset supports inline completions at the
/// cursor position. In this case the completion might be stored
/// in the BufferView's inlineCompletion property.
virtual bool inlineCompletionSupported(Cursor const & /*cur*/) const
{ return false; }
/// Return true if the inline completion should be automatic.
virtual bool automaticInlineCompletion() const { return true; }
/// Return true if the popup completion should be automatic.
virtual bool automaticPopupCompletion() const { return true; }
/// Returns completion suggestions at cursor position. Return an
/// null pointer if no completion is a available or possible.
/// The caller is responsible to free the returned object!
virtual CompletionList const * createCompletionList(Cursor const &) const
{ return 0; }
/// Returns the completion prefix to filter the suggestions for completion.
/// This is only called if completionList returned a non-null list.
virtual docstring completionPrefix(Cursor const &) const
{ return docstring(); }
/// Do a completion at the cursor position. Return true on success.
/// The completion does not contain the prefix. If finished is true, the
/// completion is final. If finished is false, completion might only be
/// a partial completion.
virtual bool insertCompletion(Cursor & /*cur*/,
docstring const & /*completion*/, bool /*finished*/)
{ return false; }
/// Get the completion inset position and size
virtual void completionPosAndDim(Cursor const &, int & /*x*/, int & /*y*/,
Dimension & /*dim*/) const {}
/// returns true if the inset can hold an inset of given type
virtual bool insetAllowed(InsetCode) const { return false; }
Fix bug 4037 and related problems. The patch has been cleaned up a bit from the one posted to the list. The basic idea has two parts. First, we hard code an "empty layout" (called PlainLayout, for want of a better name) in TextClass and read it before doing anything else. It can therefore be customized by classes, if they want---say, to make it left-aligned. Second, InsetText's are divided into three types: (i) normal ones, that use the "default" layout defined by the text class; (ii) highly restrictive ones, such as ERT and (not quite an inset) table cells, which demand the empty layout; (iii) middling ones, which default to an empty layout and use the empty layout in place of the default. (This is so we don't get the same problem we had with ERT in e.g. footnotes.) The type of inset is signaled by new methods InsetText::forceEmptyLayout() and InsetText::useEmptyLayout(). (The latter might better be called: useEmptyLayoutInsteadOfDefault(), but that's silly.) The old InsetText::forceDefaultParagraphs() has been split into these, plus a new method InsetText::allowParagraphCustomization(). A lot of the changes just adapt to this change. The other big change is in GuiToolbar: We want to show LyXDefault and the "default" layout only when they're active. There are a handful of places where I'm not entirely sure whether we should be using forceEmptyLayout or !allowParagraphCustomization() or both. The InsetCaption is one of these. These places, and some others, are marked with FIXMEs, so I'd appreciate it if people would search through the patch and let me know whether these need changing. If they don't, the FIXMEs can be deleted. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@22966 a592a061-630c-0410-9148-cb99ea01b6c8
2008-02-12 17:31:07 +00:00
/// should this inset use the empty layout by default rather than
/// the standard layout? (default: only if that is forced.)
virtual bool useEmptyLayout() const { return forceEmptyLayout(); }
/// if this inset has paragraphs should they be forced to use the
/// empty layout?
virtual bool forceEmptyLayout() const { return false; }
/// if this inset has paragraphs should the user be allowed to
/// customize alignment, etc?
virtual bool allowParagraphCustomization(idx_type) const { return true; }
/// Is the width forced to some value?
virtual bool hasFixedWidth() const { return false; }
/// \return Tool tip for this inset.
/// This default implementation returns an empty string.
virtual docstring toolTip(BufferView const & bv, int x, int y) const;
/// \return Context menu identifier for this inset.
/// This default implementation returns an empty string.
virtual docstring contextMenu(BufferView const & bv, int x, int y) const;
// FIXME This should really disappear in favor of
// docstring name() const { return from_ascii(insetName(lyxCode()))); }
// There's no reason to be using different names in different places.
// But to do this we would need to change the file format, since the names
// used there don't correspond to what is used here.
///
virtual docstring name() const;
///
virtual InsetLayout const & getLayout(BufferParams const & bp) const;
/// used to toggle insets
/// is the inset open?
/// should this inset be handled like a normal charater
virtual bool isChar() const { return false; }
/// is this equivalent to a letter?
virtual bool isLetter() const { return false; }
/// is this equivalent to a space (which is BTW different from
/// a line separator)?
virtual bool isSpace() const { return false; }
enum DisplayType {
Inline = 0,
AlignLeft,
AlignCenter,
AlignRight
};
/// should we have a non-filled line before this inset?
virtual DisplayType display() const { return Inline; }
/// should we break lines after this inset?
virtual bool isLineSeparator() const { return false; }
/// should paragraph indendation be ommitted in any case?
virtual bool neverIndent(Buffer const &) const { return false; }
/// dumps content to lyxerr
virtual void dump() const;
/// write inset in .lyx format
virtual void write(Buffer const &, std::ostream &) const {}
/// read inset in .lyx format
virtual void read(Buffer const &, Lexer &) {}
Make the output of \inputencoding commands (and the change of output encodings) more fine grained: From paragraph level to individual character level. The inputenc package supports that since at least 2000. * src/insets/insetbase.h (latex): Document the differences between output to a string stream and a file stream * src/buffer.h (writeLaTeXSource): ditto * src/output_latex.h (latexParagraphs): ditto (switchEncoding): new function to change the encoding of a stream (and output \inputencoding commands) * src/paragraph_pimpl.C (Paragraph::Pimpl::simpleTeXSpecialC): Adjust to latexWriteEndChanges changes * src/support/docstream.[Ch] (setEncoding, operator<<): New stream modifier that changes the encoding of file streams * src/lyxfont.[Ch] (LyXFont::latexWriteStartChanges): Change stream encoding if needed (LyXFont::latexWriteEndChanges): Change stream encoding if needed * src/lyxfont.h (public:): * src/paragraph.C (Paragraph::simpleTeXOnePar): Adjust to latexWriteStartChanges and latexWriteEndChanges changes (bool Paragraph::simpleTeXOnePar): (bool Paragraph::simpleTeXOnePar): (bool Paragraph::simpleTeXOnePar): (bool Paragraph::simpleTeXOnePar): (bool Paragraph::simpleTeXOnePar): * src/output_latex.C (TeXOnePar): Remove the ugly hack to for wencoding changes and use switchEncoding instead. A nice side effect is that the old hack would not work if the main language encoding is latin1 and a character would be mapped to a cedilla in the "fake ucs4" encoding, because iconv refuses to convert such a character to latin1, although it exists in latin1 (it wants to attach it to a base character). git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16633 a592a061-630c-0410-9148-cb99ea01b6c8
2007-01-09 19:25:40 +00:00
/** Export the inset to LaTeX.
* Don't use a temporary stringstream if the final output is
* supposed to go to a file.
* \sa Buffer::writeLaTeXSource for the reason.
* \return the number of rows (\n's) of generated LaTeX code.
*/
virtual int latex(Buffer const &, odocstream &,
OutputParams const &) const { return 0; }
/// returns true to override begin and end inset in file
virtual bool directWrite() const;
///
virtual bool allowSpellCheck() const { return false; }
/// if this insets owns text cells (e.g. InsetText) return cell num
virtual Text * getText(int /*num*/) const { return 0; }
/** Adds a LaTeX snippet to the Preview Loader for transformation
* 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 addPreview(graphics::PreviewLoader &) const {}
/// Add an entry to the TocList
/// pit is the ParConstIterator of the paragraph containing the inset
virtual void addToToc(Buffer const &, ParConstIterator const &) const {}
/// report files that can be embedded with the lyx file
virtual void registerEmbeddedFiles(Buffer const &, EmbeddedFileList &) const {}
/// use embedded or external file after the embedding status of a file is changed
virtual void updateEmbeddedFile(Buffer const &, EmbeddedFile const &) {}
/// Fill keys with BibTeX information
virtual void fillWithBibKeys(Buffer const &,
BiblioInfo &, InsetIterator const &) const {}
/// Update the counters of this inset and of its contents
Rewrite the label numbering code. * buffer_funcs.cpp (updateLabels): new function taking a buffer and a ParIterator as arguments. This one is used to update labels into an InsetText. Cleanup the code to reset depth. Call setLabel for each paragraph, and then updateLabel on each inset it contains. (setCaptionLabels, setCaptions): removed. (setLabel): use Counters::current_float to make caption paragraphs labels. * insets/Inset.h (updateLabels): new virtual method, empty by default; this numbers the inset itself (if relevant) and then all the paragraphs it may contain. * insets/InsetText.cpp (updateLabels): basically calls lyx::updateLabels from buffer_func.cpp. * insets/InsetCaption.cpp (addToToc): use the label constructed by updateLabels. (computeFullLabel): removed. (metrics, plaintext): don't use computeFullLabel. (updateLabels): new method; set the label from Counters::current_float. * insets/InsetWrap.cpp (updateLabels): * insets/InsetFloat.cpp (updateLabel): new method; sets Counters::current_float to the float type. * insets/InsetBranch.cpp (updateLabels): new method; the numbering is reset afterwards if the branch is inactive. (bug 2671) * insets/InsetNote.cpp (updateLabels): new method; the numbering is reset after the underlying InsetText has been numbered. (bug 2671) * insets/InsetTabular.cpp (updateLabels): new method (also handles longtable) * insets/InsetListings.cpp (updateLabels): new method; mimics what is done for Floats (although Listings are not floats technically) * insets/InsetInclude.cpp (getScreenLabel): in the listings case, use the computed label. (updateLabels): new method; that either renumbers the child document or number the current listing. * LyXFunc.cpp (menuNew): do not updateLabels on empty documents (why do we do that at all?) git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@19482 a592a061-630c-0410-9148-cb99ea01b6c8
2007-08-12 21:43:58 +00:00
virtual void updateLabels(Buffer const &, ParIterator const &) {}
/// Updates the inset's dialog
virtual Buffer const * updateFrontend() const;
public:
/// returns LyX code associated with the inset. Used for TOC, ...)
virtual InsetCode lyxCode() const { return NO_CODE; }
/// -1: text mode, 1: math mode, 0 undecided
enum mode_type {UNDECIDED_MODE, TEXT_MODE, MATH_MODE};
/// return text or mathmode if that is possible to determine
virtual mode_type currentMode() const { return UNDECIDED_MODE; }
/// returns whether this inset is allowed in other insets of given mode
virtual bool allowedIn(mode_type) const { return true; }
/**
* Is this inset allowed within a font change?
*
* FIXME: noFontChange means currently that the font change is closed
* in LaTeX before the inset, and that the contents of the inset
* will be in default font. This should be changed so that the inset
* changes the font again.
*/
virtual bool noFontChange() const { return false; }
/// set the change for the entire inset
virtual void setChange(Change const &) {}
/// accept the changes within the inset
virtual void acceptChanges(BufferParams const &) {};
/// reject the changes within the inset
virtual void rejectChanges(BufferParams const &) {};
///
virtual Dimension const dimension(BufferView const &) const;
///
int scroll() const { return 0; }
///
virtual ColorCode backgroundColor() const;
///
enum CollapseStatus {
Collapsed,
Open
};
///
virtual void setStatus(Cursor &, CollapseStatus) {}
//
enum { TEXT_TO_INSET_OFFSET = 4 };
protected:
/// Constructor
explicit Inset() : buffer_(0) {}
/// replicate ourselves
friend class InsetList;
friend class MathAtom;
virtual Inset * clone() const = 0;
/** The real dispatcher.
* Gets normally called from Cursor::dispatch(). Cursor::dispatch()
* assumes the common case of 'LFUN handled, need update'.
* This has to be overriden by calling Cursor::undispatched() or
* Cursor::noUpdate() if appropriate.
* If you need to call the dispatch method of some inset directly
* you may have to explicitly request an update at that place. Don't
* do it in doDispatch(), since that causes nested updates when
* called from Cursor::dispatch(), and these can lead to crashes.
* \sa getStatus
*/
virtual void doDispatch(Cursor & cur, FuncRequest & cmd);
Buffer * buffer_;
};
} // namespace lyx
#endif