]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt/GuiWorkArea.cpp
Avoid deprecation warnings
[features.git] / src / frontends / qt / GuiWorkArea.cpp
index f323fbc3d971905a2c6c5c34c687e7b6e1ecec64..02e03aaaeb780565d741ffd284345b3c09a852e9 100644 (file)
@@ -15,7 +15,6 @@
 #include "GuiWorkArea_Private.h"
 
 #include "ColorCache.h"
-#include "FontLoader.h"
 #include "GuiApplication.h"
 #include "GuiCompleter.h"
 #include "GuiKeySymbol.h"
@@ -33,7 +32,6 @@
 #include "Font.h"
 #include "FuncRequest.h"
 #include "KeySymbol.h"
-#include "Language.h"
 #include "LyX.h"
 #include "LyXRC.h"
 #include "LyXVC.h"
 #include "Undo.h"
 #include "version.h"
 
-#include "graphics/GraphicsImage.h"
-#include "graphics/GraphicsLoader.h"
-
 #include "support/convert.h"
 #include "support/debug.h"
 #include "support/lassert.h"
 #include "support/TempFile.h"
 
 #include "frontends/Application.h"
+#include "frontends/CaretGeometry.h"
+
 #include "frontends/FontMetrics.h"
 #include "frontends/WorkAreaManager.h"
 
@@ -79,8 +76,6 @@
 #include <cmath>
 #include <iostream>
 
-int const TabIndicatorWidth = 3;
-
 #undef KeyPress
 #undef NoModifier
 
@@ -98,7 +93,7 @@ static mouse_button::state q_button_state(Qt::MouseButton button)
                case Qt::LeftButton:
                        b = mouse_button::button1;
                        break;
-               case Qt::MidButton:
+               case Qt::MiddleButton:
                        b = mouse_button::button2;
                        break;
                case Qt::RightButton:
@@ -117,7 +112,7 @@ mouse_button::state q_motion_state(Qt::MouseButtons state)
        mouse_button::state b = mouse_button::none;
        if (state & Qt::LeftButton)
                b |= mouse_button::button1;
-       if (state & Qt::MidButton)
+       if (state & Qt::MiddleButton)
                b |= mouse_button::button2;
        if (state & Qt::RightButton)
                b |= mouse_button::button3;
