commit 197c193e210cea1697a1217e9f252a35f266273a
Author: Juergen Spitzmueller <[email protected]>
Date: Sat Dec 17 12:58:33 2016 +0100
Context menu for quote insets
Allows to switch quote type.
---
lib/ui/stdcontext.inc | 8 +++
src/frontends/qt4/Menus.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++-
src/insets/InsetQuotes.cpp | 94 ++++++++++++++++++++++++++++++++++++++-
src/insets/InsetQuotes.h | 16 +++++++
4 files changed, 215 insertions(+), 5 deletions(-)
diff --git a/lib/ui/stdcontext.inc b/lib/ui/stdcontext.inc
index a229b4a..89cf287 100644
--- a/lib/ui/stdcontext.inc
+++ b/lib/ui/stdcontext.inc
@@ -218,6 +218,14 @@ Menuset
Item "Vertical Phantom|V" "inset-modify phantom Phantom
VPhantom"
End
+
+#
+# InsetQuotes context menu
+#
+ Menu "context-quote"
+ SwitchQuotes
+ End
+
#
# InsetSpace context menu
#
diff --git a/src/frontends/qt4/Menus.cpp b/src/frontends/qt4/Menus.cpp
index 53a8455..5a7e8e0 100644
--- a/src/frontends/qt4/Menus.cpp
+++ b/src/frontends/qt4/Menus.cpp
@@ -60,6 +60,7 @@
#include "insets/Inset.h"
#include "insets/InsetCitation.h"
#include "insets/InsetGraphics.h"
+#include "insets/InsetQuotes.h"
#include "support/lassert.h"
#include "support/convert.h"
@@ -188,7 +189,9 @@ public:
in the InsetCaption context menu. */
SwitchCaptions,
/** Commands to separate environments. */
- EnvironmentSeparators
+ EnvironmentSeparators,
+ /** This is the list of quotation marks available */
+ SwitchQuotes
};
explicit MenuItem(Kind kind) : kind_(kind), optional_(false) {}
@@ -362,6 +365,7 @@ public:
void expandArguments(BufferView const *, bool switcharg = false);
void expandCaptions(Buffer const * buf, bool switchcap = false);
void expandEnvironmentSeparators(BufferView const *);
+ void expandQuotes(BufferView const *);
///
ItemList items_;
///
@@ -474,7 +478,8 @@ void MenuDefinition::read(Lexer & lex)
md_switcharguments,
md_captions,
md_switchcaptions,
- md_env_separators
+ md_env_separators,
+ md_switchquotes
};
LexerKeyword menutags[] = {
@@ -509,6 +514,7 @@ void MenuDefinition::read(Lexer & lex)
{ "submenu", md_submenu },
{ "switcharguments", md_switcharguments },
{ "switchcaptions", md_switchcaptions },
+ { "switchquotes", md_switchquotes },
{ "toc", md_toc },
{ "toolbars", md_toolbars },
{ "updateformats", md_updateformats },
@@ -656,6 +662,10 @@ void MenuDefinition::read(Lexer & lex)
add(MenuItem(MenuItem::EnvironmentSeparators));
break;
+ case md_switchquotes:
+ add(MenuItem(MenuItem::SwitchQuotes));
+ break;
+
case md_optsubmenu:
case md_submenu: {
lex.next(true);
@@ -1641,6 +1651,90 @@ void MenuDefinition::expandCaptions(Buffer const * buf,
bool switchcap)
}
+void MenuDefinition::expandQuotes(BufferView const * bv)
+{
+ if (!bv)
+ return;
+
+ if (!bv->cursor().inTexted())
+ return;
+
+ Inset const * inset = bv->cursor().nextInset();
+ if (!inset || inset->lyxCode() != QUOTE_CODE) {
+ add(MenuItem(MenuItem::Command,
+ qt_("No Quote in Scope!"),
+ FuncRequest(LFUN_NOACTION)));
+ return;
+ }
+ InsetQuotes const * qinset =
+ static_cast<InsetQuotes const *>(inset);
+
+ map<string, docstring> styles = qinset->getTypes();
+ string const qtype = qinset->getType();
+
+ map<string, docstring>::const_iterator qq = styles.begin();
+ map<string, docstring>::const_iterator end = styles.end();
+
+ MenuDefinition eqs;
+ MenuDefinition sqs;
+ MenuDefinition gqs;
+ MenuDefinition pqs;
+ MenuDefinition fqs;
+ MenuDefinition aqs;
+ for (; qq != end; ++qq) {
+ docstring const style = from_ascii(qq->first);
+ FuncRequest const cmd = FuncRequest(LFUN_INSET_MODIFY,
from_ascii("changetype ") + style);
+ docstring const desc = contains(style, 'l') ?
+ bformat(_("%1$stext"), qq->second) :
bformat(_("text%1$s"), qq->second);
+ if (prefixIs(style, qtype[0]))
+ add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
+ else if (prefixIs(style, 'e') && !prefixIs(qtype, "e"))
+ eqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
+ else if (prefixIs(style, 's') && !prefixIs(qtype, "s"))
+ sqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
+ else if (prefixIs(style, 'g') && !prefixIs(qtype, "g"))
+ gqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
+ else if (prefixIs(style, 'p') && !prefixIs(qtype, "p"))
+ pqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
+ else if (prefixIs(style, 'f') && !prefixIs(qtype, "f"))
+ fqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
+ else if (prefixIs(style, 'a') && !prefixIs(qtype, "a"))
+ aqs.add(MenuItem(MenuItem::Command, toqstr(desc), cmd));
+ }
+
+ if (!eqs.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_("``text''"));
+ item.setSubmenu(eqs);
+ add(item);
+ }
+ if (!sqs.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_("''text''"));
+ item.setSubmenu(sqs);
+ add(item);
+ }
+ if (!gqs.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_(",,text``"));
+ item.setSubmenu(gqs);
+ add(item);
+ }
+ if (!pqs.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_(",,text''"));
+ item.setSubmenu(pqs);
+ add(item);
+ }
+ if (!fqs.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_("<<text>>"));
+ item.setSubmenu(fqs);
+ add(item);
+ }
+ if (!aqs.empty()) {
+ MenuItem item(MenuItem::Submenu, qt_(">>text<<"));
+ item.setSubmenu(aqs);
+ add(item);
+ }
+}
+
+
void MenuDefinition::expandEnvironmentSeparators(BufferView const * bv)
{
if (!bv)
@@ -2071,6 +2165,10 @@ void Menus::Impl::expand(MenuDefinition const & frommenu,
tomenu.expandEnvironmentSeparators(bv);
break;
+ case MenuItem::SwitchQuotes:
+ tomenu.expandQuotes(bv);
+ break;
+
case MenuItem::Submenu: {
MenuItem item(*cit);
item.setSubmenu(MenuDefinition(cit->submenuname()));
diff --git a/src/insets/InsetQuotes.cpp b/src/insets/InsetQuotes.cpp
index b445936..147e177 100644
--- a/src/insets/InsetQuotes.cpp
+++ b/src/insets/InsetQuotes.cpp
@@ -15,8 +15,11 @@
#include "Buffer.h"
#include "BufferParams.h"
#include "BufferView.h"
+#include "Cursor.h"
#include "Dimension.h"
#include "Font.h"
+#include "FuncStatus.h"
+#include "FuncRequest.h"
#include "Language.h"
#include "LaTeXFeatures.h"
#include "Lexer.h"
@@ -223,6 +226,35 @@ InsetQuotes::QuoteLanguage InsetQuotes::getLanguage(string
const & s)
}
+map<string, docstring> InsetQuotes::getTypes() const
+{
+ map<string, docstring> res;
+
+ int l, s, t;
+ QuoteLanguage lang;
+ QuoteSide side;
+ QuoteTimes times;
+ string type;
+
+ // get all quote types
+ for (l = 0; l < 6; ++l) {
+ lang = QuoteLanguage(l);
+ for (s = 0; s < 2; ++s) {
+ side = QuoteSide(s);
+ for (t = 0; t < 2; ++t) {
+ type += language_char[lang];
+ type += side_char[s];
+ times = QuoteTimes(t);
+ type += times_char[t];
+ res[type] = docstring(1,
display_quote_char[times][quote_index[side][lang]]);
+ type.clear();
+ }
+ }
+ }
+ return res;
+}
+
+
docstring InsetQuotes::displayString() const
{
// In PassThru, we use straight quotes
@@ -265,14 +297,18 @@ void InsetQuotes::draw(PainterInfo & pi, int x, int y)
const
pi.pain.text(x, y, displayString(), font);
}
-
-void InsetQuotes::write(ostream & os) const
+string InsetQuotes::getType() const
{
string text;
text += language_char[language_];
text += side_char[side_];
text += times_char[times_];
- os << "Quotes " << text;
+ return text;
+}
+
+void InsetQuotes::write(ostream & os) const
+{
+ os << "Quotes " << getType();
}
@@ -285,6 +321,52 @@ void InsetQuotes::read(Lexer & lex)
}
+void InsetQuotes::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) {
+ // not for us
+ // this will not be handled higher up
+ cur.undispatched();
+ return;
+ }
+ cur.recordUndoInset(this);
+ parseString(cmd.getArg(1));
+ cur.buffer()->updateBuffer();
+ break;
+ }
+ default:
+ Inset::doDispatch(cur, cmd);
+ break;
+ }
+}
+
+
+bool InsetQuotes::getStatus(Cursor & cur, FuncRequest const & cmd,
+ FuncStatus & flag) 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);
+ flag.setOnOff(type == getType());
+ flag.setEnabled(!pass_thru_);
+ return true;
+ }
+ return Inset::getStatus(cur, cmd, flag);
+ }
+
+ default:
+ return Inset::getStatus(cur, cmd, flag);
+ }
+}
+
+
void InsetQuotes::latex(otexstream & os, OutputParams const & runparams) const
{
const int quoteind = quote_index[side_][language_];
@@ -439,4 +521,10 @@ void InsetQuotes::validate(LaTeXFeatures & features) const
}
}
+
+string InsetQuotes::contextMenuName() const
+{
+ return "context-quote";
+}
+
} // namespace lyx
diff --git a/src/insets/InsetQuotes.h b/src/insets/InsetQuotes.h
index 024304b..3054054 100644
--- a/src/insets/InsetQuotes.h
+++ b/src/insets/InsetQuotes.h
@@ -78,6 +78,8 @@ public:
///
void read(Lexer & lex);
///
+ bool getStatus(Cursor &, FuncRequest const &, FuncStatus &) const;
+ ///
void latex(otexstream &, OutputParams const &) const;
///
int plaintext(odocstringstream & ods, OutputParams const & op,
@@ -98,9 +100,16 @@ public:
///
void validate(LaTeXFeatures &) const;
///
+ std::string contextMenuName() const;
+ ///
InsetCode lyxCode() const { return QUOTE_CODE; }
/// should this inset be handled like a normal character
bool isChar() const { return true; }
+
+ /// Returns the current quote type
+ std::string getType() const;
+ /// Returns a map of quotation marks
+ std::map<std::string, docstring> getTypes() const;
private:
///
@@ -129,6 +138,13 @@ private:
std::string context_lang_;
/// Is this in a pass-thru context?
bool pass_thru_;
+
+protected:
+ /// \name Protected functions inherited from Inset class
+ //@{
+ ///
+ void doDispatch(Cursor & cur, FuncRequest & cmd);
+ //@}
};
} // namespace lyx