/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ /* * 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/. */ #include #include #include #include const char* const QtInstanceDialog::PROPERTY_VCL_RESPONSE_CODE = "response-code"; QtInstanceDialog::QtInstanceDialog(QDialog* pDialog) : QtInstanceWindow(pDialog) , m_pDialog(pDialog) , m_pContentArea(nullptr) , m_aRunAsyncFunc(nullptr) { } QtInstanceDialog::~QtInstanceDialog() { SolarMutexGuard g; GetQtInstance().RunInMainThread([&] { m_pDialog.reset(); }); } bool QtInstanceDialog::runAsync(const std::shared_ptr& rxOwner, const std::function& func) { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); if (!rQtInstance.IsMainThread()) { bool bRet = false; rQtInstance.RunInMainThread([&] { bRet = runAsync(rxOwner, func); }); return bRet; } assert(m_pDialog); m_xRunAsyncDialogController = rxOwner; m_aRunAsyncFunc = func; connect(m_pDialog.get(), &QDialog::finished, this, &QtInstanceDialog::dialogFinished); m_pDialog->open(); return true; } bool QtInstanceDialog::runAsync(std::shared_ptr const& rxSelf, const std::function& func) { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); if (!rQtInstance.IsMainThread()) { bool bRet; rQtInstance.RunInMainThread([&] { bRet = runAsync(rxSelf, func); }); return bRet; } assert(m_pDialog); assert(rxSelf.get() == this); m_xRunAsyncDialog = rxSelf; m_aRunAsyncFunc = func; connect(m_pDialog.get(), &QDialog::finished, this, &QtInstanceDialog::dialogFinished); m_pDialog->open(); return true; } void QtInstanceDialog::collapse(weld::Widget*, weld::Widget*) { assert(false && "Not implemented yet"); } void QtInstanceDialog::undo_collapse() { assert(false && "Not implemented yet"); } void QtInstanceDialog::SetInstallLOKNotifierHdl(const Link&) { } int QtInstanceDialog::run() { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); if (!rQtInstance.IsMainThread()) { int nResult = 0; rQtInstance.RunInMainThread([&] { nResult = run(); }); return nResult; } return m_pDialog->exec(); } void QtInstanceDialog::response(int nResponse) { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); rQtInstance.RunInMainThread([&] { m_pDialog->done(nResponse); }); } void QtInstanceDialog::add_button(const OUString&, int, const OUString&) { assert(false && "Not implemented yet"); } void QtInstanceDialog::set_modal(bool bModal) { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); if (!rQtInstance.IsMainThread()) { rQtInstance.RunInMainThread([&] { set_modal(bModal); }); return; } m_pDialog->setModal(bModal); } bool QtInstanceDialog::get_modal() const { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); if (!rQtInstance.IsMainThread()) { bool bModal = false; rQtInstance.RunInMainThread([&] { bModal = get_modal(); }); return bModal; } return m_pDialog->isModal(); } void QtInstanceDialog::set_centered_on_parent(bool) { // QDialog is centered on parent toplevel by default } std::unique_ptr QtInstanceDialog::weld_button_for_response(int) { assert(false && "Not implemented yet"); return nullptr; } void QtInstanceDialog::set_default_response(int) { assert(false && "Not implemented yet"); } std::unique_ptr QtInstanceDialog::weld_content_area() { if (!m_pContentArea) { if (QBoxLayout* pBoxLayout = qobject_cast(m_pDialog->layout())) { // insert an extra widget and layout at beginning of the dialog's layout m_pContentArea = new QWidget; m_pContentArea->setLayout(new QVBoxLayout); pBoxLayout->insertWidget(0, m_pContentArea); } else { assert(false && "Dialog has layout that's not supported (yet)"); } } return std::make_unique(m_pContentArea); } void QtInstanceDialog::dialogFinished(int nResult) { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); if (!rQtInstance.IsMainThread()) { rQtInstance.RunInMainThread([&] { dialogFinished(nResult); }); return; } disconnect(m_pDialog.get(), &QDialog::finished, this, &QtInstanceDialog::dialogFinished); // use local variables for these, as members might have got de-allocated by the time they're reset std::shared_ptr xRunAsyncDialog = m_xRunAsyncDialog; std::shared_ptr xRunAsyncDialogController = m_xRunAsyncDialogController; std::function aFunc = m_aRunAsyncFunc; m_aRunAsyncFunc = nullptr; m_xRunAsyncDialogController.reset(); m_xRunAsyncDialog.reset(); if (aFunc) aFunc(nResult); xRunAsyncDialogController.reset(); xRunAsyncDialog.reset(); } void QtInstanceDialog::handleButtonClick(QDialog& rDialog, QAbstractButton& rButton) { SolarMutexGuard g; QtInstance& rQtInstance = GetQtInstance(); if (!rQtInstance.IsMainThread()) { rQtInstance.RunInMainThread([&] { handleButtonClick(rDialog, rButton); }); return; } // skip default handling if a custom click handler is set if (QtInstanceButton::hasCustomClickHandler(rButton)) return; QVariant aResponseProperty = rButton.property(QtInstanceDialog::PROPERTY_VCL_RESPONSE_CODE); if (!aResponseProperty.isValid()) return; assert(aResponseProperty.canConvert()); const int nResponseCode = aResponseProperty.toInt(); // close dialog with button's response code unless it's the "Help" button if (nResponseCode != RET_HELP) { rDialog.done(nResponseCode); return; } // handle "Help" button Help* pHelp = Application::GetHelp(); if (!pHelp) return; QtInstanceWidget aButtonWidget(&rButton); pHelp->Start(aButtonWidget.get_help_id(), &aButtonWidget); } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */