Merge pull request #25713 from kadet1090/split-button

Gui: Use SplitButton for config migration modal
This commit is contained in:
Chris Hennes
2025-12-01 10:52:19 -06:00
committed by GitHub
9 changed files with 213 additions and 36 deletions

View File

@@ -2667,6 +2667,18 @@ void Application::setStyleSheet(const QString& qssFile, bool tiledBackground)
mw->setProperty("fc_currentStyleSheet", qssFile);
mw->setProperty("fc_tiledBackground", tiledBackground);
QString defaultStyleSheet = [this]() {
QFile f("qss:defaults.qss");
if (!f.open(QFile::ReadOnly)) {
return QString();
}
QTextStream in(&f);
return replaceVariablesInQss(in.readAll());
}();
if (!qssFile.isEmpty()) {
// Search for stylesheet in user-defined search paths.
// For qss they are set-up in runApplication() with the prefix "qss"
@@ -2686,7 +2698,7 @@ void Application::setStyleSheet(const QString& qssFile, bool tiledBackground)
QString styleSheetContent = replaceVariablesInQss(str.readAll());
qApp->setStyleSheet(styleSheetContent);
qApp->setStyleSheet(defaultStyleSheet + QStringLiteral("\n") + styleSheetContent);
ActionStyleEvent e(ActionStyleEvent::Clear);
qApp->sendEvent(mw, &e);
@@ -2714,13 +2726,13 @@ void Application::setStyleSheet(const QString& qssFile, bool tiledBackground)
}
else {
if (tiledBackground) {
qApp->setStyleSheet(QString());
qApp->setStyleSheet(defaultStyleSheet);
ActionStyleEvent e(ActionStyleEvent::Restore);
qApp->sendEvent(getMainWindow(), &e);
mdi->setBackground(QPixmap(QLatin1String("images:background.png")));
}
else {
qApp->setStyleSheet(QString());
qApp->setStyleSheet(defaultStyleSheet);
ActionStyleEvent e(ActionStyleEvent::Restore);
qApp->sendEvent(getMainWindow(), &e);
mdi->setBackground(QBrush(QColor(160, 160, 160)));

View File

@@ -1226,6 +1226,7 @@ SET(Widget_CPP_SRCS
ElideLabel.cpp
ElideCheckBox.cpp
FontScaledSVG.cpp
SplitButton.cpp
)
SET(Widget_HPP_SRCS
ComboLinks.h
@@ -1251,6 +1252,7 @@ SET(Widget_HPP_SRCS
ElideLabel.h
ElideCheckBox.h
FontScaledSVG.h
SplitButton.h
)
SET(Widget_SRCS
${Widget_CPP_SRCS}

View File

@@ -40,6 +40,8 @@
#include <cstdlib>
#include "DlgVersionMigrator.h"
#include "SplitButton.h"
#include "ui_DlgVersionMigrator.h"
#include "../MainWindow.h"
@@ -152,19 +154,22 @@ DlgVersionMigrator::DlgVersionMigrator(MainWindow* mw)
#endif
ui->sizeLabel->setText(calculatingSizeString);
connect(ui->copyButton, &QPushButton::clicked, this, &DlgVersionMigrator::migrate);
ui->copyButton->mainButton()->setDefault(true);
ui->copyButton->mainButton()->setAutoDefault(true);
ui->copyButton->mainButton()->setText(tr("Copy Configuration (Recommended)"));
connect(ui->copyButton, &SplitButton::defaultClicked, this, &DlgVersionMigrator::migrate);
connect(ui->helpButton, &QPushButton::clicked, this, &DlgVersionMigrator::help);
// Set up the menu actions for the two hidden options
auto* menu = new QMenu(ui->menuButton);
connect(ui->copyButton->mainButton(), &QPushButton::clicked, this, &DlgVersionMigrator::migrate);
auto* menu = ui->copyButton->menu();
QAction* share = menu->addAction(tr("Share configuration with previous version"));
QAction* reset = menu->addAction(tr("Use a new default configuration"));
ui->menuButton->setMenu(menu);
ui->menuButton->setPopupMode(QToolButton::InstantPopup);
ui->menuButton->setStyleSheet(
QStringLiteral("QToolButton::menu-indicator { image: none; width: 0px; }")
);
ui->menuButton->setProperty("flat", true);
connect(share, &QAction::triggered, this, &DlgVersionMigrator::share);
connect(reset, &QAction::triggered, this, &DlgVersionMigrator::freshStart);
}

View File

@@ -102,32 +102,20 @@
</spacer>
</item>
<item>
<widget class="QPushButton" name="copyButton">
<property name="text">
<string>Copy Configuration (Recommended)</string>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="menuButton">
<property name="text">
<string notr="true">⋮</string>
</property>
<property name="toolButtonStyle">
<enum>Qt::ToolButtonTextOnly</enum>
</property>
</widget>
<widget class="Gui::SplitButton" name="copyButton" native="true"/>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::SplitButton</class>
<extends>QWidget</extends>
<header>Gui/SplitButton.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

62
src/Gui/SplitButton.cpp Normal file
View File

@@ -0,0 +1,62 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2025 Kacper Donat <kacper@kadet.net> *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#include "SplitButton.h"
#include <QHBoxLayout>
using namespace Gui;
SplitButton::SplitButton(QWidget* parent)
: SplitButton(QStringLiteral(""), parent)
{}
SplitButton::SplitButton(const QString& text, QWidget* parent)
: QWidget(parent)
, m_main(new QPushButton(text, this))
, m_menuButton(new QToolButton(this))
, m_menu(new QMenu(this))
{
auto* layout = new QHBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
layout->addWidget(m_main);
layout->addWidget(m_menuButton);
// Behavior
m_main->setAutoDefault(false);
m_main->setDefault(false);
m_menuButton->setMenu(m_menu);
m_menuButton->setPopupMode(QToolButton::InstantPopup);
m_menuButton->setArrowType(Qt::DownArrow);
m_menuButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
connect(m_main, &QPushButton::clicked, this, &SplitButton::defaultClicked);
connect(m_menu, &QMenu::triggered, this, &SplitButton::triggered);
// Styling to make it look like a single split button
m_main->setProperty("splitRole", "main");
m_menuButton->setProperty("splitRole", "menu");
}

69
src/Gui/SplitButton.h Normal file
View File

@@ -0,0 +1,69 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/****************************************************************************
* *
* Copyright (c) 2025 Kacper Donat <kacper@kadet.net> *
* *
* This file is part of FreeCAD. *
* *
* FreeCAD is free software: you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 2.1 of the *
* License, or (at your option) any later version. *
* *
* FreeCAD is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with FreeCAD. If not, see *
* <https://www.gnu.org/licenses/>. *
* *
***************************************************************************/
#ifndef FREECAD_FCSPLITBUTTON_H
#define FREECAD_FCSPLITBUTTON_H
#include <QWidget>
#include <QPushButton>
#include <QToolButton>
#include <QMenu>
namespace Gui
{
class SplitButton: public QWidget
{
Q_OBJECT
public:
explicit SplitButton(QWidget* parent = nullptr);
explicit SplitButton(const QString& text, QWidget* parent = nullptr);
QPushButton* mainButton() const
{
return m_main;
}
QToolButton* menuButton() const
{
return m_menuButton;
}
QMenu* menu() const
{
return m_menu;
}
Q_SIGNALS:
void defaultClicked();
void triggered(QAction*);
private:
QPushButton* m_main;
QToolButton* m_menuButton;
QMenu* m_menu;
};
} // namespace Gui
#endif // FREECAD_FCSPLITBUTTON_H

View File

@@ -1,9 +1,10 @@
SET(Stylesheets_Files
"FreeCAD.qss"
#remove below after testing new stylesheet system 8/6/2025
"FreeCAD Dark.qss"
"FreeCAD Light.qss"
"FreeCAD.qss"
"defaults.qss"
#remove below after testing new stylesheet system 8/6/2025
"FreeCAD Dark.qss"
"FreeCAD Light.qss"
)
SET(Parameters_Files

View File

@@ -1369,6 +1369,24 @@ QToolButton::menu-arrow:hover {
image: url(qss:@IconsLocationFolderName/arrow-down-@StylesheetIconsColor.svg);
}
/* Gui::SplitButton --------------------------------------------------------- */
Gui--SplitButton QPushButton[splitRole="main"] {
border-right: none;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
Gui--SplitButton QToolButton[splitRole="menu"] {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
Gui--SplitButton QToolButton::menu-indicator {
image: none;
border-image: none;
}
/* QCommandLinkButton -----------------------------------------------------
--------------------------------------------------------------------------- */

View File

@@ -0,0 +1,20 @@
/*
* This is a file with default QSS styles that will be preincluded for all themes. It should cover only the styles for
* our own controls and not alter visuals of stuff like buttons etc. This is created so we can use QSS to add color
* to links or control certain aspects of program looks that should be shared across all styles, including classic.
*/
/* Gui::SplitButton --------------------------------------------------------- */
Gui--SplitButton QToolButton[splitRole="menu"] {
width: 24px;
margin: 0;
padding: 0;
min-height: 0px;
max-height: none;
}
Gui--SplitButton QToolButton::menu-indicator {
image: none;
border-image: none;
}