@@ -127,110 +122,6 @@ mouse_button::state q_motion_state(Qt::MouseButtons state)
 
 namespace frontend {
 
-class CaretWidget {
-public:
-       CaretWidget() : rtl_(false), l_shape_(false), completable_(false),
-               x_(0), caret_width_(0)
-       {}
-
-       /* Draw the caret. Parameter \c horiz_offset is not 0 when there
-        * has been horizontal scrolling in current row
-        */
-       void draw(QPainter & painter, int horiz_offset)
-       {
-               if (!rect_.isValid())
-                       return;
-
-               int const x = x_ - horiz_offset;
-               int const y = rect_.top();
-               int const l = x_ - rect_.left();
-               int const r = rect_.right() - x_;
-               int const bot = rect_.bottom();
-
-               // draw vertical line
-               painter.fillRect(x, y, caret_width_, rect_.height(), color_);
-
-               // draw RTL/LTR indication
-               painter.setPen(color_);
-               if (l_shape_) {
-                       if (rtl_)
-                               painter.drawLine(x, bot, x - l + 1, bot);
-                       else
-                               painter.drawLine(x, bot, x + caret_width_ + r - 1, bot);
-               }
-
-               // draw completion triangle
-               if (completable_) {
-                       int m = y + rect_.height() / 2;
-                       int d = TabIndicatorWidth - 1;
-                       if (rtl_) {
-                               painter.drawLine(x - 1, m - d, x - 1 - d, m);
-                               painter.drawLine(x - 1, m + d, x - 1 - d, m);
-                       } else {
-                               painter.drawLine(x + caret_width_, m - d, x + caret_width_ + d, m);
-                               painter.drawLine(x + caret_width_, m + d, x + caret_width_ + d, m);
-                       }
-               }
-       }
-
-       void update(int x, int y, int h, bool l_shape,
-               bool rtl, bool completable)
-       {
-               color_ = guiApp->colorCache().get(Color_cursor);
-               l_shape_ = l_shape;
-               rtl_ = rtl;
-               completable_ = completable;
-               x_ = x;
-
-               // extension to left and right
-               int l = 0;
-               int r = 0;
-
-               // RTL/LTR indication
-               if (l_shape_) {
-                       if (rtl)
-                               l += h / 3;
-                       else
-                               r += h / 3;
-               }
-
-               // completion triangle
-               if (completable_) {
-                       if (rtl)
-                               l = max(l, TabIndicatorWidth);
-                       else
-                               r = max(r, TabIndicatorWidth);
-               }
-
-               //FIXME: LyXRC::cursor_width should be caret_width
-               caret_width_ = lyxrc.cursor_width
-                       ? lyxrc.cursor_width
-                       : 1 + int((lyxrc.currentZoom + 50) / 200.0);
-
-               // compute overall rectangle
-               rect_ = QRect(x - l, y, caret_width_ + r + l, h);
-       }
-
-       QRect const & rect() { return rect_; }
-
-private:
-       /// caret is in RTL or LTR text
-       bool rtl_;
-       /// indication for RTL or LTR
-       bool l_shape_;
-       /// triangle to show that a completion is available
-       bool completable_;
-       ///
-       QColor color_;
-       /// rectangle, possibly with l_shape and completion triangle
-       QRect rect_;
-       /// x position (were the vertical line is drawn)
-       int x_;
-       /// the width of the vertical blinking bar
-       int caret_width_;
-};
-
-
 // This is a 'heartbeat' generating synthetic mouse move events when the
 // cursor is at the top or bottom edge of the viewport. One scroll per 0.2 s
 SyntheticMouseEvent::SyntheticMouseEvent()
@@ -239,26 +130,15 @@ SyntheticMouseEvent::SyntheticMouseEvent()
 
 
 GuiWorkArea::Private::Private(GuiWorkArea * parent)
-: p(parent), buffer_view_(nullptr), lyx_view_(nullptr), caret_(nullptr),
-  caret_visible_(false), need_resize_(false), preedit_lines_(1),
-  last_pixel_ratio_(1.0), completer_(new GuiCompleter(p, p)),
-  dialog_mode_(false), shell_escape_(false), read_only_(false),
-  clean_(true), externally_modified_(false), needs_caret_geometry_update_(true)
-{
-/* Qt on macOS and Wayland does not respect the
- * Qt::WA_OpaquePaintEvent attribute and resets the widget backing
- * store at each update. Therefore, we use our own backing store in
- * these two cases. */
-#if QT_VERSION >= 0x050000
+       : p(parent), completer_(new GuiCompleter(p, p))
+{
+       /* Qt on macOS and Wayland does not respect the
+        * Qt::WA_OpaquePaintEvent attribute and resets the widget backing
+        * store at each update. Therefore, we use our own backing store
+        * in these two cases.
+        */
        use_backingstore_ = guiApp->platformName() == "cocoa"
                || guiApp->platformName().contains("wayland");
-#else
-#  ifdef Q_OS_MAC
-       use_backingstore_ = true;
-#  else
-       use_backingstore_ = false;
-#  endif
-#endif
 
        int const time = QApplication::cursorFlashTime() / 2;
        if (time > 0) {
@@ -278,7 +158,6 @@ GuiWorkArea::Private::~Private()
                buffer_view_->buffer().workAreaManager().remove(p);
        } catch(...) {}
        delete buffer_view_;
-       delete caret_;
        // Completer has a QObject parent and is thus automatically destroyed.
        // See #4758.
        // delete completer_;
@@ -328,7 +207,6 @@ void GuiWorkArea::init()
        // With Qt4.5 a mouse event will happen before the first paint event
        // so make sure that the buffer view has an up to date metrics.
        d->buffer_view_->resize(viewport()->width(), viewport()->height());
-       d->caret_ = new frontend::CaretWidget();
 
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setAcceptDrops(true);
@@ -611,6 +489,15 @@ void GuiWorkArea::Private::resetCaret()
        if (!buffer_view_->caretInView())
                return;
 
+       // completion indicator
+       Cursor const & cur = buffer_view_->cursor();
+       bool const completable = cur.inset().showCompletionCursor()
+               && completer_->completionAvailable()
+               && !completer_->popupVisible()
+               && !completer_->inlineVisible();
+
+       buffer_view_->buildCaretGeometry(completable);
+
        needs_caret_geometry_update_ = true;
        caret_visible_ = true;
 }
@@ -624,37 +511,11 @@ void GuiWorkArea::Private::updateCaretGeometry()
            || !buffer_view_->caretInView())
                return;
 
-       Point point;
-       int h = 0;
-       buffer_view_->caretPosAndHeight(point, h);
-
-       // RTL or not RTL
-       bool l_shape = false;
-       Font const & realfont = buffer_view_->cursor().real_current_font;
-       BufferParams const & bp = buffer_view_->buffer().params();
-       bool const samelang = realfont.language() == bp.language;
-       bool const isrtl = realfont.isVisibleRightToLeft();
-
-       if (!samelang || isrtl != bp.language->rightToLeft())
-               l_shape = true;
-
-       // The ERT language hack needs fixing up
-       if (realfont.language() == latex_language)
-               l_shape = false;
-
-       // show caret on screen
-       Cursor & cur = buffer_view_->cursor();
-       bool completable = cur.inset().showCompletionCursor()
-               && completer_->completionAvailable()
-               && !completer_->popupVisible()
-               && !completer_->inlineVisible();
 
-       caret_->update(point.x_, point.y_, h, l_shape, isrtl, completable);
        needs_caret_geometry_update_ = false;
 }
 
 
