forked from qt-creator/qt-creator
QtSupport: Improve QtVersionItem
- Make it self-contained with regards to the icon. - Make it consistent by also showing a corresponding tooltip whenever an error icon is displayed. - Remove unused member. Task-number: QTCREATORBUG-31574 Change-Id: I054f6f75bf8a0372d55df1edae0a4bd5723582d3 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
#include <QTextBrowser>
|
#include <QTextBrowser>
|
||||||
#include <QTreeView>
|
#include <QTreeView>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
@@ -55,6 +56,78 @@ const char kInstallSettingsKey[] = "Settings/InstallSettings";
|
|||||||
namespace QtSupport {
|
namespace QtSupport {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
static const QIcon &invalidVersionIcon()
|
||||||
|
{
|
||||||
|
static const QIcon theIcon(Utils::Icons::CRITICAL.icon());
|
||||||
|
return theIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QIcon &warningVersionIcon()
|
||||||
|
{
|
||||||
|
static const QIcon theIcon(Utils::Icons::WARNING.icon());
|
||||||
|
return theIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QIcon &validVersionIcon()
|
||||||
|
{
|
||||||
|
static const QIcon theIcon;
|
||||||
|
return theIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString nonUniqueDisplayNameWarning()
|
||||||
|
{
|
||||||
|
return Tr::tr("Display Name is not unique.");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UnsupportedAbisInfo
|
||||||
|
{
|
||||||
|
enum class Status { Ok, SomeMissing, AllMissing } status = Status::Ok;
|
||||||
|
QString message;
|
||||||
|
};
|
||||||
|
|
||||||
|
UnsupportedAbisInfo checkForUnsupportedAbis(const QtVersion *version)
|
||||||
|
{
|
||||||
|
Abis missingToolchains;
|
||||||
|
const Abis qtAbis = version->qtAbis();
|
||||||
|
|
||||||
|
for (const Abi &abi : qtAbis) {
|
||||||
|
const auto abiComparePred = [&abi] (const Toolchain *tc) {
|
||||||
|
return Utils::contains(tc->supportedAbis(),
|
||||||
|
[&abi](const Abi &sabi) { return sabi.isCompatibleWith(abi); });
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!ToolchainManager::toolchain(abiComparePred))
|
||||||
|
missingToolchains.append(abi);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnsupportedAbisInfo info;
|
||||||
|
if (!missingToolchains.isEmpty()) {
|
||||||
|
const auto formatAbiHtmlList = [](const Abis &abis) {
|
||||||
|
QString result = QStringLiteral("<ul><li>");
|
||||||
|
for (int i = 0, count = abis.size(); i < count; ++i) {
|
||||||
|
if (i)
|
||||||
|
result += QStringLiteral("</li><li>");
|
||||||
|
result += abis.at(i).toString();
|
||||||
|
}
|
||||||
|
result += QStringLiteral("</li></ul>");
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (missingToolchains.count() == qtAbis.size()) {
|
||||||
|
info.status = UnsupportedAbisInfo::Status::AllMissing;
|
||||||
|
info.message =
|
||||||
|
Tr::tr("No compiler can produce code for this Qt version."
|
||||||
|
" Please define one or more compilers for: %1").arg(formatAbiHtmlList(qtAbis));
|
||||||
|
} else {
|
||||||
|
info.status = UnsupportedAbisInfo::Status::SomeMissing;
|
||||||
|
info.message = Tr::tr("The following ABIs are currently not supported: %1")
|
||||||
|
.arg(formatAbiHtmlList(missingToolchains));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
class QtVersionItem : public TreeItem
|
class QtVersionItem : public TreeItem
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -101,39 +174,51 @@ public:
|
|||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == Qt::DecorationRole && column == 0)
|
if (role == Qt::DecorationRole && column == 0) {
|
||||||
return m_icon;
|
if (!m_version->isValid())
|
||||||
|
return invalidVersionIcon();
|
||||||
|
if (!m_version->warningReason().isEmpty() || hasNonUniqueDisplayName())
|
||||||
|
return warningVersionIcon();
|
||||||
|
const UnsupportedAbisInfo abisInfo = checkForUnsupportedAbis(m_version);
|
||||||
|
switch (abisInfo.status) {
|
||||||
|
case UnsupportedAbisInfo::Status::AllMissing:
|
||||||
|
return invalidVersionIcon();
|
||||||
|
case UnsupportedAbisInfo::Status::SomeMissing:
|
||||||
|
return warningVersionIcon();
|
||||||
|
case UnsupportedAbisInfo::Status::Ok:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return validVersionIcon();
|
||||||
|
}
|
||||||
|
|
||||||
if (role == Qt::ToolTipRole) {
|
if (role == Qt::ToolTipRole) {
|
||||||
const QString row = "<dt style=\"font-weight:bold\">%1:</dt>"
|
const QString row = "<dt style=\"font-weight:bold\">%1:</dt>"
|
||||||
"<dd>%2</dd>";
|
"<dd>%2</dd>";
|
||||||
return QString("<dl style=\"white-space:pre\">"
|
QString desc = "<dl style=\"white-space:pre\">";
|
||||||
+ row.arg(Tr::tr("Qt Version"), m_version->qtVersionString())
|
if (m_version->isValid())
|
||||||
+ row.arg(Tr::tr("Location of qmake"), m_version->qmakeFilePath().toUserOutput())
|
desc += row.arg(Tr::tr("Qt Version"), m_version->qtVersionString());
|
||||||
+ "</dl>");
|
desc += row.arg(Tr::tr("Location of qmake"), m_version->qmakeFilePath().toUserOutput());
|
||||||
|
if (m_version->isValid()) {
|
||||||
|
const UnsupportedAbisInfo abisInfo = checkForUnsupportedAbis(m_version);
|
||||||
|
if (abisInfo.status == UnsupportedAbisInfo::Status::AllMissing)
|
||||||
|
desc += row.arg(Tr::tr("Error"), abisInfo.message);
|
||||||
|
if (abisInfo.status == UnsupportedAbisInfo::Status::SomeMissing)
|
||||||
|
desc += row.arg(Tr::tr("Warning"), abisInfo.message);
|
||||||
|
const QStringList warnings = m_version->warningReason();
|
||||||
|
for (const QString &w : warnings)
|
||||||
|
desc += row.arg(Tr::tr("Warning"), w);
|
||||||
|
} else {
|
||||||
|
desc += row.arg(Tr::tr("Error"), m_version->invalidReason());
|
||||||
|
}
|
||||||
|
if (hasNonUniqueDisplayName())
|
||||||
|
desc += row.arg(Tr::tr("Warning"), nonUniqueDisplayNameWarning());
|
||||||
|
desc += "</dl>";
|
||||||
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setIcon(const QIcon &icon)
|
|
||||||
{
|
|
||||||
if (m_icon.cacheKey() == icon.cacheKey())
|
|
||||||
return;
|
|
||||||
m_icon = icon;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString buildLog() const
|
|
||||||
{
|
|
||||||
return m_buildLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setBuildLog(const QString &buildLog)
|
|
||||||
{
|
|
||||||
m_buildLog = buildLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setChanged(bool changed)
|
void setChanged(bool changed)
|
||||||
{
|
{
|
||||||
if (changed == m_changed)
|
if (changed == m_changed)
|
||||||
@@ -142,10 +227,16 @@ public:
|
|||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setIsNameUnique(const std::function<bool(QtVersion *)> &isNameUnique)
|
||||||
|
{
|
||||||
|
m_isNameUnique = isNameUnique;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool hasNonUniqueDisplayName() const { return m_isNameUnique && !m_isNameUnique(m_version); }
|
||||||
|
|
||||||
QtVersion *m_version = nullptr;
|
QtVersion *m_version = nullptr;
|
||||||
QIcon m_icon;
|
std::function<bool(QtVersion *)> m_isNameUnique;
|
||||||
QString m_buildLog;
|
|
||||||
bool m_changed = false;
|
bool m_changed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -187,7 +278,6 @@ private:
|
|||||||
QString description;
|
QString description;
|
||||||
QString message;
|
QString message;
|
||||||
QString toolTip;
|
QString toolTip;
|
||||||
QIcon icon;
|
|
||||||
};
|
};
|
||||||
ValidityInfo validInformation(const QtVersion *version);
|
ValidityInfo validInformation(const QtVersion *version);
|
||||||
QList<ProjectExplorer::Toolchain*> toolChains(const QtVersion *version);
|
QList<ProjectExplorer::Toolchain*> toolChains(const QtVersion *version);
|
||||||
@@ -212,9 +302,6 @@ private:
|
|||||||
QPushButton *m_cleanUpButton;
|
QPushButton *m_cleanUpButton;
|
||||||
|
|
||||||
QTextBrowser *m_infoBrowser;
|
QTextBrowser *m_infoBrowser;
|
||||||
QIcon m_invalidVersionIcon;
|
|
||||||
QIcon m_warningVersionIcon;
|
|
||||||
QIcon m_validVersionIcon;
|
|
||||||
QtConfigWidget *m_configurationWidget;
|
QtConfigWidget *m_configurationWidget;
|
||||||
|
|
||||||
QLineEdit *m_nameEdit;
|
QLineEdit *m_nameEdit;
|
||||||
@@ -227,8 +314,6 @@ private:
|
|||||||
QtSettingsPageWidget::QtSettingsPageWidget()
|
QtSettingsPageWidget::QtSettingsPageWidget()
|
||||||
: m_specifyNameString(Tr::tr("<specify a name>"))
|
: m_specifyNameString(Tr::tr("<specify a name>"))
|
||||||
, m_infoBrowser(new QTextBrowser)
|
, m_infoBrowser(new QTextBrowser)
|
||||||
, m_invalidVersionIcon(Utils::Icons::CRITICAL.icon())
|
|
||||||
, m_warningVersionIcon(Utils::Icons::WARNING.icon())
|
|
||||||
, m_configurationWidget(nullptr)
|
, m_configurationWidget(nullptr)
|
||||||
{
|
{
|
||||||
m_qtdirList = new QTreeView(this);
|
m_qtdirList = new QTreeView(this);
|
||||||
@@ -455,76 +540,38 @@ void QtSettingsPageWidget::infoAnchorClicked(const QUrl &url)
|
|||||||
QDesktopServices::openUrl(url);
|
QDesktopServices::openUrl(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString formatAbiHtmlList(const Abis &abis)
|
|
||||||
{
|
|
||||||
QString result = QStringLiteral("<ul><li>");
|
|
||||||
for (int i = 0, count = abis.size(); i < count; ++i) {
|
|
||||||
if (i)
|
|
||||||
result += QStringLiteral("</li><li>");
|
|
||||||
result += abis.at(i).toString();
|
|
||||||
}
|
|
||||||
result += QStringLiteral("</li></ul>");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
QtSettingsPageWidget::ValidityInfo QtSettingsPageWidget::validInformation(const QtVersion *version)
|
QtSettingsPageWidget::ValidityInfo QtSettingsPageWidget::validInformation(const QtVersion *version)
|
||||||
{
|
{
|
||||||
ValidityInfo info;
|
ValidityInfo info;
|
||||||
info.icon = m_validVersionIcon;
|
|
||||||
|
|
||||||
if (!version)
|
if (!version)
|
||||||
return info;
|
return info;
|
||||||
|
|
||||||
info.description = Tr::tr("Qt version %1 for %2").arg(version->qtVersionString(), version->description());
|
info.description = Tr::tr("Qt version %1 for %2").arg(version->qtVersionString(), version->description());
|
||||||
if (!version->isValid()) {
|
if (!version->isValid()) {
|
||||||
info.icon = m_invalidVersionIcon;
|
|
||||||
info.message = version->invalidReason();
|
info.message = version->invalidReason();
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do we have tool chain issues?
|
|
||||||
Abis missingToolchains;
|
|
||||||
const Abis qtAbis = version->qtAbis();
|
|
||||||
|
|
||||||
for (const Abi &abi : qtAbis) {
|
|
||||||
const auto abiCompatePred = [&abi] (const Toolchain *tc)
|
|
||||||
{
|
|
||||||
return Utils::contains(tc->supportedAbis(),
|
|
||||||
[&abi](const Abi &sabi) { return sabi.isCompatibleWith(abi); });
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!ToolchainManager::toolchain(abiCompatePred))
|
|
||||||
missingToolchains.append(abi);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool useable = true;
|
bool useable = true;
|
||||||
QStringList warnings;
|
QStringList warnings;
|
||||||
if (!isNameUnique(version))
|
if (!isNameUnique(version))
|
||||||
warnings << Tr::tr("Display Name is not unique.");
|
warnings << nonUniqueDisplayNameWarning();
|
||||||
|
|
||||||
if (!missingToolchains.isEmpty()) {
|
const UnsupportedAbisInfo unsupportedAbisInfo = checkForUnsupportedAbis(version);
|
||||||
if (missingToolchains.count() == qtAbis.size()) {
|
if (unsupportedAbisInfo.status == UnsupportedAbisInfo::Status::AllMissing) {
|
||||||
// Yes, this Qt version can't be used at all!
|
info.message = unsupportedAbisInfo.message;
|
||||||
info.message =
|
useable = false;
|
||||||
Tr::tr("No compiler can produce code for this Qt version."
|
} else if (unsupportedAbisInfo.status == UnsupportedAbisInfo::Status::SomeMissing) {
|
||||||
" Please define one or more compilers for: %1").arg(formatAbiHtmlList(qtAbis));
|
warnings << Tr::tr(
|
||||||
info.icon = m_invalidVersionIcon;
|
"Not all possible target environments can be supported due to missing compilers.");
|
||||||
useable = false;
|
info.toolTip = unsupportedAbisInfo.message;
|
||||||
} else {
|
|
||||||
// Yes, some ABIs are unsupported
|
|
||||||
warnings << Tr::tr("Not all possible target environments can be supported due to missing compilers.");
|
|
||||||
info.toolTip = Tr::tr("The following ABIs are currently not supported: %1")
|
|
||||||
.arg(formatAbiHtmlList(missingToolchains));
|
|
||||||
info.icon = m_warningVersionIcon;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useable) {
|
if (useable) {
|
||||||
warnings += version->warningReason();
|
warnings += version->warningReason();
|
||||||
if (!warnings.isEmpty()) {
|
if (!warnings.isEmpty())
|
||||||
info.message = warnings.join(QLatin1Char('\n'));
|
info.message = warnings.join(QLatin1Char('\n'));
|
||||||
info.icon = m_warningVersionIcon;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
@@ -569,14 +616,8 @@ bool QtSettingsPageWidget::isNameUnique(const QtVersion *version)
|
|||||||
|
|
||||||
void QtSettingsPageWidget::updateVersionItem(QtVersionItem *item)
|
void QtSettingsPageWidget::updateVersionItem(QtVersionItem *item)
|
||||||
{
|
{
|
||||||
if (!item)
|
if (item)
|
||||||
return;
|
item->update();
|
||||||
if (!item->version())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const ValidityInfo info = validInformation(item->version());
|
|
||||||
item->update();
|
|
||||||
item->setIcon(info.icon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtSettingsPageWidget::updateQtVersions(const QList<int> &additions, const QList<int> &removals,
|
void QtSettingsPageWidget::updateQtVersions(const QList<int> &additions, const QList<int> &removals,
|
||||||
@@ -604,6 +645,7 @@ void QtSettingsPageWidget::updateQtVersions(const QList<int> &additions, const Q
|
|||||||
for (int a : std::as_const(toAdd)) {
|
for (int a : std::as_const(toAdd)) {
|
||||||
QtVersion *version = QtVersionManager::version(a)->clone();
|
QtVersion *version = QtVersionManager::version(a)->clone();
|
||||||
auto *item = new QtVersionItem(version);
|
auto *item = new QtVersionItem(version);
|
||||||
|
item->setIsNameUnique([this](QtVersion *v) { return isNameUnique(v); });
|
||||||
|
|
||||||
// Insert in the right place:
|
// Insert in the right place:
|
||||||
TreeItem *parent = version->isAutodetected()? m_autoItem : m_manualItem;
|
TreeItem *parent = version->isAutodetected()? m_autoItem : m_manualItem;
|
||||||
@@ -664,7 +706,7 @@ void QtSettingsPageWidget::addQtDir()
|
|||||||
QtVersion *version = QtVersionFactory::createQtVersionFromQMakePath(qtVersion, false, QString(), &error);
|
QtVersion *version = QtVersionFactory::createQtVersionFromQMakePath(qtVersion, false, QString(), &error);
|
||||||
if (version) {
|
if (version) {
|
||||||
auto item = new QtVersionItem(version);
|
auto item = new QtVersionItem(version);
|
||||||
item->setIcon(version->isValid()? m_validVersionIcon : m_invalidVersionIcon);
|
item->setIsNameUnique([this](QtVersion *v) { return isNameUnique(v); });
|
||||||
m_manualItem->appendChild(item);
|
m_manualItem->appendChild(item);
|
||||||
QModelIndex source = m_model->indexForItem(item);
|
QModelIndex source = m_model->indexForItem(item);
|
||||||
m_qtdirList->setCurrentIndex(m_filterModel->mapFromSource(source)); // should update the rest of the ui
|
m_qtdirList->setCurrentIndex(m_filterModel->mapFromSource(source)); // should update the rest of the ui
|
||||||
@@ -719,10 +761,9 @@ void QtSettingsPageWidget::editPath()
|
|||||||
version->setUnexpandedDisplayName(current->displayName());
|
version->setUnexpandedDisplayName(current->displayName());
|
||||||
|
|
||||||
// Update ui
|
// Update ui
|
||||||
if (QtVersionItem *item = currentItem()) {
|
if (QtVersionItem *item = currentItem())
|
||||||
item->setVersion(version);
|
item->setVersion(version);
|
||||||
item->setIcon(version->isValid()? m_validVersionIcon : m_invalidVersionIcon);
|
|
||||||
}
|
|
||||||
userChangedCurrentVersion();
|
userChangedCurrentVersion();
|
||||||
|
|
||||||
delete current;
|
delete current;
|
||||||
@@ -763,7 +804,7 @@ void QtSettingsPageWidget::updateDescriptionLabel()
|
|||||||
}
|
}
|
||||||
m_infoWidget->setSummaryText(info.description);
|
m_infoWidget->setSummaryText(info.description);
|
||||||
if (item)
|
if (item)
|
||||||
item->setIcon(info.icon);
|
item->update();
|
||||||
|
|
||||||
m_infoBrowser->clear();
|
m_infoBrowser->clear();
|
||||||
if (version) {
|
if (version) {
|
||||||
|
Reference in New Issue
Block a user