/* -*- 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 . */ #include "Qt5Frame.hxx" #include "Qt5Tools.hxx" #include "Qt5Instance.hxx" #include "Qt5Graphics.hxx" #include "Qt5Widget.hxx" #include "Qt5Data.hxx" #include #include #include #include #include #include #include #include #include #include #include static void SvpDamageHandler(void* handle, sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight) { Qt5Frame* pThis = static_cast(handle); pThis->Damage(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight); } Qt5Frame::Qt5Frame(Qt5Frame* pParent, SalFrameStyleFlags nStyle, bool bUseCairo) : m_bUseCairo(bUseCairo) , m_bGraphicsInUse(false) , m_ePointerStyle(PointerStyle::Arrow) , m_bDefaultSize(true) , m_bDefaultPos(true) { Qt5Instance* pInst = static_cast(GetSalData()->m_pInstance); pInst->insertFrame(this); m_aDamageHandler.handle = this; m_aDamageHandler.damaged = ::SvpDamageHandler; if (nStyle & SalFrameStyleFlags::DEFAULT) // ensure default style { nStyle |= SalFrameStyleFlags::MOVEABLE | SalFrameStyleFlags::SIZEABLE | SalFrameStyleFlags::CLOSEABLE; nStyle &= ~SalFrameStyleFlags::FLOAT; } m_nStyle = nStyle; m_pParent = pParent; Qt::WindowFlags aWinFlags; if (!(nStyle & SalFrameStyleFlags::SYSTEMCHILD)) { if (nStyle & SalFrameStyleFlags::INTRO) aWinFlags |= Qt::SplashScreen; else if (nStyle & (SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::TOOLTIP)) aWinFlags |= Qt::ToolTip; else if ((nStyle & SalFrameStyleFlags::FLOAT) && !(nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION)) aWinFlags |= Qt::Popup; else if (nStyle & SalFrameStyleFlags::DIALOG && pParent) aWinFlags |= Qt::Dialog; else if (nStyle & SalFrameStyleFlags::TOOLWINDOW) aWinFlags |= Qt::Tool; else if ((nStyle & SalFrameStyleFlags::OWNERDRAWDECORATION)) aWinFlags |= Qt::Window | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus; else aWinFlags |= Qt::Window; } m_pQWidget.reset(new Qt5Widget(*this, pParent ? pParent->GetQWidget() : nullptr, aWinFlags)); if (pParent && !(pParent->m_nStyle & SalFrameStyleFlags::PLUG)) { QWindow* pParentWindow = pParent->GetQWidget()->window()->windowHandle(); QWindow* pChildWindow = m_pQWidget->window()->windowHandle(); if (pParentWindow != pChildWindow) pChildWindow->setTransientParent(pParentWindow); } } Qt5Frame::~Qt5Frame() { Qt5Instance* pInst = static_cast(GetSalData()->m_pInstance); pInst->eraseFrame(this); } void Qt5Frame::Damage(sal_Int32 nExtentsX, sal_Int32 nExtentsY, sal_Int32 nExtentsWidth, sal_Int32 nExtentsHeight) const { m_pQWidget->update(nExtentsX, nExtentsY, nExtentsWidth, nExtentsHeight); } void Qt5Frame::TriggerPaintEvent() { QSize aSize(m_pQWidget->size()); SalPaintEvent aPaintEvt(0, 0, aSize.width(), aSize.height(), true); CallCallback(SalEvent::Paint, &aPaintEvt); } void Qt5Frame::TriggerPaintEvent(QRect aRect) { SalPaintEvent aPaintEvt(aRect.x(), aRect.y(), aRect.width(), aRect.height(), true); CallCallback(SalEvent::Paint, &aPaintEvt); } SalGraphics* Qt5Frame::AcquireGraphics() { if (m_bGraphicsInUse) return nullptr; m_bGraphicsInUse = true; if (m_bUseCairo) { if (!m_pSvpGraphics.get()) { int width = m_pQWidget->size().width(); int height = m_pQWidget->size().height(); m_pSvpGraphics.reset(new SvpSalGraphics()); m_pSurface.reset(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height)); m_pSvpGraphics->setSurface(m_pSurface.get(), basegfx::B2IVector(width, height)); cairo_surface_set_user_data(m_pSurface.get(), SvpSalGraphics::getDamageKey(), &m_aDamageHandler, nullptr); TriggerPaintEvent(); } return m_pSvpGraphics.get(); } else { if (!m_pQt5Graphics.get()) { m_pQt5Graphics.reset(new Qt5Graphics(this)); m_pQImage.reset(new QImage(m_pQWidget->size(), Qt5_DefaultFormat32)); m_pQt5Graphics->ChangeQImage(m_pQImage.get()); TriggerPaintEvent(); } return m_pQt5Graphics.get(); } } void Qt5Frame::ReleaseGraphics(SalGraphics* pSalGraph) { (void)pSalGraph; if (m_bUseCairo) assert(pSalGraph == m_pSvpGraphics.get()); else assert(pSalGraph == m_pQt5Graphics.get()); m_bGraphicsInUse = false; } bool Qt5Frame::PostEvent(ImplSVEvent* pData) { Qt5Instance* pInst = static_cast(GetSalData()->m_pInstance); pInst->PostEvent(this, pData, SalEvent::UserEvent); return true; } void Qt5Frame::SetTitle(const OUString& rTitle) { m_pQWidget->window()->setWindowTitle(toQString(rTitle)); } void Qt5Frame::SetIcon(sal_uInt16 nIcon) { if (m_nStyle & (SalFrameStyleFlags::PLUG | SalFrameStyleFlags::SYSTEMCHILD | SalFrameStyleFlags::FLOAT | SalFrameStyleFlags::INTRO | SalFrameStyleFlags::OWNERDRAWDECORATION) || !m_pQWidget->isWindow()) return; const char* appicon; 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"; QIcon aIcon = QIcon::fromTheme(appicon); m_pQWidget->window()->setWindowIcon(aIcon); } void Qt5Frame::SetMenu(SalMenu* pMenu) {} void Qt5Frame::DrawMenuBar() {} void Qt5Frame::SetExtendedFrameStyle(SalExtStyle nExtStyle) {} void Qt5Frame::Show(bool bVisible, bool bNoActivate) { assert(m_pQWidget.get()); m_pQWidget->setVisible(bVisible); } void Qt5Frame::SetMinClientSize(long nWidth, long nHeight) { if (!isChild()) m_pQWidget->setMinimumSize(nWidth, nHeight); } void Qt5Frame::SetMaxClientSize(long nWidth, long nHeight) { if (!isChild()) m_pQWidget->setMaximumSize(nWidth, nHeight); } void Qt5Frame::Center() { if (m_pParent) { QWidget* pWindow = m_pParent->GetQWidget()->window(); m_pQWidget->move(pWindow->frameGeometry().topLeft() + pWindow->rect().center() - m_pQWidget->rect().center()); } } Size Qt5Frame::CalcDefaultSize() { assert(m_pQWidget->isWindow()); QScreen* pScreen = m_pQWidget->windowHandle()->screen(); if (!pScreen) return Size(); return bestmaxFrameSizeForScreenSize(toSize(pScreen->size())); } void Qt5Frame::SetDefaultSize() { Size aDefSize = CalcDefaultSize(); SetPosSize(0, 0, aDefSize.Width(), aDefSize.Height(), SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT); } void Qt5Frame::SetPosSize(long nX, long nY, long nWidth, long nHeight, sal_uInt16 nFlags) { if (!m_pQWidget->isWindow() || isChild(true, false)) return; if ((nFlags & (SAL_FRAME_POSSIZE_WIDTH | SAL_FRAME_POSSIZE_HEIGHT)) && (nWidth > 0 && nHeight > 0) // sometimes stupid things happen ) { m_bDefaultSize = false; if (isChild(false) || !m_pQWidget->isMaximized()) { m_pQWidget->resize(nWidth, nHeight); } } else if (m_bDefaultSize) SetDefaultSize(); m_bDefaultSize = false; if (nFlags & (SAL_FRAME_POSSIZE_X | SAL_FRAME_POSSIZE_Y)) { if (m_pParent) { QRect aRect = m_pParent->GetQWidget()->geometry(); nX += aRect.x(); nY += aRect.y(); } m_bDefaultPos = false; m_pQWidget->move(nX, nY); } else if (m_bDefaultPos) Center(); m_bDefaultPos = false; } void Qt5Frame::GetClientSize(long& rWidth, long& rHeight) { rWidth = m_pQWidget->width(); rHeight = m_pQWidget->height(); } void Qt5Frame::GetWorkArea(tools::Rectangle& rRect) { if (!m_pQWidget->isWindow()) return; QScreen* pScreen = m_pQWidget->windowHandle()->screen(); if (!pScreen) return; QSize aSize = pScreen->availableVirtualSize(); rRect = tools::Rectangle(0, 0, aSize.width(), aSize.height()); } SalFrame* Qt5Frame::GetParent() const { return m_pParent; } void Qt5Frame::SetWindowState(const SalFrameState* pState) { if (!m_pQWidget->isWindow() || !pState || isChild(true, false)) return; const WindowStateMask nMaxGeometryMask = WindowStateMask::X | WindowStateMask::Y | WindowStateMask::Width | WindowStateMask::Height | WindowStateMask::MaximizedX | WindowStateMask::MaximizedY | WindowStateMask::MaximizedWidth | WindowStateMask::MaximizedHeight; if ((pState->mnMask & WindowStateMask::State) && (pState->mnState & WindowStateState::Maximized) && (pState->mnMask & nMaxGeometryMask) == nMaxGeometryMask) m_pQWidget->showMaximized(); else if (pState->mnMask & (WindowStateMask::X | WindowStateMask::Y | WindowStateMask::Width | WindowStateMask::Height)) { sal_uInt16 nPosSizeFlags = 0; QPoint aPos = m_pQWidget->pos(); QPoint aParentPos; if (m_pParent) aParentPos = m_pParent->GetQWidget()->window()->pos(); long nX = pState->mnX - aParentPos.x(); long nY = pState->mnY - aParentPos.y(); if (pState->mnMask & WindowStateMask::X) nPosSizeFlags |= SAL_FRAME_POSSIZE_X; else nX = aPos.x() - aParentPos.x(); if (pState->mnMask & WindowStateMask::Y) nPosSizeFlags |= SAL_FRAME_POSSIZE_Y; else nY = aPos.y() - aParentPos.y(); if (pState->mnMask & WindowStateMask::Width) nPosSizeFlags |= SAL_FRAME_POSSIZE_WIDTH; if (pState->mnMask & WindowStateMask::Height) nPosSizeFlags |= SAL_FRAME_POSSIZE_HEIGHT; SetPosSize(nX, nY, pState->mnWidth, pState->mnHeight, nPosSizeFlags); } else if (pState->mnMask & WindowStateMask::State && !isChild()) { if ((pState->mnState & WindowStateState::Minimized) && m_pQWidget->isWindow()) m_pQWidget->showMinimized(); else m_pQWidget->showNormal(); } } bool Qt5Frame::GetWindowState(SalFrameState* pState) { pState->mnState = WindowStateState::Normal; pState->mnMask = WindowStateMask::State; if (m_pQWidget->isMinimized() || !m_pQWidget->windowHandle()) pState->mnState |= WindowStateState::Minimized; else if (m_pQWidget->isMaximized()) { pState->mnState |= WindowStateState::Maximized; } else { QRect rect = m_pQWidget->geometry(); pState->mnX = rect.x(); pState->mnY = rect.y(); pState->mnWidth = rect.width(); pState->mnHeight = rect.height(); pState->mnMask |= WindowStateMask::X | WindowStateMask::Y | WindowStateMask::Width | WindowStateMask::Height; } return true; } void Qt5Frame::ShowFullScreen(bool bFullScreen, sal_Int32 nDisplay) {} void Qt5Frame::StartPresentation(bool bStart) {} void Qt5Frame::SetAlwaysOnTop(bool bOnTop) {} void Qt5Frame::ToTop(SalFrameToTop nFlags) {} void Qt5Frame::SetPointer(PointerStyle ePointerStyle) { QWindow* pWindow = m_pQWidget->window()->windowHandle(); if (!pWindow) return; if (ePointerStyle == m_ePointerStyle) return; m_ePointerStyle = ePointerStyle; pWindow->setCursor(static_cast(GetSalData())->getCursor(ePointerStyle)); } void Qt5Frame::CaptureMouse(bool bMouse) {} void Qt5Frame::SetPointerPos(long nX, long nY) {} void Qt5Frame::Flush() {} void Qt5Frame::Flush(const tools::Rectangle& rRect) {} void Qt5Frame::SetInputContext(SalInputContext* pContext) {} void Qt5Frame::EndExtTextInput(EndExtTextInputFlags nFlags) {} OUString Qt5Frame::GetKeyName(sal_uInt16 nKeyCode) { return OUString(); } bool Qt5Frame::MapUnicodeToKeyCode(sal_Unicode aUnicode, LanguageType aLangType, vcl::KeyCode& rKeyCode) { return false; } LanguageType Qt5Frame::GetInputLanguage() { return LANGUAGE_DONTKNOW; } void Qt5Frame::UpdateSettings(AllSettings& rSettings) {} void Qt5Frame::Beep() {} const SystemEnvData* Qt5Frame::GetSystemData() const { return nullptr; } SalFrame::SalPointerState Qt5Frame::GetPointerState() { SalPointerState aState; QPoint pos = QCursor::pos(); aState.maPos = Point(pos.x(), pos.y()); aState.mnState = GetMouseModCode(qApp->mouseButtons()) | GetKeyModCode(qApp->keyboardModifiers()); return aState; } KeyIndicatorState Qt5Frame::GetIndicatorState() { return KeyIndicatorState(); } void Qt5Frame::SimulateKeyPress(sal_uInt16 nKeyCode) {} void Qt5Frame::SetParent(SalFrame* pNewParent) { m_pParent = static_cast(pNewParent); } bool Qt5Frame::SetPluginParent(SystemParentData* pNewParent) { return false; } void Qt5Frame::ResetClipRegion() {} void Qt5Frame::BeginSetClipRegion(sal_uLong nRects) {} void Qt5Frame::UnionClipRegion(long nX, long nY, long nWidth, long nHeight) {} void Qt5Frame::EndSetClipRegion() {} void Qt5Frame::SetScreenNumber(unsigned int) {} void Qt5Frame::SetApplicationID(const OUString&) {} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */