X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Finsets%2FInset.cpp;h=1c0312f5a3107be6ef4e3bc1c1755a316ff3926e;hb=65192d6cf87f8cf70cbb4d879e97faecdb44a19e;hp=952aa0a2a286a80b43a86af891cecf2d263b79f8;hpb=97aa558caca65a79a6fd57504564b51819f8cd79;p=lyx.git diff --git a/src/insets/Inset.cpp b/src/insets/Inset.cpp index 952aa0a2a2..1c0312f5a3 100644 --- a/src/insets/Inset.cpp +++ b/src/insets/Inset.cpp @@ -4,10 +4,10 @@ * Licence details can be found in the file COPYING. * * \author Alejandro Aguilar Sierra - * \author Jürgen Vigna - * \author Lars Gullik Bjønnes + * \author Jürgen Vigna + * \author Lars Gullik Bjønnes * \author Matthias Ettrich - * \author André Pönitz + * \author André Pönitz * * Full author contact details are available in file CREDITS. */ @@ -16,108 +16,205 @@ #include "Inset.h" +#include "buffer_funcs.h" #include "Buffer.h" +#include "BufferList.h" #include "BufferParams.h" #include "BufferView.h" #include "CoordCache.h" #include "Cursor.h" -#include "debug.h" #include "Dimension.h" #include "DispatchResult.h" #include "FuncRequest.h" #include "FuncStatus.h" -#include "gettext.h" +#include "MetricsInfo.h" +#include "output_xhtml.h" #include "Text.h" #include "TextClass.h" -#include "MetricsInfo.h" -#include "MetricsInfo.h" -#include "frontends/Painter.h" #include "frontends/Application.h" +#include "frontends/Painter.h" -#include "support/convert.h" - -#include +#include "support/debug.h" +#include "support/docstream.h" +#include "support/ExceptionMessage.h" +#include "support/gettext.h" +#include "support/lassert.h" #include -#include +using namespace std; +using namespace lyx::support; namespace lyx { -extern bool quitting; - class InsetName { public: - InsetName(std::string const & n, InsetCode c) : name(n), code(c) {} - std::string name; - InsetCode code; + InsetName(string const & n = string(), docstring const & dn = docstring()) + : name(n), display_name(dn) {} + string name; + docstring display_name; }; -typedef std::map TranslatorMap; - - -static TranslatorMap const build_translator() -{ - InsetName const insetnames[] = { - InsetName("toc", TOC_CODE), - InsetName("quote", QUOTE_CODE), - InsetName("ref", REF_CODE), - InsetName("href", HYPERLINK_CODE), - InsetName("separator", SEPARATOR_CODE), - InsetName("ending", ENDING_CODE), - InsetName("label", LABEL_CODE), - InsetName("note", NOTE_CODE), - InsetName("accent", ACCENT_CODE), - InsetName("math", MATH_CODE), - InsetName("index", INDEX_CODE), - InsetName("nomenclature", NOMENCL_CODE), - InsetName("include", INCLUDE_CODE), - InsetName("graphics", GRAPHICS_CODE), - InsetName("bibitem", BIBITEM_CODE), - InsetName("bibtex", BIBTEX_CODE), - InsetName("text", TEXT_CODE), - InsetName("ert", ERT_CODE), - InsetName("foot", FOOT_CODE), - InsetName("margin", MARGIN_CODE), - InsetName("float", FLOAT_CODE), - InsetName("wrap", WRAP_CODE), - InsetName("specialchar", SPECIALCHAR_CODE), - InsetName("tabular", TABULAR_CODE), - InsetName("external", EXTERNAL_CODE), - InsetName("caption", CAPTION_CODE), - InsetName("mathmacro", MATHMACRO_CODE), - InsetName("citation", CITE_CODE), - InsetName("floatlist", FLOAT_LIST_CODE), - InsetName("index_print", INDEX_PRINT_CODE), - InsetName("nomencl_print", NOMENCL_PRINT_CODE), - InsetName("optarg", OPTARG_CODE), - InsetName("environment", ENVIRONMENT_CODE), - InsetName("hfill", HFILL_CODE), - InsetName("newline", NEWLINE_CODE), - InsetName("line", LINE_CODE), - InsetName("branch", BRANCH_CODE), - InsetName("box", BOX_CODE), - InsetName("flex", FLEX_CODE), - InsetName("vspace", VSPACE_CODE), - InsetName("mathmacroarg", MATHMACROARG_CODE), - InsetName("listings", LISTINGS_CODE), - InsetName("info", INFO_CODE), - InsetName("collapsable", COLLAPSABLE_CODE), - InsetName("newpage", NEWPAGE_CODE), - }; - - std::size_t const insetnames_size = - sizeof(insetnames) / sizeof(insetnames[0]); - - std::map data; - for (std::size_t i = 0; i != insetnames_size; ++i) { - InsetName const & var = insetnames[i]; - data[var.name] = var.code; +static InsetName insetnames[INSET_CODE_SIZE]; + + +// This list should be kept in sync with the list of dialogs in +// src/frontends/qt4/GuiView.cpp, I.e., if a dialog goes with an +// inset, the dialog should have the same name as the inset. +// Changes should be also recorded in LFUN_DIALOG_SHOW doxygen +// docs in LyXAction.cpp. +static void build_translator() +{ + static bool passed = false; + if (passed) + return; + insetnames[TOC_CODE] = InsetName("toc"); + insetnames[QUOTE_CODE] = InsetName("quote"); + insetnames[REF_CODE] = InsetName("ref"); + insetnames[HYPERLINK_CODE] = InsetName("href"); + insetnames[SEPARATOR_CODE] = InsetName("separator"); + insetnames[ENDING_CODE] = InsetName("ending"); + insetnames[LABEL_CODE] = InsetName("label"); + insetnames[NOTE_CODE] = InsetName("note"); + insetnames[PHANTOM_CODE] = InsetName("phantom"); + insetnames[ACCENT_CODE] = InsetName("accent"); + insetnames[MATH_CODE] = InsetName("math"); + insetnames[INDEX_CODE] = InsetName("index"); + insetnames[NOMENCL_CODE] = InsetName("nomenclature"); + insetnames[INCLUDE_CODE] = InsetName("include"); + insetnames[GRAPHICS_CODE] = InsetName("graphics"); + insetnames[BIBITEM_CODE] = InsetName("bibitem", _("Bibliography Entry")); + insetnames[BIBTEX_CODE] = InsetName("bibtex"); + insetnames[TEXT_CODE] = InsetName("text"); + insetnames[ERT_CODE] = InsetName("ert", _("TeX Code")); + insetnames[FOOT_CODE] = InsetName("foot"); + insetnames[MARGIN_CODE] = InsetName("margin"); + insetnames[FLOAT_CODE] = InsetName("float", _("Float")); + insetnames[WRAP_CODE] = InsetName("wrap"); + insetnames[SPECIALCHAR_CODE] = InsetName("specialchar"); + insetnames[TABULAR_CODE] = InsetName("tabular", _("Table")); + insetnames[EXTERNAL_CODE] = InsetName("external"); + insetnames[CAPTION_CODE] = InsetName("caption"); + insetnames[MATHMACRO_CODE] = InsetName("mathmacro"); + insetnames[CITE_CODE] = InsetName("citation"); + insetnames[FLOAT_LIST_CODE] = InsetName("floatlist"); + insetnames[INDEX_PRINT_CODE] = InsetName("index_print"); + insetnames[NOMENCL_PRINT_CODE] = InsetName("nomencl_print"); + insetnames[ARG_CODE] = InsetName("optarg"); + insetnames[NEWLINE_CODE] = InsetName("newline"); + insetnames[LINE_CODE] = InsetName("line"); + insetnames[BRANCH_CODE] = InsetName("branch", _("Branch")); + insetnames[BOX_CODE] = InsetName("box", _("Box")); + insetnames[FLEX_CODE] = InsetName("flex"); + insetnames[SPACE_CODE] = InsetName("space", _("Horizontal Space")); + insetnames[VSPACE_CODE] = InsetName("vspace", _("Vertical Space")); + insetnames[MATH_MACROARG_CODE] = InsetName("mathmacroarg"); + insetnames[LISTINGS_CODE] = InsetName("listings"); + insetnames[INFO_CODE] = InsetName("info", _("Info")); + insetnames[COLLAPSABLE_CODE] = InsetName("collapsable"); + insetnames[NEWPAGE_CODE] = InsetName("newpage"); + insetnames[SCRIPT_CODE] = InsetName("script"); + insetnames[CELL_CODE] = InsetName("tablecell"); + insetnames[MATH_AMSARRAY_CODE] = InsetName("mathamsarray"); + insetnames[MATH_ARRAY_CODE] = InsetName("matharray"); + insetnames[MATH_BIG_CODE] = InsetName("mathbig"); + insetnames[MATH_BOLDSYMBOL_CODE] = InsetName("mathboldsymbol"); + insetnames[MATH_BOX_CODE] = InsetName("mathbox"); + insetnames[MATH_BRACE_CODE] = InsetName("mathbrace"); + insetnames[MATH_CASES_CODE] = InsetName("mathcases"); + insetnames[MATH_CHAR_CODE] = InsetName("mathchar"); + insetnames[MATH_COLOR_CODE] = InsetName("mathcolor"); + insetnames[MATH_COMMENT_CODE] = InsetName("mathcomment"); + insetnames[MATH_DECORATION_CODE] = InsetName("mathdecoration"); + insetnames[MATH_DELIM_CODE] = InsetName("mathdelim"); + insetnames[MATH_DIFF_CODE] = InsetName("mathdiff"); + insetnames[MATH_DOTS_CODE] = InsetName("mathdots"); + insetnames[MATH_ENSUREMATH_CODE] = InsetName("mathensuremath"); + insetnames[MATH_ENV_CODE] = InsetName("mathenv"); + insetnames[MATH_EXFUNC_CODE] = InsetName("mathexfunc"); + insetnames[MATH_EXINT_CODE] = InsetName("mathexint"); + insetnames[MATH_FONT_CODE] = InsetName("mathfont"); + insetnames[MATH_FONTOLD_CODE] = InsetName("mathfontold"); + insetnames[MATH_FRAC_CODE] = InsetName("mathfrac"); + insetnames[MATH_GRID_CODE] = InsetName("mathgrid"); + insetnames[MATH_CODE] = InsetName("math"); + insetnames[MATH_HULL_CODE] = InsetName("mathhull"); + insetnames[MATH_KERN_CODE] = InsetName("mathkern"); + insetnames[MATH_LEFTEQN_CODE] = InsetName("mathlefteqn"); + insetnames[MATH_LIM_CODE] = InsetName("mathlim"); + insetnames[MATH_MATRIX_CODE] = InsetName("mathmatrix"); + insetnames[MATH_MBOX_CODE] = InsetName("mathmbox"); + insetnames[MATH_NEST_CODE] = InsetName("mathnest"); + insetnames[MATH_NUMBER_CODE] = InsetName("mathnumber"); + insetnames[MATH_OVERSET_CODE] = InsetName("mathoverset"); + insetnames[MATH_PAR_CODE] = InsetName("mathpar"); + insetnames[MATH_PHANTOM_CODE] = InsetName("mathphantom"); + insetnames[MATH_REF_CODE] = InsetName("mathref"); + insetnames[MATH_ROOT_CODE] = InsetName("mathroot"); + insetnames[MATH_SCRIPT_CODE] = InsetName("mathscript"); + insetnames[MATH_SIZE_CODE] = InsetName("mathsize"); + insetnames[MATH_SPACE_CODE] = InsetName("mathspace", _("Horizontal Math Space")); + insetnames[MATH_SPECIALCHAR_CODE] = InsetName("mathspecialchar"); + insetnames[MATH_SPLIT_CODE] = InsetName("mathsplit"); + insetnames[MATH_SQRT_CODE] = InsetName("mathsqrt"); + insetnames[MATH_STACKREL_CODE] = InsetName("mathstackrel"); + insetnames[MATH_STRING_CODE] = InsetName("mathstring"); + insetnames[MATH_SUBSTACK_CODE] = InsetName("mathsubstack"); + insetnames[MATH_SYMBOL_CODE] = InsetName("mathsymbol"); + insetnames[MATH_TABULAR_CODE] = InsetName("mathtabular"); + insetnames[MATH_UNDERSET_CODE] = InsetName("mathunderset"); + insetnames[MATH_UNKNOWN_CODE] = InsetName("mathunknown"); + insetnames[MATH_XARROW_CODE] = InsetName("mathxarrow"); + insetnames[MATH_XYARROW_CODE] = InsetName("mathxyarrow"); + insetnames[MATH_XYMATRIX_CODE] = InsetName("mathxymatrix"); + insetnames[MATH_DIAGRAM_CODE] = InsetName("mathdiagram"); + insetnames[MATH_MACRO_CODE] = InsetName("mathmacro"); + + passed = true; +} + + +void Inset::setBuffer(Buffer & buffer) +{ + buffer_ = &buffer; +} + + +Buffer & Inset::buffer() +{ + if (!buffer_) { + odocstringstream s; + lyxerr << "Inset: " << this + << " LyX Code: " << lyxCode() + << " name: " << insetName(lyxCode()) + << std::endl; + s << "LyX Code: " << lyxCode() << " name: " << name(); + LASSERT(false, /**/); + throw ExceptionMessage(BufferException, + from_ascii("Inset::buffer_ member not initialized!"), s.str()); } + return *buffer_; +} + + +Buffer const & Inset::buffer() const +{ + return const_cast(this)->buffer(); +} + - return data; +bool Inset::isBufferLoaded() const +{ + return buffer_ && theBufferList().isLoaded(buffer_); +} + + +bool Inset::isBufferValid() const +{ + return buffer_ + && (isBufferLoaded() || buffer_->isClone()); } @@ -127,47 +224,142 @@ docstring Inset::name() const } -Dimension const Inset::dimension(BufferView const & bv) const +bool Inset::isFreeSpacing() const { - return bv.coordCache().getInsets().dim(this); + return getLayout().isFreeSpacing(); +} + + +bool Inset::allowEmpty() const +{ + return getLayout().isKeepEmpty(); +} + + +bool Inset::forceLTR() const +{ + return getLayout().forceLTR(); +} + + +bool Inset::isInToc() const +{ + return getLayout().isInToc(); +} + + +docstring Inset::toolTip(BufferView const &, int, int) const +{ + return docstring(); } -InsetCode insetCode(std::string const & name) +docstring Inset::contextMenu(BufferView const &, int, int) const { - static TranslatorMap const translator = build_translator(); + return contextMenuName(); +} + - TranslatorMap::const_iterator it = translator.find(name); - return it == translator.end() ? NO_CODE : it->second; +docstring Inset::contextMenuName() const +{ + return docstring(); } -std::string insetName(InsetCode c) +Dimension const Inset::dimension(BufferView const & bv) const { - static TranslatorMap const translator = build_translator(); + return bv.coordCache().getInsets().dim(this); +} - TranslatorMap::const_iterator it = translator.begin(); - TranslatorMap::const_iterator end = translator.end(); - for (; it != end; ++it) { - if (it->second == c) - return it->first; + +InsetCode insetCode(string const & name) +{ + build_translator(); + for (int i = 1; i != int(INSET_CODE_SIZE); ++i) { + if (insetnames[i].name == name) + return InsetCode(i); } - return std::string(); + return NO_CODE; +} + + +string insetName(InsetCode c) +{ + build_translator(); + return insetnames[c].name; +} + + +docstring insetDisplayName(InsetCode c) +{ + build_translator(); + return insetnames[c].display_name; } void Inset::dispatch(Cursor & cur, FuncRequest & cmd) { - cur.updateFlags(Update::Force | Update::FitCursor); + if (buffer_ == 0) { + lyxerr << "Unassigned buffer_ member in Inset::dispatch()" << std::endl; + lyxerr << "LyX Code: " << lyxCode() << " name: " + << insetName(lyxCode()) << std::endl; + } else if (cur.buffer() != buffer_) + lyxerr << "cur.buffer() != buffer_ in Inset::dispatch()" << std::endl; + cur.screenUpdateFlags(Update::Force | Update::FitCursor); cur.dispatched(); doDispatch(cur, cmd); } -void Inset::doDispatch(Cursor & cur, FuncRequest &) +bool Inset::showInsetDialog(BufferView * bv) const +{ + InsetCode const code = lyxCode(); + switch (code){ + case ERT_CODE: + case FLOAT_CODE: + case BOX_CODE: + case BIBITEM_CODE: + case BRANCH_CODE: + case INFO_CODE: + case MATH_SPACE_CODE: + case SPACE_CODE: + case TABULAR_CODE: + case VSPACE_CODE: + bv->showDialog(insetName(code)); + break; + default: + return false; + } + return true; +} + + +void Inset::doDispatch(Cursor & cur, FuncRequest &cmd) { - cur.noUpdate(); - cur.undispatched(); + switch (cmd.action()) { + case LFUN_MOUSE_RELEASE: + // if the derived inset did not explicitly handle mouse_release, + // we assume we request the settings dialog + if (!cur.selection() && cmd.button() == mouse_button::button1 + && hasSettings()) { + FuncRequest tmpcmd(LFUN_INSET_SETTINGS); + dispatch(cur, tmpcmd); + } + break; + + case LFUN_INSET_SETTINGS: + if (cmd.argument().empty() || cmd.getArg(0) == insetName(lyxCode())) { + showInsetDialog(&cur.bv()); + cur.dispatched(); + } else + cur.undispatched(); + break; + + default: + cur.noScreenUpdate(); + cur.undispatched(); + break; + } } @@ -178,40 +370,60 @@ bool Inset::getStatus(Cursor &, FuncRequest const & cmd, // be applied. This is either changed to LFUN_INSET_MODIFY (if the // dialog belongs to us) or LFUN_INSET_INSERT (if the dialog does // not belong to us, i. e. the dialog was open, and the user moved - // the cursor in our inset) in LyXFunc::getStatus(). + // the cursor in our inset) in lyx::getStatus(). // Dialogs::checkStatus() ensures that the dialog is deactivated if // LFUN_INSET_APPLY is disabled. - switch (cmd.action) { + switch (cmd.action()) { case LFUN_INSET_MODIFY: // Allow modification of our data. // This needs to be handled in the doDispatch method of our // instantiatable children. - flag.enabled(true); + // FIXME: Why don't we let the insets determine whether this + // should be enabled or not ? Now we need this check for + // the tabular features. (vfr) + if (cmd.getArg(0) == "tabular") + return false; + flag.setEnabled(true); return true; case LFUN_INSET_INSERT: // Don't allow insertion of new insets. // Every inset that wants to allow new insets from open // dialogs needs to override this. - flag.enabled(false); + flag.setEnabled(false); + return true; + + case LFUN_INSET_SETTINGS: + if (cmd.argument().empty() || cmd.getArg(0) == insetName(lyxCode())) { + bool const enable = hasSettings(); + flag.setEnabled(enable); + return true; + } else { + return false; + } + + case LFUN_IN_MATHMACROTEMPLATE: + // By default we're not in a MathMacroTemplate inset + flag.setEnabled(false); return true; default: - return false; + break; } + return false; } -void Inset::edit(Cursor &, bool) +void Inset::edit(Cursor &, bool, EntryDirection) { - LYXERR(Debug::INSETS, BOOST_CURRENT_FUNCTION << ": edit left/right"); + LYXERR(Debug::INSETS, "edit left/right"); } Inset * Inset::editXY(Cursor &, int x, int y) { - LYXERR(Debug::INSETS, BOOST_CURRENT_FUNCTION << ": x=" << x << " y= " << y); + LYXERR(Debug::INSETS, "x: " << x << " y: " << y); return this; } @@ -219,11 +431,9 @@ Inset * Inset::editXY(Cursor &, int x, int y) Inset::idx_type Inset::index(row_type row, col_type col) const { if (row != 0) - lyxerr << BOOST_CURRENT_FUNCTION - << ": illegal row: " << row << std::endl; + LYXERR0("illegal row: " << row); if (col != 0) - lyxerr << BOOST_CURRENT_FUNCTION - << ": illegal col: " << col << std::endl; + LYXERR0("illegal col: " << col); return 0; } @@ -240,41 +450,48 @@ bool Inset::idxUpDown(Cursor &, bool) const } -int Inset::docbook(Buffer const &, - odocstream &, OutputParams const &) const +int Inset::docbook(odocstream &, OutputParams const &) const { return 0; } +docstring Inset::xhtml(XHTMLStream & xs, OutputParams const &) const +{ + xs << "[[Inset: " << from_ascii(insetName(lyxCode())) << "]]"; + return docstring(); +} + + bool Inset::directWrite() const { return false; } -Inset::EDITABLE Inset::editable() const +bool Inset::editable() const { - return NOT_EDITABLE; + return false; } -bool Inset::autoDelete() const +bool Inset::hasSettings() const { return false; } -docstring const Inset::editMessage() const + +bool Inset::autoDelete() const { - return _("Opened inset"); + return false; } void Inset::cursorPos(BufferView const & /*bv*/, CursorSlice const &, bool, int & x, int & y) const { - lyxerr << "Inset::cursorPos called directly" << std::endl; + LYXERR0("Inset::cursorPos called directly"); x = 100; y = 100; } @@ -297,7 +514,7 @@ void Inset::metricsMarkers2(Dimension & dim, int framesize) const void Inset::drawMarkers(PainterInfo & pi, int x, int y) const { - ColorCode pen_color = mouseHovered() || editing(pi.base.bv)? + ColorCode pen_color = mouseHovered(pi.base.bv) || editing(pi.base.bv)? Color_mathframe : Color_mathcorners; Dimension const dim = dimension(*pi.base.bv); @@ -314,7 +531,7 @@ void Inset::drawMarkers(PainterInfo & pi, int x, int y) const void Inset::drawMarkers2(PainterInfo & pi, int x, int y) const { - ColorCode pen_color = mouseHovered() || editing(pi.base.bv)? + ColorCode pen_color = mouseHovered(pi.base.bv) || editing(pi.base.bv)? Color_mathframe : Color_mathcorners; drawMarkers(pi, x, y); @@ -329,7 +546,7 @@ void Inset::drawMarkers2(PainterInfo & pi, int x, int y) const } -bool Inset::editing(BufferView * bv) const +bool Inset::editing(BufferView const * bv) const { return bv->cursor().isInside(this); } @@ -353,28 +570,42 @@ bool Inset::covers(BufferView const & bv, int x, int y) const } -InsetLayout const & Inset::getLayout(BufferParams const & bp) const +InsetLayout const & Inset::getLayout() const +{ + if (!buffer_) + return DocumentClass::plainInsetLayout(); + return buffer().params().documentClass().insetLayout(name()); +} + + +bool Inset::undefined() const { - return bp.getTextClass().insetlayout(name()); + docstring const & n = getLayout().name(); + return n.empty() || n == DocumentClass::plainInsetLayout().name(); } void Inset::dump() const { - Buffer buf("foo", 1); - write(buf, lyxerr); + write(lyxerr); } -ColorCode Inset::backgroundColor() const +ColorCode Inset::backgroundColor(PainterInfo const & /*pi*/) const { - return Color_background; + return Color_none; +} + + +ColorCode Inset::labelColor() const +{ + return Color_foreground; } void Inset::setPosCache(PainterInfo const & pi, int x, int y) const { - //lyxerr << "Inset:: position cache to " << x << " " << y << std::endl; + //LYXERR("Inset: set position cache to " << x << " " << y); pi.base.bv->coordCache().insets().add(this, x, y); } @@ -387,9 +618,13 @@ void Inset::setDimCache(MetricsInfo const & mi, Dimension const & dim) const Buffer const * Inset::updateFrontend() const { - if (quitting) - return 0; - return theApp()->updateInset(this); + return theApp() ? theApp()->updateInset(this) : 0; +} + + +docstring Inset::completionPrefix(Cursor const &) const +{ + return docstring(); } } // namespace lyx