mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-26 11:16:55 +00:00
Give textstyle-apply a history
The last 20 applications are saved now and accessible both via the lfun (textstyle-apply n) and the toolbar (via button menu) Fixes: #7133 This also changes the default icon and toolbar position of the action, as requested in #11427
This commit is contained in:
parent
057d83d8ae
commit
154b4fdece
@ -473,6 +473,7 @@ dist_images_DATA1X = \
|
||||
images/down.svgz \
|
||||
images/dynamic-char-styles.svgz \
|
||||
images/dynamic-custom-insets.svgz \
|
||||
images/dynamic-freefonts.svgz \
|
||||
images/editclear.svgz \
|
||||
images/emblem-readonly.svgz \
|
||||
images/emblem-shellescape.svgz \
|
||||
@ -1759,6 +1760,7 @@ dist_imagesoxygen_DATA1X = \
|
||||
images/oxygen/dialog-toggle_toc.svgz \
|
||||
images/oxygen/dynamic-char-styles.svgz \
|
||||
images/oxygen/dynamic-custom-insets.svgz \
|
||||
images/oxygen/dynamic-freefonts.svgz \
|
||||
images/oxygen/down.svgz \
|
||||
images/oxygen/editclear.svgz \
|
||||
images/oxygen/ert-insert.svgz \
|
||||
@ -1965,6 +1967,7 @@ dist_imagesclassic_DATA = \
|
||||
images/classic/dialog-show_vclog.png \
|
||||
images/classic/dialog-toggle_findreplaceadv.png \
|
||||
images/classic/dialog-toggle_toc.png \
|
||||
images/classic/dynamic-freefonts.png \
|
||||
images/classic/down.png \
|
||||
images/classic/ert-insert.png \
|
||||
images/classic/file-open.png \
|
||||
|
BIN
lib/images/classic/dynamic-freefonts.png
Normal file
BIN
lib/images/classic/dynamic-freefonts.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 247 B |
BIN
lib/images/dynamic-freefonts.svgz
Normal file
BIN
lib/images/dynamic-freefonts.svgz
Normal file
Binary file not shown.
BIN
lib/images/oxygen/dynamic-freefonts.svgz
Normal file
BIN
lib/images/oxygen/dynamic-freefonts.svgz
Normal file
Binary file not shown.
Binary file not shown.
@ -87,7 +87,6 @@ ToolbarSet
|
||||
Item "Toggle emphasis" "font-emph"
|
||||
Item "Toggle noun" "font-noun"
|
||||
DynamicMenu "dynamic-char-styles" "Custom text styles"
|
||||
Item "Apply last text properties" "textstyle-apply"
|
||||
Separator
|
||||
Item "Insert math" "math-mode on"
|
||||
Item "Insert graphics" "dialog-show-new-inset graphics"
|
||||
@ -139,6 +138,7 @@ ToolbarSet
|
||||
Item "Include file" "dialog-show-new-inset include"
|
||||
Separator
|
||||
Item "Text properties" "dialog-show character"
|
||||
DynamicMenu "dynamic-freefonts" "Apply recent text properties"
|
||||
Item "Paragraph settings" "layout-paragraph"
|
||||
Item "Thesaurus" "thesaurus-entry"
|
||||
End
|
||||
|
41
src/Font.cpp
41
src/Font.cpp
@ -143,41 +143,41 @@ void Font::update(Font const & newfont,
|
||||
}
|
||||
|
||||
|
||||
docstring const stateText(FontInfo const & f)
|
||||
docstring const stateText(FontInfo const & f, bool const terse)
|
||||
{
|
||||
odocstringstream os;
|
||||
if (f.family() != INHERIT_FAMILY)
|
||||
if (f.family() != INHERIT_FAMILY && (!terse || f.family() != IGNORE_FAMILY))
|
||||
os << _(GUIFamilyNames[f.family()]) << ", ";
|
||||
if (f.series() != INHERIT_SERIES)
|
||||
if (f.series() != INHERIT_SERIES && (!terse || f.series() != IGNORE_SERIES))
|
||||
os << _(GUISeriesNames[f.series()]) << ", ";
|
||||
if (f.shape() != INHERIT_SHAPE)
|
||||
if (f.shape() != INHERIT_SHAPE && (!terse || f.shape() != IGNORE_SHAPE))
|
||||
os << _(GUIShapeNames[f.shape()]) << ", ";
|
||||
if (f.size() != FONT_SIZE_INHERIT)
|
||||
if (f.size() != FONT_SIZE_INHERIT && (!terse || f.size() != FONT_SIZE_IGNORE))
|
||||
os << _(GUISizeNames[f.size()]) << ", ";
|
||||
if (f.color() != Color_inherit)
|
||||
if (f.color() != Color_inherit && (!terse || f.color() != Color_ignore))
|
||||
os << lcolor.getGUIName(f.color()) << ", ";
|
||||
// FIXME: uncomment this when we support background.
|
||||
//if (f.background() != Color_inherit)
|
||||
// os << lcolor.getGUIName(f.background()) << ", ";
|
||||
if (f.emph() != FONT_INHERIT)
|
||||
if (f.emph() != FONT_INHERIT && (!terse || f.emph() != FONT_IGNORE))
|
||||
os << bformat(_("Emphasis %1$s, "),
|
||||
_(GUIMiscNames[f.emph()]));
|
||||
if (f.underbar() != FONT_INHERIT)
|
||||
if (f.underbar() != FONT_INHERIT && (!terse || f.underbar() == FONT_ON))
|
||||
os << bformat(_("Underline %1$s, "),
|
||||
_(GUIMiscNames[f.underbar()]));
|
||||
if (f.strikeout() != FONT_INHERIT)
|
||||
os << bformat(_("Strike out %1$s, "),
|
||||
_(GUIMiscNames[f.strikeout()]));
|
||||
if (f.xout() != FONT_INHERIT)
|
||||
os << bformat(_("Cross out %1$s, "),
|
||||
_(GUIMiscNames[f.xout()]));
|
||||
if (f.uuline() != FONT_INHERIT)
|
||||
if (f.uuline() != FONT_INHERIT && (!terse || f.uuline() == FONT_ON))
|
||||
os << bformat(_("Double underline %1$s, "),
|
||||
_(GUIMiscNames[f.uuline()]));
|
||||
if (f.uwave() != FONT_INHERIT)
|
||||
if (f.uwave() != FONT_INHERIT && (!terse || f.uwave() == FONT_ON))
|
||||
os << bformat(_("Wavy underline %1$s, "),
|
||||
_(GUIMiscNames[f.uwave()]));
|
||||
if (f.noun() != FONT_INHERIT)
|
||||
if (f.strikeout() != FONT_INHERIT && (!terse || f.strikeout() == FONT_ON))
|
||||
os << bformat(_("Strike out %1$s, "),
|
||||
_(GUIMiscNames[f.strikeout()]));
|
||||
if (f.xout() != FONT_INHERIT && (!terse || f.strikeout() == FONT_ON))
|
||||
os << bformat(_("Cross out %1$s, "),
|
||||
_(GUIMiscNames[f.xout()]));
|
||||
if (f.noun() != FONT_INHERIT && (!terse || f.noun() != FONT_IGNORE))
|
||||
os << bformat(_("Noun %1$s, "),
|
||||
_(GUIMiscNames[f.noun()]));
|
||||
if (f == inherit_font)
|
||||
@ -187,11 +187,12 @@ docstring const stateText(FontInfo const & f)
|
||||
}
|
||||
|
||||
|
||||
docstring const Font::stateText(BufferParams * params) const
|
||||
docstring const Font::stateText(BufferParams * params, bool const terse) const
|
||||
{
|
||||
odocstringstream os;
|
||||
os << lyx::stateText(bits_);
|
||||
if (!params || (language() != params->language)) {
|
||||
os << lyx::stateText(bits_, terse);
|
||||
if ((!params || (language() != params->language))
|
||||
&& (!terse || language() != ignore_language)) {
|
||||
// reset_language is a null pointer!
|
||||
os << bformat(_("Language: %1$s, "),
|
||||
(language() == reset_language) ? _("Default")
|
||||
|
@ -90,7 +90,7 @@ public:
|
||||
|
||||
|
||||
/// Build GUI description of font state
|
||||
docstring const stateText(BufferParams * params) const;
|
||||
docstring const stateText(BufferParams * params, bool const terse = false) const;
|
||||
|
||||
///
|
||||
void validate(LaTeXFeatures & features) const;
|
||||
|
@ -3830,8 +3830,10 @@ void LyXAction::init()
|
||||
|
||||
/*!
|
||||
* \var lyx::FuncCode lyx::LFUN_TEXTSTYLE_APPLY
|
||||
* \li Action: Toggle user-defined (=last-time used) text style.
|
||||
* \li Notion: This style is set via #LFUN_TEXTSTYLE_UPDATE, which is
|
||||
* \li Action: Apply last used text properties.
|
||||
* \li Syntax: textstyle-apply [<NUM>]
|
||||
* \li Params: <NUM>: number of the selection in the internal freefonts stack to be applied.
|
||||
* \li Notion: These properties are stored via #LFUN_TEXTSTYLE_UPDATE, which is
|
||||
automatically triggered when using Text Style dialog.
|
||||
* \li Syntax: textstyle-apply
|
||||
* \li Origin: leeming, 12 Mar 2003
|
||||
|
@ -109,6 +109,8 @@ public:
|
||||
|
||||
///
|
||||
void toggleFree(Cursor & cur, Font const &, bool toggleall = false);
|
||||
/// Stack to save recent text propterty applications
|
||||
std::vector<docstring> getFreeFonts() const;
|
||||
|
||||
/// ???
|
||||
/// FIXME: replace Cursor with DocIterator.
|
||||
|
@ -72,6 +72,7 @@
|
||||
#include "support/debug.h"
|
||||
#include "support/gettext.h"
|
||||
#include "support/lassert.h"
|
||||
#include "support/limited_stack.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "support/lyxalgo.h"
|
||||
#include "support/lyxtime.h"
|
||||
@ -105,7 +106,8 @@ using cap::pasteSimpleText;
|
||||
using frontend::Clipboard;
|
||||
|
||||
// globals...
|
||||
static Font freefont(ignore_font, ignore_language);
|
||||
typedef limited_stack<pair<docstring, Font>> FontStack;
|
||||
static FontStack freeFonts(15);
|
||||
static bool toggleall = false;
|
||||
|
||||
static void toggleAndShow(Cursor & cur, Text * text,
|
||||
@ -2364,10 +2366,26 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
|
||||
break;
|
||||
}
|
||||
|
||||
case LFUN_TEXTSTYLE_APPLY:
|
||||
toggleAndShow(cur, this, freefont, toggleall);
|
||||
cur.message(_("Character set"));
|
||||
case LFUN_TEXTSTYLE_APPLY: {
|
||||
unsigned int num = 0;
|
||||
string const arg = to_utf8(cmd.argument());
|
||||
// Argument?
|
||||
if (!arg.empty()) {
|
||||
if (isStrUnsignedInt(arg)) {
|
||||
num = convert<uint>(arg);
|
||||
if (num >= freeFonts.size()) {
|
||||
cur.message(_("Invalid argument (number exceeds stack size)!"));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cur.message(_("Invalid argument (must be a positive number)!"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
toggleAndShow(cur, this, freeFonts[num].second, toggleall);
|
||||
cur.message(bformat(_("Text properties applied: %1$s"), freeFonts[num].first));
|
||||
break;
|
||||
}
|
||||
|
||||
// Set the freefont using the contents of \param data dispatched from
|
||||
// the frontends and apply it at the current cursor location.
|
||||
@ -2375,17 +2393,17 @@ void Text::dispatch(Cursor & cur, FuncRequest & cmd)
|
||||
Font font;
|
||||
bool toggle;
|
||||
if (font.fromString(to_utf8(cmd.argument()), toggle)) {
|
||||
freefont = font;
|
||||
docstring const props = font.stateText(&bv->buffer().params(), true);
|
||||
freeFonts.push(make_pair(props, font));
|
||||
toggleall = toggle;
|
||||
toggleAndShow(cur, this, freefont, toggleall);
|
||||
toggleAndShow(cur, this, font, toggleall);
|
||||
// We need a buffer update if we change the language
|
||||
// of an info inset
|
||||
if (cur.insetInSelection(INFO_CODE))
|
||||
cur.forceBufferUpdate();
|
||||
cur.message(_("Character set"));
|
||||
} else {
|
||||
lyxerr << "Argument not ok";
|
||||
}
|
||||
cur.message(bformat(_("Text properties applied: %1$s"), props));
|
||||
} else
|
||||
LYXERR0("Invalid argument of textstyle-update");
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3378,11 +3396,14 @@ bool Text::getStatus(Cursor & cur, FuncRequest const & cmd,
|
||||
case LFUN_FONT_CROSSOUT:
|
||||
case LFUN_FONT_UNDERUNDERLINE:
|
||||
case LFUN_FONT_UNDERWAVE:
|
||||
case LFUN_TEXTSTYLE_APPLY:
|
||||
case LFUN_TEXTSTYLE_UPDATE:
|
||||
enable = !cur.paragraph().isPassThru();
|
||||
break;
|
||||
|
||||
case LFUN_TEXTSTYLE_APPLY:
|
||||
enable = !freeFonts.empty();
|
||||
break;
|
||||
|
||||
case LFUN_WORD_DELETE_FORWARD:
|
||||
case LFUN_WORD_DELETE_BACKWARD:
|
||||
case LFUN_LINE_DELETE_FORWARD:
|
||||
@ -3506,4 +3527,19 @@ bool Text::inDescriptionItem(Cursor & cur) const
|
||||
&& (pos == 0 || par.getChar(pos - 1) != ' ')));
|
||||
}
|
||||
|
||||
|
||||
std::vector<docstring> Text::getFreeFonts() const
|
||||
{
|
||||
vector<docstring> ffList;
|
||||
|
||||
FontStack::const_iterator cit = freeFonts.begin();
|
||||
FontStack::const_iterator end = freeFonts.end();
|
||||
for (; cit != end; ++cit)
|
||||
// we do not use cit-> here because gcc 2.9x does not
|
||||
// like it (JMarc)
|
||||
ffList.push_back((*cit).first);
|
||||
|
||||
return ffList;
|
||||
}
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -42,7 +42,8 @@ int const num_math_fonts = sizeof(math_fonts) / sizeof(*math_fonts);
|
||||
|
||||
namespace lyx {
|
||||
|
||||
extern docstring const stateText(FontInfo const & f);
|
||||
extern docstring const stateText(FontInfo const & f,
|
||||
bool const terse = false);
|
||||
|
||||
namespace frontend {
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "insets/InsetText.h"
|
||||
|
||||
#include "support/convert.h"
|
||||
#include "support/debug.h"
|
||||
#include "support/gettext.h"
|
||||
#include "support/lstrings.h"
|
||||
@ -318,8 +319,9 @@ void DynamicMenuButton::initialize()
|
||||
|
||||
bool DynamicMenuButton::isMenuType(string const & s)
|
||||
{
|
||||
return s == "dynamic-custom-insets" ||
|
||||
s == "dynamic-char-styles";
|
||||
return s == "dynamic-custom-insets"
|
||||
|| s == "dynamic-char-styles"
|
||||
|| s == "dynamic-freefonts";
|
||||
}
|
||||
|
||||
|
||||
@ -336,28 +338,54 @@ void DynamicMenuButton::updateTriggered()
|
||||
setEnabled(false);
|
||||
setMinimumWidth(sizeHint().width());
|
||||
d->text_class_.reset();
|
||||
d->inset_ = 0;
|
||||
d->inset_ = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
DocumentClassConstPtr text_class =
|
||||
bv->buffer().params().documentClassPtr();
|
||||
InsetText const * inset = &(bv->cursor().innerText()->inset());
|
||||
// if the text class has changed, then we need to reload the menu
|
||||
if (d->text_class_ != text_class) {
|
||||
d->text_class_ = text_class;
|
||||
// at the moment, we can just call loadFlexInsets, and it will
|
||||
// handle both types. if there were more types of menus, then we
|
||||
// might need to have other options.
|
||||
loadFlexInsets();
|
||||
string const & menutype = tbitem_.name_;
|
||||
if (menutype == "dynamic-custom-insets" || menutype == "dynamic-char-styles") {
|
||||
DocumentClassConstPtr text_class =
|
||||
bv->buffer().params().documentClassPtr();
|
||||
InsetText const * inset = &(bv->cursor().innerText()->inset());
|
||||
// if the text class has changed, then we need to reload the menu
|
||||
if (d->text_class_ != text_class) {
|
||||
d->text_class_ = text_class;
|
||||
// at the moment, we can just call loadFlexInsets, and it will
|
||||
// handle both types. if there were more types of menus, then we
|
||||
// might need to have other options.
|
||||
loadFlexInsets();
|
||||
}
|
||||
// remember where we are
|
||||
d->inset_ = inset;
|
||||
// note that enabling here might need to be more subtle if there
|
||||
// were other kinds of menus.
|
||||
setEnabled(!bv->buffer().isReadonly()
|
||||
&& !m->isEmpty()
|
||||
&& inset->insetAllowed(FLEX_CODE));
|
||||
} else if (menutype == "dynamic-freefonts") {
|
||||
m->clear();
|
||||
vector<docstring> ffList = bv->cursor().innerText()->getFreeFonts();
|
||||
unsigned int i = 0;
|
||||
Action * default_act = nullptr;
|
||||
for (auto const & f : ffList) {
|
||||
FuncRequest func(LFUN_TEXTSTYLE_APPLY, convert<docstring>(i),
|
||||
FuncRequest::TOOLBAR);
|
||||
docstring const lb = char_type('&') + convert<docstring>(i)
|
||||
+ from_ascii(". ") + f ;
|
||||
Action * act = new Action(func, QIcon(), toqstr(lb), toqstr(f), this);
|
||||
m->addAction(act);
|
||||
// The most recent one is the default
|
||||
if (i == 0)
|
||||
default_act = act;
|
||||
++i;
|
||||
}
|
||||
if (default_act) {
|
||||
QToolButton::setDefaultAction(default_act);
|
||||
QToolButton::setIcon(getIcon(FuncRequest(LFUN_TEXTSTYLE_APPLY), false));
|
||||
}
|
||||
setPopupMode(QToolButton::DelayedPopup);
|
||||
setEnabled(lyx::getStatus(FuncRequest(LFUN_TEXTSTYLE_APPLY)).enabled());
|
||||
}
|
||||
// remember where we are
|
||||
d->inset_ = inset;
|
||||
// note that enabling here might need to be more subtle if there
|
||||
// were other kinds of menus.
|
||||
setEnabled(!bv->buffer().isReadonly() &&
|
||||
!m->isEmpty() &&
|
||||
inset->insetAllowed(FLEX_CODE));
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,6 +86,7 @@ protected Q_SLOTS:
|
||||
/// (stdtoolbars.inc, usually) and must be one of:
|
||||
/// dynamic-custom-insets
|
||||
/// dynamic-char-styles
|
||||
/// dynamic-freefonts
|
||||
/// To add a new one of these, you must add a routine, like
|
||||
/// loadFlexInsets, that will populate the menu, and call it from
|
||||
/// updateTriggered. Make sure to add the new type to isMenuType().
|
||||
|
Loading…
Reference in New Issue
Block a user