#include "insets/InsetFloatList.h"
#include "insets/InsetGraphics.h"
#include "insets/InsetGraphicsParams.h"
+#include "insets/InsetInfo.h"
#include "insets/InsetIPAMacro.h"
#include "insets/InsetNewline.h"
#include "insets/InsetQuotes.h"
#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"
#include "mathed/InsetMathHull.h"
#include "mathed/InsetMathMacroTemplate.h"
+#include "lyxfind.h"
#include <clocale>
#include <sstream>
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,
if (cmd.action() == LFUN_INDEX_INSERT)
copySelectionToTemp(cur);
else
- cutSelectionToTemp(cur, false, pastesel);
+ cutSelectionToTemp(cur, pastesel);
cur.clearSelection();
gotsel = true;
} else if (cmd.action() == LFUN_INDEX_INSERT) {
case LFUN_WORD_DELETE_FORWARD:
if (cur.selection())
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
else
deleteWordForward(cur, cmd.getArg(0) == "force");
finishChange(cur, false);
case LFUN_WORD_DELETE_BACKWARD:
if (cur.selection())
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
else
deleteWordBackward(cur, cmd.getArg(0) == "force");
finishChange(cur, false);
case LFUN_LINE_DELETE_FORWARD:
if (cur.selection())
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
else
tm->deleteLineForward(cur);
finishChange(cur, false);
needsUpdate |= erase(cur);
cur.resetAnchor();
} else {
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
singleParUpdate = false;
}
moveCursor(cur, false);
}
}
} else {
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
singleParUpdate = false;
}
break;
pit_type prev = pit > 0 ? depthHook(pit, par.getDepth()) : pit;
if (prev < pit && cur.pos() == par.beginOfBody()
&& !par.size() && !par.isEnvSeparator(cur.pos())
+ && !par.layout().keepempty
&& !par.layout().isCommand()
&& pars_[prev].layout() != par.layout()
&& pars_[prev].layout().isEnvironment()
}
*/
if (cur.selection())
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
cur.insert(inset);
cur.forceBufferUpdate();
if (inset->editable() && inset->asInsetText())
}
case LFUN_CUT:
- cutSelection(cur, true, true);
+ cutSelection(cur, true);
cur.message(_("Cut"));
break;
DocIterator scur = cur;
depth_type const max_depth = cur.paragraph().params().depth() + 1;
cur.forwardPar();
- while (cur.paragraph().params().depth() < min(nextpar_depth, max_depth))
+ while (cur.paragraph().params().depth() < min(nextpar_depth, max_depth)) {
+ depth_type const olddepth = cur.paragraph().params().depth();
lyx::dispatch(FuncRequest(LFUN_DEPTH_INCREMENT));
+ if (olddepth == cur.paragraph().params().depth())
+ // leave loop if no incrementation happens
+ break;
+ }
cur.setCursor(scur);
}
break;
}
- case LFUN_DATE_INSERT: {
- string const format = cmd.argument().empty()
- ? lyxrc.date_insert_format : to_utf8(cmd.argument());
- string const time = formatted_time(current_time(), format);
- lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, time));
- break;
- }
-
case LFUN_MOUSE_TRIPLE:
if (cmd.button() == mouse_button::button1) {
tm->cursorHome(cur);
// true (on).
if (lyxrc.auto_region_delete && cur.selection())
- cutSelection(cur, false, false);
-
+ cutSelection(cur, false);
cur.clearSelection();
- docstring::const_iterator cit = cmd.argument().begin();
- docstring::const_iterator const end = cmd.argument().end();
- for (; cit != end; ++cit)
- bv->translateAndInsert(*cit, this, cur);
+ for (char_type c : cmd.argument())
+ bv->translateAndInsert(c, this, cur);
cur.resetAnchor();
moveCursor(cur, false);
}
case LFUN_INFO_INSERT: {
- Inset * inset;
- if (cmd.argument().empty() && cur.selection()) {
- // if command argument is empty use current selection as parameter.
- docstring ds = cur.selectionAsString(false);
- cutSelection(cur, true, false);
- FuncRequest cmd0(cmd, ds);
- inset = createInset(cur.buffer(), cmd0);
+ if (cmd.argument().empty()) {
+ bv->showDialog("info", cur.current_font.language()->lang());
} else {
+ Inset * inset;
inset = createInset(cur.buffer(), cmd);
+ if (!inset)
+ break;
+ cur.recordUndo();
+ insertInset(cur, inset);
+ cur.forceBufferUpdate();
+ cur.posForward();
}
- if (!inset)
- break;
- cur.recordUndo();
- insertInset(cur, inset);
- cur.forceBufferUpdate();
- cur.posForward();
break;
}
case LFUN_CAPTION_INSERT:
selectWordWhenUnderCursor(cur, WHOLE_WORD_STRICT);
Font font(ignore_font, lang);
toggleAndShow(cur, this, font, toggle);
+ // We need a buffer update if we change the language
+ // of an info inset
+ if (cur.insetInSelection(INFO_CODE))
+ cur.forceBufferUpdate();
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 non-negative 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.
case LFUN_TEXTSTYLE_UPDATE: {
- Font font;
+ Font font(ignore_font, ignore_language);
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);
- cur.message(_("Character set"));
- } else {
- lyxerr << "Argument not ok";
- }
+ 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(bformat(_("Text properties applied: %1$s"), props));
+ } else
+ LYXERR0("Invalid argument of textstyle-update");
break;
}
if (tclass.floats().typeExist(to_utf8(cmd.argument()))) {
cur.recordUndo();
if (cur.selection())
- cutSelection(cur, true, false);
+ cutSelection(cur, false);
breakParagraph(cur);
if (cur.lastpos() != 0) {
break;
case LFUN_INFO_INSERT:
code = INFO_CODE;
+ enable = cmd.argument().empty()
+ || infoparams.validateArgument(cur.buffer(), cmd.argument(), true);
break;
case LFUN_ARGUMENT_INSERT: {
code = ARG_CODE;
if (!cur.buffer()->areChangesPresent())
break;
- for (DocIterator it = cur.selectionBegin(); it < cur.selectionEnd(); it.forwardPar()) {
+ for (DocIterator it = cur.selectionBegin(); ; it.forwardPar()) {
pos_type const beg = it.pos();
pos_type end;
- if (it.paragraph().id() == cur.selectionEnd().paragraph().id())
+ bool const in_last_par = (it.pit() == cur.selectionEnd().pit() &&
+ it.idx() == cur.selectionEnd().idx());
+ if (in_last_par)
end = cur.selectionEnd().pos();
else
- end = it.paragraph().size();
+ end = it.lastpos();
if (beg != end && it.paragraph().isChanged(beg, end)) {
enable = true;
break;
}
+ if (in_last_par)
+ break;
}
}
break;
enable = !inDescriptionItem(cur);
break;
- case LFUN_DATE_INSERT: {
- string const format = cmd.argument().empty()
- ? lyxrc.date_insert_format : to_utf8(cmd.argument());
- enable = support::os::is_valid_strftime(format);
- break;
- }
-
case LFUN_LANGUAGE:
enable = !cur.paragraph().isPassThru();
flag.setOnOff(cmd.getArg(0) == cur.real_current_font.language()->lang());
case LFUN_ACCENT_UMLAUT:
case LFUN_ACCENT_UNDERBAR:
case LFUN_ACCENT_UNDERDOT:
- case LFUN_FONT_DEFAULT:
case LFUN_FONT_FRAK:
case LFUN_FONT_SIZE:
case LFUN_FONT_STATE:
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_FONT_DEFAULT: {
+ Font font(inherit_font, ignore_language);
+ BufferParams const & bp = cur.buffer()->masterParams();
+ if (cur.selection()) {
+ enable = false;
+ // Check if we have a non-default font attribute
+ // in the selection range.
+ DocIterator const from = cur.selectionBegin();
+ DocIterator const to = cur.selectionEnd();
+ for (DocIterator dit = from ; dit != to && !dit.atEnd(); ) {
+ if (!dit.inTexted()) {
+ dit.forwardPos();
+ continue;
+ }
+ Paragraph const & par = dit.paragraph();
+ pos_type const pos = dit.pos();
+ Font tmp = par.getFontSettings(bp, pos);
+ if (tmp.fontInfo() != font.fontInfo()
+ || tmp.language() != bp.language) {
+ enable = true;
+ break;
+ }
+ dit.forwardPos();
+ }
+ break;
+ }
+ // Disable if all is default already.
+ enable = (cur.current_font.fontInfo() != font.fontInfo()
+ || cur.current_font.language() != bp.language);
+ break;
+ }
+
+ case LFUN_TEXTSTYLE_APPLY:
+ enable = !freeFonts.empty();
+ break;
+
case LFUN_WORD_DELETE_FORWARD:
case LFUN_WORD_DELETE_BACKWARD:
case LFUN_LINE_DELETE_FORWARD:
break;
}
+ case LFUN_SEARCH_IGNORE: {
+ bool const value = cmd.getArg(1) == "true";
+ setIgnoreFormat(cmd.getArg(0), value);
+ break;
+ }
+
default:
return false;
}
&& (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