#include "insets/InsetText.h"
#include "frontends/alert.h"
+#include "frontends/Application.h"
#include "frontends/Delegates.h"
#include "frontends/FontMetrics.h"
#include "frontends/Painter.h"
#include "support/convert.h"
#include "support/debug.h"
+#include "support/ExceptionMessage.h"
#include "support/FileFilterList.h"
#include "support/filetools.h"
#include "support/gettext.h"
tmpcur.clearSelection();
bv->setCursor(tmpcur);
+ bv->showCursor();
}
}
+docstring BufferView::toolTip(int x, int y) const
+{
+ // Get inset under mouse, if there is one.
+ Inset const * covering_inset = getCoveringInset(buffer_.text(), x, y);
+ if (!covering_inset)
+ // No inset, no tooltip...
+ return docstring();
+ return covering_inset->toolTip(*this, x, y);
+}
+
+
+docstring BufferView::contextMenu(int x, int y) const
+{
+ // Get inset under mouse, if there is one.
+ Inset const * covering_inset = getCoveringInset(buffer_.text(), x, y);
+ if (covering_inset)
+ return covering_inset->contextMenu(*this, x, y);
+
+ // FIXME: Do something more elaborate here.
+ return from_ascii("edit");
+}
+
+
void BufferView::scrollDocView(int value)
{
int const offset = value - d->scrollbarParameters_.position;
CursorSlice & bot = d->cursor_.bottom();
TextMetrics & tm = d->text_metrics_[bot.text()];
- int const bot_pit = d->cursor_.bottom().pit();
+ pos_type const max_pit = pos_type(bot.text()->paragraphs().size() - 1);
+ int bot_pit = d->cursor_.bottom().pit();
+ if (bot_pit > max_pit) {
+ // FIXME: Why does this happen?
+ LYXERR0("bottom pit is greater that max pit: "
+ << bot_pit << " > " << max_pit);
+ bot_pit = max_pit;
+ }
+
if (bot_pit == tm.first().first - 1)
tm.newParMetricsUp();
else if (bot_pit == tm.last().first + 1)
if (d->anchor_pit_ == 0)
d->anchor_ypos_ = offset + pm.ascent();
- else if (d->anchor_pit_ >= pos_type(bot.text()->paragraphs().size() - 1)) {
- d->anchor_pit_ = bot.text()->paragraphs().size() - 1;
+ else if (d->anchor_pit_ == max_pit)
d->anchor_ypos_ = height_ - offset - row_dim.descent();
- } else {
- d->anchor_ypos_ = offset + pm.ascent() - height_ / 2;
- }
+ else
+ d->anchor_ypos_ = defaultRowHeight() * 2 - offset - row_dim.descent();
updateMetrics();
buffer_.changed();
case LFUN_SCREEN_RECENTER:
case LFUN_BIBTEX_DATABASE_ADD:
case LFUN_BIBTEX_DATABASE_DEL:
- case LFUN_WORDS_COUNT:
+ case LFUN_STATISTICS:
case LFUN_NEXT_INSET_TOGGLE:
flag.enabled(true);
break;
case LFUN_SCREEN_UP:
case LFUN_SCREEN_DOWN:
+ case LFUN_SCROLL:
flag.enabled(true);
break;
cur.clearSelection();
if (!cur.textUndo())
cur.message(_("No further undo information"));
+ else
+ processUpdateFlags(Update::Force | Update::FitCursor);
break;
case LFUN_REDO:
cur.clearSelection();
if (!cur.textRedo())
cur.message(_("No further redo information"));
+ else
+ processUpdateFlags(Update::Force | Update::FitCursor);
break;
case LFUN_FONT_STATE:
if (b == &buffer_) {
// Set the cursor
setCursor(makeDocIterator(par, 0));
+ showCursor();
} else {
// Switch to other buffer view and resend cmd
theLyXFunc().dispatch(FuncRequest(
break;
}
- case LFUN_WORDS_COUNT: {
+ case LFUN_STATISTICS: {
DocIterator from, to;
if (cur.selection()) {
from = cur.selectionBegin();
from = doc_iterator_begin(buffer_.inset());
to = doc_iterator_end(buffer_.inset());
}
- int const count = countWords(from, to);
+ int const words = countWords(from, to);
+ int const chars = countChars(from, to, false);
+ int const chars_blanks = countChars(from, to, true);
docstring message;
- if (count != 1) {
- if (cur.selection())
- message = bformat(_("%1$d words in selection."),
- count);
- else
- message = bformat(_("%1$d words in document."),
- count);
- }
- else {
- if (cur.selection())
- message = _("One word in selection.");
- else
- message = _("One word in document.");
- }
-
- Alert::information(_("Count words"), message);
+ if (cur.selection())
+ message = _("Statistics for the selection:\n");
+ else
+ message = _("Statistics for the document:\n");
+ if (words != 1)
+ message += bformat(_("\n%1$d words"), words);
+ else
+ message += _("\nOne word");
+ if (chars_blanks != 1)
+ message += bformat(_("\n%1$d characters (including blanks)"),
+ chars_blanks);
+ else
+ message += _("\nOne character (including blanks)");
+ if (chars != 1)
+ message += bformat(_("\n%1$d characters (excluding blanks)"),
+ chars);
+ else
+ message += _("\nOne character (excluding blanks)");
+
+ Alert::information(_("Statistics"), message);
}
break;
buffer_.params().compressed = !buffer_.params().compressed;
break;
- case LFUN_BUFFER_TOGGLE_EMBEDDING:
+ case LFUN_BUFFER_TOGGLE_EMBEDDING: {
// turn embedding on/off
- buffer_.embeddedFiles().enable(!buffer_.params().embedded);
+ try {
+ buffer_.embeddedFiles().enable(!buffer_.params().embedded);
+ } catch (ExceptionMessage const & message) {
+ Alert::error(message.title_, message.details_);
+ }
break;
+ }
case LFUN_NEXT_INSET_TOGGLE: {
// this is the real function we want to invoke
if (!cur.result().dispatched())
cur.dispatch(tmpcmd);
- if (cur.result().dispatched())
- cur.clearSelection();
-
+ if (!cur.result().dispatched())
+ // It did not work too; no action needed.
+ break;
+ cur.clearSelection();
+ processUpdateFlags(Update::SinglePar | Update::FitCursor);
break;
}
break;
}
+ case LFUN_SCROLL:
+ lfunScroll(cmd);
+ break;
+
case LFUN_SCREEN_UP_SELECT:
case LFUN_SCREEN_DOWN_SELECT: {
// Those two are not ready yet for consumption.
}
-Inset const * BufferView::getCoveringInset(Text const & text, int x, int y)
+Inset const * BufferView::getCoveringInset(Text const & text,
+ int x, int y) const
{
TextMetrics & tm = d->text_metrics_[&text];
Inset * inset = tm.checkInsetHit(x, y);
}
+void BufferView::lfunScroll(FuncRequest const & cmd)
+{
+ string const scroll_type = cmd.getArg(0);
+ int const scroll_step =
+ (scroll_type == "line")? d->scrollbarParameters_.lineScrollHeight
+ : (scroll_type == "page")? height_ : 0;
+ if (scroll_step == 0)
+ return;
+ string const scroll_quantity = cmd.getArg(1);
+ if (scroll_quantity == "up")
+ scrollUp(scroll_step);
+ else if (scroll_quantity == "down")
+ scrollDown(scroll_step);
+ else {
+ int const scroll_value = convert<int>(scroll_quantity);
+ if (scroll_value)
+ scroll(scroll_step * scroll_value);
+ }
+}
+
+
void BufferView::scroll(int y)
{
if (y > 0)
it->getLabelList(buffer_, labels);
if (find(labels.begin(), labels.end(), label) != labels.end()) {
setCursor(it);
- processUpdateFlags(Update::FitCursor);
+ showCursor();
return;
}
}
if (!changed)
return false;
+ d->cursor_ = cur;
+
updateLabels(buffer_);
updateMetrics();
int y1 = d->anchor_ypos_ - anchor_pm.ascent();
// We are now just above the anchor paragraph.
pit_type pit1 = d->anchor_pit_ - 1;
- for (; pit1 >= 0 && y1 > 0; --pit1) {
+ for (; pit1 >= 0 && y1 >= 0; --pit1) {
tm.redoParagraph(pit1);
ParagraphMetrics & pm = tm.par_metrics_[pit1];
y1 -= pm.descent();
int y2 = d->anchor_ypos_ + anchor_pm.descent();
// We are now just below the anchor paragraph.
pit_type pit2 = d->anchor_pit_ + 1;
- for (; pit2 < npit && y2 < height_; ++pit2) {
+ for (; pit2 < npit && y2 <= height_; ++pit2) {
tm.redoParagraph(pit2);
ParagraphMetrics & pm = tm.par_metrics_[pit2];
y2 += pm.ascent();