Context menu for quote insets

Allows to switch quote type.
This commit is contained in:
Juergen Spitzmueller 2016-12-17 12:58:33 +01:00
parent 7cf315f855
commit 197c193e21
4 changed files with 215 additions and 5 deletions

View File

@ -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
#

View File

@ -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()));

View File

@ -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

View File

@ -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