]> git.lyx.org Git - features.git/blobdiff - src/frontends/qt/GuiWorkArea.cpp
Avoid deprecation warnings
[features.git] / src / frontends / qt / GuiWorkArea.cpp
index 0104c8dd83f667ac56d2b8b0db30aee75741a7ad..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,100 +122,6 @@ mouse_button::state q_motion_state(Qt::MouseButtons state)
 
 namespace frontend {
 
-class CaretWidget {
-public:
-       CaretWidget() : dir(1), l_shape(false), completable(false),
-                                       x(0), y(0), slope(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 (dim.empty())
-                       return;
-               // correction is (1) for horizontal scrolling and (2) for
-               // better positionning of large cursors.
-               int const xx = x - horiz_offset - dim.wid / 2;
-               int const lx = dim.height() / 3;
-
-               // draw caret box
-               painter.setPen(color);
-               QPainterPath path;
-               path.moveTo(xx + dim.asc * slope, y);
-               path.lineTo(xx - dim.des * slope, y + dim.height());
-               path.lineTo(xx + dir * dim.wid - dim.des * slope, y + dim.height());
-               path.lineTo(xx + dir * dim.wid + dim.asc * slope, y);
-               painter.setRenderHint(QPainter::Antialiasing, true);
-               painter.fillPath(path, color);
-               painter.setRenderHint(QPainter::Antialiasing, false);
-
-               // draw RTL/LTR indication
-               if (l_shape)
-                       painter.fillRect(xx - dim.des * slope,
-                                        y + dim.height() - dim.wid + 1,
-                                        dir * (dim.wid + lx - 1), dim.wid, color);
-
-               // draw completion triangle
-               if (completable) {
-                       int const m = y + dim.height() / 2;
-                       int const d = TabIndicatorWidth * dim.wid - 1;
-                       // offset for slanted carret
-                       int const sx = (dim.asc - (dim.height() / 2 - d)) * slope;
-                       painter.drawLine(xx + dir * (dim.wid + 1) + sx, m - d,
-                                        xx + dir * (dim.wid + d + 1) + sx, m);
-                       painter.drawLine(xx + dir * (dim.wid + 1) + sx, m + d,
-                                        xx + dir * (dim.wid + d + 1) + sx, m);
-               }
-       }
-
-       void update(BufferView const * bv, bool complet) {
-               // Cursor size and position
-               Point point;
-               bv->caretPosAndDim(point, dim);
-               x = point.x_;
-               y = point.y_;
-               completable = complet;
-
-               Cursor const & cur = bv->cursor();
-               Font const & realfont = cur.real_current_font;
-               FontMetrics const & fm = theFontMetrics(realfont.fontInfo());
-               BufferParams const & bp = bv->buffer().params();
-               bool const samelang = realfont.language() == bp.language;
-               bool const isrtl = realfont.isVisibleRightToLeft();
-               dir = isrtl ? -1 : 1;
-               // special shape
-               l_shape = (!samelang || isrtl != bp.language->rightToLeft())
-                       && realfont.language() != latex_language;
-
-               // use slanted caret for italics in text edit mode
-               // except for selections because the selection rect does not slant
-               bool const slant = fm.italic() && cur.inTexted() && !cur.selection();
-               slope = slant ? fm.italicSlope() : 0;
-
-               color = guiApp->colorCache().get(Color_cursor);
-       }
-
-       /// text direction (1 for LtR, -1 for RtL)
-       int dir;
-       /// indication for language change
-       bool l_shape;
-       /// triangle to show that a completion is available
-       bool completable;
-       ///
-       QColor color;
-       /// dimension uf base caret
-       Dimension dim;
-       /// x position (were the vertical line is drawn)
-       int x;
-       /// y position (the top of the caret)
-       int y;
-       /// the slope for drawing slanted caret
-       double slope;
-};
-
-
 // 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()
@@ -229,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) {
@@ -268,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_;
@@ -318,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);
@@ -608,7 +496,7 @@ void GuiWorkArea::Private::resetCaret()
                && !completer_->popupVisible()
                && !completer_->inlineVisible();
 
-       caret_->update(buffer_view_, completable);
+       buffer_view_->buildCaretGeometry(completable);
 
        needs_caret_geometry_update_ = true;
        caret_visible_ = true;
@@ -649,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
@@ -1196,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_->x;
-       int cur_y = caret_->y + height;
+       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.
@@ -1251,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
@@ -1349,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());
@@ -1392,10 +1309,11 @@ void GuiWorkArea::inputMethodEvent(QInputMethodEvent * e)
 
 
        // redraw area of preedit string.
-       int height = d->caret_->dim.height();
-       int cur_y = d->caret_->y;
-       viewport()->update(0, cur_y, 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;
@@ -1410,16 +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:
-                       return QRect(d->caret_->x - 10 * (d->preedit_lines_ != 1),
-                                                d->caret_->y + d->caret_->dim.height() * d->preedit_lines_,
-                                                d->caret_->dim.width(), d->caret_->dim.height());
-               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);
        }
 }
 
@@ -1626,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);
@@ -1635,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);
@@ -2195,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()));