Files
libreoffice/vcl/qt5/QtBuilder.cxx

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

399 lines
13 KiB
C++
Raw Normal View History

tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02: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/.
*/
#include <QtBuilder.hxx>
#include <QtInstanceMessageDialog.hxx>
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
#include <QtTools.hxx>
#include <rtl/ustrbuf.hxx>
#include <QtWidgets/QCheckBox>
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
#include <QtWidgets/QDialog>
#include <QtWidgets/QDialogButtonBox>
tdf#130857 qt weld: Create QGroupBox for "GtkFrame" Handle "GtkFrame" objects from .ui files and create a QGroupBox [1] for them. While there's also a QFrame class in Qt, QGroupBox seems more suitable, as it allows setting a title, while QFrame doesn't. Add special handling for the label child of the "GtkFrame". Quoting from the GtkFrame doc [2]: > The GtkFrame implementation of the GtkBuildable interface supports > placing a child in the label position by specifying “label” as the > “type” attribute of a <child> element. A normal content child can be > specified without specifying a <child> type attribute. Example for a frame label in chart2/uiconfig/ui/insertaxisdlg.ui: <child type="label"> <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can-focus">False</property> <property name="hexpand">True</property> <property name="label" translatable="yes" context="insertaxisdlg|label1">Axes</property> <attributes> <attribute name="weight" value="bold"/> </attributes> </object> </child> In order to set the label's text as the text for the QGroupBox, identify that label child in QtBuilder::tweakInsertedChild, take over its text as the QGroupBox title, and mark the label for deletion, as it's no longer needed, since the QGroupBox handles its title itself from then on. [1] https://doc.qt.io/qt-6/qgroupbox.html [2] https://docs.gtk.org/gtk4/class.Frame.html Change-Id: Ie917a501466bad8821fc3e7f5049db7c1a56995f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174465 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-10-04 10:38:32 +02:00
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
#include <QtWidgets/QLayout>
#include <QtWidgets/QPlainTextEdit>
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
#include <QtWidgets/QPushButton>
#include <QtWidgets/QScrollArea>
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
namespace
{
QString convertAccelerator(const OUString& rText)
{
// preserve literal '&'s and use '&' instead of '_' for the accelerator
return toQString(rText.replaceAll("&", "&&").replace('_', '&'));
}
}
QtBuilder::QtBuilder(QObject* pParent, std::u16string_view sUIRoot, const OUString& rUIFile)
: WidgetBuilder(sUIRoot, rUIFile, false)
{
processUIFile(pParent);
}
QtBuilder::~QtBuilder() {}
QObject* QtBuilder::get_by_name(std::u16string_view sID)
{
for (auto const& child : m_aChildren)
{
if (child.m_sID == sID)
return child.m_pWindow;
}
return nullptr;
}
void QtBuilder::insertComboBoxOrListBoxItems(QObject*, stringmap&,
const std::vector<ComboBoxTextItem>&)
{
assert(false && "comboboxes and list boxes are not supported yet");
}
QObject* QtBuilder::insertObject(QObject* pParent, const OUString& rClass, const OUString& rID,
stringmap& rProps, stringmap&, stringmap&)
{
QObject* pCurrentChild = nullptr;
pCurrentChild = makeObject(pParent, rClass, rID, rProps);
setProperties(pCurrentChild, rProps);
rProps.clear();
return pCurrentChild;
}
QObject* QtBuilder::makeObject(QObject* pParent, std::u16string_view sName, const OUString& sID,
stringmap& rMap)
{
// ignore placeholders
if (sName.empty())
return nullptr;
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
QWidget* pParentWidget = qobject_cast<QWidget*>(pParent);
QLayout* pParentLayout = qobject_cast<QLayout*>(pParent);
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
QObject* pObject = nullptr;
if (sName == u"GtkMessageDialog")
{
pObject = new QMessageBox(pParentWidget);
}
else if (sName == u"GtkBox")
{
// for a QMessageBox, return the existing layout instead of creating a new one
if (QMessageBox* pMessageBox = qobject_cast<QMessageBox*>(pParent))
{
pObject = pMessageBox->layout();
assert(pObject && "QMessageBox has no layout");
}
else
{
const bool bVertical = hasOrientationVertical(rMap);
if (bVertical)
pObject = new QVBoxLayout(pParentWidget);
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
else
pObject = new QHBoxLayout(pParentWidget);
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
}
}
else if (sName == u"GtkButtonBox")
{
QWidget* pTopLevel = windowForObject(pParent);
if (QMessageBox* pMessageBox = qobject_cast<QMessageBox*>(pTopLevel))
{
// for a QMessageBox, return the existing button box instead of creating a new one
QDialogButtonBox* pButtonBox = findButtonBox(pMessageBox);
assert(pButtonBox && "Could not find QMessageBox's button box");
pObject = pButtonBox;
// skip adding to layout below, button box is already contained in dialog
pParentLayout = nullptr;
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
}
else
{
pObject = new QDialogButtonBox(pParentWidget);
}
}
else if (sName == u"GtkButton")
{
if (QDialogButtonBox* pButtonBox = qobject_cast<QDialogButtonBox*>(pParentWidget))
{
pObject = pButtonBox->addButton("", QDialogButtonBox::NoRole);
// for message boxes, avoid implicit standard buttons in addition to those explicitly added
if (QMessageBox* pMessageBox = qobject_cast<QMessageBox*>(pParentWidget->window()))
pMessageBox->setStandardButtons(QMessageBox::NoButton);
}
else
{
pObject = new QPushButton(pParentWidget);
}
}
else if (sName == u"GtkCheckButton")
{
pObject = new QCheckBox(pParentWidget);
}
else if (sName == u"GtkDialog")
{
pObject = new QDialog(pParentWidget);
}
else if (sName == u"GtkEntry")
{
pObject = new QLineEdit(pParentWidget);
}
tdf#130857 qt weld: Create QGroupBox for "GtkFrame" Handle "GtkFrame" objects from .ui files and create a QGroupBox [1] for them. While there's also a QFrame class in Qt, QGroupBox seems more suitable, as it allows setting a title, while QFrame doesn't. Add special handling for the label child of the "GtkFrame". Quoting from the GtkFrame doc [2]: > The GtkFrame implementation of the GtkBuildable interface supports > placing a child in the label position by specifying “label” as the > “type” attribute of a <child> element. A normal content child can be > specified without specifying a <child> type attribute. Example for a frame label in chart2/uiconfig/ui/insertaxisdlg.ui: <child type="label"> <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can-focus">False</property> <property name="hexpand">True</property> <property name="label" translatable="yes" context="insertaxisdlg|label1">Axes</property> <attributes> <attribute name="weight" value="bold"/> </attributes> </object> </child> In order to set the label's text as the text for the QGroupBox, identify that label child in QtBuilder::tweakInsertedChild, take over its text as the QGroupBox title, and mark the label for deletion, as it's no longer needed, since the QGroupBox handles its title itself from then on. [1] https://doc.qt.io/qt-6/qgroupbox.html [2] https://docs.gtk.org/gtk4/class.Frame.html Change-Id: Ie917a501466bad8821fc3e7f5049db7c1a56995f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174465 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-10-04 10:38:32 +02:00
else if (sName == u"GtkFrame")
{
pObject = new QGroupBox(pParentWidget);
}
else if (sName == u"GtkLabel")
{
pObject = new QLabel(pParentWidget);
}
else if (sName == u"GtkScrolledWindow")
{
pObject = new QScrollArea(pParentWidget);
}
else if (sName == u"GtkTextView")
{
pObject = new QPlainTextEdit(pParentWidget);
}
else
{
SAL_WARN("vcl.qt", "Widget type not supported yet: "
<< OUStringToOString(sName, RTL_TEXTENCODING_UTF8));
assert(false && "Widget type not supported yet");
}
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
if (QWidget* pWidget = qobject_cast<QWidget*>(pObject))
{
// add widget to parent layout
if (pParentLayout)
pParentLayout->addWidget(pWidget);
QtInstanceWidget::setHelpId(*pWidget, getHelpRoot() + sID);
#if QT_VERSION >= QT_VERSION_CHECK(6, 9, 0)
// Set GtkBuilder ID as accessible ID
pWidget->setAccessibleIdentifier(toQString(sID));
#endif
}
else if (QLayout* pLayout = qobject_cast<QLayout*>(pObject))
{
// add layout to parent layout
if (QBoxLayout* pParentBoxLayout = qobject_cast<QBoxLayout*>(pParentLayout))
pParentBoxLayout->addLayout(pLayout);
}
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
m_aChildren.emplace_back(sID, pObject);
return pObject;
}
tdf#130857 qt weld: Create QGroupBox for "GtkFrame" Handle "GtkFrame" objects from .ui files and create a QGroupBox [1] for them. While there's also a QFrame class in Qt, QGroupBox seems more suitable, as it allows setting a title, while QFrame doesn't. Add special handling for the label child of the "GtkFrame". Quoting from the GtkFrame doc [2]: > The GtkFrame implementation of the GtkBuildable interface supports > placing a child in the label position by specifying “label” as the > “type” attribute of a <child> element. A normal content child can be > specified without specifying a <child> type attribute. Example for a frame label in chart2/uiconfig/ui/insertaxisdlg.ui: <child type="label"> <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can-focus">False</property> <property name="hexpand">True</property> <property name="label" translatable="yes" context="insertaxisdlg|label1">Axes</property> <attributes> <attribute name="weight" value="bold"/> </attributes> </object> </child> In order to set the label's text as the text for the QGroupBox, identify that label child in QtBuilder::tweakInsertedChild, take over its text as the QGroupBox title, and mark the label for deletion, as it's no longer needed, since the QGroupBox handles its title itself from then on. [1] https://doc.qt.io/qt-6/qgroupbox.html [2] https://docs.gtk.org/gtk4/class.Frame.html Change-Id: Ie917a501466bad8821fc3e7f5049db7c1a56995f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174465 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-10-04 10:38:32 +02:00
void QtBuilder::tweakInsertedChild(QObject* pParent, QObject* pCurrentChild, std::string_view sType,
tdf#130857 qt weld: Ensure dialog button box is last in layout For QDialog, make sure that if a button box is included in the dialog's layout, that this is the last item in the layout, by removing from the layout and adding it at the end again. I don't see any explicit child index explicitly being set in the .ui file for the "Help" -> "License Information" dialog ("sfx/ui/licensedialog.ui"). Potentially GTK implicitly visually makes the dialog's button box the last item in the dialog. Corresponding child is this one: <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area1"> Potentially the `<child internal-child="action_area">` identifies this as the dialog's button box that should be last, at least dialog newly created in glade also has that set. For QMessageBox, which is a QDialog subclass, this special handling is not needed, as its default button box is used, which is already at the right place. This addresses the first aspect mentioned in previous commit: Change-Id: Ic9393755ec474f77ff22a1115e3cccba9d7b26cb Author: Michael Weghorn <m.weghorn@posteo.de> Date: Sat Sep 28 00:07:28 2024 +0200 tdf#130857 qt weld: Add initial support for dialog and label > However, currently buttons and the label with the text > are in the wrong order (i.e. buttons are above the text) Still missing: > and clicking the buttons doesn't yet have any effect. Change-Id: Id991551548c1e54fdf2e169886a6c67fc307931f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174077 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2024-09-28 00:26:52 +02:00
std::string_view)
{
tdf#130857 qt weld: Create QGroupBox for "GtkFrame" Handle "GtkFrame" objects from .ui files and create a QGroupBox [1] for them. While there's also a QFrame class in Qt, QGroupBox seems more suitable, as it allows setting a title, while QFrame doesn't. Add special handling for the label child of the "GtkFrame". Quoting from the GtkFrame doc [2]: > The GtkFrame implementation of the GtkBuildable interface supports > placing a child in the label position by specifying “label” as the > “type” attribute of a <child> element. A normal content child can be > specified without specifying a <child> type attribute. Example for a frame label in chart2/uiconfig/ui/insertaxisdlg.ui: <child type="label"> <object class="GtkLabel" id="label1"> <property name="visible">True</property> <property name="can-focus">False</property> <property name="hexpand">True</property> <property name="label" translatable="yes" context="insertaxisdlg|label1">Axes</property> <attributes> <attribute name="weight" value="bold"/> </attributes> </object> </child> In order to set the label's text as the text for the QGroupBox, identify that label child in QtBuilder::tweakInsertedChild, take over its text as the QGroupBox title, and mark the label for deletion, as it's no longer needed, since the QGroupBox handles its title itself from then on. [1] https://doc.qt.io/qt-6/qgroupbox.html [2] https://docs.gtk.org/gtk4/class.Frame.html Change-Id: Ie917a501466bad8821fc3e7f5049db7c1a56995f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174465 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-10-04 10:38:32 +02:00
if (sType == "label")
{
if (QLabel* pLabel = qobject_cast<QLabel*>(pCurrentChild))
{
if (QGroupBox* pGroupBox = qobject_cast<QGroupBox*>(pParent))
{
// GtkFrame has a `child-type="label"` child for the GtkFrame label
// in the GtkBuilder .ui file, s. https://docs.gtk.org/gtk3/class.Frame.html
// For QGroupBox, the title can be set directly. Therefore, take over the
// title from the label and delete the separate label widget again
pGroupBox->setTitle(pLabel->text());
pLabel->setParent(nullptr);
pLabel->deleteLater();
}
}
}
tdf#130857 qt weld: Ensure dialog button box is last in layout For QDialog, make sure that if a button box is included in the dialog's layout, that this is the last item in the layout, by removing from the layout and adding it at the end again. I don't see any explicit child index explicitly being set in the .ui file for the "Help" -> "License Information" dialog ("sfx/ui/licensedialog.ui"). Potentially GTK implicitly visually makes the dialog's button box the last item in the dialog. Corresponding child is this one: <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area1"> Potentially the `<child internal-child="action_area">` identifies this as the dialog's button box that should be last, at least dialog newly created in glade also has that set. For QMessageBox, which is a QDialog subclass, this special handling is not needed, as its default button box is used, which is already at the right place. This addresses the first aspect mentioned in previous commit: Change-Id: Ic9393755ec474f77ff22a1115e3cccba9d7b26cb Author: Michael Weghorn <m.weghorn@posteo.de> Date: Sat Sep 28 00:07:28 2024 +0200 tdf#130857 qt weld: Add initial support for dialog and label > However, currently buttons and the label with the text > are in the wrong order (i.e. buttons are above the text) Still missing: > and clicking the buttons doesn't yet have any effect. Change-Id: Id991551548c1e54fdf2e169886a6c67fc307931f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174077 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2024-09-28 00:26:52 +02:00
if (QDialog* pDialog = qobject_cast<QDialog*>(pCurrentChild))
{
// no action needed for QMessageBox, where the default button box is used
// and button click is handled in QtInstanceMessageDialog
tdf#130857 qt weld: Ensure dialog button box is last in layout For QDialog, make sure that if a button box is included in the dialog's layout, that this is the last item in the layout, by removing from the layout and adding it at the end again. I don't see any explicit child index explicitly being set in the .ui file for the "Help" -> "License Information" dialog ("sfx/ui/licensedialog.ui"). Potentially GTK implicitly visually makes the dialog's button box the last item in the dialog. Corresponding child is this one: <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area1"> Potentially the `<child internal-child="action_area">` identifies this as the dialog's button box that should be last, at least dialog newly created in glade also has that set. For QMessageBox, which is a QDialog subclass, this special handling is not needed, as its default button box is used, which is already at the right place. This addresses the first aspect mentioned in previous commit: Change-Id: Ic9393755ec474f77ff22a1115e3cccba9d7b26cb Author: Michael Weghorn <m.weghorn@posteo.de> Date: Sat Sep 28 00:07:28 2024 +0200 tdf#130857 qt weld: Add initial support for dialog and label > However, currently buttons and the label with the text > are in the wrong order (i.e. buttons are above the text) Still missing: > and clicking the buttons doesn't yet have any effect. Change-Id: Id991551548c1e54fdf2e169886a6c67fc307931f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174077 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2024-09-28 00:26:52 +02:00
if (!qobject_cast<QMessageBox*>(pDialog))
{
if (QDialogButtonBox* pButtonBox = findButtonBox(pDialog))
{
// ensure that button box is the last item in QDialog's layout
// (that seems to be implicitly the case for GtkDialog in GTK)
tdf#130857 qt weld: Ensure dialog button box is last in layout For QDialog, make sure that if a button box is included in the dialog's layout, that this is the last item in the layout, by removing from the layout and adding it at the end again. I don't see any explicit child index explicitly being set in the .ui file for the "Help" -> "License Information" dialog ("sfx/ui/licensedialog.ui"). Potentially GTK implicitly visually makes the dialog's button box the last item in the dialog. Corresponding child is this one: <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area1"> Potentially the `<child internal-child="action_area">` identifies this as the dialog's button box that should be last, at least dialog newly created in glade also has that set. For QMessageBox, which is a QDialog subclass, this special handling is not needed, as its default button box is used, which is already at the right place. This addresses the first aspect mentioned in previous commit: Change-Id: Ic9393755ec474f77ff22a1115e3cccba9d7b26cb Author: Michael Weghorn <m.weghorn@posteo.de> Date: Sat Sep 28 00:07:28 2024 +0200 tdf#130857 qt weld: Add initial support for dialog and label > However, currently buttons and the label with the text > are in the wrong order (i.e. buttons are above the text) Still missing: > and clicking the buttons doesn't yet have any effect. Change-Id: Id991551548c1e54fdf2e169886a6c67fc307931f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174077 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2024-09-28 00:26:52 +02:00
QLayout* pLayout = pDialog->layout();
assert(pLayout && "dialog has no layout");
pLayout->removeWidget(pButtonBox);
pLayout->addWidget(pButtonBox);
// connect button click handler
const QList<QAbstractButton*> aButtons = pButtonBox->buttons();
for (QAbstractButton* pButton : aButtons)
{
assert(pButton);
QObject::connect(pButton, &QAbstractButton::clicked, pDialog,
[pDialog, pButton] {
QtInstanceDialog::handleButtonClick(*pDialog, *pButton);
});
}
tdf#130857 qt weld: Ensure dialog button box is last in layout For QDialog, make sure that if a button box is included in the dialog's layout, that this is the last item in the layout, by removing from the layout and adding it at the end again. I don't see any explicit child index explicitly being set in the .ui file for the "Help" -> "License Information" dialog ("sfx/ui/licensedialog.ui"). Potentially GTK implicitly visually makes the dialog's button box the last item in the dialog. Corresponding child is this one: <child internal-child="action_area"> <object class="GtkButtonBox" id="dialog-action_area1"> Potentially the `<child internal-child="action_area">` identifies this as the dialog's button box that should be last, at least dialog newly created in glade also has that set. For QMessageBox, which is a QDialog subclass, this special handling is not needed, as its default button box is used, which is already at the right place. This addresses the first aspect mentioned in previous commit: Change-Id: Ic9393755ec474f77ff22a1115e3cccba9d7b26cb Author: Michael Weghorn <m.weghorn@posteo.de> Date: Sat Sep 28 00:07:28 2024 +0200 tdf#130857 qt weld: Add initial support for dialog and label > However, currently buttons and the label with the text > are in the wrong order (i.e. buttons are above the text) Still missing: > and clicking the buttons doesn't yet have any effect. Change-Id: Id991551548c1e54fdf2e169886a6c67fc307931f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/174077 Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Jenkins
2024-09-28 00:26:52 +02:00
}
}
}
}
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
void QtBuilder::setMnemonicWidget(const OUString&, const OUString&)
{
SAL_WARN("vcl.qt", "QtBuilder::setMnemonicWidget not implemented yet");
}
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
void QtBuilder::setPriority(QObject*, int) { SAL_WARN("vcl.qt", "Ignoring priority"); }
void QtBuilder::setContext(QObject*, std::vector<vcl::EnumContext::Context>&&)
{
SAL_WARN("vcl.qt", "Ignoring context");
}
void QtBuilder::applyAtkProperties(QObject* pObject, const stringmap& rProperties, bool)
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
{
if (!pObject || !pObject->isWidgetType())
return;
QWidget* pWidget = static_cast<QWidget*>(pObject);
for (auto const & [ rKey, rValue ] : rProperties)
{
if (rKey == "AtkObject::accessible-description")
pWidget->setAccessibleDescription(toQString(rValue));
else if (rKey == "AtkObject::accessible-name")
pWidget->setAccessibleName(toQString(rValue));
}
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
}
void QtBuilder::applyPackingProperties(QObject*, QObject*, const stringmap&)
{
SAL_WARN("vcl.qt", "QtBuilder::applyPackingProperties not implemented yet");
}
void QtBuilder::set_response(std::u16string_view sID, short nResponse)
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
{
QPushButton* pPushButton = get<QPushButton>(sID);
assert(pPushButton);
pPushButton->setProperty(QtInstanceMessageDialog::PROPERTY_VCL_RESPONSE_CODE, int(nResponse));
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
}
void QtBuilder::setProperties(QObject* pObject, stringmap& rProps)
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
{
if (QMessageBox* pMessageBox = qobject_cast<QMessageBox*>(pObject))
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
{
for (auto const & [ rKey, rValue ] : rProps)
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
{
if (rKey == u"text")
{
pMessageBox->setText(toQString(rValue));
}
else if (rKey == u"title")
{
pMessageBox->setWindowTitle(toQString(rValue));
}
else if (rKey == u"secondary-text")
{
pMessageBox->setInformativeText(toQString(rValue));
}
else if (rKey == u"message-type")
{
if (rValue == u"error")
pMessageBox->setIcon(QMessageBox::Critical);
else if (rValue == u"info")
pMessageBox->setIcon(QMessageBox::Information);
else if (rValue == u"question")
pMessageBox->setIcon(QMessageBox::Question);
else if (rValue == u"warning")
pMessageBox->setIcon(QMessageBox::Warning);
else
assert(false && "Unhandled message-type");
}
}
}
else if (QCheckBox* pCheckBox = qobject_cast<QCheckBox*>(pObject))
{
for (auto const & [ rKey, rValue ] : rProps)
{
if (rKey == u"active")
pCheckBox->setChecked(toBool(rValue));
else if (rKey == u"label")
pCheckBox->setText(convertAccelerator(rValue));
}
}
else if (QDialog* pDialog = qobject_cast<QDialog*>(pObject))
{
for (auto const & [ rKey, rValue ] : rProps)
{
if (rKey == u"modal")
pDialog->setModal(toBool(rValue));
else if (rKey == u"title")
pDialog->setWindowTitle(toQString(rValue));
}
}
else if (QLabel* pLabel = qobject_cast<QLabel*>(pObject))
{
for (auto const & [ rKey, rValue ] : rProps)
{
if (rKey == u"label")
pLabel->setText(toQString(rValue));
else if (rKey == u"wrap")
pLabel->setWordWrap(toBool(rValue));
}
}
else if (QPushButton* pButton = qobject_cast<QPushButton*>(pObject))
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
{
for (auto const & [ rKey, rValue ] : rProps)
{
if (rKey == u"label")
pButton->setText(convertAccelerator(rValue));
}
}
}
QWidget* QtBuilder::windowForObject(QObject* pObject)
{
if (QWidget* pWidget = qobject_cast<QWidget*>(pObject))
return pWidget->window();
if (QLayout* pLayout = qobject_cast<QLayout*>(pObject))
{
if (QWidget* pParentWidget = pLayout->parentWidget())
return pParentWidget->window();
}
return nullptr;
}
QDialogButtonBox* QtBuilder::findButtonBox(QDialog* pDialog)
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
{
assert(pDialog);
QLayout* pLayout = pDialog->layout();
if (!pLayout)
return nullptr;
tdf#130857 qt weld: Implement QtBuilder + use it for first msg dialog This implements an initial QtBuilder, which is used by QtInstanceBuilder to create weld::Widget instances using native Qt widgets. This tries to be close to the VCL implementation (VclBuilder). The selected approach is based on Caolán's suggestion in [1] to rework VclBuilder to have overridable methods for widgets creation. This way, we can have common code for the UI parser but the function for widget creation is different. Qt equivalents for Gtk's widget classes in the .ui files: * GtkMessageDialog -> QMessageBox * GtkBox -> QLayout (can be QVBoxLayout/QHBoxLayout based on property in .ui file) * GtkButtonBox -> QDialogButtonBox * GtkButton -> QPushButton As QMessageBox already comes with a layout and a QDialogButtonBox, don't create new ones, but return the existing ones in QtBuilder::makeObject. This commit implements initial support for the above-mentioned widget types and adds the first message dialog to the list of supported .ui files in QtInstanceBuilder::IsUIFileSupported, so a native QMessageBox is used for it now, unless environment variable SAL_VCL_QT_NO_WELDED_WIDGETS is set when starting LibreOffice. The dialog ("modules/swriter/ui/inforeadonlydialog.ui") gets shown when taking the following steps: * start Writer * type "hello world" * select text * "Insert" -> "Section" * tick the "Protect" checkbox in the "Write Protection" section * close dialog via "Insert" button * try to type in the protected section The dialog can be dismissed using the default "OK" button. (Handling for response codes for buttons is not implemented yet, which will be needed when welding dialogs that have multiple buttons resulting in different behavior depending on what button gets clicked.) This change was originally submitted as a WIP change as part of Omkar Acharekar's Outreachy project "Implement Qt/KDE Frameworks theming using native Qt widgets" (see [2]), then further refined by Michael Weghorn. [1] https://lists.freedesktop.org/archives/libreoffice/2023-December/091288.html [2] https://lists.freedesktop.org/archives/libreoffice/2023-December/091281.html Co-authored-by: Michael Weghorn <m.weghorn@posteo.de> Change-Id: I6dd010a2138c245dc1e6d83dd08123898e9d9048 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161831 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
2024-09-25 09:48:09 +02:00
for (int i = 0; i < pLayout->count(); i++)
{
QLayoutItem* pItem = pLayout->itemAt(i);
if (QWidget* pItemWidget = pItem->widget())
{
if (QDialogButtonBox* pButtonBox = qobject_cast<QDialogButtonBox*>(pItemWidget))
return pButtonBox;
}
}
return nullptr;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */