#include "VSpace.h"
#include "WordLangTuple.h"
-
#include "insets/InsetBibtex.h"
#include "insets/InsetCommand.h" // ChangeRefs
#include "insets/InsetRef.h"
#include "graphics/Previews.h"
#include "support/convert.h"
+#include "support/lstrings.h"
#include "support/FileFilterList.h"
#include "support/filetools.h"
#include "support/Package.h"
/// A map from a Text to the associated text metrics
typedef std::map<Text const *, TextMetrics> TextMetricsCache;
+enum ScreenUpdateStrategy {
+ NoScreenUpdate,
+ SingleParUpdate,
+ FullScreenUpdate,
+ DecorationUpdate
+};
+
} // anon namespace
///
ScrollbarParameters scrollbarParameters_;
///
- ViewMetricsInfo metrics_info_;
+ ScreenUpdateStrategy update_strategy_;
///
CoordCache coord_cache_;
// causes screen update(), I reset last_inset_ to avoid such a problem.
d->last_inset_ = 0;
// This is close to a hot-path.
- LYXERR(Debug::DEBUG)
- << BOOST_CURRENT_FUNCTION
+ LYXERR(Debug::DEBUG, "BufferView::processUpdateFlags()"
<< "[fitcursor = " << (flags & Update::FitCursor)
<< ", forceupdate = " << (flags & Update::Force)
<< ", singlepar = " << (flags & Update::SinglePar)
- << "] buffer: " << &buffer_ << endl;
+ << "] buffer: " << &buffer_);
// Update macro store
if (!(cursor().inMathed() && cursor().inMacroMode()))
// Case when no explicit update is requested.
if (!flags) {
// no need to redraw anything.
- d->metrics_info_.update_strategy = NoScreenUpdate;
+ d->update_strategy_ = NoScreenUpdate;
return;
}
if (flags == Update::Decoration) {
- d->metrics_info_.update_strategy = DecorationUpdate;
+ d->update_strategy_ = DecorationUpdate;
buffer_.changed();
return;
}
return;
}
if (flags & Update::Decoration) {
- d->metrics_info_.update_strategy = DecorationUpdate;
+ d->update_strategy_ = DecorationUpdate;
buffer_.changed();
return;
}
// no screen update is needed.
- d->metrics_info_.update_strategy = NoScreenUpdate;
+ d->update_strategy_ = NoScreenUpdate;
return;
}
d->offset_ref_ = 0;
}
- LYXERR(Debug::GUI)
- << BOOST_CURRENT_FUNCTION
+ LYXERR(Debug::GUI, BOOST_CURRENT_FUNCTION
<< " Updating scrollbar: height: " << t.paragraphs().size()
<< " curr par: " << d->cursor_.bottom().pit()
- << " default height " << defaultRowHeight() << endl;
+ << " default height " << defaultRowHeight());
// It would be better to fix the scrollbar to understand
// values in [0..1] and divide everything by wh
void BufferView::scrollDocView(int value)
{
- LYXERR(Debug::GUI) << BOOST_CURRENT_FUNCTION
- << "[ value = " << value << "]" << endl;
+ LYXERR(Debug::GUI, BOOST_CURRENT_FUNCTION << "[ value = " << value << "]");
Text & t = buffer_.text();
TextMetrics & tm = d->text_metrics_[&t];
setCursor(doc_it);
// set the current font.
d->cursor_.setCurrentFont();
- // center the screen on this new position.
- center();
+ // To center the screen on this new position we need the
+ // paragraph position which is computed at draw() time.
+ // So we need a redraw!
+ buffer_.changed();
+ if (fitCursor())
+ // We need another redraw because of the screen recentering.
+ buffer_.changed();
}
return success;
// << [ cmd = " << cmd << "]" << endl;
// Make sure that the cached BufferView is correct.
- LYXERR(Debug::ACTION) << BOOST_CURRENT_FUNCTION
+ LYXERR(Debug::ACTION, BOOST_CURRENT_FUNCTION
<< " action[" << cmd.action << ']'
<< " arg[" << to_utf8(cmd.argument()) << ']'
<< " x[" << cmd.x << ']'
<< " y[" << cmd.y << ']'
- << " button[" << cmd.button() << ']'
- << endl;
+ << " button[" << cmd.button() << ']');
Cursor & cur = d->cursor_;
// Default Update flags.
ParIterator par = b->getParFromID(id);
if (par == b->par_iterator_end()) {
- LYXERR(Debug::INFO)
- << "No matching paragraph found! ["
- << id << "]." << endl;
+ LYXERR(Debug::INFO, "No matching paragraph found! [" << id << "].");
} else {
- LYXERR(Debug::INFO)
- << "Paragraph " << par->id()
+ LYXERR(Debug::INFO, "Paragraph " << par->id()
<< " found in buffer `"
- << b->absFileName() << "'." << endl;
+ << b->absFileName() << "'.");
if (b == &buffer_) {
// Set the cursor
//FIXME: updateMetrics() does not update paragraph position
// This is done at draw() time. So we need a redraw!
// But no screen update is needed.
- d->metrics_info_.update_strategy = NoScreenUpdate;
+ d->update_strategy_ = NoScreenUpdate;
buffer_.changed();
p = getPos(cur, cur.boundary());
}
}
// FIXME: we need to do a redraw again because of the selection
// But no screen update is needed.
- d->metrics_info_.update_strategy = NoScreenUpdate;
+ d->update_strategy_ = NoScreenUpdate;
buffer_.changed();
updateFlags = Update::Force | Update::FitCursor;
break;
if (!need_redraw)
return;
- // if last metrics update was in singlepar mode, WorkArea::redraw() will
- // not expose the button for redraw. We adjust here the metrics dimension
- // to enable a full redraw in any case as this is not costly.
- TextMetrics & tm = d->text_metrics_[&buffer_.text()];
- std::pair<pit_type, ParagraphMetrics const *> firstpm = tm.first();
- std::pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
- int y1 = firstpm.second->position() - firstpm.second->ascent();
- int y2 = lastpm.second->position() + lastpm.second->descent();
- d->metrics_info_ = ViewMetricsInfo(firstpm.first, lastpm.first, y1, y2,
- FullScreenUpdate, buffer_.text().paragraphs().size());
- // Reinitialize anchor to first pit.
- d->anchor_ref_ = firstpm.first;
- d->offset_ref_ = -y1;
- LYXERR(Debug::PAINTING)
- << "Mouse hover detected at: (" << cmd.x << ", " << cmd.y << ")"
- << "\nTriggering redraw: y1: " << y1 << " y2: " << y2
- << " pit1: " << firstpm.first << " pit2: " << lastpm.first << endl;
+ LYXERR(Debug::PAINTING, "Mouse hover detected at: ("
+ << cmd.x << ", " << cmd.y << ")");
+
+ d->update_strategy_ = DecorationUpdate;
// This event (moving without mouse click) is not passed further.
// This should be changed if it is further utilized.
}
-ViewMetricsInfo const & BufferView::viewMetricsInfo()
-{
- return d->metrics_info_;
-}
-
-
bool BufferView::singleParUpdate()
{
Text & buftext = buffer_.text();
// the singlePar optimisation.
return false;
- int y1 = pm.position() - pm.ascent();
- int y2 = pm.position() + pm.descent();
- d->metrics_info_ = ViewMetricsInfo(bottom_pit, bottom_pit, y1, y2,
- SingleParUpdate, buftext.paragraphs().size());
- LYXERR(Debug::PAINTING)
- << BOOST_CURRENT_FUNCTION
- << "\ny1: " << y1
- << " y2: " << y2
+ d->update_strategy_ = SingleParUpdate;
+
+ LYXERR(Debug::PAINTING, BOOST_CURRENT_FUNCTION
+ << "\ny1: " << pm.position() - pm.ascent()
+ << " y2: " << pm.position() + pm.descent()
<< " pit: " << bottom_pit
- << " singlepar: 1"
- << endl;
+ << " singlepar: 1");
return true;
}
// Take care of descent of last line
y2 += tm.parMetrics(pit2).descent();
- LYXERR(Debug::PAINTING)
- << BOOST_CURRENT_FUNCTION
+ LYXERR(Debug::PAINTING, BOOST_CURRENT_FUNCTION
<< "\n y1: " << y1
<< " y2: " << y2
<< " pit1: " << pit1
<< " pit2: " << pit2
<< " npit: " << npit
- << " singlepar: 0"
- << endl;
+ << " singlepar: 0");
- d->metrics_info_ = ViewMetricsInfo(pit1, pit2, y1, y2,
- FullScreenUpdate, npit);
+ d->update_strategy_ = FullScreenUpdate;
if (lyxerr.debugging(Debug::WORKAREA)) {
- LYXERR(Debug::WORKAREA) << "BufferView::updateMetrics" << endl;
+ LYXERR(Debug::WORKAREA, "BufferView::updateMetrics");
d->coord_cache_.dump();
}
}
void BufferView::draw(frontend::Painter & pain)
{
- LYXERR(Debug::PAINTING) << "\t\t*** START DRAWING ***" << endl;
+ LYXERR(Debug::PAINTING, "\t\t*** START DRAWING ***");
Text & text = buffer_.text();
TextMetrics const & tm = d->text_metrics_[&text];
- int const y = d->metrics_info_.y1
- + tm.parMetrics(d->metrics_info_.p1).ascent();
+ int const y = - d->offset_ref_ + tm.parMetrics(d->anchor_ref_).ascent();
PainterInfo pi(this, pain);
- switch (d->metrics_info_.update_strategy) {
+ switch (d->update_strategy_) {
case NoScreenUpdate:
// If no screen painting is actually needed, only some the different
break;
case SingleParUpdate:
- // Only the current outermost paragraph will be redrawn.
pi.full_repaint = false;
- tm.drawParagraph(pi, d->metrics_info_.p1, 0, y);
+ // In general, only the current row of the outermost paragraph
+ // will be redrawn. Particular cases where selection spans
+ // multiple paragraph are correctly detected in TextMetrics.
+ tm.draw(pi, 0, y);
break;
case DecorationUpdate:
// The whole screen, including insets, will be refreshed.
pi.full_repaint = true;
- // Clear background (if not delegated to rows)
- pain.fillRectangle(0, d->metrics_info_.y1, width_,
- d->metrics_info_.y2 - d->metrics_info_.y1,
+ // Clear background.
+ pain.fillRectangle(0, 0, width_, height_,
buffer_.inset().backgroundColor());
tm.draw(pi, 0, y);
- // and grey out above (should not happen later)
- if (d->metrics_info_.y1 > 0)
- pain.fillRectangle(0, 0, width_,
- d->metrics_info_.y1, Color_bottomarea);
-
// and possibly grey out below
- if (d->metrics_info_.y2 < height_)
- pain.fillRectangle(0, d->metrics_info_.y2, width_,
- height_ - d->metrics_info_.y2, Color_bottomarea);
+ std::pair<pit_type, ParagraphMetrics const *> lastpm = tm.last();
+ int const y2 = lastpm.second->position() + lastpm.second->descent();
+ if (y2 < height_)
+ pain.fillRectangle(0, y2, width_, height_ - y2, Color_bottomarea);
break;
}
- LYXERR(Debug::PAINTING) << "\n\t\t*** END DRAWING ***" << endl;
+ LYXERR(Debug::PAINTING, "\n\t\t*** END DRAWING ***");
}
void BufferView::showDialog(std::string const & name)
{
if (d->gui_)
- d->gui_->showDialog(name);
-}
-
-
-void BufferView::showDialogWithData(std::string const & name,
- std::string const & data)
-{
- if (d->gui_)
- d->gui_->showDialogWithData(name, data);
+ d->gui_->showDialog(name, string());
}
-void BufferView::showInsetDialog(std::string const & name,
+void BufferView::showDialog(std::string const & name,
std::string const & data, Inset * inset)
{
if (d->gui_)
- d->gui_->showInsetDialog(name, data, inset);
+ d->gui_->showDialog(name, data, inset);
}