diff options
29 files changed, 725 insertions, 285 deletions
diff --git a/include/sfx2/basedlgs.hxx b/include/sfx2/basedlgs.hxx index d4279599fe4b..1c3e2b37caa6 100644 --- a/include/sfx2/basedlgs.hxx +++ b/include/sfx2/basedlgs.hxx @@ -107,6 +107,41 @@ public: DECL_LINK(TimerHdl, Timer *, void); }; +class SFX2_DLLPUBLIC SfxDialogController : public weld::GenericDialogController +{ +private: + DECL_DLLPRIVATE_LINK(InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*); +public: + SfxDialogController(weld::Widget* pParent, const OUString& rUIFile, const OString& rDialogId); +}; + +class SfxModelessDialog_Impl; +class SFX2_DLLPUBLIC SfxModelessDialogController : public SfxDialogController +{ + SfxBindings* m_pBindings; + std::unique_ptr<SfxModelessDialog_Impl> m_xImpl; + + SfxModelessDialogController(SfxModelessDialogController&) = delete; + void operator =(SfxModelessDialogController&) = delete; + + void Init(SfxBindings *pBindinx, SfxChildWindow *pCW); + + DECL_DLLPRIVATE_LINK(FocusInHdl, weld::Widget&, void); + DECL_DLLPRIVATE_LINK(FocusOutHdl, weld::Widget&, void); +protected: + SfxModelessDialogController(SfxBindings*, SfxChildWindow* pChildWin, + weld::Window* pParent, const OUString& rUIXMLDescription, const OString& rID); + virtual ~SfxModelessDialogController() override; + +public: + virtual void FillInfo(SfxChildWinInfo&) const; + void Initialize (SfxChildWinInfo const * pInfo); + void Close(); + void DeInit(); + void EndDialog(); + SfxBindings& GetBindings() { return *m_pBindings; } +}; + // class SfxFloatingWindow -------------------------------------------------- class SfxFloatingWindow_Impl; class SFX2_DLLPUBLIC SfxFloatingWindow: public FloatingWindow @@ -188,14 +223,6 @@ private: std::unique_ptr<SingleTabDlgImpl> pImpl; }; -class SFX2_DLLPUBLIC SfxDialogController : public weld::GenericDialogController -{ -private: - DECL_DLLPRIVATE_LINK(InstallLOKNotifierHdl, void*, vcl::ILibreOfficeKitNotifier*); -public: - SfxDialogController(weld::Widget* pParent, const OUString& rUIFile, const OString& rDialogId); -}; - class SFX2_DLLPUBLIC SfxSingleTabDialogController : public SfxDialogController { private: diff --git a/include/sfx2/childwin.hxx b/include/sfx2/childwin.hxx index 8c46889e533f..9a12bf896071 100644 --- a/include/sfx2/childwin.hxx +++ b/include/sfx2/childwin.hxx @@ -143,9 +143,10 @@ public: class SFX2_DLLPUBLIC SfxChildWindow { - VclPtr<vcl::Window> pParent; // parent window ( Topwindow ) - sal_uInt16 const nType; // ChildWindow-Id + VclPtr<vcl::Window> pParent; // parent window ( Topwindow ) + sal_uInt16 const nType; // ChildWindow-Id VclPtr<vcl::Window> pWindow; // actual contents + std::shared_ptr<SfxModelessDialogController> xController; // actual contents SfxChildAlignment eChildAlignment; // Current css::drawing::Alignment std::unique_ptr< SfxChildWindow_Impl> pImpl; // Implementation data std::unique_ptr<SfxChildWindowContext> pContext; // With context-sensitive ChildWindows: @@ -161,6 +162,9 @@ public: void Destroy(); vcl::Window* GetWindow() const { return pWindow; } + void SetController(std::shared_ptr<SfxModelessDialogController> controller) { xController = controller; } + void ClearController() { xController.reset(); } + std::shared_ptr<SfxModelessDialogController>& GetController() { return xController; } vcl::Window* GetParent() const { return pParent; } SfxChildAlignment GetAlignment() const diff --git a/include/vcl/dialog.hxx b/include/vcl/dialog.hxx index c5a3997566ff..b6d7bbdb110e 100644 --- a/include/vcl/dialog.hxx +++ b/include/vcl/dialog.hxx @@ -139,7 +139,7 @@ public: virtual FactoryFunction GetUITestFactory() const override; private: - bool ImplStartExecuteModal(); + bool ImplStartExecute(); static void ImplEndExecuteModal(); void ImplSetModalInputMode(bool bModal); public: @@ -174,6 +174,9 @@ public: void GrabFocusToFirstControl(); virtual void Resize() override; + void Activate() override; + + void SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink); void add_button(PushButton* pButton, int nResponse, bool bTransferOwnership); @@ -188,8 +191,6 @@ class VCL_DLLPUBLIC ModelessDialog : public Dialog public: explicit ModelessDialog( vcl::Window* pParent, const OUString& rID, const OUString& rUIXMLDescription, Dialog::InitFlag eFlag = Dialog::InitFlag::Default ); - - void Activate() override; }; class VCL_DLLPUBLIC ModalDialog : public Dialog diff --git a/include/vcl/weld.hxx b/include/vcl/weld.hxx index 7fcd7b884a52..fdb0cba3379e 100644 --- a/include/vcl/weld.hxx +++ b/include/vcl/weld.hxx @@ -196,8 +196,14 @@ public: virtual void set_busy_cursor(bool bBusy) = 0; virtual void window_move(int x, int y) = 0; virtual void set_modal(bool bModal) = 0; + virtual bool get_modal() const = 0; virtual bool get_extents_relative_to(Window& rRelative, int& x, int& y, int& width, int& height) = 0; + virtual bool get_resizable() const = 0; + virtual Size get_size() const = 0; + virtual Point get_position() const = 0; + virtual void set_window_state(const OString& rStr) = 0; + virtual OString get_window_state(WindowStateMask nMask) const = 0; virtual css::uno::Reference<css::awt::XWindow> GetXWindow() = 0; diff --git a/sfx2/source/appl/childwin.cxx b/sfx2/source/appl/childwin.cxx index aa8018eb0ed4..e2bbc3ee9e7f 100644 --- a/sfx2/source/appl/childwin.cxx +++ b/sfx2/source/appl/childwin.cxx @@ -194,7 +194,10 @@ SfxChildWindow::~SfxChildWindow() { pContext.reset(); ClearWorkwin(); - pWindow.disposeAndClear(); + if (xController) + xController->DeInit(); + else + pWindow.disposeAndClear(); } @@ -270,7 +273,7 @@ SfxChildWindow* SfxChildWindow::CreateChildWindow( sal_uInt16 nId, DBG_ASSERT(pFact && (pChild || !rInfo.bVisible), "ChildWindow-Typ not registered!"); - if ( pChild && !pChild->pWindow ) + if (pChild && (!pChild->pWindow && !pChild->xController)) { DELETEZ(pChild); SAL_INFO("sfx.appl", "ChildWindow has no Window!"); @@ -319,26 +322,38 @@ void SfxChildWindow::SetAlignment(SfxChildAlignment eAlign) SfxChildWinInfo SfxChildWindow::GetInfo() const { - SfxChildWinInfo aInfo(pImpl->pFact->aInfo); - aInfo.aPos = pWindow->GetPosPixel(); - aInfo.aSize = pWindow->GetSizePixel(); - if ( pWindow->IsSystemWindow() ) + if (xController) { + weld::Dialog* pDialog = xController->getDialog(); + aInfo.aPos = pDialog->get_position(); + aInfo.aSize = pDialog->get_size(); WindowStateMask nMask = WindowStateMask::Pos | WindowStateMask::State; - if ( pWindow->GetStyle() & WB_SIZEABLE ) - nMask |= ( WindowStateMask::Width | WindowStateMask::Height ); - aInfo.aWinState = static_cast<SystemWindow*>(pWindow.get())->GetWindowState( nMask ); + if (pDialog->get_resizable()) + nMask |= (WindowStateMask::Width | WindowStateMask::Height); + aInfo.aWinState = pDialog->get_window_state(nMask); } - else if (DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pWindow.get())) + else if (pWindow) { - if (pDockingWindow->GetFloatingWindow()) - aInfo.aWinState = pDockingWindow->GetFloatingWindow()->GetWindowState(); - else if (SfxDockingWindow* pSfxDockingWindow = dynamic_cast<SfxDockingWindow*>(pDockingWindow)) + aInfo.aPos = pWindow->GetPosPixel(); + aInfo.aSize = pWindow->GetSizePixel(); + if ( pWindow->IsSystemWindow() ) { - SfxChildWinInfo aTmpInfo; - pSfxDockingWindow->FillInfo( aTmpInfo ); - aInfo.aExtraString = aTmpInfo.aExtraString; + WindowStateMask nMask = WindowStateMask::Pos | WindowStateMask::State; + if ( pWindow->GetStyle() & WB_SIZEABLE ) + nMask |= ( WindowStateMask::Width | WindowStateMask::Height ); + aInfo.aWinState = static_cast<SystemWindow*>(pWindow.get())->GetWindowState( nMask ); + } + else if (DockingWindow* pDockingWindow = dynamic_cast<DockingWindow*>(pWindow.get())) + { + if (pDockingWindow->GetFloatingWindow()) + aInfo.aWinState = pDockingWindow->GetFloatingWindow()->GetWindowState(); + else if (SfxDockingWindow* pSfxDockingWindow = dynamic_cast<SfxDockingWindow*>(pDockingWindow)) + { + SfxChildWinInfo aTmpInfo; + pSfxDockingWindow->FillInfo( aTmpInfo ); + aInfo.aExtraString = aTmpInfo.aExtraString; + } } } @@ -608,12 +623,24 @@ void SfxChildWindow::SetVisible_Impl( bool bVis ) void SfxChildWindow::Hide() { - pWindow->Hide(); + if (xController) + xController->EndDialog(); + else + pWindow->Hide(); } void SfxChildWindow::Show( ShowFlags nFlags ) { - pWindow->Show(true, nFlags); + if (xController) + { + if (!xController->getDialog()->get_visible()) + { + weld::DialogController::runAsync(xController, + [=](sal_Int32 /*nResult*/){ xController->Close(); }); + } + } + else + pWindow->Show(true, nFlags); } vcl::Window* SfxChildWindow::GetContextWindow( SfxModule const *pModule ) const @@ -646,7 +673,15 @@ bool SfxChildWindow::QueryClose() } if ( bAllow ) - bAllow = !GetWindow()->IsInModalMode(); + { + if (GetController()) + { + weld::Dialog* pDialog = GetController()->getDialog(); + bAllow = !pDialog->get_visible() || !pDialog->get_modal(); + } + else if (GetWindow()) + bAllow = !GetWindow()->IsInModalMode(); + } return bAllow; } diff --git a/sfx2/source/appl/workwin.cxx b/sfx2/source/appl/workwin.cxx index 363b3005d1f9..69e29d2e6d83 100644 --- a/sfx2/source/appl/workwin.cxx +++ b/sfx2/source/appl/workwin.cxx @@ -864,7 +864,6 @@ bool SfxWorkWindow::PrepareClose_Impl() return true; } - SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( vcl::Window& rWindow, SfxChildAlignment eAlign ) { @@ -885,6 +884,19 @@ SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl( vcl::Window& rWindow, return aChildren.back(); } +SfxChild_Impl* SfxWorkWindow::RegisterChild_Impl(std::shared_ptr<SfxModelessDialogController>& rController, + SfxChildAlignment eAlign ) +{ + DBG_ASSERT( aChildren.size() < 255, "too many children" ); + DBG_ASSERT( SfxChildAlignValid(eAlign), "invalid align" ); + + SfxChild_Impl *pChild = new SfxChild_Impl(rController, eAlign); + + aChildren.push_back(pChild); + bSorted = false; + nChildren++; + return aChildren.back(); +} void SfxWorkWindow::ReleaseChild_Impl( vcl::Window& rWindow ) { @@ -910,6 +922,29 @@ void SfxWorkWindow::ReleaseChild_Impl( vcl::Window& rWindow ) } } +void SfxWorkWindow::ReleaseChild_Impl(SfxModelessDialogController& rController) +{ + + SfxChild_Impl *pChild = nullptr; + decltype(aChildren)::size_type nPos; + for ( nPos = 0; nPos < aChildren.size(); ++nPos ) + { + pChild = aChildren[nPos]; + if (pChild && pChild->xController.get() == &rController) + break; + } + + if ( nPos < aChildren.size() ) + { + bSorted = false; + nChildren--; + aChildren.erase(aChildren.begin() + nPos); + delete pChild; + } + else { + OSL_FAIL( "releasing unregistered child" ); + } +} SfxChild_Impl* SfxWorkWindow::FindChild_Impl( const vcl::Window& rWindow ) const { @@ -933,8 +968,10 @@ void SfxWorkWindow::ShowChildren_Impl() for (SfxChild_Impl* pCli : aChildren) { + if (!pCli) + continue; SfxChildWin_Impl* pCW = nullptr; - if ( pCli && pCli->pWin ) + if (pCli->pWin || pCli->xController) { // We have to find the SfxChildWin_Impl to retrieve the // SFX_CHILDWIN flags that can influence visibility. @@ -961,12 +998,27 @@ void SfxWorkWindow::ShowChildren_Impl() if ( SfxChildVisibility::VISIBLE == (pCli->nVisible & SfxChildVisibility::VISIBLE) && bVisible ) { ShowFlags nFlags = pCli->bSetFocus ? ShowFlags::NONE : ShowFlags::NoFocusChange | ShowFlags::NoActivate; - pCli->pWin->Show(true, nFlags); + if (pCli->xController) + { + if (!pCli->xController->getDialog()->get_visible()) + { + weld::DialogController::runAsync(pCli->xController, + [=](sal_Int32 /*nResult*/){ pCli->xController->Close(); }); + } + } + else + pCli->pWin->Show(true, nFlags); pCli->bSetFocus = false; } else { - pCli->pWin->Hide(); + if (pCli->xController) + { + if (pCli->xController->getDialog()->get_visible()) + pCli->xController->response(RET_CLOSE); + } + else + pCli->pWin->Hide(); } } } @@ -978,12 +1030,15 @@ void SfxWorkWindow::HideChildren_Impl() for ( sal_uInt16 nPos = aChildren.size(); nPos > 0; --nPos ) { SfxChild_Impl *pChild = aChildren[nPos-1]; - if (pChild && pChild->pWin) + if (!pChild) + continue; + if (pChild->xController) + pChild->xController->response(RET_CLOSE); + else if (pChild->pWin) pChild->pWin->Hide(); } } - void SfxWorkWindow::ResetObjectBars_Impl() { for ( auto & n: aObjBarList ) @@ -1324,7 +1379,10 @@ void SfxWorkWindow::CreateChildWin_Impl( SfxChildWin_Impl *pCW, bool bSetFocus ) { // The window is not docked or docked outside of one split windows // and must therefore be registered explicitly as a Child - pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment()); + if (pChildWin->GetController()) + pCW->pCli = RegisterChild_Impl(pChildWin->GetController(), pChildWin->GetAlignment()); + else + pCW->pCli = RegisterChild_Impl(*(pChildWin->GetWindow()), pChildWin->GetAlignment()); pCW->pCli->nVisible = SfxChildVisibility::VISIBLE; if ( pChildWin->GetAlignment() != SfxChildAlignment::NOALIGNMENT && bIsFullScreen ) pCW->pCli->nVisible ^= SfxChildVisibility::ACTIVE; @@ -1363,7 +1421,10 @@ void SfxWorkWindow::RemoveChildWin_Impl( SfxChildWin_Impl *pCW ) // Child window is a direct child window and must therefore unregister // itself from the WorkWindow pCW->pCli = nullptr; - ReleaseChild_Impl(*pChildWin->GetWindow()); + if (pChildWin->GetController()) + ReleaseChild_Impl(*pChildWin->GetController()); + else + ReleaseChild_Impl(*pChildWin->GetWindow()); } else { @@ -2382,8 +2443,12 @@ void SfxWorkWindow::DataChanged_Impl() for (n=0; n<nCount; n++) { SfxChildWin_Impl*pCW = aChildWins[n].get(); - if ( pCW && pCW->pWin ) - pCW->pWin->GetWindow()->UpdateSettings( Application::GetSettings() ); + if (pCW && pCW->pWin) + { + // TODO does this really have any meaning ? + if (pCW->pWin->GetWindow()) + pCW->pWin->GetWindow()->UpdateSettings(Application::GetSettings()); + } } ArrangeChildren_Impl(); diff --git a/sfx2/source/dialog/basedlgs.cxx b/sfx2/source/dialog/basedlgs.cxx index f4a07696af43..8fcb0cb1137f 100644 --- a/sfx2/source/dialog/basedlgs.cxx +++ b/sfx2/source/dialog/basedlgs.cxx @@ -56,6 +56,7 @@ public: OString aWinState; SfxChildWindow* pMgr; bool bConstructed; + bool bClosing; void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override; Idle aMoveIdle; @@ -284,6 +285,7 @@ void SfxModelessDialog::Init(SfxBindings *pBindinx, SfxChildWindow *pCW) pImpl.reset(new SfxModelessDialog_Impl); pImpl->pMgr = pCW; pImpl->bConstructed = false; + pImpl->bClosing = false; if ( pBindinx ) pImpl->StartListening( *pBindinx ); pImpl->aMoveIdle.SetPriority(TaskPriority::RESIZE); @@ -382,6 +384,129 @@ void SfxModelessDialog::FillInfo(SfxChildWinInfo& rInfo) const rInfo.nFlags |= SfxChildWindowFlags::ZOOMIN; } +void SfxModelessDialogController::Initialize(SfxChildWinInfo const *pInfo) + +/* [Description] + + Initialization of the class SfxModelessDialog via a SfxChildWinInfo. + The initialization is done only in a 2nd step after the constructor, this + constructor should be called from the derived class or from the + SfxChildWindows. +*/ + +{ + if (!pInfo) + return; + m_xImpl->aWinState = pInfo->aWinState; + if (m_xImpl->aWinState.isEmpty()) + return; + m_xDialog->set_window_state(m_xImpl->aWinState); +} + +SfxModelessDialogController::SfxModelessDialogController(SfxBindings* pBindinx, + SfxChildWindow *pCW, weld::Window *pParent, const OUString& rUIXMLDescription, + const OString& rID) + : SfxDialogController(pParent, rUIXMLDescription, rID) +{ + Init(pBindinx, pCW); + m_xDialog->connect_focus_in(LINK(this, SfxModelessDialogController, FocusInHdl)); + m_xDialog->connect_focus_out(LINK(this, SfxModelessDialogController, FocusOutHdl)); +} + +void SfxModelessDialogController::Init(SfxBindings *pBindinx, SfxChildWindow *pCW) +{ + m_pBindings = pBindinx; + m_xImpl.reset(new SfxModelessDialog_Impl); + m_xImpl->pMgr = pCW; + m_xImpl->bConstructed = true; + m_xImpl->bClosing = false; + if (pBindinx) + m_xImpl->StartListening( *pBindinx ); +} + +void SfxModelessDialogController::DeInit() +{ + if (m_xImpl->pMgr) + { + WindowStateMask nMask = WindowStateMask::Pos | WindowStateMask::State; + if (m_xDialog->get_resizable()) + nMask |= ( WindowStateMask::Width | WindowStateMask::Height ); + m_xImpl->aWinState = m_xDialog->get_window_state(nMask); + GetBindings().GetWorkWindow_Impl()->ConfigChild_Impl( SfxChildIdentifier::DOCKINGWINDOW, SfxDockingConfig::ALIGNDOCKINGWINDOW, m_xImpl->pMgr->GetType() ); + } + + m_xImpl->pMgr = nullptr; +} + +/* [Description] + + If a ModelessDialog is enabled its ViewFrame will be activated. + This is necessary by PluginInFrames. +*/ +IMPL_LINK_NOARG(SfxModelessDialogController, FocusInHdl, weld::Widget&, void) +{ + if (!m_xImpl) + return; + m_pBindings->SetActiveFrame(m_xImpl->pMgr->GetFrame()); + m_xImpl->pMgr->Activate_Impl(); +} + +IMPL_LINK_NOARG(SfxModelessDialogController, FocusOutHdl, weld::Widget&, void) +{ + if (!m_xImpl) + return; + m_pBindings->SetActiveFrame(css::uno::Reference< css::frame::XFrame>()); +} + +SfxModelessDialogController::~SfxModelessDialogController() +{ + if (!m_xImpl->pMgr) + return; + auto xFrame = m_xImpl->pMgr->GetFrame(); + if (!xFrame) + return; + if (xFrame == m_pBindings->GetActiveFrame()) + m_pBindings->SetActiveFrame(nullptr); +} + +void SfxModelessDialogController::EndDialog() +{ + if (!m_xDialog->get_visible()) + return; + m_xImpl->bClosing = true; + response(RET_CLOSE); + m_xImpl->bClosing = false; +} + +/* [Description] + + The window is closed when the ChildWindow is destroyed by running the + ChildWindow-slots. +*/ +void SfxModelessDialogController::Close() +{ + if (m_xImpl->bClosing) + return; + // Execute with Parameters, since Toggle is ignored by some ChildWindows. + SfxBoolItem aValue(m_xImpl->pMgr->GetType(), false); + m_pBindings->GetDispatcher_Impl()->ExecuteList( + m_xImpl->pMgr->GetType(), + SfxCallMode::RECORD|SfxCallMode::SYNCHRON, { &aValue } ); +} + +/* [Description] + + Fills a SfxChildWinInfo with specific data from SfxModelessDialog, + so that it can be written in the INI file. It is assumed that rinfo + receives all other possible relevant data in the ChildWindow class. + ModelessDialogs have no specific information, so that the base + implementation does nothing and therefore must not be called. +*/ +void SfxModelessDialogController::FillInfo(SfxChildWinInfo& rInfo) const +{ + rInfo.aSize = m_xDialog->get_size(); +} + bool SfxFloatingWindow::EventNotify( NotifyEvent& rEvt ) /* [Description] @@ -756,7 +881,6 @@ void SfxSingleTabDialogController::SetTabPage(SfxTabPage* pTabPage) aUserItem >>= sUserData; m_xSfxPage->SetUserData(sUserData); m_xSfxPage->Reset(GetInputItemSet()); -//TODO m_xSfxPage->Show(); m_xHelpBtn->show(Help::IsContextHelpEnabled()); diff --git a/sfx2/source/inc/workwin.hxx b/sfx2/source/inc/workwin.hxx index 7b37d065afa4..38c41653dfdb 100644 --- a/sfx2/source/inc/workwin.hxx +++ b/sfx2/source/inc/workwin.hxx @@ -84,6 +84,7 @@ namespace o3tl struct SfxChild_Impl { VclPtr<vcl::Window> pWin; + std::shared_ptr<SfxModelessDialogController> xController; Size aSize; SfxChildAlignment eAlign; SfxChildVisibility nVisible; @@ -97,6 +98,14 @@ struct SfxChild_Impl { nVisible = bIsVisible ? SfxChildVisibility::VISIBLE : SfxChildVisibility::NOT_VISIBLE; } + + SfxChild_Impl(std::shared_ptr<SfxModelessDialogController>& rChild, + SfxChildAlignment eAlignment): + pWin(nullptr), xController(rChild), eAlign(eAlignment), bResize(false), + bSetFocus( false ) + { + nVisible = xController->getDialog()->get_visible() ? SfxChildVisibility::VISIBLE : SfxChildVisibility::NOT_VISIBLE; + } }; struct SfxChildWin_Impl @@ -239,7 +248,9 @@ public: // Methods for all Child windows void DataChanged_Impl(); void ReleaseChild_Impl( vcl::Window& rWindow ); + void ReleaseChild_Impl(SfxModelessDialogController&); SfxChild_Impl* RegisterChild_Impl( vcl::Window& rWindow, SfxChildAlignment eAlign ); + SfxChild_Impl* RegisterChild_Impl(std::shared_ptr<SfxModelessDialogController>& rController, SfxChildAlignment eAlign); void ShowChildren_Impl(); void HideChildren_Impl(); bool PrepareClose_Impl(); diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx index 642218f530d8..99d55a84dfb5 100644 --- a/sw/inc/swabstdlg.hxx +++ b/sw/inc/swabstdlg.hxx @@ -200,7 +200,7 @@ protected: public: virtual void UpdateCounts() = 0; virtual void SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) = 0; - virtual vcl::Window * GetWindow() = 0; //this method is added for return a Window type pointer + virtual std::shared_ptr<SfxModelessDialogController> GetController() = 0; }; class AbstractSwInsertAbstractDlg : public VclAbstractDialog @@ -364,7 +364,7 @@ public: virtual VclPtr<SfxAbstractDialog> CreateSwBackgroundDialog(weld::Window* pParent, const SfxItemSet& rSet) = 0; virtual VclPtr<AbstractSwWordCountFloatDlg> CreateSwWordCountDialog(SfxBindings* pBindings, - SfxChildWindow* pChild, vcl::Window *pParent, SfxChildWinInfo* pInfo) = 0; + SfxChildWindow* pChild, weld::Window *pParent, SfxChildWinInfo* pInfo) = 0; virtual VclPtr<AbstractSwInsertAbstractDlg> CreateSwInsertAbstractDlg() = 0; virtual VclPtr<SfxAbstractDialog> CreateSwAddressAbstractDlg(vcl::Window* pParent, const SfxItemSet& rSet) = 0; diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx index db92346bc587..fe904ffcd36e 100644 --- a/sw/inc/viewsh.hxx +++ b/sw/inc/viewsh.hxx @@ -170,7 +170,7 @@ class SW_DLLPUBLIC SwViewShell : public sw::Ring<SwViewShell> protected: static ShellResource* mpShellRes; ///< Resources for the Shell. static vcl::DeleteOnDeinit< VclPtr<vcl::Window> > mpCareWindow; ///< Avoid this window. - static vcl::DeleteOnDeinit< std::shared_ptr<weld::Dialog> > mpCareDialog; ///< Avoid this window. + static vcl::DeleteOnDeinit< std::shared_ptr<weld::Window> > mpCareDialog; ///< Avoid this window. SwRect maVisArea; ///< The modern version of VisArea. rtl::Reference<SwDoc> mxDoc; ///< The document; never 0. @@ -432,12 +432,12 @@ public: static ShellResource* GetShellRes(); static void SetCareWin( vcl::Window* pNew ); - static vcl::Window* GetCareWin(SwViewShell const & rVSh) - { return (*mpCareWindow.get()) ? mpCareWindow.get()->get() : CareChildWin(rVSh); } - static vcl::Window* CareChildWin(SwViewShell const & rVSh); - static void SetCareDialog(const std::shared_ptr<weld::Dialog>& rNew); - static weld::Dialog* GetCareDialog() - { return (*mpCareDialog.get()) ? mpCareDialog.get()->get() : nullptr; } + static vcl::Window* GetCareWin() + { return (*mpCareWindow.get()) ? mpCareWindow.get()->get() : nullptr; } + static weld::Window* CareChildWin(SwViewShell const & rVSh); + static void SetCareDialog(const std::shared_ptr<weld::Window>& rNew); + static weld::Window* GetCareDialog(SwViewShell const & rVSh) + { return (*mpCareDialog.get()) ? mpCareDialog.get()->get() : CareChildWin(rVSh); } SfxViewShell *GetSfxViewShell() const { return mpSfxViewShell; } void SetSfxViewShell(SfxViewShell *pNew) { mpSfxViewShell = pNew; } diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx index 23ef8f436318..4f38a4d4041e 100644 --- a/sw/source/core/view/viewsh.cxx +++ b/sw/source/core/view/viewsh.cxx @@ -93,7 +93,7 @@ bool SwViewShell::mbLstAct = false; ShellResource *SwViewShell::mpShellRes = nullptr; vcl::DeleteOnDeinit< VclPtr<vcl::Window> > SwViewShell::mpCareWindow(new VclPtr<vcl::Window>); -vcl::DeleteOnDeinit<std::shared_ptr<weld::Dialog>> SwViewShell::mpCareDialog(new std::shared_ptr<weld::Dialog>); +vcl::DeleteOnDeinit<std::shared_ptr<weld::Window>> SwViewShell::mpCareDialog(new std::shared_ptr<weld::Window>); static bool bInSizeNotify = false; @@ -581,7 +581,7 @@ const SwRect& SwViewShell::VisArea() const void SwViewShell::MakeVisible( const SwRect &rRect ) { - if ( !VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareWin(*this) || GetCareDialog() ) + if ( !VisArea().IsInside( rRect ) || IsScrollMDI( this, rRect ) || GetCareWin() || GetCareDialog(*this) ) { if ( !IsViewLocked() ) { @@ -609,19 +609,23 @@ void SwViewShell::MakeVisible( const SwRect &rRect ) } } -vcl::Window* SwViewShell::CareChildWin(SwViewShell const & rVSh) +weld::Window* SwViewShell::CareChildWin(SwViewShell const & rVSh) { - if(rVSh.mpSfxViewShell) - { + if (!rVSh.mpSfxViewShell) + return nullptr; #if HAVE_FEATURE_DESKTOP - const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId(); - SfxViewFrame* pVFrame = rVSh.mpSfxViewShell->GetViewFrame(); - const SfxChildWindow* pChWin = pVFrame->GetChildWindow( nId ); - vcl::Window *pWin = pChWin ? pChWin->GetWindow() : nullptr; - if ( pWin && pWin->IsVisible() ) - return pWin; + const sal_uInt16 nId = SvxSearchDialogWrapper::GetChildWindowId(); + SfxViewFrame* pVFrame = rVSh.mpSfxViewShell->GetViewFrame(); + SfxChildWindow* pChWin = pVFrame->GetChildWindow( nId ); + if (!pChWin) + return nullptr; + weld::DialogController* pController = pChWin->GetController().get(); + if (!pController) + return nullptr; + weld::Window* pWin = pController->getDialog(); + if (pWin && pWin->get_visible()) + return pWin; #endif - } return nullptr; } @@ -2503,7 +2507,7 @@ void SwViewShell::SetCareWin( vcl::Window* pNew ) (*mpCareWindow.get()) = pNew; } -void SwViewShell::SetCareDialog(const std::shared_ptr<weld::Dialog>& rNew) +void SwViewShell::SetCareDialog(const std::shared_ptr<weld::Window>& rNew) { (*mpCareDialog.get()) = rNew; } diff --git a/sw/source/ui/dialog/swdlgfact.cxx b/sw/source/ui/dialog/swdlgfact.cxx index c30b671d3b29..b634d18970d2 100644 --- a/sw/source/ui/dialog/swdlgfact.cxx +++ b/sw/source/ui/dialog/swdlgfact.cxx @@ -87,7 +87,11 @@ using namespace ::com::sun::star; using namespace css::frame; using namespace css::uno; -IMPL_ABSTDLG_BASE(AbstractSwWordCountFloatDlg_Impl); +short AbstractSwWordCountFloatDlg_Impl::Execute() +{ + return m_xDlg->run(); +} + IMPL_ABSTDLG_BASE(AbstractSwInsertAbstractDlg_Impl); IMPL_ABSTDLG_BASE(SwAbstractSfxDialog_Impl); @@ -695,19 +699,19 @@ vcl::Window* AbstractAuthMarkFloatDlg_Impl::GetWindow() return static_cast<vcl::Window*>(pDlg); } -vcl::Window* AbstractSwWordCountFloatDlg_Impl::GetWindow() +std::shared_ptr<SfxModelessDialogController> AbstractSwWordCountFloatDlg_Impl::GetController() { - return static_cast<vcl::Window*>(pDlg); + return m_xDlg; } void AbstractSwWordCountFloatDlg_Impl::UpdateCounts() { - pDlg->UpdateCounts(); + m_xDlg->UpdateCounts(); } void AbstractSwWordCountFloatDlg_Impl::SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) { - pDlg->SetCounts(rCurrCnt, rDocStat); + m_xDlg->SetCounts(rCurrCnt, rDocStat); } AbstractMailMergeWizard_Impl::~AbstractMailMergeWizard_Impl() @@ -1109,11 +1113,10 @@ VclPtr<AbstractMarkFloatDlg> SwAbstractDialogFactory_Impl::CreateAuthMarkFloatDl VclPtr<AbstractSwWordCountFloatDlg> SwAbstractDialogFactory_Impl::CreateSwWordCountDialog( SfxBindings* pBindings, SfxChildWindow* pChild, - vcl::Window *pParent, + weld::Window *pParent, SfxChildWinInfo* pInfo) { - VclPtr<SwWordCountFloatDlg> pDlg = VclPtr<SwWordCountFloatDlg>::Create( pBindings, pChild, pParent, pInfo ); - return VclPtr<AbstractSwWordCountFloatDlg_Impl>::Create( pDlg ); + return VclPtr<AbstractSwWordCountFloatDlg_Impl>::Create(o3tl::make_unique<SwWordCountFloatDlg>(pBindings, pChild, pParent, pInfo)); } VclPtr<VclAbstractDialog> SwAbstractDialogFactory_Impl::CreateIndexMarkModalDlg( diff --git a/sw/source/ui/dialog/swdlgfact.hxx b/sw/source/ui/dialog/swdlgfact.hxx index 103b04b35a02..14b802ef7e2d 100644 --- a/sw/source/ui/dialog/swdlgfact.hxx +++ b/sw/source/ui/dialog/swdlgfact.hxx @@ -74,10 +74,17 @@ bool Class::StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx) \ class SwWordCountFloatDlg; class AbstractSwWordCountFloatDlg_Impl : public AbstractSwWordCountFloatDlg { - DECL_ABSTDLG_BASE(AbstractSwWordCountFloatDlg_Impl,SwWordCountFloatDlg) - virtual void UpdateCounts() override; - virtual void SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) override; - virtual vcl::Window * GetWindow() override; //this method is added for return a Window type pointer +protected: + std::shared_ptr<SwWordCountFloatDlg> m_xDlg; +public: + explicit AbstractSwWordCountFloatDlg_Impl(std::unique_ptr<SwWordCountFloatDlg> p) + : m_xDlg(std::move(p)) + { + } + virtual short Execute() override; + virtual void UpdateCounts() override; + virtual void SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat) override; + virtual std::shared_ptr<SfxModelessDialogController> GetController() override; }; class AbstractSwInsertAbstractDlg_Impl : public AbstractSwInsertAbstractDlg @@ -596,7 +603,7 @@ public: virtual VclPtr<SfxAbstractDialog> CreateSwDropCapsDialog(weld::Window* pParent, const SfxItemSet& rSet) override; virtual VclPtr<SfxAbstractDialog> CreateSwBackgroundDialog(weld::Window* pParent, const SfxItemSet& rSet) override; virtual VclPtr<AbstractSwWordCountFloatDlg> CreateSwWordCountDialog(SfxBindings* pBindings, - SfxChildWindow* pChild, vcl::Window *pParent, SfxChildWinInfo* pInfo) override; + SfxChildWindow* pChild, weld::Window *pParent, SfxChildWinInfo* pInfo) override; virtual VclPtr<AbstractSwInsertAbstractDlg> CreateSwInsertAbstractDlg() override; virtual VclPtr<SfxAbstractDialog> CreateSwAddressAbstractDlg(vcl::Window* pParent, const SfxItemSet& rSet) override; virtual VclPtr<AbstractSwAsciiFilterDlg> CreateSwAsciiFilterDlg(weld::Window* pParent, SwDocShell& rDocSh, diff --git a/sw/source/ui/dialog/wordcountdialog.cxx b/sw/source/ui/dialog/wordcountdialog.cxx index cc350e6fb9c8..b24767823963 100644 --- a/sw/source/ui/dialog/wordcountdialog.cxx +++ b/sw/source/ui/dialog/wordcountdialog.cxx @@ -31,126 +31,92 @@ #include <unotools/localedatawrapper.hxx> #include <vcl/settings.hxx> -IMPL_STATIC_LINK_NOARG(SwWordCountFloatDlg, CloseHdl, Button*, void) -{ - SfxViewFrame* pVFrame = ::GetActiveView()->GetViewFrame(); - if (pVFrame != nullptr) - { - pVFrame->ToggleChildWindow(FN_WORDCOUNT_DIALOG); - } -} - SwWordCountFloatDlg::~SwWordCountFloatDlg() { - disposeOnce(); -} - -void SwWordCountFloatDlg::dispose() -{ SwViewShell::SetCareWin( nullptr ); - m_pCurrentWordFT.clear(); - m_pCurrentCharacterFT.clear(); - m_pCurrentCharacterExcludingSpacesFT.clear(); - m_pCurrentCjkcharsFT.clear(); - m_pCurrentStandardizedPagesFT.clear(); - m_pDocWordFT.clear(); - m_pDocCharacterFT.clear(); - m_pDocCharacterExcludingSpacesFT.clear(); - m_pDocCjkcharsFT.clear(); - m_pDocStandardizedPagesFT.clear(); - m_pCjkcharsLabelFT.clear(); - m_pStandardizedPagesLabelFT.clear(); - m_pClosePB.clear(); - SfxModelessDialog::dispose(); } namespace { - void setValue(FixedText *pWidget, sal_uLong nValue, const LocaleDataWrapper& rLocaleData) + void setValue(weld::Label& rWidget, sal_uLong nValue, const LocaleDataWrapper& rLocaleData) { - pWidget->SetText(rLocaleData.getNum(nValue, 0)); + rWidget.set_label(rLocaleData.getNum(nValue, 0)); } - void setDoubleValue(FixedText *pWidget, double fValue) + void setDoubleValue(weld::Label& rWidget, double fValue) { OUString sValue(OUString::number(::rtl::math::round(fValue, 1))); - pWidget->SetText(sValue); + rWidget.set_label(sValue); } } void SwWordCountFloatDlg::SetValues(const SwDocStat& rCurrent, const SwDocStat& rDoc) { - const LocaleDataWrapper& rLocaleData = GetSettings().GetUILocaleDataWrapper(); - setValue(m_pCurrentWordFT, rCurrent.nWord, rLocaleData); - setValue(m_pCurrentCharacterFT, rCurrent.nChar, rLocaleData); - setValue(m_pCurrentCharacterExcludingSpacesFT, rCurrent.nCharExcludingSpaces, rLocaleData); - setValue(m_pCurrentCjkcharsFT, rCurrent.nAsianWord, rLocaleData); - setValue(m_pDocWordFT, rDoc.nWord, rLocaleData); - setValue(m_pDocCharacterFT, rDoc.nChar, rLocaleData); - setValue(m_pDocCharacterExcludingSpacesFT, rDoc.nCharExcludingSpaces, rLocaleData); - setValue(m_pDocCjkcharsFT, rDoc.nAsianWord, rLocaleData); - - if (m_pStandardizedPagesLabelFT->IsVisible()) + const LocaleDataWrapper& rLocaleData = Application::GetSettings().GetUILocaleDataWrapper(); + setValue(*m_xCurrentWordFT, rCurrent.nWord, rLocaleData); + setValue(*m_xCurrentCharacterFT, rCurrent.nChar, rLocaleData); + setValue(*m_xCurrentCharacterExcludingSpacesFT, rCurrent.nCharExcludingSpaces, rLocaleData); + setValue(*m_xCurrentCjkcharsFT, rCurrent.nAsianWord, rLocaleData); + setValue(*m_xDocWordFT, rDoc.nWord, rLocaleData); + setValue(*m_xDocCharacterFT, rDoc.nChar, rLocaleData); + setValue(*m_xDocCharacterExcludingSpacesFT, rDoc.nCharExcludingSpaces, rLocaleData); + setValue(*m_xDocCjkcharsFT, rDoc.nAsianWord, rLocaleData); + + if (m_xStandardizedPagesLabelFT->get_visible()) { sal_Int64 nCharsPerStandardizedPage = officecfg::Office::Writer::WordCount::StandardizedPageSize::get(); - setDoubleValue(m_pCurrentStandardizedPagesFT, + setDoubleValue(*m_xCurrentStandardizedPagesFT, static_cast<double>(rCurrent.nChar) / nCharsPerStandardizedPage); - setDoubleValue(m_pDocStandardizedPagesFT, + setDoubleValue(*m_xDocStandardizedPagesFT, static_cast<double>(rDoc.nChar) / nCharsPerStandardizedPage); } bool bShowCJK = (SvtCJKOptions().IsAnyEnabled() || rDoc.nAsianWord); - bool bToggleCJK = m_pCurrentCjkcharsFT->IsVisible() != bShowCJK; + bool bToggleCJK = m_xCurrentCjkcharsFT->get_visible() != bShowCJK; if (bToggleCJK) { showCJK(bShowCJK); - setOptimalLayoutSize(); //force resize of dialog + m_xDialog->resize_to_request(); //force resize of dialog } } void SwWordCountFloatDlg::showCJK(bool bShowCJK) { - m_pCurrentCjkcharsFT->Show(bShowCJK); - m_pDocCjkcharsFT->Show(bShowCJK); - m_pCjkcharsLabelFT->Show(bShowCJK); + m_xCurrentCjkcharsFT->show(bShowCJK); + m_xDocCjkcharsFT->show(bShowCJK); + m_xCjkcharsLabelFT->show(bShowCJK); } void SwWordCountFloatDlg::showStandardizedPages(bool bShowStandardizedPages) { - m_pCurrentStandardizedPagesFT->Show(bShowStandardizedPages); - m_pDocStandardizedPagesFT->Show(bShowStandardizedPages); - m_pStandardizedPagesLabelFT->Show(bShowStandardizedPages); + m_xCurrentStandardizedPagesFT->show(bShowStandardizedPages); + m_xDocStandardizedPagesFT->show(bShowStandardizedPages); + m_xStandardizedPagesLabelFT->show(bShowStandardizedPages); } SwWordCountFloatDlg::SwWordCountFloatDlg(SfxBindings* _pBindings, SfxChildWindow* pChild, - vcl::Window *pParent, + weld::Window *pParent, SfxChildWinInfo const * pInfo) - : SfxModelessDialog(_pBindings, pChild, pParent, "WordCountDialog", "modules/swriter/ui/wordcount.ui") + : SfxModelessDialogController(_pBindings, pChild, pParent, "modules/swriter/ui/wordcount.ui", "WordCountDialog") + , m_xCurrentWordFT(m_xBuilder->weld_label("selectwords")) + , m_xCurrentCharacterFT(m_xBuilder->weld_label("selectchars")) + , m_xCurrentCharacterExcludingSpacesFT(m_xBuilder->weld_label("selectcharsnospaces")) + , m_xCurrentCjkcharsFT(m_xBuilder->weld_label("selectcjkchars")) + , m_xCurrentStandardizedPagesFT(m_xBuilder->weld_label("selectstandardizedpages")) + , m_xDocWordFT(m_xBuilder->weld_label("docwords")) + , m_xDocCharacterFT(m_xBuilder->weld_label("docchars")) + , m_xDocCharacterExcludingSpacesFT(m_xBuilder->weld_label("doccharsnospaces")) + , m_xDocCjkcharsFT(m_xBuilder->weld_label("doccjkchars")) + , m_xDocStandardizedPagesFT(m_xBuilder->weld_label("docstandardizedpages")) + , m_xCjkcharsLabelFT(m_xBuilder->weld_label("cjkcharsft")) + , m_xStandardizedPagesLabelFT(m_xBuilder->weld_label("standardizedpages")) + , m_xClosePB(m_xBuilder->weld_button("close")) { - get(m_pCurrentWordFT, "selectwords"); - get(m_pCurrentCharacterFT, "selectchars"); - get(m_pCurrentCharacterExcludingSpacesFT, "selectcharsnospaces"); - get(m_pCurrentCjkcharsFT, "selectcjkchars"); - get(m_pCurrentStandardizedPagesFT, "selectstandardizedpages"); - - get(m_pDocWordFT, "docwords"); - get(m_pDocCharacterFT, "docchars"); - get(m_pDocCharacterExcludingSpacesFT, "doccharsnospaces"); - get(m_pDocCjkcharsFT, "doccjkchars"); - get(m_pDocStandardizedPagesFT, "docstandardizedpages"); - - get(m_pCjkcharsLabelFT, "cjkcharsft"); - get(m_pStandardizedPagesLabelFT, "standardizedpages"); - - get(m_pClosePB, "close"); - showCJK(SvtCJKOptions().IsAnyEnabled()); showStandardizedPages(officecfg::Office::Writer::WordCount::ShowStandardizedPageCount::get()); Initialize(pInfo); - - m_pClosePB->SetClickHdl(LINK(this, SwWordCountFloatDlg, CloseHdl)); } void SwWordCountFloatDlg::UpdateCounts() diff --git a/sw/source/uibase/dialog/wordcountwrapper.cxx b/sw/source/uibase/dialog/wordcountwrapper.cxx index 090410509a0d..2a205fb3bf12 100644 --- a/sw/source/uibase/dialog/wordcountwrapper.cxx +++ b/sw/source/uibase/dialog/wordcountwrapper.cxx @@ -14,15 +14,15 @@ SFX_IMPL_CHILDWINDOW_WITHID(SwWordCountWrapper, FN_WORDCOUNT_DIALOG) -SwWordCountWrapper::SwWordCountWrapper( vcl::Window *pParentWindow, +SwWordCountWrapper::SwWordCountWrapper(vcl::Window *pParentWindow, sal_uInt16 nId, SfxBindings* pBindings, - SfxChildWinInfo* pInfo ) : - SfxChildWindow(pParentWindow, nId) + SfxChildWinInfo* pInfo ) + : SfxChildWindow(pParentWindow, nId) { SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); - xAbstDlg.reset(pFact->CreateSwWordCountDialog(pBindings, this, pParentWindow, pInfo)); - SetWindow(xAbstDlg->GetWindow()); + xAbstDlg.reset(pFact->CreateSwWordCountDialog(pBindings, this, pParentWindow->GetFrameWeld(), pInfo)); + SetController(xAbstDlg->GetController()); } SwWordCountWrapper::~SwWordCountWrapper() diff --git a/sw/source/uibase/inc/wordcountdialog.hxx b/sw/source/uibase/inc/wordcountdialog.hxx index ea95266a5cac..e63ef3c07c6b 100644 --- a/sw/source/uibase/inc/wordcountdialog.hxx +++ b/sw/source/uibase/inc/wordcountdialog.hxx @@ -25,37 +25,32 @@ struct SwDocStat; #include <sfx2/childwin.hxx> #include <swabstdlg.hxx> -class SwWordCountFloatDlg : public SfxModelessDialog +class SwWordCountFloatDlg : public SfxModelessDialogController { void SetValues(const SwDocStat& rCurrent, const SwDocStat& rDoc); void showCJK(bool bShowCJK); void showStandardizedPages(bool bShowStandardizedPages); - VclPtr<FixedText> m_pCurrentWordFT; - VclPtr<FixedText> m_pCurrentCharacterFT; - VclPtr<FixedText> m_pCurrentCharacterExcludingSpacesFT; - VclPtr<FixedText> m_pCurrentCjkcharsFT; - VclPtr<FixedText> m_pCurrentStandardizedPagesFT; + std::unique_ptr<weld::Label> m_xCurrentWordFT; + std::unique_ptr<weld::Label> m_xCurrentCharacterFT; + std::unique_ptr<weld::Label> m_xCurrentCharacterExcludingSpacesFT; + std::unique_ptr<weld::Label> m_xCurrentCjkcharsFT; + std::unique_ptr<weld::Label> m_xCurrentStandardizedPagesFT; + std::unique_ptr<weld::Label> m_xDocWordFT; + std::unique_ptr<weld::Label> m_xDocCharacterFT; + std::unique_ptr<weld::Label> m_xDocCharacterExcludingSpacesFT; + std::unique_ptr<weld::Label> m_xDocCjkcharsFT; + std::unique_ptr<weld::Label> m_xDocStandardizedPagesFT; + std::unique_ptr<weld::Label> m_xCjkcharsLabelFT; + std::unique_ptr<weld::Label> m_xStandardizedPagesLabelFT; + std::unique_ptr<weld::Button> m_xClosePB; - VclPtr<FixedText> m_pDocWordFT; - VclPtr<FixedText> m_pDocCharacterFT; - VclPtr<FixedText> m_pDocCharacterExcludingSpacesFT; - VclPtr<FixedText> m_pDocCjkcharsFT; - VclPtr<FixedText> m_pDocStandardizedPagesFT; - - VclPtr<FixedText> m_pCjkcharsLabelFT; - VclPtr<FixedText> m_pStandardizedPagesLabelFT; - - VclPtr<CloseButton> m_pClosePB; - - DECL_STATIC_LINK( SwWordCountFloatDlg, CloseHdl, Button*, void ); public: - SwWordCountFloatDlg( SfxBindings* pBindings, - SfxChildWindow* pChild, - vcl::Window *pParent, - SfxChildWinInfo const * pInfo); + SwWordCountFloatDlg(SfxBindings* pBindings, + SfxChildWindow* pChild, + weld::Window *pParent, + SfxChildWinInfo const * pInfo); virtual ~SwWordCountFloatDlg() override; - virtual void dispose() override; void UpdateCounts(); void SetCounts(const SwDocStat &rCurrCnt, const SwDocStat &rDocStat); diff --git a/sw/source/uibase/uiview/viewport.cxx b/sw/source/uibase/uiview/viewport.cxx index e52c3c778940..331309ef025a 100644 --- a/sw/source/uibase/uiview/viewport.cxx +++ b/sw/source/uibase/uiview/viewport.cxx @@ -403,8 +403,8 @@ void SwView::Scroll( const tools::Rectangle &rRect, sal_uInt16 nRangeX, sal_uInt tools::Rectangle aOldVisArea( m_aVisArea ); long nDiffY = 0; - vcl::Window* pCareWn = SwViewShell::GetCareWin(GetWrtShell()); - weld::Dialog* pCareDialog = SwViewShell::GetCareDialog(); + vcl::Window* pCareWn = SwViewShell::GetCareWin(); + weld::Window* pCareDialog = SwViewShell::GetCareDialog(GetWrtShell()); if (pCareWn || pCareDialog) { int x, y, width, height; diff --git a/sw/uiconfig/swriter/ui/wordcount.ui b/sw/uiconfig/swriter/ui/wordcount.ui index 86595e5125cf..6da9a2c96b8e 100644 --- a/sw/uiconfig/swriter/ui/wordcount.ui +++ b/sw/uiconfig/swriter/ui/wordcount.ui @@ -1,13 +1,18 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.20.2 --> +<!-- Generated with glade 3.22.1 --> <interface domain="sw"> <requires lib="gtk+" version="3.18"/> <object class="GtkDialog" id="WordCountDialog"> <property name="can_focus">False</property> <property name="border_width">6</property> <property name="title" translatable="yes" context="wordcount|WordCountDialog">Word Count</property> + <property name="default_width">0</property> + <property name="default_height">0</property> <property name="destroy_with_parent">True</property> <property name="type_hint">dialog</property> + <child> + <placeholder/> + </child> <child internal-child="vbox"> <object class="GtkBox" id="dialog-vbox1"> <property name="can_focus">False</property> @@ -319,6 +324,7 @@ </object> </child> <action-widgets> + <action-widget response="-7">close</action-widget> <action-widget response="-11">help</action-widget> </action-widgets> </object> diff --git a/vcl/inc/qt5/Qt5Frame.hxx b/vcl/inc/qt5/Qt5Frame.hxx index 9d7b15792731..f3fd1f19b0ec 100644 --- a/vcl/inc/qt5/Qt5Frame.hxx +++ b/vcl/inc/qt5/Qt5Frame.hxx @@ -147,6 +147,7 @@ public: virtual void GetWorkArea(tools::Rectangle& rRect) override; virtual SalFrame* GetParent() const override; virtual void SetModal(bool bModal) override; + virtual bool GetModal() const override; virtual void SetWindowState(const SalFrameState* pState) override; virtual bool GetWindowState(SalFrameState* pState) override; virtual void ShowFullScreen(bool bFullScreen, sal_Int32 nDisplay) override; diff --git a/vcl/inc/salframe.hxx b/vcl/inc/salframe.hxx index e2662d415fc2..b27b46d828c8 100644 --- a/vcl/inc/salframe.hxx +++ b/vcl/inc/salframe.hxx @@ -240,6 +240,11 @@ public: { } + virtual bool GetModal() const + { + return false; + } + // return true to indicate tooltips are shown natively, false otherwise virtual bool ShowTooltip(const OUString& /*rHelpText*/, const tools::Rectangle& /*rHelpArea*/) { diff --git a/vcl/inc/unx/gtk/gtkframe.hxx b/vcl/inc/unx/gtk/gtkframe.hxx index 7b2e78a5414e..a77c7c61686b 100644 --- a/vcl/inc/unx/gtk/gtkframe.hxx +++ b/vcl/inc/unx/gtk/gtkframe.hxx @@ -537,6 +537,7 @@ public: #if GTK_CHECK_VERSION(3,0,0) virtual void PositionByToolkit(const tools::Rectangle& rRect, FloatWinPopupFlags nFlags) override; virtual void SetModal(bool bModal) override; + virtual bool GetModal() const override; void HideTooltip(); virtual bool ShowTooltip(const OUString& rHelpText, const tools::Rectangle& rHelpArea) override; virtual void* ShowPopover(const OUString& rHelpText, vcl::Window* pParent, const tools::Rectangle& rHelpArea, QuickHelpFlags nFlags) override; diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 21448efd9496..452a88e6f9f5 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -40,6 +40,7 @@ class VirtualDevice; class PhysicalFontCollection; class ImplFontCache; class VCLXWindow; +class WindowStateData; class SalFrame; class SalObject; enum class MouseEventModifiers; @@ -414,6 +415,9 @@ bool ImplHandleMouseEvent( const VclPtr<vcl::Window>& xWindow, MouseNotifyEvent sal_uInt16 nCode, MouseEventModifiers nMode ); void ImplHandleResize( vcl::Window* pWindow, long nNewWidth, long nNewHeight ); +VCL_DLLPUBLIC void ImplWindowStateFromStr(WindowStateData& rData, const OString& rStr); +VCL_DLLPUBLIC OString ImplWindowStateToStr(const WindowStateData& rData); + #endif // INCLUDED_VCL_INC_WINDOW_H /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/qt5/Qt5Frame.cxx b/vcl/qt5/Qt5Frame.cxx index 17fb684e3c0e..f7e6a571458c 100644 --- a/vcl/qt5/Qt5Frame.cxx +++ b/vcl/qt5/Qt5Frame.cxx @@ -474,6 +474,13 @@ void Qt5Frame::SetModal(bool bModal) } } +bool Qt5Frame::GetModal() const +{ + if (isWindow()) + return windowHandle()->getModality() == Qt::WindowModal; + return false; +} + void Qt5Frame::SetWindowState(const SalFrameState* pState) { if (!isWindow() || !pState || isChild(true, false)) diff --git a/vcl/source/app/salvtables.cxx b/vcl/source/app/salvtables.cxx index 485b404ac200..d3bbd9385470 100644 --- a/vcl/source/app/salvtables.cxx +++ b/vcl/source/app/salvtables.cxx @@ -730,11 +730,15 @@ public: virtual void set_modal(bool bModal) override { if (::Dialog* pDialog = dynamic_cast<::Dialog*>(m_xWindow.get())) - { - pDialog->SetModalInputMode(bModal); - return; - } - m_xWindow->ImplGetFrame()->SetModal(bModal); + return pDialog->SetModalInputMode(bModal); + return m_xWindow->ImplGetFrame()->SetModal(bModal); + } + + virtual bool get_modal() const override + { + if (const ::Dialog* pDialog = dynamic_cast<const ::Dialog*>(m_xWindow.get())) + return pDialog->IsModalInputMode(); + return m_xWindow->ImplGetFrame()->GetModal(); } virtual void window_move(int x, int y) override @@ -757,6 +761,35 @@ public: return true; } + virtual Size get_size() const override + { + return m_xWindow->GetSizePixel(); + } + + virtual Point get_position() const override + { + return m_xWindow->GetPosPixel(); + } + + virtual bool get_resizable() const override + { + return m_xWindow->GetStyle() & WB_SIZEABLE; + } + + virtual void set_window_state(const OString& rStr) override + { + SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get()); + assert(pSysWin); + pSysWin->SetWindowState(rStr); + } + + virtual OString get_window_state(WindowStateMask nMask) const override + { + SystemWindow* pSysWin = dynamic_cast<SystemWindow*>(m_xWindow.get()); + assert(pSysWin); + return pSysWin->GetWindowState(nMask); + } + virtual SystemEnvData get_system_data() const override { return *m_xWindow->GetSystemData(); diff --git a/vcl/source/window/builder.cxx b/vcl/source/window/builder.cxx index 85ed792d5f39..480c2f7b6c47 100644 --- a/vcl/source/window/builder.cxx +++ b/vcl/source/window/builder.cxx @@ -831,6 +831,18 @@ namespace return bResizable; } + bool extractModal(VclBuilder::stringmap &rMap) + { + bool bModal = false; + VclBuilder::stringmap::iterator aFind = rMap.find(OString("modal")); + if (aFind != rMap.end()) + { + bModal = toBool(aFind->second); + rMap.erase(aFind); + } + return bModal; + } + bool extractDecorated(VclBuilder::stringmap &rMap) { bool bDecorated = true; @@ -1521,6 +1533,8 @@ VclPtr<vcl::Window> VclBuilder::makeObject(vcl::Window *pParent, const OString & if (extractResizable(rMap)) nBits |= WB_SIZEABLE; xWindow = VclPtr<Dialog>::Create(pParent, nBits, !pParent ? Dialog::InitFlag::NoParent : Dialog::InitFlag::Default); + if (!m_bLegacy && !extractModal(rMap)) + xWindow->SetType(WindowType::MODELESSDIALOG); } else if (name == "GtkMessageDialog") { diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx index 53ebce93689b..11a92bb9a8f4 100644 --- a/vcl/source/window/dialog.cxx +++ b/vcl/source/window/dialog.cxx @@ -819,7 +819,7 @@ bool Dialog::Close() return bRet; } - if ( IsInExecute() ) + if (IsInExecute() || mpDialogImpl->maEndCtx.isSet()) { EndDialog(); mbInClose = false; @@ -832,11 +832,11 @@ bool Dialog::Close() } } -bool Dialog::ImplStartExecuteModal() +bool Dialog::ImplStartExecute() { setDeferredProperties(); - if ( mbInExecute || mpDialogImpl->maEndCtx.isSet() ) + if (IsInExecute() || mpDialogImpl->maEndCtx.isSet()) { #ifdef DBG_UTIL SAL_WARN( "vcl", "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " @@ -854,68 +854,74 @@ bool Dialog::ImplStartExecuteModal() SetLOKNotifier(pViewShell); } - switch ( Application::GetDialogCancelMode() ) + const bool bModal = GetType() != WindowType::MODELESSDIALOG; + + if (bModal) { - case Application::DialogCancelMode::Off: - break; - case Application::DialogCancelMode::Silent: - if (GetLOKNotifier()) + switch ( Application::GetDialogCancelMode() ) { - // check if there's already some dialog being ::Execute()d - const bool bDialogExecuting = std::any_of(pSVData->maWinData.mpExecuteDialogs.begin(), - pSVData->maWinData.mpExecuteDialogs.end(), - [](const Dialog* pDialog) { - return pDialog->IsInSyncExecute(); - }); - if (!(bDialogExecuting && IsInSyncExecute())) - break; - else - SAL_WARN("lok.dialog", "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog."); - } + case Application::DialogCancelMode::Off: + break; + case Application::DialogCancelMode::Silent: + if (bModal && GetLOKNotifier()) + { + // check if there's already some dialog being ::Execute()d + const bool bDialogExecuting = std::any_of(pSVData->maWinData.mpExecuteDialogs.begin(), + pSVData->maWinData.mpExecuteDialogs.end(), + [](const Dialog* pDialog) { + return pDialog->IsInSyncExecute(); + }); + if (!(bDialogExecuting && IsInSyncExecute())) + break; + else + SAL_WARN("lok.dialog", "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog."); + } - SAL_INFO( - "vcl", - "Dialog \"" << ImplGetDialogText(this) - << "\"cancelled in silent mode"); - return false; - default: // default cannot happen - case Application::DialogCancelMode::Fatal: - std::abort(); - } + SAL_INFO( + "vcl", + "Dialog \"" << ImplGetDialogText(this) + << "\"cancelled in silent mode"); + return false; + default: // default cannot happen + case Application::DialogCancelMode::Fatal: + std::abort(); + } #ifdef DBG_UTIL - vcl::Window* pParent = GetParent(); - if ( pParent ) - { - pParent = pParent->ImplGetFirstOverlapWindow(); - SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", - "Dialog::StartExecuteModal() - Parent not visible" ); - SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", - "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); - SAL_WARN_IF( pParent->IsInModalMode(), "vcl", - "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); + vcl::Window* pParent = GetParent(); + if ( pParent ) + { + pParent = pParent->ImplGetFirstOverlapWindow(); + SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl", + "Dialog::StartExecuteModal() - Parent not visible" ); + SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl", + "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ); + SAL_WARN_IF( pParent->IsInModalMode(), "vcl", + "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ); - } + } #endif - // link all dialogs which are being executed - pSVData->maWinData.mpExecuteDialogs.push_back(this); + // link all dialogs which are being executed + pSVData->maWinData.mpExecuteDialogs.push_back(this); - // stop capturing, in order to have control over the dialog - if ( pSVData->maWinData.mpTrackWin ) - pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel ); - if ( pSVData->maWinData.mpCaptureWin ) - pSVData->maWinData.mpCaptureWin->ReleaseMouse(); - EnableInput(); + // stop capturing, in order to have control over the dialog + if ( pSVData->maWinData.mpTrackWin ) + pSVData->maWinData.mpTrackWin->EndTracking( TrackingEventFlags::Cancel ); + if ( pSVData->maWinData.mpCaptureWin ) + pSVData->maWinData.mpCaptureWin->ReleaseMouse(); + EnableInput(); - if ( GetParent() ) - { - NotifyEvent aNEvt( MouseNotifyEvent::EXECUTEDIALOG, this ); - GetParent()->CompatNotify( aNEvt ); + if ( GetParent() ) + { + NotifyEvent aNEvt( MouseNotifyEvent::EXECUTEDIALOG, this ); + GetParent()->CompatNotify( aNEvt ); + } } + mbInExecute = true; // no real modality in LibreOfficeKit - if (!bKitActive) + if (!bKitActive && bModal) SetModalInputMode(true); // FIXME: no layouting, workaround some clipping issues @@ -927,13 +933,17 @@ bool Dialog::ImplStartExecuteModal() ShowFlags showFlags = bForceFocusAndToFront ? ShowFlags::ForegroundTask : ShowFlags::NONE; Show(true, showFlags); - pSVData->maAppData.mnModalMode++; + if (bModal) + pSVData->maAppData.mnModalMode++; css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW); css::document::DocumentEvent aObject; aObject.EventName = "DialogExecute"; xEventBroadcaster->documentEventOccured(aObject); - UITestLogger::getInstance().log("ModalDialogExecuted Id:" + get_id()); + if (bModal) + UITestLogger::getInstance().log("ModalDialogExecuted Id:" + get_id()); + else + UITestLogger::getInstance().log("ModelessDialogExecuted Id:" + get_id()); if (bKitActive) { @@ -1015,7 +1025,7 @@ short Dialog::Execute() mbInSyncExecute = false; }); - if ( !ImplStartExecuteModal() ) + if ( !ImplStartExecute() ) return 0; // Yield util EndDialog is called or dialog gets destroyed @@ -1054,7 +1064,8 @@ short Dialog::Execute() // virtual bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx ) { - if ( !ImplStartExecuteModal() ) + const bool bModal = GetType() != WindowType::MODELESSDIALOG; + if (!ImplStartExecute()) { rCtx.mxOwner.disposeAndClear(); rCtx.mxOwnerDialog.reset(); @@ -1062,7 +1073,7 @@ bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx ) } mpDialogImpl->maEndCtx = rCtx; - mpDialogImpl->mbStartedModal = true; + mpDialogImpl->mbStartedModal = bModal; return true; } @@ -1081,47 +1092,60 @@ void Dialog::EndDialog( long nResult ) if ( !mbInExecute ) return; - SetModalInputMode(false); + const bool bModal = GetType() != WindowType::MODELESSDIALOG; - RemoveFromDlgList(); - - // set focus to previous modal dialogue if it is modal for - // the same frame parent (or NULL) - ImplSVData* pSVData = ImplGetSVData(); - if (!pSVData->maWinData.mpExecuteDialogs.empty()) + if (bModal) { - VclPtr<Dialog> pPrevious = pSVData->maWinData.mpExecuteDialogs.back(); + SetModalInputMode(false); - vcl::Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent(); - vcl::Window* pPrevFrameParent = pPrevious->ImplGetFrameWindow()? pPrevious->ImplGetFrameWindow()->ImplGetParent(): nullptr; - if( ( !pFrameParent && !pPrevFrameParent ) || - ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() ) - ) + RemoveFromDlgList(); + + // set focus to previous modal dialogue if it is modal for + // the same frame parent (or NULL) + ImplSVData* pSVData = ImplGetSVData(); + if (!pSVData->maWinData.mpExecuteDialogs.empty()) { - pPrevious->GrabFocus(); + VclPtr<Dialog> pPrevious = pSVData->maWinData.mpExecuteDialogs.back(); + + vcl::Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent(); + vcl::Window* pPrevFrameParent = pPrevious->ImplGetFrameWindow()? pPrevious->ImplGetFrameWindow()->ImplGetParent(): nullptr; + if( ( !pFrameParent && !pPrevFrameParent ) || + ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() ) + ) + { + pPrevious->GrabFocus(); + } } } Hide(); - if ( GetParent() ) + + if (bModal) { - NotifyEvent aNEvt( MouseNotifyEvent::ENDEXECUTEDIALOG, this ); - GetParent()->CompatNotify( aNEvt ); + if ( GetParent() ) + { + NotifyEvent aNEvt( MouseNotifyEvent::ENDEXECUTEDIALOG, this ); + GetParent()->CompatNotify( aNEvt ); + } } mpDialogImpl->mnResult = nResult; if ( mpDialogImpl->mbStartedModal ) - { ImplEndExecuteModal(); - if (mpDialogImpl->maEndCtx.isSet()) - { - mpDialogImpl->maEndCtx.maEndDialogFn(nResult); - mpDialogImpl->maEndCtx.maEndDialogFn = nullptr; - } + + if (mpDialogImpl->maEndCtx.isSet()) + { + mpDialogImpl->maEndCtx.maEndDialogFn(nResult); + mpDialogImpl->maEndCtx.maEndDialogFn = nullptr; + } + + if ( mpDialogImpl->mbStartedModal ) + { mpDialogImpl->mbStartedModal = false; mpDialogImpl->mnResult = -1; } + mbInExecute = false; // Destroy ourselves (if we have a context with VclPtr owner) @@ -1474,15 +1498,18 @@ ModalDialog::ModalDialog( vcl::Window* pParent, const OUString& rID, const OUStr { } -void ModelessDialog::Activate() +void Dialog::Activate() { - css::uno::Reference< css::uno::XComponentContext > xContext( - comphelper::getProcessComponentContext() ); - css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW); - css::document::DocumentEvent aObject; - aObject.EventName = "ModelessDialogVisible"; - xEventBroadcaster->documentEventOccured(aObject); - Dialog::Activate(); + if (GetType() == WindowType::MODELESSDIALOG) + { + css::uno::Reference< css::uno::XComponentContext > xContext( + comphelper::getProcessComponentContext() ); + css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_QUERY_THROW); + css::document::DocumentEvent aObject; + aObject.EventName = "ModelessDialogVisible"; + xEventBroadcaster->documentEventOccured(aObject); + } + SystemWindow::Activate(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx index 734e1d0b946f..72f2eb5bf46d 100644 --- a/vcl/source/window/syswin.cxx +++ b/vcl/source/window/syswin.cxx @@ -431,7 +431,7 @@ const Size& SystemWindow::GetMaxOutputSizePixel() const return mpImplData->maMaxOutSize; } -static void ImplWindowStateFromStr(WindowStateData& rData, +void ImplWindowStateFromStr(WindowStateData& rData, const OString& rStr) { WindowStateMask nValidMask = WindowStateMask::NONE; @@ -545,7 +545,7 @@ static void ImplWindowStateFromStr(WindowStateData& rData, rData.SetMask( nValidMask ); } -static OString ImplWindowStateToStr(const WindowStateData& rData) +OString ImplWindowStateToStr(const WindowStateData& rData) { const WindowStateMask nValidMask = rData.GetMask(); if ( nValidMask == WindowStateMask::NONE ) diff --git a/vcl/unx/gtk3/gtk3gtkframe.cxx b/vcl/unx/gtk3/gtk3gtkframe.cxx index 048f15c19207..bb1cbf48b569 100644 --- a/vcl/unx/gtk3/gtk3gtkframe.cxx +++ b/vcl/unx/gtk3/gtk3gtkframe.cxx @@ -2467,6 +2467,13 @@ void GtkSalFrame::SetModal(bool bModal) gtk_window_set_modal(GTK_WINDOW(m_pWindow), bModal); } +bool GtkSalFrame::GetModal() const +{ + if (!m_pWindow) + return false; + return gtk_window_get_modal(GTK_WINDOW(m_pWindow)); +} + gboolean GtkSalFrame::signalTooltipQuery(GtkWidget*, gint /*x*/, gint /*y*/, gboolean /*keyboard_mode*/, GtkTooltip *tooltip, gpointer frame) diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 09594386fa1d..2d624e2d6197 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -36,7 +36,9 @@ #include <vcl/ImageTree.hxx> #include <vcl/quickselectionengine.hxx> #include <vcl/mnemonic.hxx> +#include <vcl/syswin.hxx> #include <vcl/weld.hxx> +#include <window.h> using namespace com::sun::star; using namespace com::sun::star::uno; @@ -2057,6 +2059,11 @@ public: gtk_window_set_modal(m_pWindow, bModal); } + virtual bool get_modal() const override + { + return gtk_window_get_modal(m_pWindow); + } + virtual void resize_to_request() override { gtk_window_resize(m_pWindow, 1, 1); @@ -2083,6 +2090,87 @@ public: return SystemEnvData(); } + virtual Size get_size() const override + { + int current_width, current_height; + gtk_window_get_size(m_pWindow, ¤t_width, ¤t_height); + return Size(current_width, current_height); + } + + virtual Point get_position() const override + { + int current_x, current_y; + gtk_window_get_position(m_pWindow, ¤t_x, ¤t_y); + return Point(current_x, current_y); + } + + virtual bool get_resizable() const override + { + return gtk_window_get_resizable(m_pWindow); + } + + virtual void set_window_state(const OString& rStr) override + { + WindowStateData aData; + ImplWindowStateFromStr( aData, rStr ); + + auto nMask = aData.GetMask(); + auto nState = aData.GetState() & WindowStateState::SystemMask; + + if (nMask & WindowStateMask::Width && nMask & WindowStateMask::Height) + { + gtk_window_set_default_size(m_pWindow, aData.GetWidth(), aData.GetHeight()); + } + if (nMask & WindowStateMask::State) + { + if (nState & WindowStateState::Maximized) + gtk_window_maximize(m_pWindow); + else + gtk_window_unmaximize(m_pWindow); + } + } + + virtual OString get_window_state(WindowStateMask nMask) const override + { + bool bPositioningAllowed = true; +#if defined(GDK_WINDOWING_WAYLAND) + // drop x/y when under wayland + GdkDisplay *pDisplay = gtk_widget_get_display(m_pWidget); + bPositioningAllowed = !GDK_IS_WAYLAND_DISPLAY(pDisplay); +#endif + + WindowStateData aData; + WindowStateMask nAvailable = WindowStateMask::State | + WindowStateMask::Width | WindowStateMask::Height; + if (bPositioningAllowed) + nAvailable |= WindowStateMask::X | WindowStateMask::Y; + aData.SetMask(nMask & nAvailable); + + if (nMask & WindowStateMask::State) + { + WindowStateState nState = WindowStateState::Normal; + if (gtk_window_is_maximized(m_pWindow)) + nState |= WindowStateState::Maximized; + aData.SetState(nState); + } + + if (bPositioningAllowed && (nMask & (WindowStateMask::X | WindowStateMask::Y))) + { + auto aPos = get_position(); + aData.SetX(aPos.X()); + aData.SetY(aPos.Y()); + } + + if (nMask & (WindowStateMask::Width | WindowStateMask::Height)) + { + auto aSize = get_size(); + aData.SetWidth(aSize.Width()); + aData.SetHeight(aSize.Height()); + } + + return ImplWindowStateToStr(aData); + } + virtual ~GtkInstanceWindow() override { if (m_xWindow.is()) @@ -2232,11 +2320,7 @@ public: m_xDialogController = rDialogController; m_aFunc = func; - if (!gtk_widget_get_visible(m_pWidget)) - { - sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog))); - gtk_widget_show(m_pWidget); - } + show(); m_nResponseSignalId = g_signal_connect(m_pDialog, "response", G_CALLBACK(signalAsyncResponse), this); @@ -2275,8 +2359,11 @@ public: virtual void show() override { - sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog))); - gtk_widget_show(m_pWidget); + if (!gtk_widget_get_visible(m_pWidget)) + { + sort_native_button_order(GTK_BOX(gtk_dialog_get_action_area(m_pDialog))); + gtk_widget_show(m_pWidget); + } } static int VclToGtk(int nResponse) |