Merge pull request #5091 from chennes/sketcherMoveColorsToPrefs

[Sketcher] Make constraint label smaller and styleable
This commit is contained in:
abdullahtahiriyo
2021-10-13 11:34:11 +02:00
committed by GitHub
20 changed files with 801 additions and 108 deletions

View File

@@ -2276,3 +2276,38 @@ QPushButton#NavigationIndicator::menu-indicator {
image: none;
width: 0px;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2243,3 +2243,39 @@ QPushButton#NavigationIndicator::menu-indicator {
image: none;
width: 0px;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2269,3 +2269,38 @@ QToolBar QToolButton[popupMode="1"] {
width: 100px;
background: red;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2242,3 +2242,38 @@ QPushButton#NavigationIndicator::menu-indicator {
image: none;
width: 0px;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2243,3 +2243,38 @@ QPushButton#NavigationIndicator::menu-indicator {
image: none;
width: 0px;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2269,3 +2269,38 @@ QToolBar QToolButton[popupMode="1"] {
width: 100px;
background: red;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2269,3 +2269,38 @@ QToolBar QToolButton[popupMode="1"] {
width: 100px;
background: red;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2269,3 +2269,38 @@ QToolBar QToolButton[popupMode="1"] {
width: 100px;
background: red;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,91,255,255); /* Deep sky blue */
text-decoration : underline;
}

View File

@@ -2244,3 +2244,38 @@ QPushButton#NavigationIndicator::menu-indicator {
image: none;
width: 0px;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(0,0,0,127); /* 50% opacity black */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(0,0,0,255); /* Black */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,0,255,255); /* Blue */
text-decoration : underline;
}

View File

@@ -2244,3 +2244,39 @@ QPushButton#NavigationIndicator::menu-indicator {
image: none;
width: 0px;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(0,0,0,127); /* 50% opacity black */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(0,0,0,255); /* Black */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,0,255,255); /* Blue */
text-decoration : underline;
}

View File

@@ -2244,3 +2244,38 @@ QPushButton#NavigationIndicator::menu-indicator {
image: none;
width: 0px;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(0,0,0,127); /* 50% opacity black */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(0,0,0,255); /* Black */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}
Gui--UrlLabel {
color : rgba(0,0,255,255); /* Blue */
text-decoration : underline;
}

View File

@@ -2494,3 +2494,34 @@ QToolBar QToolButton[popupMode="1"] {
width: 100px;
background: red;
}
/*==================================================================================================
SKETCHER
==================================================================================================*/
Gui--StatefulLabel[state="empty_sketch"] {
color : rgba(255,255,255,127); /* 50% opacity white */
}
Gui--StatefulLabel[state="under_constrained"] {
color : rgba(255,255,255,255); /* White */
}
Gui--StatefulLabel[state="conflicting_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="malformed_constraints"] {
color : rgba(255,0,0,255); /* Red */
}
Gui--StatefulLabel[state="redundant_constraints"] {
color : rgba(255,69,0,255); /* Orange red */
}
Gui--StatefulLabel[state="partially_redundant_constraints"] {
color : rgba(65,105,225,255); /* Royal blue */
}
Gui--StatefulLabel[state="solver_failed"] {
color : rgba(255,0,0,255); /* Red */
font-weight: bold;
}
Gui--StatefulLabel[state="fully_constrained"] {
color : rgba(0,255,0,255); /* Green */
font-weight: bold;
}

View File

@@ -835,6 +835,7 @@ void ColorButton::onRejected()
UrlLabel::UrlLabel(QWidget* parent, Qt::WindowFlags f)
: QLabel(parent, f)
, _url (QStringLiteral("http://localhost"))
, _launchExternal(true)
{
setToolTip(this->_url);
setCursor(Qt::PointingHandCursor);
@@ -846,9 +847,18 @@ UrlLabel::~UrlLabel()
{
}
void Gui::UrlLabel::setLaunchExternal(bool l)
{
_launchExternal = l;
}
void UrlLabel::mouseReleaseEvent(QMouseEvent*)
{
QDesktopServices::openUrl(this->_url);
if (_launchExternal)
QDesktopServices::openUrl(this->_url);
else
// Someone else will deal with it...
Q_EMIT linkClicked(_url);
}
QString UrlLabel::url() const
@@ -856,6 +866,11 @@ QString UrlLabel::url() const
return this->_url;
}
bool Gui::UrlLabel::launchExternal() const
{
return _launchExternal;
}
void UrlLabel::setUrl(const QString& u)
{
this->_url = u;
@@ -864,6 +879,157 @@ void UrlLabel::setUrl(const QString& u)
// --------------------------------------------------------------------
StatefulLabel::StatefulLabel(QWidget* parent)
: QLabel(parent)
, _overridePreference(false)
{
// Always attach to the parameter group that stores the main FreeCAD stylesheet
_stylesheetGroup = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/General");
_stylesheetGroup->Attach(this);
}
StatefulLabel::~StatefulLabel()
{
if (_parameterGroup.isValid())
_parameterGroup->Detach(this);
_stylesheetGroup->Detach(this);
}
void StatefulLabel::setDefaultStyle(const QString& defaultStyle)
{
_defaultStyle = defaultStyle;
}
void StatefulLabel::setParameterGroup(const std::string& groupName)
{
if (_parameterGroup.isValid())
_parameterGroup->Detach(this);
// Attach to the Parametergroup so we know when it changes
_parameterGroup = App::GetApplication().GetParameterGroupByPath(groupName.c_str());
if (_parameterGroup.isValid())
_parameterGroup->Attach(this);
}
void StatefulLabel::registerState(const QString& state, const QString& styleCSS,
const std::string& preferenceName)
{
_availableStates[state] = { styleCSS, preferenceName };
}
void StatefulLabel::registerState(const QString& state, const QColor& color,
const std::string& preferenceName)
{
QString css;
if (color.isValid())
css = QString::fromUtf8("Gui--StatefulLabel{ color : rgba(%1,%2,%3,%4) ;}").arg(color.red()).arg(color.green()).arg(color.blue()).arg(color.alpha());
_availableStates[state] = { css, preferenceName };
}
void StatefulLabel::registerState(const QString& state, const QColor& fg, const QColor& bg,
const std::string& preferenceName)
{
QString colorEntries;
if (fg.isValid())
colorEntries.append(QString::fromUtf8("color : rgba(%1,%2,%3,%4);").arg(fg.red()).arg(fg.green()).arg(fg.blue()).arg(fg.alpha()));
if (bg.isValid())
colorEntries.append(QString::fromUtf8("background-color : rgba(%1,%2,%3,%4);").arg(bg.red()).arg(bg.green()).arg(bg.blue()).arg(bg.alpha()));
QString css = QString::fromUtf8("Gui--StatefulLabel{ %1 }").arg(colorEntries);
_availableStates[state] = { css, preferenceName };
}
/** Observes the parameter group and clears the cache if it changes */
void StatefulLabel::OnChange(Base::Subject<const char*>& rCaller, const char* rcReason)
{
Q_UNUSED(rCaller);
auto changedItem = std::string(rcReason);
if (changedItem == "StyleSheet") {
_styleCache.clear();
}
else {
for (const auto& state : _availableStates) {
if (state.second.preferenceString == changedItem) {
_styleCache.erase(_styleCache.find(state.first));
}
}
}
}
void StatefulLabel::setOverridePreference(bool overridePreference)
{
_overridePreference = overridePreference;
}
void StatefulLabel::setState(QString state)
{
_state = state;
this->ensurePolished();
// If the stylesheet insists, ignore all other logic and let it do its thing. This
// property is *only* set by the stylesheet.
if (_overridePreference)
return;
// Check the cache first:
if (auto style = _styleCache.find(_state); style != _styleCache.end()) {
auto test = style->second.toStdString();
this->setStyleSheet(style->second);
return;
}
if (auto entry = _availableStates.find(state); entry != _availableStates.end()) {
// Order of precedence: first, check if the user has set this in their preferences:
if (!entry->second.preferenceString.empty()) {
// First, try to see if it's just stored a color (as an unsigned int):
auto availableColorPrefs = _parameterGroup->GetUnsignedMap();
std::string lookingForGroup = entry->second.preferenceString;
for (const auto &unsignedEntry : availableColorPrefs) {
std::string foundGroup = unsignedEntry.first;
if (unsignedEntry.first == entry->second.preferenceString) {
// Convert the stored Uint into usable color data:
unsigned int col = unsignedEntry.second;
QColor qcolor((col >> 24) & 0xff, (col >> 16) & 0xff, (col >> 8) & 0xff);
this->setStyleSheet(QString::fromUtf8("Gui--StatefulLabel{ color : rgba(%1,%2,%3,%4) ;}").arg(qcolor.red()).arg(qcolor.green()).arg(qcolor.blue()).arg(qcolor.alpha()));
_styleCache[state] = this->styleSheet();
return;
}
}
// If not, try to see if there's an entire style string set as ASCII:
auto availableStringPrefs = _parameterGroup->GetASCIIMap();
for (const auto& stringEntry : availableStringPrefs) {
if (stringEntry.first == entry->second.preferenceString) {
QString css = QString::fromUtf8("Gui--StatefulLabel{ %1 }").arg(QString::fromStdString(stringEntry.second));
this->setStyleSheet(css);
_styleCache[state] = this->styleSheet();
return;
}
}
}
// If there is no preferences entry for this label, allow the stylesheet to set it, and only set to the default
// formatting if there is no stylesheet entry
if (qApp->styleSheet().isEmpty()) {
this->setStyleSheet(entry->second.defaultCSS);
_styleCache[state] = this->styleSheet();
return;
}
// else the stylesheet sets our appearance: make sure it recalculates the appearance:
this->setStyleSheet(QString());
this->setStyle(qApp->style());
this->style()->unpolish(this);
this->style()->polish(this);
}
else {
if (styleSheet().isEmpty()) {
this->setStyleSheet(_defaultStyle);
_styleCache[state] = this->styleSheet();
}
}
}
// --------------------------------------------------------------------
/* TRANSLATOR Gui::LabelButton */
/**

View File

@@ -36,6 +36,7 @@
#include <QToolButton>
#include <QModelIndex>
#include "ExpressionBinding.h"
#include "Base/Parameter.h"
namespace Gui {
class PrefCheckBox;
@@ -258,21 +259,107 @@ class GuiExport UrlLabel : public QLabel
{
Q_OBJECT
Q_PROPERTY( QString url READ url WRITE setUrl)
Q_PROPERTY( bool launchExternal READ launchExternal WRITE setLaunchExternal)
public:
UrlLabel ( QWidget * parent = 0, Qt::WindowFlags f = Qt::WindowFlags() );
virtual ~UrlLabel();
QString url() const;
bool launchExternal() const;
Q_SIGNALS:
void linkClicked(QString url);
public Q_SLOTS:
void setUrl( const QString &u );
void setLaunchExternal(bool l);
protected:
void mouseReleaseEvent ( QMouseEvent * );
private:
QString _url;
bool _launchExternal;
};
/**
* A text label whose appearance can change based on a specified state.
*
* The state is an arbitrary string exposed as a Qt Property (and thus available for selection via
* a stylesheet). This is intended for things like messages to the user, where a message that is an
* "error" might be colored differently than one that is a "warning" or a "message".
*
* In order of style precedence for a given state: User preference > Stylesheet > Default
* unless the stylesheet sets the overridePreference, in which case the stylesheet will
* take precedence. If a stylesheet sets styles for this widgets states, it should also
* set the "handledByStyle" property to ensure the style values are used, rather than the
* defaults.
*
* For example, the .qss might contain:
* Gui--StatefulLabel {
* qproperty-overridePreference: true;
* }
* Gui--StatefulLabel[state="special_state"] {
* color: red;
* }
* In this case, StatefulLabels with state "special_state" will be colored red, regardless of any
* entry in preferences. Use the "overridePreference" stylesheet option with care!
*
* @author Chris Hennes
*/
class GuiExport StatefulLabel : public QLabel, public Base::Observer<const char*>
{
Q_OBJECT
Q_PROPERTY( bool overridePreference MEMBER _overridePreference WRITE setOverridePreference)
Q_PROPERTY( QString state MEMBER _state WRITE setState )
public:
StatefulLabel(QWidget* parent = nullptr);
virtual ~StatefulLabel();
/** If an unrecognized state is set, use this style */
void setDefaultStyle(const QString &defaultStyle);
/** If any of the states have user preferences associated with them, this sets the parameter
group that stores those preferences. All states must be in the same parameter group, but
the group does not have to have entries for all of them. */
void setParameterGroup(const std::string& groupName);
/** Register a state and its corresponding style (optionally attached to a user preference) */
void registerState(const QString &state, const QString &styleCSS,
const std::string& preferenceName = std::string());
/** For convenience, allow simple color-only states via QColor (optionally attached to a user preference) */
void registerState(const QString& state, const QColor& color,
const std::string& preferenceName = std::string());
/** For convenience, allow simple color-only states via QColor (optionally attached to a user preference) */
void registerState(const QString& state, const QColor& foregroundColor, const QColor& backgroundColor,
const std::string& preferenceName = std::string());
/** Observes the parameter group and clears the cache if it changes */
void OnChange(Base::Subject<const char *>& rCaller, const char* rcReason);
public Q_SLOTS:
void setState(QString state);
void setOverridePreference(bool overridePreference);
private:
QString _state;
bool _overridePreference;
ParameterGrp::handle _parameterGroup;
ParameterGrp::handle _stylesheetGroup;
struct StateData {
QString defaultCSS;
std::string preferenceString;
};
std::map<QString, StateData> _availableStates;
std::map<QString, QString> _styleCache;
QString _defaultStyle;
};
// ----------------------------------------------------------------------

View File

@@ -111,6 +111,7 @@ WidgetFactorySupplier::WidgetFactorySupplier()
new WidgetProducer<Gui::ActionSelector>;
new WidgetProducer<Gui::ColorButton>;
new WidgetProducer<Gui::UrlLabel>;
new WidgetProducer<Gui::StatefulLabel>;
new WidgetProducer<Gui::FileChooser>;
new WidgetProducer<Gui::UIntSpinBox>;
new WidgetProducer<Gui::IntSpinBox>;

View File

@@ -59,8 +59,7 @@ TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch *sketchView) :
this->groupLayout()->addWidget(proxy);
connectionSetUp = sketchView->signalSetUp.connect(boost::bind(&SketcherGui::TaskSketcherMessages::slotSetUp, this, bp::_1));
connectionSolved = sketchView->signalSolved.connect(boost::bind(&SketcherGui::TaskSketcherMessages::slotSolved, this, bp::_1));
connectionSetUp = sketchView->signalSetUp.connect(boost::bind(&SketcherGui::TaskSketcherMessages::slotSetUp, this, bp::_1, bp::_2, bp::_3, bp::_4));
ui->labelConstrainStatus->setOpenExternalLinks(false);
@@ -72,6 +71,23 @@ TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch *sketchView) :
else
sketchView->getSketchObject()->noRecomputes=true;
// Set up the possible state values for the status label
ui->labelConstrainStatus->setParameterGroup("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
ui->labelConstrainStatus->registerState(QString::fromUtf8("empty_sketch"), QColor("black"), std::string("EmptySketchMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("under_constrained"), QColor("black"), std::string("UnderconstrainedMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("malformed_constraints"), QColor("red"), std::string("MalformedConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("conflicting_constraints"), QColor("orangered"), std::string("ConflictingConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("redundant_constraints"), QColor("red"), std::string("RedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("partially_redundant_constraints"), QColor("royalblue"), std::string("PartiallyRedundantConstraintMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("solver_failed"), QColor("red"), std::string("SolverFailedMessageColor"));
ui->labelConstrainStatus->registerState(QString::fromUtf8("fully_constrained"), QColor("green"), std::string("FullyConstrainedMessageColor"));
ui->labelConstrainStatusLink->setLaunchExternal(false);
// Manually connect the link since it uses "clicked()", which labels don't have natively
connect(ui->labelConstrainStatusLink, &Gui::UrlLabel::linkClicked,
this, &TaskSketcherMessages::on_labelConstrainStatusLink_linkClicked);
/*QObject::connect(
ui->labelConstrainStatus, SIGNAL(linkActivated(const QString &)),
this , SLOT (on_labelConstrainStatus_linkActivated(const QString &))
@@ -89,20 +105,17 @@ TaskSketcherMessages::TaskSketcherMessages(ViewProviderSketch *sketchView) :
TaskSketcherMessages::~TaskSketcherMessages()
{
connectionSetUp.disconnect();
connectionSolved.disconnect();
}
void TaskSketcherMessages::slotSetUp(QString msg)
void TaskSketcherMessages::slotSetUp(const QString& state, const QString& msg, const QString& link, const QString& linkText)
{
ui->labelConstrainStatus->setState(state);
ui->labelConstrainStatus->setText(msg);
ui->labelConstrainStatusLink->setUrl(link);
ui->labelConstrainStatusLink->setText(linkText);
}
void TaskSketcherMessages::slotSolved(QString msg)
{
ui->labelSolverStatus->setText(msg);
}
void TaskSketcherMessages::on_labelConstrainStatus_linkActivated(const QString &str)
void TaskSketcherMessages::on_labelConstrainStatusLink_linkClicked(const QString &str)
{
if( str == QString::fromLatin1("#conflicting"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectConflictingConstraints");
@@ -115,7 +128,7 @@ void TaskSketcherMessages::on_labelConstrainStatus_linkActivated(const QString &
else
if( str == QString::fromLatin1("#malformed"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectMalformedConstraints");
else
else
if( str == QString::fromLatin1("#partiallyredundant"))
Gui::Application::Instance->commandManager().runCommandByName("Sketcher_SelectPartiallyRedundantConstraints");

View File

@@ -47,11 +47,10 @@ public:
TaskSketcherMessages(ViewProviderSketch *sketchView);
~TaskSketcherMessages();
void slotSetUp(QString msg);
void slotSolved(QString msg);
void slotSetUp(const QString &state, const QString &msg, const QString& link, const QString& linkText);
private Q_SLOTS:
void on_labelConstrainStatus_linkActivated(const QString &);
void on_labelConstrainStatusLink_linkClicked(const QString &);
void on_autoUpdate_stateChanged(int state);
void on_autoRemoveRedundants_stateChanged(int state);
void on_manualUpdate_clicked(bool checked);
@@ -59,7 +58,6 @@ private Q_SLOTS:
protected:
ViewProviderSketch *sketchView;
Connection connectionSetUp;
Connection connectionSolved;
private:
QWidget* proxy;

View File

@@ -15,24 +15,35 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="labelConstrainStatus">
<property name="text">
<string>Undefined degrees of freedom</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelSolverStatus">
<property name="text">
<string>Not solved yet</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="Gui::StatefulLabel" name="labelConstrainStatus">
<property name="text">
<string>DOF</string>
</property>
</widget>
</item>
<item>
<widget class="Gui::UrlLabel" name="labelConstrainStatusLink">
<property name="text">
<string>Link</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="Gui::PrefCheckBox" name="autoRemoveRedundants">
@@ -94,6 +105,16 @@
<extends>QCheckBox</extends>
<header>Gui/PrefWidgets.h</header>
</customwidget>
<customwidget>
<class>Gui::StatefulLabel</class>
<extends>QLabel</extends>
<header>Gui/Widgets.h</header>
</customwidget>
<customwidget>
<class>Gui::UrlLabel</class>
<extends>QLabel</extends>
<header>Gui/Widgets.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>

View File

@@ -402,6 +402,9 @@ ViewProviderSketch::ViewProviderSketch()
//rubberband selection
rubberband = new Gui::Rubberband();
// Status message states:
subscribeToParameters();
}
@@ -1309,10 +1312,6 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
if (getSketchObject()->moveTemporaryPoint(GeoId, PosId, vec, false) == 0) {
setPositionText(Base::Vector2d(x,y));
draw(true,false);
signalSolved(QString::fromLatin1("Solved in %1 sec").arg(getSolvedSketch().getSolveTime()));
} else {
signalSolved(QString::fromLatin1("Unsolved (%1 sec)").arg(getSolvedSketch().getSolveTime()));
//Base::Console().Log("Error solving:%d\n",ret);
}
}
}
@@ -1350,9 +1349,6 @@ bool ViewProviderSketch::mouseMove(const SbVec2s &cursorPos, Gui::View3DInventor
if (getSketchObject()->moveTemporaryPoint(edit->DragCurve, Sketcher::none, vec, relative) == 0) {
setPositionText(Base::Vector2d(x,y));
draw(true,false);
signalSolved(QString::fromLatin1("Solved in %1 sec").arg(getSolvedSketch().getSolveTime()));
} else {
signalSolved(QString::fromLatin1("Unsolved (%1 sec)").arg(getSolvedSketch().getSolveTime()));
}
}
return true;
@@ -6581,6 +6577,29 @@ QString ViewProviderSketch::appendConstraintMsg(const QString & singularmsg,
return msg;
}
inline QString intListHelper(const std::vector<int> &ints)
{
QString results;
if (ints.size() < 8) { // The 8 is a bit heuristic... more than that and we shift formats
for (const auto i : ints) {
if (results.isEmpty())
results.append(QString::fromUtf8("%1").arg(i));
else
results.append(QString::fromUtf8(", %1").arg(i));
}
}
else {
const int numToShow = 3;
int more = ints.size() - numToShow;
for (int i = 0; i < numToShow; ++i) {
results.append(QString::fromUtf8("%1, ").arg(ints[i]));
}
results.append(QCoreApplication::translate("ViewProviderSketch","and %1 more").arg(more));
}
std::string testString = results.toStdString();
return results;
}
void ViewProviderSketch::UpdateSolverInformation()
{
// Updates Solver Information with the Last solver execution at SketchObject level
@@ -6591,76 +6610,48 @@ void ViewProviderSketch::UpdateSolverInformation()
bool hasMalformed = getSketchObject()->getLastHasMalformedConstraints();
if (getSketchObject()->Geometry.getSize() == 0) {
signalSetUp(tr("Empty sketch"));
signalSolved(QString());
signalSetUp(QString::fromUtf8("empty_sketch"), tr("Empty sketch"), QString(), QString());
}
else if (dofs < 0) { // over-constrained sketch
std::string msg;
SketchObject::appendConflictMsg(getSketchObject()->getLastConflicting(), msg);
signalSetUp(QString::fromLatin1("<font color='red'>%1 <a href=\"#conflicting\"><span style=\" text-decoration: underline; color:#0000ff; background-color: #F8F8FF;\">%2</span></a><br/>%3</font><br/>")
.arg(tr("Over-constrained sketch"))
.arg(tr("(click to select)"))
.arg(QString::fromStdString(msg)));
signalSolved(QString());
else if (dofs < 0 || hasConflicts) { // over-constrained sketch
signalSetUp(QString::fromUtf8("conflicting_constraints"),
tr("Over-constrained: "),
QString::fromUtf8("#conflicting"),
QString::fromUtf8("(%1)").arg(intListHelper(getSketchObject()->getLastConflicting())));
}
else if (hasMalformed) { // malformed constraints
signalSetUp(QString::fromLatin1("<font color='red'>%1 <a href=\"#malformed\"><span style=\" text-decoration: underline; color:#0000ff; background-color: #F8F8FF;\">%2</span></a><br/>%3</font><br/>")
.arg(tr("Sketch contains malformed constraints"))
.arg(tr("(click to select)"))
.arg(appendMalformedMsg(getSketchObject()->getLastMalformedConstraints())));
signalSolved(QString());
signalSetUp(QString::fromUtf8("malformed_constraints"),
tr("Malformed constraints: "),
QString::fromUtf8("#malformed"),
QString::fromUtf8("(%1)").arg(intListHelper(getSketchObject()->getLastMalformedConstraints())));
}
else if (hasConflicts) { // conflicting constraints
signalSetUp(QString::fromLatin1("<font color='red'>%1 <a href=\"#conflicting\"><span style=\" text-decoration: underline; color:#0000ff; background-color: #F8F8FF;\">%2</span></a><br/>%3</font><br/>")
.arg(tr("Sketch contains conflicting constraints"))
.arg(tr("(click to select)"))
.arg(appendConflictMsg(getSketchObject()->getLastConflicting())));
signalSolved(QString());
else if (hasRedundancies) {
signalSetUp(QString::fromUtf8("redundant_constraints"),
tr("Redundant constraints:"),
QString::fromUtf8("#redundant"),
QString::fromUtf8("(%1)").arg(intListHelper(getSketchObject()->getLastRedundant())));
}
else if (hasPartiallyRedundant) {
signalSetUp(QString::fromUtf8("partially_redundant_constraints"),
tr("Partially redundant:"),
QString::fromUtf8("#partiallyredundant"),
QString::fromUtf8("(%1)").arg(intListHelper(getSketchObject()->getLastPartiallyRedundant())));
}
else if (getSketchObject()->getLastSolverStatus() != 0) {
signalSetUp(QString::fromUtf8("solver_failed"),
tr("Solver failed to converge"),
QString::fromUtf8(""),
QString::fromUtf8(""));
} else if (dofs > 0) {
signalSetUp(QString::fromUtf8("under_constrained"),
tr("Under constrained:"),
QString::fromUtf8("#dofs"),
QString::fromUtf8("%1 %2").arg(dofs).arg(tr("DoF")));
}
else {
if (hasRedundancies) { // redundant constraints
signalSetUp(QString::fromLatin1("<font color='orangered'>%1 <a href=\"#redundant\"><span style=\" text-decoration: underline; color:#0000ff; background-color: #F8F8FF;\">%2</span></a><br/>%3</font><br/>")
.arg(tr("Sketch contains redundant constraints"))
.arg(tr("(click to select)"))
.arg(appendRedundantMsg(getSketchObject()->getLastRedundant())));
}
QString partiallyRedundantString;
if(hasPartiallyRedundant) {
partiallyRedundantString = QString::fromLatin1("<br/><font color='royalblue'><span style=\"background-color: #ececec;\">%1 <a href=\"#partiallyredundant\"><span style=\" text-decoration: underline; color:#0000ff; background-color: #F8F8FF;\">%2</span></a><br/>%3</span></font><br/>")
.arg(tr("Sketch contains partially redundant constraints"))
.arg(tr("(click to select)"))
.arg(appendPartiallyRedundantMsg(getSketchObject()->getLastPartiallyRedundant()));
}
if (getSketchObject()->getLastSolverStatus() == 0) {
if (dofs == 0) {
// color the sketch as fully constrained if it has geometry (other than the axes)
if(getSolvedSketch().getGeometrySize()>2)
edit->FullyConstrained = true;
if (!hasRedundancies) {
signalSetUp(QString::fromLatin1("<font color='green'><span style=\"color:#008000; background-color: #ececec;\">%1</font></span> %2").arg(tr("Fully constrained sketch")).arg(partiallyRedundantString));
}
}
else if (!hasRedundancies) {
QString infoString;
if (dofs == 1)
signalSetUp(tr("Under-constrained sketch with <a href=\"#dofs\"><span style=\" text-decoration: underline; color:#0000ff; background-color: #F8F8FF;\">1 degree</span></a> of freedom. %1")
.arg(partiallyRedundantString));
else
signalSetUp(tr("Under-constrained sketch with <a href=\"#dofs\"><span style=\" text-decoration: underline; color:#0000ff; background-color: #F8F8FF;\">%1 degrees</span></a> of freedom. %2")
.arg(dofs)
.arg(partiallyRedundantString));
}
signalSolved(QString::fromLatin1("<font color='green'><span style=\"color:#008000; background-color: #ececec;\">%1</font></span>").arg(tr("Solved in %1 sec").arg(getSketchObject()->getLastSolveTime())));
}
else {
signalSolved(QString::fromLatin1("<font color='red'>%1</font>").arg(tr("Unsolved (%1 sec)").arg(getSketchObject()->getLastSolveTime())));
}
signalSetUp(QString::fromUtf8("fully_constrained"), tr("Fully constrained"), QString(), QString());
// color the sketch as fully constrained if it has geometry (other than the axes)
if(getSolvedSketch().getGeometrySize()>2)
edit->FullyConstrained = true;
}
}

View File

@@ -273,9 +273,7 @@ public:
/// signals if the constraints list has changed
boost::signals2::signal<void ()> signalConstraintsChanged;
/// signals if the sketch has been set up
boost::signals2::signal<void (QString msg)> signalSetUp;
/// signals if the sketch has been solved
boost::signals2::signal<void (QString msg)> signalSolved;
boost::signals2::signal<void (const QString &state, const QString &msg, const QString &url, const QString &linkText)> signalSetUp;
/// signals if the elements list has changed
boost::signals2::signal<void ()> signalElementsChanged;