-
 void GuiWorkArea::Private::showCaret()
 {
        if (caret_visible_)
@@ -676,6 +537,33 @@ void GuiWorkArea::Private::hideCaret()
 }
 
 
+/* Draw the caret. Parameter \c horiz_offset is not 0 when there
+ * has been horizontal scrolling in current row
+ */
+void GuiWorkArea::Private::drawCaret(QPainter & painter, int horiz_offset) const
+{
+       if (buffer_view_->caretGeometry().shapes.empty())
+               return;
+
+       QColor const color = guiApp->colorCache().get(Color_cursor);
+       painter.setPen(color);
+       painter.setRenderHint(QPainter::Antialiasing, true);
+       for (auto const & shape : buffer_view_->caretGeometry().shapes) {
+               bool first = true;
+               QPainterPath path;
+               for (Point const & p : shape) {
+                       if (first) {
+                               path.moveTo(p.x_ - horiz_offset, p.y_);
+                               first = false;
+                       } else
+                               path.lineTo(p.x_ - horiz_offset, p.y_);
+               }
+               painter.fillPath(path, color);
+       }
+       painter.setRenderHint(QPainter::Antialiasing, false);
+}
+
+
 void GuiWorkArea::Private::updateScrollbar()
 {
        // Prevent setRange() and setSliderPosition from causing recursive calls via
@@ -1088,7 +976,6 @@ void GuiWorkArea::generateSyntheticMouseEvent()
        cur.boundary(bound);
 
        d->buffer_view_->buffer().changed(false);
-       return;
 }
 
 
@@ -1224,9 +1111,11 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
        // FIXME: shall we use real_current_font here? (see #10478)
        FontInfo const font = buffer_view_->cursor().getFont().fontInfo();
        FontMetrics const & fm = theFontMetrics(font);
-       int const height = fm.maxHeight();
-       int cur_x = caret_->rect().left();
-       int cur_y = caret_->rect().bottom();
+       Point point;
+       Dimension dim;
+       buffer_view_->caretPosAndDim(point, dim);
+       int cur_x = point.x_;
+       int cur_y = point.y_ + dim.height();
 
        // get attributes of input method cursor.
        // cursor_pos : cursor position in preedit string.
