From c246076ed57e0ee80320477349d25330e9d24e64 Mon Sep 17 00:00:00 2001 From: Juergen Spitzmueller Date: Sun, 30 Dec 2012 18:29:02 +0100 Subject: [PATCH] Fix the 'caption inset mess' (bug #4647) --- development/FORMAT | 6 ++ lib/layouts/aastex.layout | 28 ++++--- lib/layouts/aguplus.inc | 27 +++---- lib/layouts/apa.layout | 29 +++---- lib/layouts/apa6.layout | 29 +++---- lib/layouts/bicaption.module | 25 +++--- lib/layouts/scrclass.inc | 57 ++++++------- lib/layouts/stdinsets.inc | 3 +- lib/lyx2lyx/lyx_2_1.py | 152 ++++++++++++++++++++++++++++++++++- lib/scripts/layout2layout.py | 11 ++- lib/ui/stdcontext.inc | 10 +++ lib/ui/stdmenus.inc | 2 +- po/lyx_pot.py | 6 ++ src/Text3.cpp | 16 +++- src/TextClass.cpp | 2 +- src/factory.cpp | 12 ++- src/frontends/qt4/Menus.cpp | 87 +++++++++++++++++++- src/insets/Inset.h | 2 + src/insets/InsetCaption.cpp | 92 +++++++++++++++++---- src/insets/InsetCaption.h | 8 +- src/insets/InsetFloat.h | 2 + src/insets/InsetListings.cpp | 9 ++- src/insets/InsetTabular.cpp | 6 ++ src/tex2lyx/TODO.txt | 1 + src/version.h | 4 +- 25 files changed, 486 insertions(+), 140 deletions(-) diff --git a/development/FORMAT b/development/FORMAT index 0a8bdbfa37..e3d16a4037 100644 --- a/development/FORMAT +++ b/development/FORMAT @@ -11,6 +11,12 @@ adjustments are made to tex2lyx and bugs are fixed in lyx2lyx. ----------------------- + +2012-12-30 Jürgen Spitzmüller + * Format incremented to 458: Extended caption inset support. + Former special caption layouts (e.g. of KOMA) are now proper caption + insets. + 2012-12-28 Georg Baum * Format incremented to 457 support for the LaTeX-package stackrel (fix bug 8464) diff --git a/lib/layouts/aastex.layout b/lib/layouts/aastex.layout index 0bf43d5849..6c2f42ea8a 100644 --- a/lib/layouts/aastex.layout +++ b/lib/layouts/aastex.layout @@ -614,23 +614,25 @@ InsetLayout "Flex:tablenotemark" End -Style FigCaption - Margin First_Dynamic - LatexType Command - LatexName figcaption - LabelSep xx - ParSkip 0.4 - TopSep 0.5 - Align Block - AlignPossible Block, Left - LabelType Static - LabelString "Fig. ---" +InsetLayout Caption:FigCaption + LabelString fig. + LaTeXType command + LatexName figcaption Argument 1 - LabelString "Short Title|S" - Tooltip "The caption as it appears in the list of figures" + LabelString "Short Title|S" + Tooltip "The caption as it appears in the list of figures" EndArgument + HTMLStyle + div.float-caption { + text-align: center; + border: 2px solid black; + padding: 1ex; + margin: 1ex; + } + EndHTMLStyle End + # Facility style definition Style Facility LeftMargin MMM diff --git a/lib/layouts/aguplus.inc b/lib/layouts/aguplus.inc index 123ae8470b..aa3fba75bd 100644 --- a/lib/layouts/aguplus.inc +++ b/lib/layouts/aguplus.inc @@ -203,21 +203,18 @@ Float End - -Style Table_Caption - Margin First_Dynamic - LatexType Command - LatexName tablecaption - NeedProtect 1 - LabelSep xx - ParSkip 0.4 - TopSep 0.5 - Align Center - LabelType Sensitive - LabelString "TableCaption" - LabelFont - Series Bold - EndFont +InsetLayout Caption:Table + LabelString table + LaTeXType command + LatexName tablecaption + HTMLStyle + div.float-caption { + text-align: center; + border: 2px solid black; + padding: 1ex; + margin: 1ex; + } + EndHTMLStyle End diff --git a/lib/layouts/apa.layout b/lib/layouts/apa.layout index b4eb952e28..e162814657 100644 --- a/lib/layouts/apa.layout +++ b/lib/layouts/apa.layout @@ -233,26 +233,23 @@ End Input stdlayouts.inc -Style CenteredCaption - Margin First_Dynamic - LatexType Command - LatexName caption - NeedProtect 1 - LabelSep xx - ParSkip 0.4 - TopSep 0.5 - Align Center - LabelType Sensitive - LabelString "Senseless!" + +InsetLayout Caption:Centered + LabelString standard + LaTeXType command + LatexName centeredcaption Argument 1 LabelString "Short Title|S" Tooltip "The caption as it appears in the list of figures/tables" EndArgument - LabelFont - Series Bold - EndFont - LatexName centeredcaption - Align Center + HTMLStyle + div.float-caption { + text-align: center; + border: 2px solid black; + padding: 1ex; + margin: 1ex; + } + EndHTMLStyle End diff --git a/lib/layouts/apa6.layout b/lib/layouts/apa6.layout index a37555c925..6f729e2340 100644 --- a/lib/layouts/apa6.layout +++ b/lib/layouts/apa6.layout @@ -345,26 +345,23 @@ End Input stdlayouts.inc -Style CenteredCaption - Margin First_Dynamic - LatexType Command - LatexName caption - NeedProtect 1 - LabelSep xx - ParSkip 0.4 - TopSep 0.5 - Align Center - LabelType Sensitive - LabelString "Senseless!" + +InsetLayout Caption:Centered + LabelString standard + LaTeXType command + LatexName centeredcaption Argument 1 LabelString "Short Title|S" Tooltip "The caption as it appears in the list of figures/tables" EndArgument - LabelFont - Series Bold - EndFont - LatexName centeredcaption - Align Center + HTMLStyle + div.float-caption { + text-align: center; + border: 2px solid black; + padding: 1ex; + margin: 1ex; + } + EndHTMLStyle End diff --git a/lib/layouts/bicaption.module b/lib/layouts/bicaption.module index ab730ce971..e60a284bb9 100644 --- a/lib/layouts/bicaption.module +++ b/lib/layouts/bicaption.module @@ -34,10 +34,11 @@ Style "Caption setup" EndBabelPreamble End -Style Bicaption - CopyStyle "Caption setup" - LatexName bicaption - Category MainText + +InsetLayout Caption:Bicaption + LabelString bilingual + LaTeXType command + LatexName bicaption Argument 1 LabelString "Second Language Caption Short Title" Tooltip "A short title (for list of figures/tables) in the second language" @@ -51,12 +52,12 @@ Style Bicaption LabelString "Main Language Caption Short Title" Tooltip "A short title (for list of figures/tables) in the main language" EndArgument - TopSep 0 - Align Center - AlignPossible Center - LabelString "Multilingual caption:" - LabelFont - Color Black - EndFont + HTMLStyle + div.float-caption { + text-align: center; + border: 2px solid black; + padding: 1ex; + margin: 1ex; + } + EndHTMLStyle End - diff --git a/lib/layouts/scrclass.inc b/lib/layouts/scrclass.inc index de575164a2..0063748834 100644 --- a/lib/layouts/scrclass.inc +++ b/lib/layouts/scrclass.inc @@ -260,49 +260,42 @@ End Input stdlayouts.inc -Style Captionabove - Category Captions - Margin First_Dynamic - LatexType Command - LatexName caption - NeedProtect 1 - LabelSep xx - ParSkip 0.4 - TopSep 0.5 - Align Center - LabelType Sensitive - LabelString "Senseless!" + +InsetLayout Caption:Above + LabelString above + LaTeXType command + LatexName captionabove Argument 1 LabelString "Short Title|S" Tooltip "The caption as it appears in the list of figures/tables" EndArgument - LabelFont - Series Bold - EndFont - LatexName captionabove + HTMLStyle + div.float-caption { + text-align: center; + border: 2px solid black; + padding: 1ex; + margin: 1ex; + } + EndHTMLStyle End -Style Captionbelow - Category Captions - Margin First_Dynamic - LatexType Command - LatexName caption - NeedProtect 1 - LabelSep xx - ParSkip 0.4 - TopSep 0.5 - Align Center - LabelType Sensitive - LabelString "Senseless!" +InsetLayout Caption:Below + LabelString below + LaTeXType command + LatexName captionbelow Argument 1 LabelString "Short Title|S" Tooltip "The caption as it appears in the list of figures/tables" EndArgument - LabelFont - Series Bold - EndFont - LatexName captionbelow + HTMLStyle + div.float-caption { + text-align: center; + border: 2px solid black; + padding: 1ex; + margin: 1ex; + } + EndHTMLStyle End diff --git a/lib/layouts/stdinsets.inc b/lib/layouts/stdinsets.inc index 4020e1ae09..0d82b4c06c 100644 --- a/lib/layouts/stdinsets.inc +++ b/lib/layouts/stdinsets.inc @@ -469,7 +469,8 @@ InsetLayout Info:shortcuts EndHTMLStyle End -InsetLayout Caption +InsetLayout Caption:Standard + LabelString standard LaTeXType command LatexName caption Argument 1 diff --git a/lib/lyx2lyx/lyx_2_1.py b/lib/lyx2lyx/lyx_2_1.py index 6bc97101ba..9e063457bc 100644 --- a/lib/lyx2lyx/lyx_2_1.py +++ b/lib/lyx2lyx/lyx_2_1.py @@ -3017,6 +3017,154 @@ def revert_epigraph(document): i = endlay +def convert_captioninsets(document): + " Converts caption insets to new syntax " + + i = 0 + while True: + i = find_token(document.body, "\\begin_inset Caption", i) + if i == -1: + return + document.body[i] = "\\begin_inset Caption Standard" + i = i + 1 + + + +def revert_captioninsets(document): + " Reverts caption insets to old syntax " + + i = 0 + while True: + i = find_token(document.body, "\\begin_inset Caption Standard", i) + if i == -1: + return + document.body[i] = "\\begin_inset Caption" + i = i + 1 + + +def convert_captionlayouts(document): + " Convert caption layouts to caption insets. " + + caption_dict = { + "Captionabove": "Above", + "Captionbelow": "Below", + "FigCaption" : "FigCaption", + "Table_Caption" : "Table", + "CenteredCaption" : "Centered", + "Bicaption" : "Bicaption", + } + + i = 0 + while True: + i = find_token(document.body, "\\begin_layout", i) + if i == -1: + return + val = get_value(document.body, "\\begin_layout", i) + if val in caption_dict.keys(): + j = find_end_of_layout(document.body, i) + if j == -1: + document.warning("Malformed LyX document: Missing `\\end_layout'.") + return + + document.body[j:j] = ["\\end_layout", "", "\\end_inset", "", ""] + document.body[i:i+1] = ["\\begin_layout %s" % document.default_layout, + "\\begin_inset Caption %s" % caption_dict[val], "", + "\\begin_layout %s" % document.default_layout] + i = i + 1 + + +def revert_captionlayouts(document): + " Revert caption insets to caption layouts. " + + caption_dict = { + "Above" : "Captionabove", + "Below" : "Captionbelow", + "FigCaption" : "FigCaption", + "Table" : "Table_Caption", + "Centered" : "CenteredCaption", + "Bicaption" : "Bicaption", + } + + i = 0 + rx = re.compile(r'^\\begin_inset Caption (\S+)$') + while True: + i = find_token(document.body, "\\begin_inset Caption", i) + if i == -1: + return + + m = rx.match(document.body[i]) + val = "" + if m: + val = m.group(1) + if val not in caption_dict.keys(): + i = i + 1 + continue + + # We either need to delete the previous \begin_layout line, or we + # need to end the previous layout if this inset is not in the first + # position of the paragraph. + layout_before = find_token_backwards(document.body, "\\begin_layout", i) + if layout_before == -1: + document.warning("Malformed LyX document: Missing `\\begin_layout'.") + return + layout_line = document.body[layout_before] + del_layout_before = True + l = layout_before + 1 + while l < i: + if document.body[l] != "": + del_layout_before = False + break + l = l + 1 + if del_layout_before: + del document.body[layout_before:i] + i = layout_before + else: + document.body[i:i] = ["\\end_layout", ""] + i = i + 2 + + # Find start of layout in the inset and end of inset + j = find_token(document.body, "\\begin_layout", i) + if j == -1: + document.warning("Malformed LyX document: Missing `\\begin_layout'.") + return + k = find_end_of_inset(document.body, i) + if k == -1: + document.warning("Malformed LyX document: Missing `\\end_inset'.") + return + + # We either need to delete the following \end_layout line, or we need + # to restart the old layout if this inset is not at the paragraph end. + layout_after = find_token(document.body, "\\end_layout", k) + if layout_after == -1: + document.warning("Malformed LyX document: Missing `\\end_layout'.") + return + del_layout_after = True + l = k + 1 + while l < layout_after: + if document.body[l] != "": + del_layout_after = False + break + l = l + 1 + if del_layout_after: + del document.body[k+1:layout_after+1] + else: + document.body[k+1:k+1] = [layout_line, ""] + + # delete \begin_layout and \end_inset and replace \begin_inset with + # "\begin_layout XXX". This works because we can only have one + # paragraph in the caption inset: The old \end_layout will be recycled. + del document.body[k] + if document.body[k] == "": + del document.body[k] + del document.body[j] + if document.body[j] == "": + del document.body[j] + document.body[i] = "\\begin_layout %s" % caption_dict[val] + if document.body[i+1] == "": + del document.body[i+1] + i = i + 1 + + ## # Conversion hub # @@ -3066,10 +3214,12 @@ convert = [ [454, [convert_overprint]], [455, []], [456, [convert_epigraph]], - [457, [convert_use_stackrel]] + [457, [convert_use_stackrel]], + [458, [convert_captioninsets, convert_captionlayouts]] ] revert = [ + [457, [revert_captioninsets, revert_captionlayouts]], [456, [revert_use_stackrel]], [455, [revert_epigraph]], [454, [revert_frametitle]], diff --git a/lib/scripts/layout2layout.py b/lib/scripts/layout2layout.py index 113f99bf04..fac9a71d6f 100644 --- a/lib/scripts/layout2layout.py +++ b/lib/scripts/layout2layout.py @@ -144,6 +144,9 @@ import os, re, string, sys # Incremented to format 42, 22 December 2012 by spitz # New Style tag "ItemCommand" +# Incremented to format 43, 30 December 2012 by spitz +# Extended InsetCaption format + # Do not forget to document format change in Customization # Manual (section "Declaring a new text class"). @@ -151,7 +154,7 @@ import os, re, string, sys # development/tools/updatelayouts.sh script to update all # layout files to the new format. -currentFormat = 42 +currentFormat = 43 def usage(prog_name): @@ -361,6 +364,12 @@ def convert(lines): i += 1 continue + if format == 42: + if lines[i] == "InsetLayout Caption": + lines[i] = "InsetLayout Caption:Standard" + i += 1 + continue + if format == 41: # nothing to do. i += 1 diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc index 4c9203294a..3bb9266790 100644 --- a/lib/ui/stdcontext.inc +++ b/lib/ui/stdcontext.inc @@ -162,6 +162,7 @@ Menuset SwitchArguments End + # # InsetBox context menu # @@ -177,6 +178,15 @@ Menuset Item "Double Frame|u" "inset-modify changetype Doublebox" End + +# +# InsetCaption context menu +# + Menu "context-caption" + SwitchCaptions + End + + # # InsetNote context menu # diff --git a/lib/ui/stdmenus.inc b/lib/ui/stdmenus.inc index 85a2555b8c..1ffd65e754 100644 --- a/lib/ui/stdmenus.inc +++ b/lib/ui/stdmenus.inc @@ -360,7 +360,7 @@ Menuset Item "Citation...|C" "dialog-show-new-inset citation" Item "Cross-Reference...|R" "dialog-show-new-inset ref" Item "Label...|L" "label-insert" - Item "Caption" "caption-insert" + Captions Indices Item "Nomenclature Entry...|y" "nomencl-insert" Separator diff --git a/po/lyx_pot.py b/po/lyx_pot.py index 94142d14dd..8f694a8fae 100755 --- a/po/lyx_pot.py +++ b/po/lyx_pot.py @@ -91,6 +91,7 @@ def layouts_l10n(input_files, output, base, layouttranslations): NameRE = re.compile(r'^\s*#\s*\\DeclareLyXModule.*{(.*)}$', re.IGNORECASE) InsetLayout = re.compile(r'^InsetLayout\s+\"?(.*)\"?\s*$', re.IGNORECASE) FlexCheck = re.compile(r'^Flex:(.*)', re.IGNORECASE) + CaptionCheck = re.compile(r'^Caption:(.*)', re.IGNORECASE) DescBegin = re.compile(r'^\s*#DescriptionBegin\s*$', re.IGNORECASE) DescEnd = re.compile(r'^\s*#\s*DescriptionEnd\s*$', re.IGNORECASE) Category = re.compile(r'^\s*#\s*Category:\s+(.*\S)\s*$', re.IGNORECASE) @@ -291,6 +292,11 @@ def layouts_l10n(input_files, output, base, layouttranslations): if not layouttranslations: writeString(out, src, base, lineno, m.group(1)) continue + m = CaptionCheck.search(string) + if m: + if not layouttranslations: + writeString(out, src, base, lineno, m.group(1)) + continue res = Category.search(line) if res != None: string = res.group(1) diff --git a/src/Text3.cpp b/src/Text3.cpp index b009e58b31..bfb392c63e 100644 --- a/src/Text3.cpp +++ b/src/Text3.cpp @@ -2528,11 +2528,21 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd, } break; } - case LFUN_CAPTION_INSERT: + case LFUN_CAPTION_INSERT: { code = CAPTION_CODE; - // not allowed in description items - enable = !inDescriptionItem(cur); + bool varia = true; + if (cur.depth() > 0) { + if (&cur[cur.depth() - 1].inset() + && !cur[cur.depth() - 1].inset().allowsCaptionVariation()) + varia = false; + } + string arg = cmd.getArg(0); + // not allowed in description items, + // and in specific insets + enable = !inDescriptionItem(cur) + && (varia || arg.empty() || arg == "Standard"); break; + } case LFUN_NOTE_INSERT: code = NOTE_CODE; // in commands (sections etc.) and description items, diff --git a/src/TextClass.cpp b/src/TextClass.cpp index 40ff9c9ace..e5d84c82e1 100644 --- a/src/TextClass.cpp +++ b/src/TextClass.cpp @@ -60,7 +60,7 @@ namespace lyx { // development/tools/updatelayouts.sh script, to update the format of // all of our layout files. // -int const LAYOUT_FORMAT = 42; // spitz: new Style tag ItemCommand +int const LAYOUT_FORMAT = 43; // spitz: extended InsetCaption format namespace { diff --git a/src/factory.cpp b/src/factory.cpp index b640c6b2ae..2ffa85018c 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -224,8 +224,12 @@ Inset * createInsetHelper(Buffer * buf, FuncRequest const & cmd) return new InsetTabular(buf, r, c); } - case LFUN_CAPTION_INSERT: - return new InsetCaption(buf); + case LFUN_CAPTION_INSERT: { + string arg = cmd.getArg(0); + if (arg.empty()) + arg = "Standard"; + return new InsetCaption(buf, arg); + } case LFUN_INDEX_PRINT: { InsetCommandParams icp(INDEX_PRINT_CODE); @@ -632,7 +636,9 @@ Inset * readInset(Lexer & lex, Buffer * buf) string tmptok = lex.getString(); inset.reset(new InsetWrap(buf, tmptok)); } else if (tmptok == "Caption") { - inset.reset(new InsetCaption(buf)); + lex.eatLine(); + string s = lex.getString(); + inset.reset(new InsetCaption(buf, s)); } else if (tmptok == "Index") { inset.reset(new InsetIndex(buf, InsetIndexParams())); } else if (tmptok == "FloatList") { diff --git a/src/frontends/qt4/Menus.cpp b/src/frontends/qt4/Menus.cpp index a6fdfe5330..1646bc4125 100644 --- a/src/frontends/qt4/Menus.cpp +++ b/src/frontends/qt4/Menus.cpp @@ -178,8 +178,14 @@ public: for insertion into the current layout. */ Arguments, /** This is the list of arguments available - for in the InsetArgument context menu. */ - SwitchArguments + in the InsetArgument context menu. */ + SwitchArguments, + /** This is the list of captions available + in the current layout. */ + Captions, + /** This is the list of captions available + in the InsetCaption context menu. */ + SwitchCaptions }; explicit MenuItem(Kind kind) : kind_(kind), optional_(false) {} @@ -356,6 +362,7 @@ public: void expandSpellingSuggestions(BufferView const *); void expandLanguageSelector(Buffer const * buf); void expandArguments(BufferView const *, bool switcharg = false); + void expandCaptions(Buffer const * buf, bool switchcap = false); /// ItemList items_; /// @@ -465,13 +472,16 @@ void MenuDefinition::read(Lexer & lex) md_spellingsuggestions, md_languageselector, md_arguments, - md_switcharguments + md_switcharguments, + md_captions, + md_switchcaptions }; LexerKeyword menutags[] = { { "arguments", md_arguments }, { "bookmarks", md_bookmarks }, { "branches", md_branches }, + { "captions", md_captions }, { "charstyles", md_charstyles }, { "citestyles", md_citestyles }, { "custom", md_custom }, @@ -497,6 +507,7 @@ void MenuDefinition::read(Lexer & lex) { "spellingsuggestions", md_spellingsuggestions }, { "submenu", md_submenu }, { "switcharguments", md_switcharguments }, + { "switchcaptions", md_switchcaptions }, { "toc", md_toc }, { "toolbars", md_toolbars }, { "updateformats", md_updateformats }, @@ -636,6 +647,14 @@ void MenuDefinition::read(Lexer & lex) add(MenuItem(MenuItem::SwitchArguments)); break; + case md_captions: + add(MenuItem(MenuItem::Captions)); + break; + + case md_switchcaptions: + add(MenuItem(MenuItem::SwitchCaptions)); + break; + case md_optsubmenu: optional = true; // fallback to md_submenu @@ -1577,6 +1596,58 @@ void MenuDefinition::expandArguments(BufferView const * bv, bool switcharg) } } + +void MenuDefinition::expandCaptions(Buffer const * buf, bool switchcap) +{ + if (!buf) + return; + + vector caps; + DocumentClass const & dc = buf->params().documentClass(); + TextClass::InsetLayouts::const_iterator lit = dc.insetLayouts().begin(); + TextClass::InsetLayouts::const_iterator len = dc.insetLayouts().end(); + for (; lit != len; ++lit) { + if (prefixIs(lit->first, from_ascii("Caption:"))) + caps.push_back(lit->first); + } + + if (caps.empty() || (switchcap && caps.size() == 1)) + return; + if (caps.size() == 1) { + docstring dummy; + docstring type = split(*caps.begin(), dummy, ':'); + add(MenuItem(MenuItem::Command, qt_("Caption"), + FuncRequest(LFUN_CAPTION_INSERT, translateIfPossible(type)))); + return; + } + + MenuDefinition captions; + + vector::const_iterator cit = caps.begin(); + vector::const_iterator end = caps.end(); + + for (int ii = 1; cit != end; ++cit, ++ii) { + docstring dummy; + docstring type = split(*cit, dummy, ':'); + docstring item = bformat(_("Caption (%1$s)"), translateIfPossible(type)); + if (switchcap) + addWithStatusCheck(MenuItem(MenuItem::Command, toqstr(item), + FuncRequest(LFUN_INSET_MODIFY, + from_ascii("changetype ") + + type), QString(), true)); + else + captions.addWithStatusCheck(MenuItem(MenuItem::Command, + toqstr(item), + FuncRequest(LFUN_CAPTION_INSERT, + type), QString(), true)); + } + if (!captions.empty()) { + MenuItem item(MenuItem::Submenu, qt_("Caption")); + item.setSubmenu(captions); + add(item); + } +} + } // namespace anon @@ -1721,7 +1792,7 @@ struct Menus::Impl { /** The entries with the following kind are expanded to a sequence of Command MenuItems: Lastfiles, Documents, ViewFormats, ExportFormats, UpdateFormats, Branches, - Indices, Arguments, SwitchArguments + Indices, Arguments, SwitchArguments, Captions, Switchcaptions */ void expand(MenuDefinition const & frommenu, MenuDefinition & tomenu, BufferView const *) const; @@ -1950,6 +2021,14 @@ void Menus::Impl::expand(MenuDefinition const & frommenu, tomenu.expandArguments(bv, true); break; + case MenuItem::Captions: + tomenu.expandCaptions(buf, false); + break; + + case MenuItem::SwitchCaptions: + tomenu.expandCaptions(buf, true); + break; + case MenuItem::Submenu: { MenuItem item(*cit); item.setSubmenu(MenuDefinition(cit->submenuname())); diff --git a/src/insets/Inset.h b/src/insets/Inset.h index b1070d8a33..b82234fbd6 100644 --- a/src/insets/Inset.h +++ b/src/insets/Inset.h @@ -347,6 +347,8 @@ public: virtual bool isActive() const { return nargs() > 0; } /// can we click at the specified position ? virtual bool clickable(int, int) const { return false; } + /// Move one cell backwards + virtual bool allowsCaptionVariation() const { return false; } /// does this contain text that can be change track marked in DVI? virtual bool canTrackChanges() const { return false; } diff --git a/src/insets/InsetCaption.cpp b/src/insets/InsetCaption.cpp index 67bb3600af..550f9fe6e1 100644 --- a/src/insets/InsetCaption.cpp +++ b/src/insets/InsetCaption.cpp @@ -49,8 +49,8 @@ using namespace lyx::support; namespace lyx { -InsetCaption::InsetCaption(Buffer * buf) - : InsetText(buf, InsetText::PlainLayout) +InsetCaption::InsetCaption(Buffer * buf, string const & type) + : InsetText(buf, InsetText::PlainLayout), type_(type) { setAutoBreakRows(true); setDrawFrame(true); @@ -60,7 +60,12 @@ InsetCaption::InsetCaption(Buffer * buf) void InsetCaption::write(ostream & os) const { - os << "Caption\n"; + os << "Caption"; + if (!type_.empty()) { + os << " " + << type_; + } + os << "\n"; text().write(os); } @@ -94,14 +99,14 @@ void InsetCaption::setCustomLabel(docstring const & label) void InsetCaption::addToToc(DocIterator const & cpit) const { - if (type_.empty()) + if (floattype_.empty()) return; DocIterator pit = cpit; pit.push_back(CursorSlice(const_cast(*this))); - Toc & toc = buffer().tocBackend().toc(type_); - docstring str = full_label_ + ". "; + Toc & toc = buffer().tocBackend().toc(floattype_); + docstring str = full_label_; text().forToc(str, TOC_ENTRY_LENGTH); toc.push_back(TocItem(pit, 0, str)); @@ -192,11 +197,53 @@ bool InsetCaption::insetAllowed(InsetCode code) const } +void InsetCaption::doDispatch(Cursor & cur, FuncRequest & cmd) +{ + switch (cmd.action()) { + + case LFUN_INSET_MODIFY: { + string const first_arg = cmd.getArg(0); + bool const change_type = first_arg == "changetype"; + if (change_type) { + cur.recordUndoInset(ATOMIC_UNDO, this); + type_ = cmd.getArg(1); + cur.forceBufferUpdate(); + break; + } + } + + default: + InsetText::doDispatch(cur, cmd); + break; + } +} + + bool InsetCaption::getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus & status) const { switch (cmd.action()) { + case LFUN_INSET_MODIFY: { + string const first_arg = cmd.getArg(0); + if (first_arg == "changetype") { + string const type = cmd.getArg(1); + status.setOnOff(type == type_); + bool varia = true; + // check if the immediate parent inset allows caption variation + if (cur.depth() > 1) { + if (&cur[cur.depth() - 2].inset() + && !cur[cur.depth() - 2].inset().allowsCaptionVariation()) + varia = false; + } + status.setEnabled(varia + && buffer().params().documentClass().hasInsetLayout( + from_ascii("Caption:" + type))); + return true; + } + return InsetText::getStatus(cur, cmd, status); + } + case LFUN_PARAGRAPH_BREAK: status.setEnabled(false); return true; @@ -226,7 +273,7 @@ void InsetCaption::latex(otexstream & os, OutputParams runparams = runparams_in; // FIXME: actually, it is moving only when there is no // optional argument. - runparams.moving_arg = true; + runparams.moving_arg = !runparams.inTableCell; InsetText::latex(os, runparams); runparams_in.encoding = runparams.encoding; } @@ -259,8 +306,8 @@ docstring InsetCaption::xhtml(XHTMLStream & xs, OutputParams const & rp) const if (rp.html_disable_captions) return docstring(); string attr = "class='float-caption"; - if (!type_.empty()) - attr += " float-caption-" + type_; + if (!floattype_.empty()) + attr += " float-caption-" + floattype_; attr += "'"; xs << html::StartTag("div", attr); docstring def = getCaptionAsHTML(xs, rp); @@ -324,7 +371,7 @@ void InsetCaption::updateBuffer(ParIterator const & it, UpdateType utype) cnts.saveLastCounter(); } // Memorize type for addToToc(). - type_ = type; + floattype_ = type; if (type.empty()) full_label_ = master.B_("Senseless!!! "); else { @@ -337,17 +384,26 @@ void InsetCaption::updateBuffer(ParIterator const & it, UpdateType utype) name = master.B_(tclass.floats().getType(type).name()); docstring counter = from_utf8(type); if (cnts.isSubfloat()) { + // only standard captions allowed in subfloats + type_ = "Standard"; counter = "sub-" + from_utf8(type); name = bformat(_("Sub-%1$s"), master.B_(tclass.floats().getType(type).name())); } + docstring sec; if (cnts.hasCounter(counter)) { cnts.step(counter, utype); - full_label_ = bformat(from_ascii("%1$s %2$s:"), - name, - cnts.theCounter(counter, lang)); - } else - full_label_ = bformat(from_ascii("%1$s #:"), name); + sec = cnts.theCounter(counter, lang); + } + if (getLayout().labelstring() != master.B_("standard")) { + if (!sec.empty()) + sec += from_ascii(" "); + sec += bformat(from_ascii("(%1$s)"), getLayout().labelstring()); + } + if (!sec.empty()) + full_label_ = bformat(from_ascii("%1$s %2$s:"), name, sec); + else + full_label_ = bformat(from_ascii("%1$s #:"), name); } // Do the real work now. @@ -357,4 +413,10 @@ void InsetCaption::updateBuffer(ParIterator const & it, UpdateType utype) } +string InsetCaption::contextMenuName() const +{ + return "context-caption"; +} + + } // namespace lyx diff --git a/src/insets/InsetCaption.h b/src/insets/InsetCaption.h index d446da8fd3..fd512e187c 100644 --- a/src/insets/InsetCaption.h +++ b/src/insets/InsetCaption.h @@ -21,7 +21,7 @@ namespace lyx { class InsetCaption : public InsetText { public: /// - InsetCaption(Buffer *); + InsetCaption(Buffer *, std::string const &); /// std::string const & type() const { return type_; } /// @@ -32,6 +32,8 @@ public: int getCaptionAsPlaintext(odocstream & os, OutputParams const &) const; /// return the caption text as HTML docstring getCaptionAsHTML(XHTMLStream & os, OutputParams const &) const; + /// + std::string contextMenuName() const; private: /// void write(std::ostream & os) const; @@ -59,6 +61,8 @@ private: /// bool insetAllowed(InsetCode code) const; /// + void doDispatch(Cursor & cur, FuncRequest & cmd); + /// bool getStatus(Cursor & cur, FuncRequest const & cmd, FuncStatus &) const; // Update the counters of this inset and of its contents void updateBuffer(ParIterator const &, UpdateType); @@ -86,6 +90,8 @@ private: /// mutable int labelwidth_; /// + std::string floattype_; + /// std::string type_; /// docstring custom_label_; diff --git a/src/insets/InsetFloat.h b/src/insets/InsetFloat.h index 4a4c7d5bfb..502422a21b 100644 --- a/src/insets/InsetFloat.h +++ b/src/insets/InsetFloat.h @@ -67,6 +67,8 @@ public: void setNewLabel(); /// InsetFloatParams const & params() const { return params_; } + /// + bool allowsCaptionVariation() const { return !params_.subfloat; } private: /// docstring layoutName() const; diff --git a/src/insets/InsetListings.cpp b/src/insets/InsetListings.cpp index 603f46ffb0..d05c946ea4 100644 --- a/src/insets/InsetListings.cpp +++ b/src/insets/InsetListings.cpp @@ -335,9 +335,12 @@ bool InsetListings::getStatus(Cursor & cur, FuncRequest const & cmd, case LFUN_INSET_DIALOG_UPDATE: status.setEnabled(true); return true; - case LFUN_CAPTION_INSERT: - status.setEnabled(!params().isInline()); - return true; + case LFUN_CAPTION_INSERT: { + if (params().isInline()) { + status.setEnabled(false); + return true; + } + } default: return InsetCollapsable::getStatus(cur, cmd, status); } diff --git a/src/insets/InsetTabular.cpp b/src/insets/InsetTabular.cpp index a2aa334b85..a43d45fbdf 100644 --- a/src/insets/InsetTabular.cpp +++ b/src/insets/InsetTabular.cpp @@ -4705,6 +4705,12 @@ bool InsetTabular::getStatus(Cursor & cur, FuncRequest const & cmd, status.setEnabled(false); return true; } + // only standard caption is allowed + string arg = cmd.getArg(0); + if (!arg.empty() && arg != "Standard") { + status.setEnabled(false); + return true; + } // check if there is already a caption bool have_caption = false; InsetTableCell itc = InsetTableCell(*tabular.cellInset(cur.idx()).get()); diff --git a/src/tex2lyx/TODO.txt b/src/tex2lyx/TODO.txt index 162d07fd47..b23aa446da 100644 --- a/src/tex2lyx/TODO.txt +++ b/src/tex2lyx/TODO.txt @@ -98,6 +98,7 @@ Format LaTeX feature LyX feature \frametitle[short}{long} 456 memoir: \epigraph{text}{source} layout Epigraph, InsetArgument 457 automatic stackrel loading \use_package stackrel +458 Extended InsetCaption syntax InsetCaption General diff --git a/src/version.h b/src/version.h index aad31feaac..07e2980ab3 100644 --- a/src/version.h +++ b/src/version.h @@ -30,8 +30,8 @@ extern char const * const lyx_version_info; // Do not remove the comment below, so we get merge conflict in // independent branches. Instead add your own. -#define LYX_FORMAT_LYX 457 // gb: automatic stackrel package loading -#define LYX_FORMAT_TEX2LYX 457 // gb: automatic stackrel package loading +#define LYX_FORMAT_LYX 458 // spitz: extended caption inset +#define LYX_FORMAT_TEX2LYX 458 // spitz: extended caption inset #if LYX_FORMAT_TEX2LYX != LYX_FORMAT_LYX #ifndef _MSC_VER -- 2.39.5