painter.setPen(color_);
if (l_shape_) {
if (rtl_)
- painter.drawLine(x_, bot, x_ - l, bot);
+ painter.drawLine(x_, bot, x_ - l + 1, bot);
else
- painter.drawLine(x_, bot, x_ + caret_width_ + r, bot);
+ painter.drawLine(x_, bot, x_ + caret_width_ + r - 1, bot);
}
// draw completion triangle
return;
updateCaretGeometry();
- p->viewport()->update(caret_->rect());
+ p->viewport()->update();
}
caret_visible_ = false;
//if (!qApp->focusWidget())
- p->viewport()->update(caret_->rect());
+ p->viewport()->update();
}
// the signal valueChanged. (#10311)
QObject::disconnect(p->verticalScrollBar(), SIGNAL(valueChanged(int)),
p, SLOT(scrollTo(int)));
- ScrollbarParameters const & scroll_ = buffer_view_->scrollbarParameters();
- p->verticalScrollBar()->setRange(scroll_.min, scroll_.max);
- p->verticalScrollBar()->setPageStep(scroll_.page_step);
- p->verticalScrollBar()->setSingleStep(scroll_.single_step);
+ ScrollbarParameters const & scroll = buffer_view_->scrollbarParameters();
+ p->verticalScrollBar()->setRange(scroll.min, scroll.max);
+ p->verticalScrollBar()->setPageStep(scroll.page_step);
+ p->verticalScrollBar()->setSingleStep(scroll.single_step);
p->verticalScrollBar()->setSliderPosition(0);
// Connect to the vertical scroll bar
QObject::connect(p->verticalScrollBar(), SIGNAL(valueChanged(int)),
{
// Wheel rotation by one notch results in a delta() of 120 (see
// documentation of QWheelEvent)
+ // But first we have to ignore horizontal scroll events.
+#if QT_VERSION < 0x050000
+ if (ev->orientation() == Qt::Horizontal) {
+ ev->accept();
+ return;
+ }
double const delta = ev->delta() / 120.0;
+#else
+ QPoint const aDelta = ev->angleDelta();
+ // skip horizontal wheel event
+ if (abs(aDelta.x()) > abs(aDelta.y())) {
+ ev->accept();
+ return;
+ }
+ double const delta = aDelta.y() / 120.0;
+#endif
+
bool zoom = false;
switch (lyxrc.scroll_wheel_zoom) {
case LyXRC::SCROLL_WHEEL_ZOOM_CTRL:
void GuiWorkArea::paintEvent(QPaintEvent * ev)
{
+ // Do not trigger the painting machinery if we are not ready (see
+ // bug #10989). The second test triggers when in the middle of a
+ // dispatch operation.
+ if (view().busy() || d->buffer_view_->buffer().undo().activeUndoGroup()) {
+ // Since macOS has turned the screen black at this point, our
+ // backing store has to be copied to screen (this is a no-op
+ // except on macOS).
+ d->updateScreen(ev->rect());
+ // Ignore this paint event, but request a new one for later.
+ viewport()->update(ev->rect());
+ ev->accept();
+ return;
+ }
+
// LYXERR(Debug::PAINTING, "paintEvent begin: x: " << rc.x()
// << " y: " << rc.y() << " w: " << rc.width() << " h: " << rc.height());
// insert the processed text in the document (handles undo)
if (!e->commitString().isEmpty()) {
- d->buffer_view_->cursor().beginUndoGroup();
- d->buffer_view_->cursor().insert(qstring_to_ucs4(e->commitString()));
+ FuncRequest cmd(LFUN_SELF_INSERT,
+ qstring_to_ucs4(e->commitString()),
+ FuncRequest::KEYBOARD);
+ dispatch(cmd);
+ // FIXME: this is supposed to remove traces from preedit
+ // string. Can we avoid calling it explicitely?
d->buffer_view_->updateMetrics();
- d->buffer_view_->cursor().endUndoGroup();
- d->updateCaretGeometry();
- viewport()->update();
}
// Hide the caret during the test transformation.
this, SLOT(closeCurrentBuffer()));
setCornerWidget(closeBufferButton, Qt::TopRightCorner);
- // setup drag'n'drop
- QTabBar* tb = new DragTabBar;
- connect(tb, SIGNAL(tabMoveRequested(int, int)),
- this, SLOT(moveTab(int, int)));
+ // set TabBar behaviour
+ QTabBar * tb = tabBar();
+ tb->setTabsClosable(!lyxrc.single_close_tab_button);
+ tb->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab);
tb->setElideMode(Qt::ElideNone);
- setTabBar(tb);
-
+ // allow dragging tabs
+ tb->setMovable(true);
// make us responsible for the context menu of the tabbar
tb->setContextMenuPolicy(Qt::CustomContextMenu);
connect(tb, SIGNAL(customContextMenuRequested(const QPoint &)),
- this, SLOT(showContextMenu(const QPoint &)));
+ this, SLOT(showContextMenu(const QPoint &)));
connect(tb, SIGNAL(tabCloseRequested(int)),
- this, SLOT(closeTab(int)));
+ this, SLOT(closeTab(int)));
setUsesScrollButtons(true);
}
DisplayPath(int tab, FileName const & filename)
: tab_(tab)
{
+ // Recode URL encoded chars via fromPercentEncoding()
filename_ = (filename.extension() == "lyx") ?
- toqstr(filename.onlyFileNameWithoutExt())
- : toqstr(filename.onlyFileName());
+ QString(QByteArray::fromPercentEncoding(
+ toqstr(filename.onlyFileNameWithoutExt()).toUtf8()))
+ : QString(QByteArray::fromPercentEncoding(
+ toqstr(filename.onlyFileName()).toUtf8()));
postfix_ = toqstr(filename.absoluteFilePath()).
split("/", QString::SkipEmptyParts);
postfix_.pop_back();
void TabWorkArea::showContextMenu(const QPoint & pos)
{
// which tab?
- clicked_tab_ = static_cast<DragTabBar *>(tabBar())->tabAt(pos);
+ clicked_tab_ = tabBar()->tabAt(pos);
if (clicked_tab_ == -1)
return;
+ GuiWorkArea * wa = workArea(clicked_tab_);
+ LASSERT(wa, return);
+
// show tab popup
QMenu popup;
popup.addAction(QIcon(getPixmap("images/", "hidetab", "svgz,png")),
qt_("Hide tab"), this, SLOT(hideCurrentTab()));
- popup.addAction(QIcon(getPixmap("images/", "closetab", "svgz,png")),
- qt_("Close tab"), this, SLOT(closeCurrentBuffer()));
+
+ // we want to show the 'close' option only if this is not a child buffer.
+ Buffer const & buf = wa->bufferView().buffer();
+ if (!buf.parent())
+ popup.addAction(QIcon(getPixmap("images/", "closetab", "svgz,png")),
+ qt_("Close tab"), this, SLOT(closeCurrentBuffer()));
popup.exec(tabBar()->mapToGlobal(pos));
clicked_tab_ = -1;
}
-DragTabBar::DragTabBar(QWidget* parent)
- : QTabBar(parent)
-{
- setAcceptDrops(true);
- setTabsClosable(!lyxrc.single_close_tab_button);
-}
-
-
-void DragTabBar::mousePressEvent(QMouseEvent * event)
-{
- if (event->button() == Qt::LeftButton)
- dragStartPos_ = event->pos();
- QTabBar::mousePressEvent(event);
-}
-
-
-void DragTabBar::mouseMoveEvent(QMouseEvent * event)
-{
- // If the left button isn't pressed anymore then return
- if (!(event->buttons() & Qt::LeftButton))
- return;
-
- // If the distance is too small then return
- if ((event->pos() - dragStartPos_).manhattanLength()
- < QApplication::startDragDistance())
- return;
-
- // did we hit something after all?
- int tab = tabAt(dragStartPos_);
- if (tab == -1)
- return;
-
- // simulate button release to remove highlight from button
- int i = currentIndex();
- QMouseEvent me(QEvent::MouseButtonRelease, dragStartPos_,
- event->button(), event->buttons(), 0);
- QTabBar::mouseReleaseEvent(&me);
- setCurrentIndex(i);
-
- // initiate Drag
- QDrag * drag = new QDrag(this);
- QMimeData * mimeData = new QMimeData;
- // a crude way to distinguish tab-reodering drops from other ones
- mimeData->setData("action", "tab-reordering") ;
- drag->setMimeData(mimeData);
-
- // get tab pixmap as cursor
- QRect r = tabRect(tab);
- QPixmap pixmap(r.size());
- render(&pixmap, - r.topLeft());
- drag->setPixmap(pixmap);
- drag->exec();
-}
-
-
-void DragTabBar::dragEnterEvent(QDragEnterEvent * event)
-{
- // Only accept if it's an tab-reordering request
- QMimeData const * m = event->mimeData();
- QStringList formats = m->formats();
- if (formats.contains("action")
- && m->data("action") == "tab-reordering")
- event->acceptProposedAction();
-}
-
-
-void DragTabBar::dropEvent(QDropEvent * event)
-{
- int fromIndex = tabAt(dragStartPos_);
- int toIndex = tabAt(event->pos());
-
- // Tell interested objects that
- if (fromIndex != toIndex)
- tabMoveRequested(fromIndex, toIndex);
- event->acceptProposedAction();
-}
-
-
GuiWorkAreaContainer::GuiWorkAreaContainer(GuiWorkArea * wa, QWidget * parent)
: QWidget(parent), wa_(wa)
{