@@ -1279,7 +1168,7 @@ void GuiWorkArea::Private::paintPreeditText(GuiPainter & pain)
                // if we reached the right extremity of the screen, go to next line.
                if (cur_x + fm.width(typed_char) > p->viewport()->width() - right_margin) {
                        cur_x = right_margin;
-                       cur_y += height + 1;
+                       cur_y += dim.height() + 1;
                        ++preedit_lines_;
                }
                // preedit strings are displayed with dashed underline
@@ -1377,7 +1266,7 @@ void GuiWorkArea::paintEvent(QPaintEvent * ev)
        if (d->caret_visible_) {
                if (d->needs_caret_geometry_update_)
                        d->updateCaretGeometry();
-               d->caret_->draw(pain, d->buffer_view_->horizScrollOffset());
+               d->drawCaret(pain, d->buffer_view_->horizScrollOffset());
        }
 
        d->updateScreen(ev->rect());
@@ -1420,10 +1309,11 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
 
 
        // redraw area of preedit string.
-       int height = d->caret_->rect().height();
-       int cur_y = d->caret_->rect().bottom();
-       viewport()->update(0, cur_y - height, viewport()->width(),
-               (height + 1) * d->preedit_lines_);
+       // int height = d->caret_->dim.height();
+       // int cur_y = d->caret_->y;
+       // viewport()->update(0, cur_y, viewport()->width(),
+       //      (height + 1) * d->preedit_lines_);
+       viewport()->update();
 
        if (d->preedit_string_.empty()) {
                d->preedit_lines_ = 1;
@@ -1438,20 +1328,21 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
 
 QVariant GuiWorkArea::inputMethodQuery(Qt::InputMethodQuery query) const
 {
-       QRect cur_r(0, 0, 0, 0);
        switch (query) {
                // this is the CJK-specific composition window position and
                // the context menu position when the menu key is pressed.
-               case Qt::ImMicroFocus:
-                       cur_r = d->caret_->rect();
-                       if (d->preedit_lines_ != 1)
-                               cur_r.moveLeft(10);
-                       cur_r.moveBottom(cur_r.bottom()
-                               + cur_r.height() * (d->preedit_lines_ - 1));
-                       // return lower right of caret in LyX.
-                       return cur_r;
-               default:
-                       return QWidget::inputMethodQuery(query);
+#if (QT_VERSION < 0x050000)
+       case Qt::ImMicroFocus: {
+#else
+       case Qt::ImCursorRectangle: {
+#endif
+               CaretGeometry const & cg = bufferView().caretGeometry();
+               return QRect(cg.left - 10 * (d->preedit_lines_ != 1),
+                            cg.top + cg.height() * d->preedit_lines_,
+                            cg.width(), cg.height());
+       }
+       default:
+               return QWidget::inputMethodQuery(query);
        }
 }
 
@@ -1658,7 +1549,7 @@ TabWorkArea::TabWorkArea(QWidget * parent)
 
 void TabWorkArea::mousePressEvent(QMouseEvent *me)
 {
-       if (me->button() == Qt::MidButton)
+       if (me->button() == Qt::MiddleButton)
                midpressed_tab_ = tabBar()->tabAt(me->pos());
        else
                QTabWidget::mousePressEvent(me);
@@ -1667,7 +1558,7 @@ void TabWorkArea::mousePressEvent(QMouseEvent *me)
 
 void TabWorkArea::mouseReleaseEvent(QMouseEvent *me)
 {
-       if (me->button() == Qt::MidButton) {
+       if (me->button() == Qt::MiddleButton) {
                int const midreleased_tab = tabBar()->tabAt(me->pos());
                if (midpressed_tab_ == midreleased_tab && posIsTab(me->pos()))
                        closeTab(midreleased_tab);
@@ -2227,7 +2118,7 @@ void GuiWorkAreaContainer::updateDisplay()
 }
 
 
-void GuiWorkAreaContainer::dispatch(FuncRequest f) const
+void GuiWorkAreaContainer::dispatch(FuncRequest const & f) const
 {
        lyx::dispatch(FuncRequest(LFUN_BUFFER_SWITCH,
                                  wa_->bufferView().buffer().absFileName()));