2017-10-21 13:50:30 +00:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
|
|
|
|
2018-06-01 15:28:26 +02:00
|
|
|
#include <Qt5Frame.hxx>
|
2018-09-18 11:25:05 +02:00
|
|
|
#include <Qt5Frame.moc>
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-06-01 15:28:26 +02:00
|
|
|
#include <Qt5Tools.hxx>
|
|
|
|
#include <Qt5Instance.hxx>
|
|
|
|
#include <Qt5Graphics.hxx>
|
|
|
|
#include <Qt5Widget.hxx>
|
2018-08-09 17:14:14 +02:00
|
|
|
#include <Qt5MainWindow.hxx>
|
2018-06-01 15:28:26 +02:00
|
|
|
#include <Qt5Data.hxx>
|
2018-05-15 16:29:15 +02:00
|
|
|
#include <Qt5Menu.hxx>
|
2018-10-04 17:12:40 +02:00
|
|
|
#include <Qt5DragAndDrop.hxx>
|
2017-10-27 13:15:37 +02:00
|
|
|
|
2019-02-27 09:40:50 +01:00
|
|
|
#include <QtCore/QMimeData>
|
2017-10-30 18:33:06 +01:00
|
|
|
#include <QtCore/QPoint>
|
|
|
|
#include <QtCore/QSize>
|
|
|
|
#include <QtGui/QIcon>
|
2017-10-27 13:15:37 +02:00
|
|
|
#include <QtGui/QWindow>
|
2017-10-30 19:44:40 +01:00
|
|
|
#include <QtGui/QScreen>
|
2018-08-09 14:51:41 +02:00
|
|
|
#include <QtWidgets/QStyle>
|
|
|
|
#include <QtWidgets/QToolTip>
|
2017-10-30 19:55:18 +01:00
|
|
|
#include <QtWidgets/QApplication>
|
2018-08-29 14:04:56 +02:00
|
|
|
#include <QtWidgets/QDesktopWidget>
|
2018-08-09 14:51:41 +02:00
|
|
|
#include <QtWidgets/QMenuBar>
|
2018-08-09 17:14:14 +02:00
|
|
|
#include <QtWidgets/QMainWindow>
|
2017-10-27 13:15:37 +02:00
|
|
|
|
2017-10-30 18:33:06 +01:00
|
|
|
#include <saldatabasic.hxx>
|
2017-11-14 00:10:58 +02:00
|
|
|
#include <window.h>
|
2017-10-30 19:44:40 +01:00
|
|
|
#include <vcl/layout.hxx>
|
2017-10-30 18:33:06 +01:00
|
|
|
#include <vcl/syswin.hxx>
|
|
|
|
|
2018-10-15 14:44:29 +02:00
|
|
|
#include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
|
|
|
|
|
2017-10-24 19:49:45 +02:00
|
|
|
#include <cairo.h>
|
|
|
|
#include <headless/svpgdi.hxx>
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
static void SvpDamageHandler(void* handle, sal_Int32 nExtentsX, sal_Int32 nExtentsY,
|
|
|
|
sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight)
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
Qt5Frame* pThis = static_cast<Qt5Frame*>(handle);
|
|
|
|
pThis->Damage(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight);
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo)
|
2018-08-09 17:14:14 +02:00
|
|
|
: m_pTopLevel(nullptr)
|
|
|
|
, m_bUseCairo(bUseCairo)
|
|
|
|
, m_pSvpGraphics(nullptr)
|
2018-09-04 09:17:11 +02:00
|
|
|
, m_bNullRegion(true)
|
2017-11-08 11:28:04 +01:00
|
|
|
, m_bGraphicsInUse(false)
|
2019-05-12 14:30:06 +02:00
|
|
|
, m_bGraphicsInvalid(false)
|
2017-11-08 11:28:04 +01:00
|
|
|
, m_ePointerStyle(PointerStyle::Arrow)
|
2018-10-15 14:44:29 +02:00
|
|
|
, m_pDragSource(nullptr)
|
|
|
|
, m_pDropTarget(nullptr)
|
|
|
|
, m_bInDrag(false)
|
2017-11-08 11:28:04 +01:00
|
|
|
, m_bDefaultSize(true)
|
|
|
|
, m_bDefaultPos(true)
|
2018-12-14 12:39:44 +03:00
|
|
|
, m_bFullScreen(false)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
Qt5Instance* pInst = static_cast<Qt5Instance*>(GetSalData()->m_pInstance);
|
|
|
|
pInst->insertFrame(this);
|
2017-10-27 13:15:37 +02:00
|
|
|
|
2017-10-24 19:49:45 +02:00
|
|
|
m_aDamageHandler.handle = this;
|
|
|
|
m_aDamageHandler.damaged = ::SvpDamageHandler;
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
if (nStyle & SalFrameStyleFlags::DEFAULT) // ensure default style
|
2017-10-27 13:15:37 +02:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
nStyle |= SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE
|
|
|
|
| SalFrameStyleFlags::CLOSEABLE;
|
2017-10-27 13:15:37 +02:00
|
|
|
nStyle &= ~SalFrameStyleFlags::FLOAT;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_nStyle = nStyle;
|
|
|
|
m_pParent = pParent;
|
|
|
|
|
|
|
|
Qt::WindowFlags aWinFlags;
|
2017-11-08 11:28:04 +01:00
|
|
|
if (!(nStyle & SalFrameStyleFlags::SYSTEMCHILD))
|
2017-10-27 13:15:37 +02:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
if (nStyle & SalFrameStyleFlags::INTRO)
|
2017-10-27 13:15:37 +02:00
|
|
|
aWinFlags |= Qt::SplashScreen;
|
2019-02-13 12:24:38 +01:00
|
|
|
// floating toolbars are frameless tool windows
|
|
|
|
// + they must be able to receive keyboard focus
|
|
|
|
else if ((nStyle & SalFrameStyleFlags::FLOAT)
|
|
|
|
&& (nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION))
|
|
|
|
aWinFlags |= Qt::Tool | Qt::FramelessWindowHint;
|
2017-11-08 11:28:04 +01:00
|
|
|
else if (nStyle & (SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::TOOLTIP))
|
2017-10-27 13:15:37 +02:00
|
|
|
aWinFlags |= Qt::ToolTip;
|
2017-11-08 11:28:04 +01:00
|
|
|
else if ((nStyle & SalFrameStyleFlags::FLOAT)
|
|
|
|
&& !(nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION))
|
2017-10-27 13:15:37 +02:00
|
|
|
aWinFlags |= Qt::Popup;
|
2017-11-08 11:28:04 +01:00
|
|
|
else if (nStyle & SalFrameStyleFlags::DIALOG && pParent)
|
2017-10-27 13:15:37 +02:00
|
|
|
aWinFlags |= Qt::Dialog;
|
2017-11-08 11:28:04 +01:00
|
|
|
else if (nStyle & SalFrameStyleFlags::TOOLWINDOW)
|
2017-10-27 13:15:37 +02:00
|
|
|
aWinFlags |= Qt::Tool;
|
|
|
|
else
|
|
|
|
aWinFlags |= Qt::Window;
|
|
|
|
}
|
|
|
|
|
2019-02-21 10:24:39 +03:00
|
|
|
if (aWinFlags == Qt::Window)
|
2018-08-09 17:14:14 +02:00
|
|
|
{
|
2019-02-21 10:24:39 +03:00
|
|
|
QWidget* pParentWidget = nullptr;
|
|
|
|
if (m_pParent)
|
|
|
|
{
|
|
|
|
pParentWidget
|
|
|
|
= (m_pParent->m_pTopLevel) ? m_pParent->m_pTopLevel : m_pParent->m_pQWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_pTopLevel = new Qt5MainWindow(*this, pParentWidget, aWinFlags);
|
2018-08-10 18:29:10 +02:00
|
|
|
m_pQWidget = new Qt5Widget(*this, aWinFlags);
|
2018-08-09 17:14:14 +02:00
|
|
|
m_pTopLevel->setCentralWidget(m_pQWidget);
|
|
|
|
}
|
2018-07-17 15:57:41 +02:00
|
|
|
else
|
2018-08-10 18:29:10 +02:00
|
|
|
m_pQWidget = new Qt5Widget(*this, aWinFlags);
|
2018-12-11 12:12:52 +01:00
|
|
|
|
|
|
|
connect(this, &Qt5Frame::tooltipRequest, static_cast<Qt5Widget*>(m_pQWidget),
|
|
|
|
&Qt5Widget::showTooltip);
|
2017-10-27 13:15:37 +02:00
|
|
|
|
|
|
|
if (pParent && !(pParent->m_nStyle & SalFrameStyleFlags::PLUG))
|
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
QWindow* pParentWindow = pParent->GetQWidget()->window()->windowHandle();
|
2019-02-21 10:24:39 +03:00
|
|
|
QWindow* pChildWindow = (m_pTopLevel ? m_pTopLevel->window()->windowHandle()
|
|
|
|
: m_pQWidget->window()->windowHandle());
|
|
|
|
if (pParentWindow && pChildWindow && (pParentWindow != pChildWindow))
|
2017-11-08 11:28:04 +01:00
|
|
|
pChildWindow->setTransientParent(pParentWindow);
|
2017-10-27 13:15:37 +02:00
|
|
|
}
|
2017-12-08 11:37:18 +00:00
|
|
|
|
|
|
|
// fake an initial geometry, gets updated via configure event or SetPosSize
|
|
|
|
if (m_bDefaultPos || m_bDefaultSize)
|
|
|
|
{
|
2018-08-29 14:04:56 +02:00
|
|
|
Size aDefSize = CalcDefaultSize();
|
2017-12-08 11:37:18 +00:00
|
|
|
maGeometry.nX = -1;
|
|
|
|
maGeometry.nY = -1;
|
|
|
|
maGeometry.nWidth = aDefSize.Width();
|
|
|
|
maGeometry.nHeight = aDefSize.Height();
|
|
|
|
maGeometry.nTopDecoration = 0;
|
|
|
|
maGeometry.nBottomDecoration = 0;
|
|
|
|
maGeometry.nLeftDecoration = 0;
|
|
|
|
maGeometry.nRightDecoration = 0;
|
|
|
|
}
|
2018-10-05 11:39:49 +02:00
|
|
|
|
|
|
|
m_aSystemData.nSize = sizeof(SystemEnvData);
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
|
|
|
|
// Calling 'QWidget::winId()' implicitly enables native windows to be used
|
|
|
|
// rather than "alien widgets" that are unknown to the windowing system,
|
|
|
|
// s. https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
|
|
|
|
// Avoid this on Wayland due to problems with missing 'mouseMoveEvent's,
|
|
|
|
// s. tdf#122293/QTBUG-75766
|
2019-05-23 17:09:51 +01:00
|
|
|
const bool bWayland = QGuiApplication::platformName() == "wayland";
|
|
|
|
if (!bWayland)
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
m_aSystemData.aWindow = m_pQWidget->winId();
|
2019-05-23 17:09:51 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// TODO implement as needed for Wayland,
|
|
|
|
// s.a. commit c0d4f3ad3307c which did this for gtk3
|
|
|
|
// QPlatformNativeInterface* native = QGuiApplication::platformNativeInterface();
|
|
|
|
// m_aSystemData.pDisplay = native->nativeResourceForWindow("display", nullptr);
|
|
|
|
// m_aSystemData.aWindow = reinterpret_cast<unsigned long>(
|
|
|
|
// native->nativeResourceForWindow("surface", m_pQWidget->windowHandle()));
|
|
|
|
}
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
|
2018-10-05 11:39:49 +02:00
|
|
|
m_aSystemData.aShellWindow = reinterpret_cast<sal_IntPtr>(this);
|
|
|
|
//m_aSystemData.pSalFrame = this;
|
|
|
|
//m_aSystemData.pWidget = m_pQWidget;
|
|
|
|
//m_aSystemData.nScreen = m_nXScreen.getXScreen();
|
|
|
|
m_aSystemData.pToolkit = "qt5";
|
2019-05-23 17:09:51 +01:00
|
|
|
if (!bWayland)
|
|
|
|
m_aSystemData.pPlatformName = "xcb";
|
|
|
|
else
|
|
|
|
m_aSystemData.pPlatformName = "wayland";
|
2019-02-27 16:13:48 +01:00
|
|
|
|
|
|
|
SetIcon(SV_ICON_ID_OFFICE);
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-10-30 18:45:46 +01:00
|
|
|
Qt5Frame::~Qt5Frame()
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
Qt5Instance* pInst = static_cast<Qt5Instance*>(GetSalData()->m_pInstance);
|
|
|
|
pInst->eraseFrame(this);
|
2018-08-09 17:14:14 +02:00
|
|
|
if (m_pTopLevel)
|
|
|
|
delete m_pTopLevel;
|
|
|
|
else
|
|
|
|
delete m_pQWidget;
|
2018-10-05 11:39:49 +02:00
|
|
|
m_aSystemData.aShellWindow = 0;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth,
|
|
|
|
sal_Int32 nExtentsHeight) const
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
m_pQWidget->update(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight);
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
|
|
|
|
2017-10-30 18:45:46 +01:00
|
|
|
void Qt5Frame::TriggerPaintEvent()
|
2017-10-31 01:07:06 +01:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
QSize aSize(m_pQWidget->size());
|
|
|
|
SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height(), true);
|
|
|
|
CallCallback(SalEvent::Paint, &aPaintEvt);
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::TriggerPaintEvent(QRect aRect)
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
SalPaintEvent aPaintEvt(aRect.x(), aRect.y(), aRect.width(), aRect.height(), true);
|
|
|
|
CallCallback(SalEvent::Paint, &aPaintEvt);
|
2017-10-31 01:07:06 +01:00
|
|
|
}
|
|
|
|
|
2018-05-31 12:14:55 +02:00
|
|
|
void Qt5Frame::InitSvpSalGraphics(SvpSalGraphics* pSvpSalGraphics)
|
2018-04-19 14:20:27 +02:00
|
|
|
{
|
2018-08-29 14:04:56 +02:00
|
|
|
int width = 640;
|
|
|
|
int height = 480;
|
2018-04-19 14:20:27 +02:00
|
|
|
m_pSvpGraphics = pSvpSalGraphics;
|
|
|
|
m_pSurface.reset(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height));
|
|
|
|
m_pSvpGraphics->setSurface(m_pSurface.get(), basegfx::B2IVector(width, height));
|
2018-05-31 12:14:55 +02:00
|
|
|
cairo_surface_set_user_data(m_pSurface.get(), SvpSalGraphics::getDamageKey(), &m_aDamageHandler,
|
|
|
|
nullptr);
|
2018-04-19 14:20:27 +02:00
|
|
|
}
|
|
|
|
|
2017-10-30 18:45:46 +01:00
|
|
|
SalGraphics* Qt5Frame::AcquireGraphics()
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
if (m_bGraphicsInUse)
|
2017-10-31 01:07:06 +01:00
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
m_bGraphicsInUse = true;
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
if (m_bUseCairo)
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2019-05-12 14:30:06 +02:00
|
|
|
if (!m_pOurSvpGraphics.get() || m_bGraphicsInvalid)
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2018-05-31 12:14:55 +02:00
|
|
|
m_pOurSvpGraphics.reset(new SvpSalGraphics());
|
|
|
|
InitSvpSalGraphics(m_pOurSvpGraphics.get());
|
2019-05-12 14:30:06 +02:00
|
|
|
m_bGraphicsInvalid = false;
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
2018-04-19 14:20:27 +02:00
|
|
|
return m_pOurSvpGraphics.get();
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-05-12 14:30:06 +02:00
|
|
|
if (!m_pQt5Graphics.get() || m_bGraphicsInvalid)
|
2017-10-24 19:49:45 +02:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
m_pQt5Graphics.reset(new Qt5Graphics(this));
|
|
|
|
m_pQImage.reset(new QImage(m_pQWidget->size(), Qt5_DefaultFormat32));
|
2018-11-07 17:48:06 +03:00
|
|
|
m_pQImage->fill(Qt::transparent);
|
2017-11-08 11:28:04 +01:00
|
|
|
m_pQt5Graphics->ChangeQImage(m_pQImage.get());
|
2019-05-12 14:30:06 +02:00
|
|
|
m_bGraphicsInvalid = false;
|
2017-10-24 19:49:45 +02:00
|
|
|
}
|
|
|
|
return m_pQt5Graphics.get();
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::ReleaseGraphics(SalGraphics* pSalGraph)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
(void)pSalGraph;
|
|
|
|
if (m_bUseCairo)
|
2018-04-19 14:20:27 +02:00
|
|
|
assert(pSalGraph == m_pOurSvpGraphics.get());
|
2017-10-24 19:49:45 +02:00
|
|
|
else
|
2017-11-08 11:28:04 +01:00
|
|
|
assert(pSalGraph == m_pQt5Graphics.get());
|
2017-10-31 01:07:06 +01:00
|
|
|
m_bGraphicsInUse = false;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2018-10-30 10:48:22 +02:00
|
|
|
bool Qt5Frame::PostEvent(std::unique_ptr<ImplSVEvent> pData)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
Qt5Instance* pInst = static_cast<Qt5Instance*>(GetSalData()->m_pInstance);
|
2018-10-30 10:48:22 +02:00
|
|
|
pInst->PostEvent(this, pData.release(), SalEvent::UserEvent);
|
2017-10-31 01:07:06 +01:00
|
|
|
return true;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2018-11-02 00:44:01 +01:00
|
|
|
bool Qt5Frame::isWindow() const
|
2018-08-09 17:14:14 +02:00
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
return m_pTopLevel->isWindow();
|
|
|
|
else
|
|
|
|
return m_pQWidget->isWindow();
|
|
|
|
}
|
|
|
|
|
2018-11-02 00:44:01 +01:00
|
|
|
QWindow* Qt5Frame::windowHandle() const
|
2018-08-09 17:14:14 +02:00
|
|
|
{
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
// set attribute 'Qt::WA_NativeWindow' first to make sure a window handle actually exists
|
2018-08-09 17:14:14 +02:00
|
|
|
if (m_pTopLevel)
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
{
|
|
|
|
m_pTopLevel->setAttribute(Qt::WA_NativeWindow);
|
2018-08-09 17:14:14 +02:00
|
|
|
return m_pTopLevel->windowHandle();
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
}
|
2018-08-09 17:14:14 +02:00
|
|
|
else
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
{
|
|
|
|
m_pQWidget->setAttribute(Qt::WA_NativeWindow);
|
2018-08-09 17:14:14 +02:00
|
|
|
return m_pQWidget->windowHandle();
|
tdf#122293 qt5: Use "alien widgets" by default on Wayland
As described in QWidget doc [1], calling 'QWidget::winId()',
implicitly enforces a native window, i.e. one that has a
native window associated with it.
For this reason, avoid calling 'QWidget::winId()' for the Wayland
case. Quoting QWidget doc:
> Introduced in Qt 4.4, alien widgets are widgets unknown to the windowing
> system. They do not have a native window handle associated with them.
> This feature significantly speeds up widget painting, resizing, and
> removes flicker.
This in particular avoids tdf#122293/QTBUG-75766, which led to
'mousePressEvent's not being emitted unless a mouse button was pressed,
causing non-existent reaction to hovering over objects.
As a consequence to widgets being non-native by default on Wayland,
'Qt5Frame::windowHandle' needs to be adapted to make sure that the
widgets handled in there are native ones, otherwise no window handle
is associated with them.
Probably more needs to be done here to make video playback via GStreamer
work under Wayland, s.a. commit c0d4f3ad3307c ("implement wayland handle
passing for gstreamer") for how it was done for gtk3.
With and without this change, slideshows with videos are currently not
handled properly with kde5 on Wayland (s. tdf#125219).
[1] https://doc.qt.io/qt-5/qwidget.html#native-widgets-vs-alien-widgets
Change-Id: Id46678e0ea594220a1765c3e59d39c41cb8bfe25
Reviewed-on: https://gerrit.libreoffice.org/72164
Tested-by: Jenkins
Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2019-05-11 21:31:33 +02:00
|
|
|
}
|
2018-08-09 17:14:14 +02:00
|
|
|
}
|
|
|
|
|
2018-11-02 00:44:01 +01:00
|
|
|
QScreen* Qt5Frame::screen() const
|
2018-08-29 14:04:56 +02:00
|
|
|
{
|
2018-09-04 09:17:11 +02:00
|
|
|
QWindow* const pWindow = windowHandle();
|
|
|
|
if (pWindow)
|
|
|
|
return pWindow->screen();
|
2018-08-29 14:04:56 +02:00
|
|
|
else
|
2018-09-04 09:17:11 +02:00
|
|
|
return nullptr;
|
2018-08-29 14:04:56 +02:00
|
|
|
}
|
|
|
|
|
2018-11-02 00:44:01 +01:00
|
|
|
bool Qt5Frame::isMinimized() const
|
2018-08-09 17:14:14 +02:00
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
2018-08-29 14:04:56 +02:00
|
|
|
return m_pTopLevel->isMinimized();
|
2018-08-09 17:14:14 +02:00
|
|
|
else
|
2018-08-29 14:04:56 +02:00
|
|
|
return m_pQWidget->isMinimized();
|
|
|
|
}
|
|
|
|
|
2018-11-02 00:44:01 +01:00
|
|
|
bool Qt5Frame::isMaximized() const
|
2018-08-29 14:04:56 +02:00
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
return m_pTopLevel->isMaximized();
|
|
|
|
else
|
|
|
|
return m_pQWidget->isMaximized();
|
2018-08-09 17:14:14 +02:00
|
|
|
}
|
|
|
|
|
2019-02-11 11:22:30 +01:00
|
|
|
void Qt5Frame::SetWindowStateImpl(Qt::WindowStates eState)
|
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
m_pTopLevel->setWindowState(eState);
|
|
|
|
else
|
|
|
|
m_pQWidget->setWindowState(eState);
|
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetTitle(const OUString& rTitle)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
m_pQWidget->window()->setWindowTitle(toQString(rTitle));
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetIcon(sal_uInt16 nIcon)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-13 09:08:30 +01:00
|
|
|
if (m_nStyle
|
|
|
|
& (SalFrameStyleFlags::PLUG | SalFrameStyleFlags::SYSTEMCHILD
|
|
|
|
| SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::INTRO
|
|
|
|
| SalFrameStyleFlags::OWNERDRAWDECORATION)
|
2018-08-09 17:14:14 +02:00
|
|
|
|| !isWindow())
|
2017-10-30 18:33:06 +01:00
|
|
|
return;
|
|
|
|
|
2019-05-10 10:09:21 +02:00
|
|
|
QString appicon;
|
2017-10-30 18:33:06 +01:00
|
|
|
|
|
|
|
if (nIcon == SV_ICON_ID_TEXT)
|
|
|
|
appicon = "libreoffice-writer";
|
|
|
|
else if (nIcon == SV_ICON_ID_SPREADSHEET)
|
|
|
|
appicon = "libreoffice-calc";
|
|
|
|
else if (nIcon == SV_ICON_ID_DRAWING)
|
|
|
|
appicon = "libreoffice-draw";
|
|
|
|
else if (nIcon == SV_ICON_ID_PRESENTATION)
|
|
|
|
appicon = "libreoffice-impress";
|
|
|
|
else if (nIcon == SV_ICON_ID_DATABASE)
|
|
|
|
appicon = "libreoffice-base";
|
|
|
|
else if (nIcon == SV_ICON_ID_FORMULA)
|
|
|
|
appicon = "libreoffice-math";
|
|
|
|
else
|
|
|
|
appicon = "libreoffice-startcenter";
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
QIcon aIcon = QIcon::fromTheme(appicon);
|
|
|
|
m_pQWidget->window()->setWindowIcon(aIcon);
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2018-05-31 12:14:55 +02:00
|
|
|
void Qt5Frame::SetMenu(SalMenu* pMenu) { m_pSalMenu = static_cast<Qt5Menu*>(pMenu); }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::DrawMenuBar() { /* not needed */}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::SetExtendedFrameStyle(SalExtStyle /*nExtStyle*/) { /* not needed */}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-18 11:25:05 +02:00
|
|
|
void Qt5Frame::setVisible(bool bVisible)
|
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
m_pTopLevel->setVisible(bVisible);
|
|
|
|
else
|
|
|
|
m_pQWidget->setVisible(bVisible);
|
|
|
|
}
|
|
|
|
|
2018-01-08 09:38:24 +02:00
|
|
|
void Qt5Frame::Show(bool bVisible, bool /*bNoActivate*/)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
assert(m_pQWidget);
|
2018-08-29 14:04:56 +02:00
|
|
|
|
|
|
|
if (m_bDefaultSize)
|
|
|
|
SetDefaultSize();
|
|
|
|
|
2019-02-25 17:00:21 +01:00
|
|
|
auto* pSalInst(static_cast<Qt5Instance*>(GetSalData()->m_pInstance));
|
|
|
|
assert(pSalInst);
|
|
|
|
pSalInst->RunInMainThread([this, bVisible]() { setVisible(bVisible); });
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetMinClientSize(long nWidth, long nHeight)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
if (!isChild())
|
2018-09-04 21:05:03 +02:00
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
m_pTopLevel->setMinimumSize(nWidth, nHeight);
|
|
|
|
else
|
|
|
|
m_pQWidget->setMinimumSize(nWidth, nHeight);
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetMaxClientSize(long nWidth, long nHeight)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
if (!isChild())
|
2018-09-04 21:05:03 +02:00
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
m_pTopLevel->setMaximumSize(nWidth, nHeight);
|
|
|
|
else
|
|
|
|
m_pQWidget->setMaximumSize(nWidth, nHeight);
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-10-30 19:44:40 +01:00
|
|
|
void Qt5Frame::Center()
|
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
if (m_pParent)
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
QWidget* pWindow = m_pParent->GetQWidget()->window();
|
2019-03-05 13:44:17 +02:00
|
|
|
QWidget* const pWidget = m_pTopLevel ? m_pTopLevel : m_pQWidget;
|
2019-02-21 10:24:39 +03:00
|
|
|
pWidget->move(pWindow->frameGeometry().topLeft() + pWindow->rect().center()
|
|
|
|
- pWidget->rect().center());
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Size Qt5Frame::CalcDefaultSize()
|
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
assert(isWindow());
|
2018-08-29 14:04:56 +02:00
|
|
|
QSize qSize(0, 0);
|
2018-08-09 17:14:14 +02:00
|
|
|
QScreen* pScreen = screen();
|
2018-08-29 14:04:56 +02:00
|
|
|
if (pScreen)
|
|
|
|
qSize = pScreen->size();
|
|
|
|
else
|
|
|
|
qSize = QApplication::desktop()->screenGeometry(0).size();
|
|
|
|
|
2018-12-14 12:39:44 +03:00
|
|
|
Size aSize = toSize(qSize);
|
|
|
|
if (!m_bFullScreen)
|
|
|
|
aSize = bestmaxFrameSizeForScreenSize(aSize);
|
|
|
|
|
|
|
|
return aSize;
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Qt5Frame::SetDefaultSize()
|
|
|
|
{
|
|
|
|
Size aDefSize = CalcDefaultSize();
|
2017-11-08 11:28:04 +01:00
|
|
|
SetPosSize(0, 0, aDefSize.Width(), aDefSize.Height(),
|
|
|
|
SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT);
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
if (!isWindow() || isChild(true, false))
|
2017-10-30 19:44:40 +01:00
|
|
|
return;
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
if ((nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT))
|
|
|
|
&& (nWidth > 0 && nHeight > 0) // sometimes stupid things happen
|
2017-11-13 09:08:30 +01:00
|
|
|
)
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
|
|
|
m_bDefaultSize = false;
|
2017-11-08 11:28:04 +01:00
|
|
|
if (isChild(false) || !m_pQWidget->isMaximized())
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2019-03-05 13:44:17 +02:00
|
|
|
QWidget* const pWidget = m_pTopLevel ? m_pTopLevel : m_pQWidget;
|
2018-11-02 18:12:25 +03:00
|
|
|
|
|
|
|
if (m_nStyle & SalFrameStyleFlags::SIZEABLE)
|
|
|
|
pWidget->resize(nWidth, nHeight);
|
2018-08-29 14:04:56 +02:00
|
|
|
else
|
2018-11-02 18:12:25 +03:00
|
|
|
pWidget->setFixedSize(nWidth, nHeight);
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
|
|
|
}
|
2017-11-08 11:28:04 +01:00
|
|
|
else if (m_bDefaultSize)
|
2017-10-30 19:44:40 +01:00
|
|
|
SetDefaultSize();
|
|
|
|
|
|
|
|
m_bDefaultSize = false;
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
if (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y))
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
if (m_pParent)
|
2017-10-30 19:44:40 +01:00
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
QRect aRect;
|
|
|
|
if (m_pParent->GetTopLevelWindow())
|
|
|
|
aRect = m_pParent->GetTopLevelWindow()->geometry();
|
|
|
|
else
|
|
|
|
aRect = m_pParent->GetQWidget()->geometry();
|
|
|
|
|
2017-10-30 19:44:40 +01:00
|
|
|
nX += aRect.x();
|
|
|
|
nY += aRect.y();
|
|
|
|
}
|
|
|
|
|
2017-12-08 11:37:18 +00:00
|
|
|
maGeometry.nX = nX;
|
|
|
|
maGeometry.nY = nY;
|
|
|
|
|
2017-10-30 19:44:40 +01:00
|
|
|
m_bDefaultPos = false;
|
2018-10-25 11:45:13 +02:00
|
|
|
if (m_pTopLevel)
|
|
|
|
m_pTopLevel->move(nX, nY);
|
|
|
|
else
|
|
|
|
m_pQWidget->move(nX, nY);
|
2017-10-30 19:44:40 +01:00
|
|
|
}
|
2017-11-08 11:28:04 +01:00
|
|
|
else if (m_bDefaultPos)
|
2017-10-30 19:44:40 +01:00
|
|
|
Center();
|
|
|
|
|
|
|
|
m_bDefaultPos = false;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2018-04-07 11:45:13 +02:00
|
|
|
void Qt5Frame::GetClientSize(long& rWidth, long& rHeight)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-31 01:07:06 +01:00
|
|
|
rWidth = m_pQWidget->width();
|
|
|
|
rHeight = m_pQWidget->height();
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::GetWorkArea(tools::Rectangle& rRect)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
if (!isWindow())
|
2017-10-30 19:44:40 +01:00
|
|
|
return;
|
2018-08-09 17:14:14 +02:00
|
|
|
QScreen* pScreen = screen();
|
2017-11-08 11:28:04 +01:00
|
|
|
if (!pScreen)
|
2017-10-30 19:44:40 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
QSize aSize = pScreen->availableVirtualSize();
|
2017-11-08 11:28:04 +01:00
|
|
|
rRect = tools::Rectangle(0, 0, aSize.width(), aSize.height());
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
SalFrame* Qt5Frame::GetParent() const { return m_pParent; }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-06-27 10:41:03 +02:00
|
|
|
void Qt5Frame::SetModal(bool bModal)
|
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
if (isWindow())
|
2018-06-27 10:41:03 +02:00
|
|
|
{
|
tdf#119856 vcl: fix Qt warning Qt5Frame::SetModal()
This prints a warning "Cannot create children for a parent that is in a
different thread"; let's fix it before it causes another hard to debug
crash.
0 check_parent_thread(QObject*, QThreadData*, QThreadData*) (parent=parent@entry=0xe88ca0, parentThreadData=<optimized out>, currentThreadData=<optimized out>) at kernel/qobject.cpp:781
1 check_parent_thread (currentThreadData=<optimized out>, parentThreadData=<optimized out>, parent=0xe88ca0) at kernel/qobject.cpp:822
2 QObject::QObject(QObject*) (this=0x9ed2e80, parent=0xe88ca0) at kernel/qobject.cpp:810
3 Adwaita::GenericData::GenericData(QObject*, QWidget*, int) () at /usr/lib64/qt5/plugins/styles/adwaita.so
4 Adwaita::WidgetStateEngine::registerWidget(QWidget*, QFlags<Adwaita::AnimationMode>) () at /usr/lib64/qt5/plugins/styles/adwaita.so
5 Adwaita::Animations::registerWidget(QWidget*) const () at /usr/lib64/qt5/plugins/styles/adwaita.so
6 Adwaita::Style::polish(QWidget*) () at /usr/lib64/qt5/plugins/styles/adwaita.so
7 QWidget::event(QEvent*) () at /lib64/libQt5Widgets.so.5
8 Qt5Widget::event(QEvent*) (this=0x7321790, pEvent=0x7f90c27d3750) at vcl/qt5/Qt5Widget.cxx:416
9 QApplicationPrivate::notify_helper(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5
10 QApplication::notify(QObject*, QEvent*) () at /lib64/libQt5Widgets.so.5
11 QCoreApplication::notifyInternal2(QObject*, QEvent*) (receiver=0x7321790, event=0x7f90c27d3750) at kernel/qcoreapplication.cpp:1047
12 QWidget::ensurePolished() const () at /lib64/libQt5Widgets.so.5
13 QWidget::setVisible(bool) () at /lib64/libQt5Widgets.so.5
14 Qt5Frame::SetModal(bool) (this=0x9f411b0, bModal=true) at vcl/qt5/Qt5Frame.cxx:482
Change-Id: Ib6b4d1ee859dfce650422a6c7860abf2eb2686f1
Reviewed-on: https://gerrit.libreoffice.org/68356
Tested-by: Jenkins
Reviewed-by: Katarina Behrens <Katarina.Behrens@cib.de>
2019-02-25 16:56:59 +01:00
|
|
|
auto* pSalInst(static_cast<Qt5Instance*>(GetSalData()->m_pInstance));
|
|
|
|
assert(pSalInst);
|
|
|
|
pSalInst->RunInMainThread([this, bModal]() {
|
|
|
|
bool wasVisible = windowHandle()->isVisible();
|
|
|
|
|
|
|
|
// modality change is only effective if the window is hidden
|
|
|
|
if (wasVisible)
|
|
|
|
{
|
|
|
|
windowHandle()->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
windowHandle()->setModality(bModal ? Qt::WindowModal : Qt::NonModal);
|
|
|
|
|
|
|
|
// and shown again if it was visible
|
|
|
|
if (wasVisible)
|
|
|
|
{
|
|
|
|
windowHandle()->show();
|
|
|
|
}
|
|
|
|
});
|
2018-06-27 10:41:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-02 18:21:20 +00:00
|
|
|
bool Qt5Frame::GetModal() const { return isWindow() && windowHandle()->isModal(); }
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetWindowState(const SalFrameState* pState)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
if (!isWindow() || !pState || isChild(true, false))
|
2017-10-30 18:33:06 +01:00
|
|
|
return;
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
const WindowStateMask nMaxGeometryMask
|
|
|
|
= WindowStateMask::X | WindowStateMask::Y | WindowStateMask::Width | WindowStateMask::Height
|
|
|
|
| WindowStateMask::MaximizedX | WindowStateMask::MaximizedY
|
|
|
|
| WindowStateMask::MaximizedWidth | WindowStateMask::MaximizedHeight;
|
2017-10-30 18:33:06 +01:00
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
if ((pState->mnMask & WindowStateMask::State) && (pState->mnState & WindowStateState::Maximized)
|
2018-08-29 14:04:56 +02:00
|
|
|
&& !isMaximized() && (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask)
|
2019-02-11 11:22:30 +01:00
|
|
|
{
|
|
|
|
if (m_pTopLevel)
|
|
|
|
{
|
|
|
|
m_pTopLevel->resize(pState->mnWidth, pState->mnHeight);
|
|
|
|
m_pTopLevel->move(pState->mnX, pState->mnY);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_pQWidget->resize(pState->mnWidth, pState->mnHeight);
|
|
|
|
m_pQWidget->move(pState->mnX, pState->mnY);
|
|
|
|
}
|
|
|
|
SetWindowStateImpl(Qt::WindowMaximized);
|
|
|
|
}
|
2017-11-13 09:08:30 +01:00
|
|
|
else if (pState->mnMask
|
|
|
|
& (WindowStateMask::X | WindowStateMask::Y | WindowStateMask::Width
|
|
|
|
| WindowStateMask::Height))
|
2017-10-30 18:33:06 +01:00
|
|
|
{
|
2017-10-30 19:44:40 +01:00
|
|
|
sal_uInt16 nPosSizeFlags = 0;
|
|
|
|
QPoint aPos = m_pQWidget->pos();
|
|
|
|
QPoint aParentPos;
|
2017-11-08 11:28:04 +01:00
|
|
|
if (m_pParent)
|
2017-10-30 19:44:40 +01:00
|
|
|
aParentPos = m_pParent->GetQWidget()->window()->pos();
|
|
|
|
long nX = pState->mnX - aParentPos.x();
|
|
|
|
long nY = pState->mnY - aParentPos.y();
|
2017-11-08 11:28:04 +01:00
|
|
|
if (pState->mnMask & WindowStateMask::X)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_X;
|
|
|
|
else
|
|
|
|
nX = aPos.x() - aParentPos.x();
|
2017-11-08 11:28:04 +01:00
|
|
|
if (pState->mnMask & WindowStateMask::Y)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_Y;
|
|
|
|
else
|
|
|
|
nY = aPos.y() - aParentPos.y();
|
2017-11-08 11:28:04 +01:00
|
|
|
if (pState->mnMask & WindowStateMask::Width)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH;
|
2017-11-08 11:28:04 +01:00
|
|
|
if (pState->mnMask & WindowStateMask::Height)
|
2017-10-30 19:44:40 +01:00
|
|
|
nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT;
|
2017-11-08 11:28:04 +01:00
|
|
|
SetPosSize(nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags);
|
2017-10-30 18:33:06 +01:00
|
|
|
}
|
2017-11-08 11:28:04 +01:00
|
|
|
else if (pState->mnMask & WindowStateMask::State && !isChild())
|
2017-10-30 18:33:06 +01:00
|
|
|
{
|
2019-02-11 11:22:30 +01:00
|
|
|
if (pState->mnState & WindowStateState::Maximized)
|
|
|
|
SetWindowStateImpl(Qt::WindowMaximized);
|
2019-02-12 09:07:17 +01:00
|
|
|
else if (pState->mnState & WindowStateState::Minimized)
|
2019-02-11 11:22:30 +01:00
|
|
|
SetWindowStateImpl(Qt::WindowMinimized);
|
2017-10-30 18:33:06 +01:00
|
|
|
else
|
2019-02-11 11:22:30 +01:00
|
|
|
SetWindowStateImpl(Qt::WindowNoState);
|
2017-10-30 18:33:06 +01:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
bool Qt5Frame::GetWindowState(SalFrameState* pState)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-30 18:33:06 +01:00
|
|
|
pState->mnState = WindowStateState::Normal;
|
2017-11-08 11:28:04 +01:00
|
|
|
pState->mnMask = WindowStateMask::State;
|
2018-08-29 14:04:56 +02:00
|
|
|
if (isMinimized() /*|| !windowHandle()*/)
|
2017-10-30 18:33:06 +01:00
|
|
|
pState->mnState |= WindowStateState::Minimized;
|
2018-10-25 11:45:13 +02:00
|
|
|
else if (isMaximized())
|
2017-10-30 18:33:06 +01:00
|
|
|
{
|
|
|
|
pState->mnState |= WindowStateState::Maximized;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-08-09 17:14:14 +02:00
|
|
|
QRect rect = m_pTopLevel ? m_pTopLevel->geometry() : m_pQWidget->geometry();
|
2017-10-30 18:33:06 +01:00
|
|
|
pState->mnX = rect.x();
|
|
|
|
pState->mnY = rect.y();
|
|
|
|
pState->mnWidth = rect.width();
|
|
|
|
pState->mnHeight = rect.height();
|
2017-11-08 11:28:04 +01:00
|
|
|
pState->mnMask |= WindowStateMask::X | WindowStateMask::Y | WindowStateMask::Width
|
|
|
|
| WindowStateMask::Height;
|
2017-10-30 18:33:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::ShowFullScreen(bool bFullScreen, sal_Int32 nScreen)
|
|
|
|
{
|
2018-10-25 12:29:34 +02:00
|
|
|
// only top-level windows can go fullscreen
|
2018-09-04 09:17:11 +02:00
|
|
|
assert(m_pTopLevel);
|
|
|
|
|
2018-12-14 12:39:44 +03:00
|
|
|
m_bFullScreen = bFullScreen;
|
|
|
|
|
2018-10-25 12:29:34 +02:00
|
|
|
// show it if it isn't shown yet
|
|
|
|
if (!isWindow())
|
|
|
|
m_pTopLevel->show();
|
2018-09-04 09:17:11 +02:00
|
|
|
|
2019-02-26 15:07:51 +01:00
|
|
|
if (m_bFullScreen)
|
|
|
|
{
|
|
|
|
m_aRestoreGeometry = m_pTopLevel->geometry();
|
|
|
|
// do that before going fullscreen
|
|
|
|
SetScreenNumber(nScreen);
|
|
|
|
windowHandle()->showFullScreen();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
windowHandle()->showNormal();
|
|
|
|
m_pTopLevel->setGeometry(m_aRestoreGeometry);
|
|
|
|
m_aRestoreGeometry = QRect();
|
|
|
|
}
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Qt5Frame::StartPresentation(bool)
|
|
|
|
{
|
|
|
|
// meh - so there's no Qt platform independent solution - defer to
|
|
|
|
// KDE5 impl. For everyone else:
|
|
|
|
// https://forum.qt.io/topic/38504/solved-qdialog-in-fullscreen-disable-os-screensaver
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::SetAlwaysOnTop(bool bOnTop)
|
|
|
|
{
|
|
|
|
QWidget* const pWidget = m_pTopLevel ? m_pTopLevel : m_pQWidget;
|
|
|
|
const Qt::WindowFlags flags = pWidget->windowFlags();
|
|
|
|
if (bOnTop)
|
|
|
|
pWidget->setWindowFlags(flags | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint);
|
|
|
|
else
|
|
|
|
pWidget->setWindowFlags(flags & ~(Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint));
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::ToTop(SalFrameToTop nFlags)
|
|
|
|
{
|
|
|
|
QWidget* const pWidget = m_pTopLevel ? m_pTopLevel : m_pQWidget;
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
if (isWindow() && !(nFlags & SalFrameToTop::GrabFocusOnly))
|
|
|
|
pWidget->raise();
|
2019-03-14 22:35:38 +01:00
|
|
|
if ((nFlags & SalFrameToTop::RestoreWhenMin) || (nFlags & SalFrameToTop::ForegroundTask))
|
|
|
|
pWidget->activateWindow();
|
|
|
|
else if ((nFlags & SalFrameToTop::GrabFocus) || (nFlags & SalFrameToTop::GrabFocusOnly))
|
|
|
|
m_pQWidget->setFocus();
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetPointer(PointerStyle ePointerStyle)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-11-08 11:28:04 +01:00
|
|
|
QWindow* pWindow = m_pQWidget->window()->windowHandle();
|
|
|
|
if (!pWindow)
|
2017-10-30 19:32:45 +01:00
|
|
|
return;
|
2017-11-08 11:28:04 +01:00
|
|
|
if (ePointerStyle == m_ePointerStyle)
|
2017-10-30 19:32:45 +01:00
|
|
|
return;
|
|
|
|
m_ePointerStyle = ePointerStyle;
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
pWindow->setCursor(static_cast<Qt5Data*>(GetSalData())->getCursor(ePointerStyle));
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::CaptureMouse(bool bMouse)
|
|
|
|
{
|
2018-09-04 21:05:03 +02:00
|
|
|
static const char* pEnv = getenv("SAL_NO_MOUSEGRABS");
|
|
|
|
if (pEnv && *pEnv)
|
|
|
|
return;
|
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
if (bMouse)
|
2018-09-04 21:05:03 +02:00
|
|
|
m_pQWidget->grabMouse();
|
2018-09-04 09:17:11 +02:00
|
|
|
else
|
2018-09-04 21:05:03 +02:00
|
|
|
m_pQWidget->releaseMouse();
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Qt5Frame::SetPointerPos(long nX, long nY)
|
|
|
|
{
|
2019-04-01 09:41:39 +02:00
|
|
|
// some cursor already exists (and it has m_ePointerStyle shape)
|
|
|
|
// so here we just reposition it
|
2018-09-05 09:01:02 +02:00
|
|
|
QCursor::setPos(m_pQWidget->mapToGlobal(QPoint(nX, nY)));
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::Flush()
|
|
|
|
{
|
2018-09-05 15:08:33 +02:00
|
|
|
// was: QGuiApplication::sync();
|
|
|
|
// but FIXME it causes too many issues, figure out sth better
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
// unclear if we need to also flush cairo surface - gtk3 backend
|
|
|
|
// does not do it. QPainter in Qt5Widget::paintEvent() is
|
|
|
|
// destroyed, so that state should be safely flushed.
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-12-11 12:12:52 +01:00
|
|
|
bool Qt5Frame::ShowTooltip(const OUString& rText, const tools::Rectangle& /*rHelpArea*/)
|
|
|
|
{
|
|
|
|
emit tooltipRequest(rText);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
// do we even need it? void Qt5Frame::Flush(const tools::Rectangle& /*rRect*/) {}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-12-21 17:25:17 +01:00
|
|
|
void Qt5Frame::SetInputContext(SalInputContext* pContext)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
2018-12-21 17:25:17 +01:00
|
|
|
if (!pContext)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(pContext->mnOptions & InputContextFlags::Text))
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_pQWidget->setAttribute(Qt::WA_InputMethodEnabled);
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::EndExtTextInput(EndExtTextInputFlags /*nFlags*/)
|
|
|
|
{
|
Qt5 IM handle (spurious?) all-empty IM events
2nd attempt to fix the bug described in commit 00221089800c ("Qt5
IM allow committing empty strings") and various siblings of it.
This also reverts it.
What I see is calls with "all-empty" events (preedit, commit and
replacementLength() == 0; no QInputMethodEvent::Attribute), some
from QIBusPlatformInputContext::updatePreeditText.
There are various Writer document edit states with (selected)
text, undo, cursor position and focus changes to other windows via
Ctrl+Tab, which will result in inputMethodEvent calls totally in
contrast to the expected text state, all somehow always related to
all-empty events. They currently result in wrongly deleted
selected text, change of selection, cursor movement or general
change of text from old preedit. Most time on focus out / window
change, some times at first meta-key press after focus in.
This patch tries hard not to corrupt Writers edit state with these
all-empty events. No idea if this is some bug on LO's qt5 side or
expected, but KDE kate and VCL gtk3 and gen work fine, so I assume
Qt's behaviour is correct. FWIW gtk3 also does some extended IM
handling with focus, so probably this is the Qt equivalent of it.
But then I couldn't find some eqivalent code in Qt's source code.
I actually expected an even more complex solution (if this really
fixes all cases).
Works for a multitude of tests I tried to come up with, but is
quite probably not the final fix to this, as qt5 current doesn't
handle replacementStart() and replacementLength() at all.
Also never saw a call to Qt5Frame::EndExtTextInput.
Change-Id: I4210e0588041cfb4d80dbdfdb937e430a5f7cbfb
Reviewed-on: https://gerrit.libreoffice.org/71988
Tested-by: Jenkins
Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
2019-05-08 11:51:15 +00:00
|
|
|
Qt5Widget* pQt5Widget = static_cast<Qt5Widget*>(m_pQWidget);
|
|
|
|
if (pQt5Widget)
|
|
|
|
pQt5Widget->endExtTextInput();
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-10-23 15:46:09 +02:00
|
|
|
OUString Qt5Frame::GetKeyName(sal_uInt16 nKeyCode)
|
|
|
|
{
|
|
|
|
vcl::KeyCode vclKeyCode(nKeyCode);
|
|
|
|
int nCode = vclKeyCode.GetCode();
|
|
|
|
int nRetCode = 0;
|
|
|
|
|
|
|
|
if (nCode >= KEY_0 && nCode <= KEY_9)
|
|
|
|
nRetCode = (nCode - KEY_0) + Qt::Key_0;
|
|
|
|
else if (nCode >= KEY_A && nCode <= KEY_Z)
|
|
|
|
nRetCode = (nCode - KEY_A) + Qt::Key_A;
|
|
|
|
else if (nCode >= KEY_F1 && nCode <= KEY_F26)
|
|
|
|
nRetCode = (nCode - KEY_F1) + Qt::Key_F1;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (nCode)
|
|
|
|
{
|
|
|
|
case KEY_DOWN:
|
|
|
|
nRetCode = Qt::Key_Down;
|
|
|
|
break;
|
|
|
|
case KEY_UP:
|
|
|
|
nRetCode = Qt::Key_Up;
|
|
|
|
break;
|
|
|
|
case KEY_LEFT:
|
|
|
|
nRetCode = Qt::Key_Left;
|
|
|
|
break;
|
|
|
|
case KEY_RIGHT:
|
|
|
|
nRetCode = Qt::Key_Right;
|
|
|
|
break;
|
|
|
|
case KEY_HOME:
|
|
|
|
nRetCode = Qt::Key_Home;
|
|
|
|
break;
|
|
|
|
case KEY_END:
|
|
|
|
nRetCode = Qt::Key_End;
|
|
|
|
break;
|
|
|
|
case KEY_PAGEUP:
|
|
|
|
nRetCode = Qt::Key_PageUp;
|
|
|
|
break;
|
|
|
|
case KEY_PAGEDOWN:
|
|
|
|
nRetCode = Qt::Key_PageDown;
|
|
|
|
break;
|
|
|
|
case KEY_RETURN:
|
|
|
|
nRetCode = Qt::Key_Return;
|
|
|
|
break;
|
|
|
|
case KEY_ESCAPE:
|
|
|
|
nRetCode = Qt::Key_Escape;
|
|
|
|
break;
|
|
|
|
case KEY_TAB:
|
|
|
|
nRetCode = Qt::Key_Tab;
|
|
|
|
break;
|
|
|
|
case KEY_BACKSPACE:
|
|
|
|
nRetCode = Qt::Key_Backspace;
|
|
|
|
break;
|
|
|
|
case KEY_SPACE:
|
|
|
|
nRetCode = Qt::Key_Space;
|
|
|
|
break;
|
|
|
|
case KEY_INSERT:
|
|
|
|
nRetCode = Qt::Key_Insert;
|
|
|
|
break;
|
|
|
|
case KEY_DELETE:
|
|
|
|
nRetCode = Qt::Key_Delete;
|
|
|
|
break;
|
|
|
|
case KEY_ADD:
|
|
|
|
nRetCode = Qt::Key_Plus;
|
|
|
|
break;
|
|
|
|
case KEY_SUBTRACT:
|
|
|
|
nRetCode = Qt::Key_Minus;
|
|
|
|
break;
|
|
|
|
case KEY_MULTIPLY:
|
|
|
|
nRetCode = Qt::Key_Asterisk;
|
|
|
|
break;
|
|
|
|
case KEY_DIVIDE:
|
|
|
|
nRetCode = Qt::Key_Slash;
|
|
|
|
break;
|
|
|
|
case KEY_POINT:
|
|
|
|
nRetCode = Qt::Key_Period;
|
|
|
|
break;
|
|
|
|
case KEY_COMMA:
|
|
|
|
nRetCode = Qt::Key_Comma;
|
|
|
|
break;
|
|
|
|
case KEY_LESS:
|
|
|
|
nRetCode = Qt::Key_Less;
|
|
|
|
break;
|
|
|
|
case KEY_GREATER:
|
|
|
|
nRetCode = Qt::Key_Greater;
|
|
|
|
break;
|
|
|
|
case KEY_EQUAL:
|
|
|
|
nRetCode = Qt::Key_Equal;
|
|
|
|
break;
|
|
|
|
case KEY_FIND:
|
|
|
|
nRetCode = Qt::Key_Find;
|
|
|
|
break;
|
|
|
|
case KEY_CONTEXTMENU:
|
|
|
|
nRetCode = Qt::Key_Menu;
|
|
|
|
break;
|
|
|
|
case KEY_HELP:
|
|
|
|
nRetCode = Qt::Key_Help;
|
|
|
|
break;
|
|
|
|
case KEY_UNDO:
|
|
|
|
nRetCode = Qt::Key_Undo;
|
|
|
|
break;
|
|
|
|
case KEY_REPEAT:
|
|
|
|
nRetCode = Qt::Key_Redo;
|
|
|
|
break;
|
|
|
|
case KEY_TILDE:
|
|
|
|
nRetCode = Qt::Key_AsciiTilde;
|
|
|
|
break;
|
|
|
|
case KEY_QUOTELEFT:
|
|
|
|
nRetCode = Qt::Key_QuoteLeft;
|
|
|
|
break;
|
|
|
|
case KEY_BRACKETLEFT:
|
|
|
|
nRetCode = Qt::Key_BracketLeft;
|
|
|
|
break;
|
|
|
|
case KEY_BRACKETRIGHT:
|
|
|
|
nRetCode = Qt::Key_BracketRight;
|
|
|
|
break;
|
|
|
|
case KEY_SEMICOLON:
|
|
|
|
nRetCode = Qt::Key_Semicolon;
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Special cases
|
|
|
|
case KEY_COPY:
|
|
|
|
nRetCode = Qt::Key_Copy;
|
|
|
|
break;
|
|
|
|
case KEY_CUT:
|
|
|
|
nRetCode = Qt::Key_Cut;
|
|
|
|
break;
|
|
|
|
case KEY_PASTE:
|
|
|
|
nRetCode = Qt::Key_Paste;
|
|
|
|
break;
|
|
|
|
case KEY_OPEN:
|
|
|
|
nRetCode = Qt::Key_Open;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (vclKeyCode.IsShift())
|
|
|
|
nRetCode += Qt::SHIFT;
|
|
|
|
if (vclKeyCode.IsMod1())
|
|
|
|
nRetCode += Qt::CTRL;
|
|
|
|
if (vclKeyCode.IsMod2())
|
|
|
|
nRetCode += Qt::ALT;
|
|
|
|
|
|
|
|
QKeySequence keySeq(nRetCode);
|
|
|
|
OUString sKeyName = toOUString(keySeq.toString());
|
|
|
|
|
|
|
|
return sKeyName;
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-01-08 09:38:24 +02:00
|
|
|
bool Qt5Frame::MapUnicodeToKeyCode(sal_Unicode /*aUnicode*/, LanguageType /*aLangType*/,
|
|
|
|
vcl::KeyCode& /*rKeyCode*/)
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2018-09-04 09:17:11 +02:00
|
|
|
// not supported yet
|
2017-10-21 13:50:30 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
LanguageType Qt5Frame::GetInputLanguage()
|
|
|
|
{
|
|
|
|
// fallback
|
|
|
|
return LANGUAGE_DONTKNOW;
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
static Color toColor(const QColor& rColor)
|
|
|
|
{
|
|
|
|
return Color(rColor.red(), rColor.green(), rColor.blue());
|
|
|
|
}
|
|
|
|
|
2017-12-08 11:37:18 +00:00
|
|
|
void Qt5Frame::UpdateSettings(AllSettings& rSettings)
|
|
|
|
{
|
2018-08-09 14:45:49 +02:00
|
|
|
if (Qt5Data::noNativeControls())
|
|
|
|
return;
|
|
|
|
|
2017-12-08 11:37:18 +00:00
|
|
|
StyleSettings style(rSettings.GetStyleSettings());
|
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
// General settings
|
|
|
|
QPalette pal = QApplication::palette();
|
|
|
|
|
|
|
|
style.SetToolbarIconSize(ToolbarIconSize::Large);
|
|
|
|
|
|
|
|
Color aFore = toColor(pal.color(QPalette::Active, QPalette::WindowText));
|
|
|
|
Color aBack = toColor(pal.color(QPalette::Active, QPalette::Window));
|
|
|
|
Color aText = toColor(pal.color(QPalette::Active, QPalette::Text));
|
|
|
|
Color aBase = toColor(pal.color(QPalette::Active, QPalette::Base));
|
|
|
|
Color aButn = toColor(pal.color(QPalette::Active, QPalette::ButtonText));
|
|
|
|
Color aMid = toColor(pal.color(QPalette::Active, QPalette::Mid));
|
|
|
|
Color aHigh = toColor(pal.color(QPalette::Active, QPalette::Highlight));
|
|
|
|
Color aHighText = toColor(pal.color(QPalette::Active, QPalette::HighlightedText));
|
2019-03-23 16:02:38 +00:00
|
|
|
Color aLink = toColor(pal.color(QPalette::Active, QPalette::Link));
|
|
|
|
Color aVisitedLink = toColor(pal.color(QPalette::Active, QPalette::LinkVisited));
|
2018-08-09 14:51:41 +02:00
|
|
|
|
|
|
|
style.SetSkipDisabledInMenus(true);
|
|
|
|
|
|
|
|
// Foreground
|
|
|
|
style.SetRadioCheckTextColor(aFore);
|
|
|
|
style.SetLabelTextColor(aFore);
|
|
|
|
style.SetDialogTextColor(aFore);
|
|
|
|
style.SetGroupTextColor(aFore);
|
|
|
|
|
|
|
|
// Text
|
|
|
|
style.SetFieldTextColor(aText);
|
|
|
|
style.SetFieldRolloverTextColor(aText);
|
|
|
|
style.SetWindowTextColor(aText);
|
|
|
|
style.SetToolTextColor(aText);
|
|
|
|
|
|
|
|
// Base
|
|
|
|
style.SetFieldColor(aBase);
|
|
|
|
style.SetWindowColor(aBase);
|
|
|
|
style.SetActiveTabColor(aBase);
|
|
|
|
|
|
|
|
// Buttons
|
|
|
|
style.SetButtonTextColor(aButn);
|
|
|
|
style.SetButtonRolloverTextColor(aButn);
|
|
|
|
style.SetButtonPressedRolloverTextColor(aButn);
|
|
|
|
|
|
|
|
// Tabs
|
|
|
|
style.SetTabTextColor(aButn);
|
|
|
|
style.SetTabRolloverTextColor(aButn);
|
|
|
|
style.SetTabHighlightTextColor(aButn);
|
|
|
|
|
|
|
|
// Disable color
|
|
|
|
style.SetDisableColor(toColor(pal.color(QPalette::Disabled, QPalette::WindowText)));
|
|
|
|
|
|
|
|
// Background
|
|
|
|
style.BatchSetBackgrounds(aBack);
|
|
|
|
style.SetInactiveTabColor(aBack);
|
|
|
|
|
|
|
|
// Workspace
|
|
|
|
style.SetWorkspaceColor(aMid);
|
|
|
|
|
|
|
|
// Selection
|
|
|
|
style.SetHighlightColor(aHigh);
|
|
|
|
style.SetHighlightTextColor(aHighText);
|
|
|
|
|
2019-03-23 16:02:38 +00:00
|
|
|
// Links
|
|
|
|
style.SetLinkColor(aLink);
|
|
|
|
style.SetVisitedLinkColor(aVisitedLink);
|
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
// Tooltip
|
|
|
|
style.SetHelpColor(toColor(QToolTip::palette().color(QPalette::Active, QPalette::ToolTipBase)));
|
|
|
|
style.SetHelpTextColor(
|
|
|
|
toColor(QToolTip::palette().color(QPalette::Active, QPalette::ToolTipText)));
|
|
|
|
|
2017-12-08 11:37:18 +00:00
|
|
|
const int flash_time = QApplication::cursorFlashTime();
|
|
|
|
style.SetCursorBlinkTime(flash_time != 0 ? flash_time / 2 : STYLE_CURSOR_NOBLINKTIME);
|
|
|
|
|
2018-08-09 14:51:41 +02:00
|
|
|
// Menu
|
2019-04-12 14:17:20 +02:00
|
|
|
std::unique_ptr<QMenuBar> pMenuBar = std::make_unique<QMenuBar>();
|
2018-08-09 14:51:41 +02:00
|
|
|
QPalette qMenuCG = pMenuBar->palette();
|
|
|
|
|
|
|
|
// Menu text and background color, theme specific
|
|
|
|
Color aMenuFore = toColor(qMenuCG.color(QPalette::WindowText));
|
|
|
|
Color aMenuBack = toColor(qMenuCG.color(QPalette::Window));
|
|
|
|
|
|
|
|
style.SetMenuTextColor(aMenuFore);
|
|
|
|
style.SetMenuBarTextColor(style.GetPersonaMenuBarTextColor().get_value_or(aMenuFore));
|
|
|
|
style.SetMenuColor(aMenuBack);
|
|
|
|
style.SetMenuBarColor(aMenuBack);
|
|
|
|
style.SetMenuHighlightColor(toColor(qMenuCG.color(QPalette::Highlight)));
|
|
|
|
style.SetMenuHighlightTextColor(toColor(qMenuCG.color(QPalette::HighlightedText)));
|
|
|
|
|
|
|
|
// set special menubar highlight text color
|
|
|
|
if (QApplication::style()->inherits("HighContrastStyle"))
|
|
|
|
ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor
|
|
|
|
= toColor(qMenuCG.color(QPalette::HighlightedText));
|
|
|
|
else
|
|
|
|
ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor = aMenuFore;
|
|
|
|
|
|
|
|
// set menubar rollover color
|
|
|
|
if (pMenuBar->style()->styleHint(QStyle::SH_MenuBar_MouseTracking))
|
|
|
|
{
|
|
|
|
style.SetMenuBarRolloverColor(toColor(qMenuCG.color(QPalette::Highlight)));
|
|
|
|
style.SetMenuBarRolloverTextColor(ImplGetSVData()->maNWFData.maMenuBarHighlightTextColor);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
style.SetMenuBarRolloverColor(aMenuBack);
|
|
|
|
style.SetMenuBarRolloverTextColor(aMenuFore);
|
|
|
|
}
|
|
|
|
style.SetMenuBarHighlightTextColor(style.GetMenuHighlightTextColor());
|
|
|
|
|
|
|
|
// Scroll bar size
|
|
|
|
style.SetScrollBarSize(QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent));
|
|
|
|
style.SetMinThumbSize(QApplication::style()->pixelMetric(QStyle::PM_ScrollBarSliderMin));
|
|
|
|
|
|
|
|
// These colors are used for the ruler text and marks
|
|
|
|
style.SetShadowColor(toColor(pal.color(QPalette::Disabled, QPalette::WindowText)));
|
|
|
|
style.SetDarkShadowColor(toColor(pal.color(QPalette::Inactive, QPalette::WindowText)));
|
|
|
|
|
2019-05-12 14:30:06 +02:00
|
|
|
m_bGraphicsInvalid = true;
|
2017-12-08 11:37:18 +00:00
|
|
|
rSettings.SetStyleSettings(style);
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::Beep() { QApplication::beep(); }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2017-10-30 18:45:46 +01:00
|
|
|
SalFrame::SalPointerState Qt5Frame::GetPointerState()
|
2017-10-21 13:50:30 +00:00
|
|
|
{
|
2017-10-30 19:55:18 +01:00
|
|
|
SalPointerState aState;
|
|
|
|
QPoint pos = QCursor::pos();
|
2017-11-08 11:28:04 +01:00
|
|
|
aState.maPos = Point(pos.x(), pos.y());
|
2018-01-08 09:40:00 +02:00
|
|
|
aState.mnState = GetMouseModCode(QGuiApplication::mouseButtons())
|
|
|
|
| GetKeyModCode(QGuiApplication::keyboardModifiers());
|
2017-10-30 19:55:18 +01:00
|
|
|
return aState;
|
2017-10-21 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
KeyIndicatorState Qt5Frame::GetIndicatorState() { return KeyIndicatorState(); }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::SimulateKeyPress(sal_uInt16 nKeyCode)
|
|
|
|
{
|
|
|
|
SAL_WARN("vcl.kde5", "missing simulate keypress " << nKeyCode);
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2017-11-08 11:28:04 +01:00
|
|
|
void Qt5Frame::SetParent(SalFrame* pNewParent) { m_pParent = static_cast<Qt5Frame*>(pNewParent); }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
bool Qt5Frame::SetPluginParent(SystemParentData* /*pNewParent*/)
|
|
|
|
{
|
|
|
|
//FIXME: no SetPluginParent impl. for kde5
|
|
|
|
return false;
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::ResetClipRegion() { m_bNullRegion = true; }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2019-02-25 14:49:41 +02:00
|
|
|
void Qt5Frame::BeginSetClipRegion(sal_uInt32)
|
2018-09-04 09:17:11 +02:00
|
|
|
{
|
|
|
|
m_aRegion = QRegion(QRect(QPoint(0, 0), m_pQWidget->size()));
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::UnionClipRegion(long nX, long nY, long nWidth, long nHeight)
|
|
|
|
{
|
2018-09-05 08:58:27 +02:00
|
|
|
m_aRegion = m_aRegion.united(QRegion(nX, nY, nWidth, nHeight));
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::EndSetClipRegion() { m_bNullRegion = false; }
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::SetScreenNumber(unsigned int nScreen)
|
|
|
|
{
|
|
|
|
if (isWindow())
|
|
|
|
{
|
|
|
|
QWindow* const pWindow = windowHandle();
|
|
|
|
if (pWindow)
|
2018-10-22 16:35:21 +02:00
|
|
|
{
|
|
|
|
QList<QScreen*> screens = QApplication::screens();
|
|
|
|
if (static_cast<int>(nScreen) < screens.size())
|
2018-10-25 12:29:34 +02:00
|
|
|
{
|
2019-05-08 14:02:37 +02:00
|
|
|
bool bSpanAllScreens = (nScreen == static_cast<unsigned int>(-1));
|
|
|
|
QRect screenGeo;
|
|
|
|
|
|
|
|
if (!bSpanAllScreens)
|
|
|
|
{
|
|
|
|
screenGeo = QApplication::desktop()->screenGeometry(nScreen);
|
|
|
|
pWindow->setScreen(QApplication::screens()[nScreen]);
|
|
|
|
}
|
|
|
|
else // special case: fullscreen over all available screens
|
|
|
|
{
|
|
|
|
// left-most screen
|
|
|
|
int nLeftScreen = QApplication::desktop()->screenNumber(QPoint(0, 0));
|
|
|
|
// entire virtual desktop
|
|
|
|
screenGeo = QApplication::screens()[nLeftScreen]->availableVirtualGeometry();
|
|
|
|
pWindow->setScreen(QApplication::screens()[nLeftScreen]);
|
|
|
|
}
|
2018-10-25 12:29:34 +02:00
|
|
|
|
|
|
|
// setScreen by itself has no effect, explicitly move the widget to
|
|
|
|
// the new screen
|
2019-05-08 14:02:37 +02:00
|
|
|
QWidget* const pWidget = m_pTopLevel ? m_pTopLevel : m_pQWidget;
|
2018-10-25 12:29:34 +02:00
|
|
|
pWidget->move(screenGeo.topLeft());
|
|
|
|
}
|
2018-10-22 16:35:21 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// index outta bounds, use primary screen
|
|
|
|
QScreen* primaryScreen = QApplication::primaryScreen();
|
|
|
|
pWindow->setScreen(primaryScreen);
|
|
|
|
}
|
|
|
|
}
|
2018-09-04 09:17:11 +02:00
|
|
|
}
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-09-04 09:17:11 +02:00
|
|
|
void Qt5Frame::SetApplicationID(const OUString&)
|
|
|
|
{
|
|
|
|
// So the hope is that QGuiApplication deals with this properly..
|
|
|
|
}
|
2017-10-21 13:50:30 +00:00
|
|
|
|
2018-10-04 17:12:40 +02:00
|
|
|
// Drag'n'drop foo
|
2018-12-03 16:40:27 +01:00
|
|
|
|
|
|
|
Qt5DragSource* Qt5DragSource::m_ActiveDragSource;
|
|
|
|
|
2018-10-04 17:12:40 +02:00
|
|
|
void Qt5Frame::registerDragSource(Qt5DragSource* pDragSource)
|
|
|
|
{
|
|
|
|
assert(!m_pDragSource);
|
|
|
|
m_pDragSource = pDragSource;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qt5Frame::deregisterDragSource(Qt5DragSource const* pDragSource)
|
|
|
|
{
|
|
|
|
assert(m_pDragSource == pDragSource);
|
|
|
|
(void)pDragSource;
|
|
|
|
m_pDragSource = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Qt5Frame::registerDropTarget(Qt5DropTarget* pDropTarget)
|
|
|
|
{
|
|
|
|
assert(!m_pDropTarget);
|
|
|
|
m_pDropTarget = pDropTarget;
|
2019-04-29 15:42:40 +02:00
|
|
|
m_pQWidget->setAcceptDrops(true);
|
2018-10-04 17:12:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Qt5Frame::deregisterDropTarget(Qt5DropTarget const* pDropTarget)
|
|
|
|
{
|
|
|
|
assert(m_pDropTarget == pDropTarget);
|
|
|
|
(void)pDropTarget;
|
|
|
|
m_pDropTarget = nullptr;
|
|
|
|
}
|
|
|
|
|
2019-02-28 15:03:12 +01:00
|
|
|
void Qt5Frame::draggingStarted(const int x, const int y, Qt::DropActions eActions,
|
2019-05-23 18:11:43 +02:00
|
|
|
Qt::KeyboardModifiers eKeyMod, const QMimeData* pQMimeData)
|
2018-10-15 14:44:29 +02:00
|
|
|
{
|
|
|
|
assert(m_pDropTarget);
|
|
|
|
|
2019-05-23 18:11:43 +02:00
|
|
|
sal_Int8 nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
|
|
|
|
if ((eKeyMod & Qt::ShiftModifier) && !(eKeyMod & Qt::ControlModifier))
|
|
|
|
nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
|
|
|
|
else if ((eKeyMod & Qt::ControlModifier) && !(eKeyMod & Qt::ShiftModifier))
|
|
|
|
nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_COPY;
|
|
|
|
else if ((eKeyMod & Qt::ShiftModifier) && (eKeyMod & Qt::ControlModifier))
|
|
|
|
nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_LINK;
|
|
|
|
|
2018-10-15 14:44:29 +02:00
|
|
|
css::datatransfer::dnd::DropTargetDragEnterEvent aEvent;
|
|
|
|
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
|
|
|
|
aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDragContext*>(m_pDropTarget);
|
|
|
|
aEvent.LocationX = x;
|
|
|
|
aEvent.LocationY = y;
|
2019-05-23 18:11:43 +02:00
|
|
|
|
|
|
|
// system drop action if neither Shift nor Control is held
|
|
|
|
if (!(eKeyMod & (Qt::ShiftModifier | Qt::ControlModifier)))
|
|
|
|
aEvent.DropAction = getPreferredDropAction(eActions);
|
|
|
|
// otherwise user-preferred action
|
|
|
|
else
|
|
|
|
aEvent.DropAction = nUserDropAction;
|
2019-02-28 15:03:12 +01:00
|
|
|
aEvent.SourceActions = toVclDropActions(eActions);
|
2018-10-15 14:44:29 +02:00
|
|
|
|
|
|
|
css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
|
2019-02-27 09:40:50 +01:00
|
|
|
if (!pQMimeData->hasFormat(sInternalMimeType))
|
2019-01-25 12:24:50 +01:00
|
|
|
xTransferable = new Qt5DnDTransferable(pQMimeData);
|
|
|
|
else
|
|
|
|
xTransferable = Qt5DragSource::m_ActiveDragSource->GetTransferable();
|
2018-10-15 14:44:29 +02:00
|
|
|
|
|
|
|
if (!m_bInDrag && xTransferable.is())
|
|
|
|
{
|
|
|
|
css::uno::Sequence<css::datatransfer::DataFlavor> aFormats
|
|
|
|
= xTransferable->getTransferDataFlavors();
|
|
|
|
aEvent.SupportedDataFlavors = aFormats;
|
|
|
|
|
|
|
|
m_pDropTarget->fire_dragEnter(aEvent);
|
|
|
|
m_bInDrag = true;
|
|
|
|
}
|
2018-10-18 13:13:29 +02:00
|
|
|
else
|
|
|
|
m_pDropTarget->fire_dragOver(aEvent);
|
2018-10-15 14:44:29 +02:00
|
|
|
}
|
|
|
|
|
2019-05-23 18:11:43 +02:00
|
|
|
void Qt5Frame::dropping(const int x, const int y, Qt::KeyboardModifiers eKeyMod,
|
|
|
|
const QMimeData* pQMimeData)
|
2018-10-18 01:01:14 +02:00
|
|
|
{
|
|
|
|
assert(m_pDropTarget);
|
|
|
|
|
|
|
|
css::datatransfer::dnd::DropTargetDropEvent aEvent;
|
|
|
|
aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(m_pDropTarget);
|
|
|
|
aEvent.Context = static_cast<css::datatransfer::dnd::XDropTargetDropContext*>(m_pDropTarget);
|
|
|
|
aEvent.LocationX = x;
|
|
|
|
aEvent.LocationY = y;
|
2019-05-23 18:11:43 +02:00
|
|
|
|
|
|
|
if (!(eKeyMod & (Qt::ShiftModifier | Qt::ControlModifier)))
|
|
|
|
aEvent.DropAction = m_pDropTarget->proposedDragAction()
|
|
|
|
| css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
|
|
|
|
else
|
|
|
|
aEvent.DropAction = m_pDropTarget->proposedDragAction();
|
2018-10-18 01:01:14 +02:00
|
|
|
aEvent.SourceActions = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
|
|
|
|
|
|
|
|
css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
|
2019-02-27 09:40:50 +01:00
|
|
|
if (!pQMimeData->hasFormat(sInternalMimeType))
|
2019-01-25 12:24:50 +01:00
|
|
|
xTransferable = new Qt5DnDTransferable(pQMimeData);
|
|
|
|
else
|
|
|
|
xTransferable = Qt5DragSource::m_ActiveDragSource->GetTransferable();
|
2018-10-18 01:01:14 +02:00
|
|
|
aEvent.Transferable = xTransferable;
|
|
|
|
|
|
|
|
m_pDropTarget->fire_drop(aEvent);
|
2018-10-18 13:13:29 +02:00
|
|
|
m_bInDrag = false;
|
|
|
|
|
|
|
|
if (m_pDragSource)
|
|
|
|
{
|
2018-11-30 10:32:11 +01:00
|
|
|
m_pDragSource->fire_dragEnd(m_pDropTarget->proposedDragAction());
|
2018-10-18 13:13:29 +02:00
|
|
|
}
|
2018-10-18 01:01:14 +02:00
|
|
|
}
|
|
|
|
|
2017-10-21 13:50:30 +00:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|