#include "MetricsInfo.h"
#include "Paragraph.h"
#include "Session.h"
+#include "texstream.h"
#include "Text.h"
#include "TextMetrics.h"
#include "TexRow.h"
#include "insets/InsetCitation.h"
#include "insets/InsetCommand.h" // ChangeRefs
#include "insets/InsetGraphics.h"
+#include "insets/InsetIndex.h"
#include "insets/InsetRef.h"
#include "insets/InsetText.h"
bool clickable_inset_;
/// shape of the caret
frontend::CaretGeometry caret_geometry_;
+ ///
+ bool mouse_selecting_ = false;
};
int BufferView::rightMargin() const
{
- // The additional test for the case the outliner is opened.
- if (full_screen_ && lyxrc.full_screen_limit)
- return max(defaultMargin(), (width_ - lyxrc.full_screen_width) / 2);
+ const int screen_width = inPixels(lyxrc.screen_width);
- return defaultMargin();
+ // The additional test for the case the outliner is opened.
+ if (!lyxrc.screen_limit || width_ < screen_width + 2 * defaultMargin()) {
+ return defaultMargin();
+ } else {
+ return (width_ - screen_width) / 2;
+ }
}
}
-void BufferView::updateScrollbar()
+void BufferView::updateScrollbarParameters()
{
if (height_ == 0 && width_ == 0)
return;
void BufferView::updateDocumentClass(DocumentClassConstPtr olddc)
{
- message(_("Converting document to new document class..."));
-
StableDocIterator backcur(d->cursor_);
ErrorList & el = buffer_.errorList("Class Switch");
cap::switchBetweenClasses(
else {
dr.screenUpdate(Update::Force | Update::FitCursor);
dr.forceBufferUpdate();
+ resetInlineCompletionPos();
if (buffer().params().citeEngine() != engine ||
buffer().params().citeEngineType() != enginetype)
buffer().invalidateCiteLabels();
else {
dr.screenUpdate(Update::Force | Update::FitCursor);
dr.forceBufferUpdate();
+ resetInlineCompletionPos();
if (buffer().params().citeEngine() != engine ||
buffer().params().citeEngineType() != enginetype)
buffer().invalidateCiteLabels();
}
if (cur.selection())
pattern = cur.selectionAsString(false);
+ else if (!cur.inTexted())
+ break; // not suitable for selectWord at cursor
else {
pos_type spos = cur.pos();
cur.innerText()->selectWord(cur, WHOLE_WORD);
break;
}
+ case LFUN_INDEX_TAG_ALL: {
+ Inset * ins = cur.nextInset();
+ if (!ins || ins->lyxCode() != INDEX_CODE)
+ // not at index inset
+ break;
+
+ // clone the index inset
+ InsetIndex * cins =
+ new InsetIndex(static_cast<InsetIndex &>(*cur.nextInset()));
+ // In order to avoid duplication, we compare the
+ // LaTeX output if we find another index inset after
+ // the word
+ odocstringstream oilatex;
+ otexstream oits(oilatex);
+ OutputParams rp(&cur.buffer()->params().encoding());
+ ins->latex(oits, rp);
+ cap::copyInsetToTemp(cur, cins);
+
+ // move backwards into preceding word
+ // skip over other index insets
+ cur.backwardPosIgnoreCollapsed();
+ while (true) {
+ if (cur.inset().lyxCode() == INDEX_CODE)
+ cur.pop_back();
+ else if (cur.prevInset() && cur.prevInset()->lyxCode() == INDEX_CODE)
+ cur.backwardPosIgnoreCollapsed();
+ else
+ break;
+ }
+ if (!cur.inTexted()) {
+ // Nothing to do here.
+ setCursorFromInset(ins);
+ break;
+ }
+ // Get word or selection
+ cur.text()->selectWord(cur, WHOLE_WORD);
+ docstring const searched_string = cur.selectionAsString(false);
+ // Start from the beginning
+ lyx::dispatch(FuncRequest(LFUN_BUFFER_BEGIN));
+ while (findOne(this, searched_string,
+ false,// case sensitive
+ true,// match whole word only
+ true,// forward
+ false,//find deleted
+ false,//check wrap
+ false,// auto-wrap
+ false,// instant
+ false// only selection
+ )) {
+ cur.clearSelection();
+ Inset * ains = cur.nextInset();
+ if (ains && ains->lyxCode() == INDEX_CODE) {
+ // We have an index inset.
+ // Check whether it has the same
+ // LaTeX content and move on if so.
+ odocstringstream filatex;
+ otexstream fits(filatex);
+ ains->latex(fits, rp);
+ if (oilatex.str() == filatex.str())
+ continue;
+ }
+ // Paste the inset and possibly continue
+ cap::pasteFromTemp(cursor(), cursor().buffer()->errorList("Paste"));
+ }
+ // Go back to start position.
+ setCursorFromInset(ins);
+ dr.screenUpdate(cur.result().screenUpdate());
+ if (cur.result().needBufferUpdate())
+ dr.forceBufferUpdate();
+ break;
+ }
+
case LFUN_MARK_OFF:
cur.clearSelection();
dr.setMessage(from_utf8(N_("Mark off")));
message += _("One word");
message += "\n";
if (chars_blanks != 1)
- message += bformat(_("%1$d characters (including blanks)"),
- chars_blanks);
+ message += bformat(_("%1$d characters"), chars_blanks);
else
- message += _("One character (including blanks)");
+ message += _("One character");
message += "\n";
if (chars != 1)
- message += bformat(_("%1$d characters (excluding blanks)"),
- chars);
+ message += bformat(_("%1$d characters (no blanks)"), chars);
else
- message += _("One character (excluding blanks)");
+ message += _("One character (no blanks)");
Alert::information(_("Statistics"), message);
}
cur.setCursor(doc_iterator_begin(cur.buffer()));
cur.selHandle(false);
// Force an immediate computation of metrics because we need it below
- updateMetrics();
+ if (scrolled)
+ processUpdateFlags(Update::Force);
d->text_metrics_[&buffer_.text()].editXY(cur, p.x_, p.y_,
true, act == LFUN_SCREEN_UP);
// an arbitrary number to limit number of iterations
const int max_iter = 100000;
int iterations = 0;
- Cursor & curs = d->cursor_;
- Cursor const savecur = curs;
- curs.reset();
- if (!curs.nextInset())
- curs.forwardInset();
- curs.beginUndoGroup();
- while(curs && iterations < max_iter) {
- Inset * const ins = curs.nextInset();
+ Cursor & bvcur = d->cursor_;
+ Cursor const savecur = bvcur;
+ bvcur.reset();
+ if (!bvcur.nextInset())
+ bvcur.forwardInset();
+ bvcur.beginUndoGroup();
+ while(bvcur && iterations < max_iter) {
+ Inset * const ins = bvcur.nextInset();
if (!ins)
break;
docstring insname = ins->layoutName();
while (!insname.empty()) {
if (insname == name || name == from_utf8("*")) {
- curs.recordUndo();
lyx::dispatch(fr, dr);
+ // we do not want to remember selection here
+ bvcur.clearSelection();
++iterations;
break;
}
insname = insname.substr(0, i);
}
// if we did not delete the inset, skip it
- if (!curs.nextInset() || curs.nextInset() == ins)
- curs.forwardInset();
+ if (!bvcur.nextInset() || bvcur.nextInset() == ins)
+ bvcur.forwardInset();
}
- curs = savecur;
- curs.fixIfBroken();
+ bvcur = savecur;
+ bvcur.fixIfBroken();
/** This is a dummy undo record only to remember the cursor
* that has just been set; this will be used on a redo action
* (see ticket #10097)
* FIXME: a better fix would be to have a way to set the
* cursor value directly, but I am not sure it is worth it.
*/
- curs.recordUndo();
- curs.endUndoGroup();
+ bvcur.recordUndo();
+ bvcur.endUndoGroup();
dr.screenUpdate(Update::Force);
dr.forceBufferUpdate();
}
+bool BufferView::mouseSelecting() const
+{
+ return d->mouse_selecting_;
+}
+
+
void BufferView::mouseEventDispatch(FuncRequest const & cmd0)
{
//lyxerr << "[ cmd0 " << cmd0 << "]" << endl;
d->mouse_position_cache_.x_ = cmd.x();
d->mouse_position_cache_.y_ = cmd.y();
+ d->mouse_selecting_ =
+ cmd.action() == LFUN_MOUSE_MOTION && cmd.button() == mouse_button::button1;
+
if (cmd.action() == LFUN_MOUSE_MOTION && cmd.button() == mouse_button::none) {
updateHoveredInset();
return;
// Notify left insets
if (cur != old) {
- bool badcursor = old.fixIfBroken() | cur.fixIfBroken();
- badcursor |= notifyCursorLeavesOrEnters(old, cur);
+ bool badcursor = old.fixIfBroken() || cur.fixIfBroken();
+ badcursor = badcursor || notifyCursorLeavesOrEnters(old, cur);
if (badcursor)
cursor().fixIfBroken();
}
{
TexRow::TextEntry start, end;
tie(start,end) = buffer_.texrow().getEntriesFromRow(row);
- LYXERR(Debug::LATEX,
+ LYXERR(Debug::OUTFILE,
"setCursorFromRow: for row " << row << ", TexRow has found "
"start (id=" << start.id << ",pos=" << start.pos << "), "
"end (id=" << end.id << ",pos=" << end.pos << ")");
//lyxerr << "cur_x=" << cur_x << ", offset=" << offset << ", row.wid=" << row.width() << ", margin=" << MARGIN << endl;
- if (offset != d->horiz_scroll_offset_)
+ if (offset != d->horiz_scroll_offset_) {
LYXERR(Debug::PAINTING, "Horiz. scroll offset changed from "
<< d->horiz_scroll_offset_ << " to " << offset);
-
- if (d->update_strategy_ == NoScreenUpdate
- && offset != d->horiz_scroll_offset_) {
- // FIXME: if one uses SingleParUpdate, then home/end
- // will not work on long rows. Why?
- d->update_strategy_ = FullScreenUpdate;
+ row.changed(true);
+ if (d->update_strategy_ == NoScreenUpdate)
+ d->update_strategy_ = SingleParUpdate;
}
d->horiz_scroll_offset_ = offset;
// The scrollbar needs an update.
// FIXME: does it always? see ticket #11947.
- updateScrollbar();
+ updateScrollbarParameters();
// Normalize anchor for next time
pair<pit_type, ParagraphMetrics const *> firstpm = tm.first();