9#include <QtDesigner/abstractformeditor.h>
10#include <QtDesigner/abstractintegration.h>
11#include <QtDesigner/abstractwidgetdatabase.h>
13#include <QtUiPlugin/customwidget.h>
15#include <QtWidgets/qaction.h>
16#include <QtWidgets/qstyle.h>
17#include <QtWidgets/qheaderview.h>
18#include <QtWidgets/qmenu.h>
19#include <QtWidgets/qpushbutton.h>
21#if QT_CONFIG(clipboard)
22# include <QtGui/QClipboard>
25#include <QtCore/qdir.h>
26#include <QtCore/qfileinfo.h>
27#include <QtCore/qpluginloader.h>
31using namespace Qt::StringLiterals;
37PluginDialog::PluginDialog(QDesignerFormEditorInterface *core, QWidget *parent)
48 const QStringList headerLabels(tr(
"Components"));
50 ui.treeWidget->setAlternatingRowColors(
false);
51 ui.treeWidget->setSelectionMode(QAbstractItemView::NoSelection);
52 ui.treeWidget->setHeaderLabels(headerLabels);
53 ui.treeWidget->header()->hide();
54 ui.treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
55 connect(ui.treeWidget, &QWidget::customContextMenuRequested,
56 this, &PluginDialog::treeWidgetContextMenu);
58 interfaceIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirOpenIcon),
59 QIcon::Normal, QIcon::On);
60 interfaceIcon.addPixmap(style()->standardPixmap(QStyle::SP_DirClosedIcon),
61 QIcon::Normal, QIcon::Off);
62 featureIcon.addPixmap(style()->standardPixmap(QStyle::SP_FileIcon));
64 setWindowTitle(tr(
"Plugin Information"));
67 QPushButton *updateButton =
new QPushButton(tr(
"Refresh"));
68 const QString tooltip = tr(
"Scan for newly installed custom widget plugins.");
69 updateButton->setToolTip(tooltip);
70 updateButton->setWhatsThis(tooltip);
71 connect(updateButton, &QAbstractButton::clicked,
this, &PluginDialog::updateCustomWidgetPlugins);
72 ui.buttonBox->addButton(updateButton, QDialogButtonBox::ActionRole);
78 ui.treeWidget->clear();
79 QDesignerPluginManager *pluginManager = m_core->pluginManager();
80 const QStringList fileNames = pluginManager->registeredPlugins();
82 if (!fileNames.isEmpty()) {
83 QTreeWidgetItem *topLevelItem = setTopLevelItem(tr(
"Loaded Plugins"));
84 QFont boldFont = topLevelItem->font(0);
86 for (
const QString &fileName : fileNames) {
87 QPluginLoader loader(fileName);
88 const QFileInfo fileInfo(fileName);
90 QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, fileInfo, boldFont);
92 if (QObject *plugin = loader.instance()) {
93 if (
const QDesignerCustomWidgetCollectionInterface *c = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(plugin)) {
94 const auto &collCustomWidgets = c->customWidgets();
95 for (
const QDesignerCustomWidgetInterface *p : collCustomWidgets)
96 setItem(pluginItem, p->name(), p->toolTip(), p->whatsThis(), p->icon());
98 if (
const QDesignerCustomWidgetInterface *p = qobject_cast<QDesignerCustomWidgetInterface*>(plugin))
99 setItem(pluginItem, p->name(), p->toolTip(), p->whatsThis(), p->icon());
105 const QStringList notLoadedPlugins = pluginManager->failedPlugins();
106 if (!notLoadedPlugins.isEmpty()) {
107 QTreeWidgetItem *topLevelItem = setTopLevelItem(tr(
"Failed Plugins"));
108 const QFont boldFont = topLevelItem->font(0);
109 for (
const QString &plugin : notLoadedPlugins) {
110 const QString failureReason = pluginManager->failureReason(plugin);
111 const QString htmlFailureReason =
"<html><head/><body><p>"_L1
112 + failureReason.toHtmlEscaped()
113 +
"</p></body></html>"_L1;
114 QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, QFileInfo(plugin), boldFont);
115 auto errorItem = setItem(pluginItem, failureReason,
116 htmlFailureReason, QString(), QIcon());
117 errorItem->setData(0, ErrorItemRole, QVariant(
true));
121 if (ui.treeWidget->topLevelItemCount() == 0) {
122 ui.label->setText(tr(
"Qt Widgets Designer couldn't find any plugins"));
123 ui.treeWidget->hide();
125 ui.label->setText(tr(
"Qt Widgets Designer found the following plugins"));
129QTreeWidgetItem*
PluginDialog::setTopLevelItem(
const QString &itemName)
131 QTreeWidgetItem *topLevelItem =
new QTreeWidgetItem(ui.treeWidget);
132 topLevelItem->setText(0, itemName);
133 topLevelItem->setExpanded(
true);
134 topLevelItem->setIcon(0, style()->standardPixmap(QStyle::SP_DirOpenIcon));
136 QFont boldFont = topLevelItem->font(0);
137 boldFont.setBold(
true);
138 topLevelItem->setFont(0, boldFont);
143QTreeWidgetItem*
PluginDialog::setPluginItem(QTreeWidgetItem *topLevelItem,
144 const QFileInfo &file,
const QFont &font)
146 QTreeWidgetItem *pluginItem =
new QTreeWidgetItem(topLevelItem);
147 QString toolTip = QDir::toNativeSeparators(file.absoluteFilePath());
149 toolTip += u'\n' + file.lastModified().toString();
150 pluginItem->setFont(0, font);
151 pluginItem->setText(0, file.fileName());
152 pluginItem->setToolTip(0, toolTip);
153 pluginItem->setExpanded(
true);
154 pluginItem->setIcon(0, style()->standardPixmap(QStyle::SP_DirOpenIcon));
159QTreeWidgetItem *
PluginDialog::setItem(QTreeWidgetItem *pluginItem,
const QString &name,
160 const QString &toolTip,
const QString &whatsThis,
163 QTreeWidgetItem *item =
new QTreeWidgetItem(pluginItem);
164 item->setText(0, name);
165 item->setToolTip(0, toolTip);
166 item->setWhatsThis(0, whatsThis);
167 item->setIcon(0, icon.isNull() ? qtLogoIcon() : icon);
173 const int before = m_core->widgetDataBase()->count();
174 m_core->integration()->updateCustomWidgetPlugins();
175 const int after = m_core->widgetDataBase()->count();
176 if (after > before) {
177 ui.message->setText(tr(
"New custom widget plugins have been found."));
180 ui.message->setText(QString());
182 populateTreeWidget();
185void PluginDialog::treeWidgetContextMenu(
const QPoint &pos)
187#if QT_CONFIG(clipboard)
188 const QTreeWidgetItem *item = ui.treeWidget->itemAt(pos);
189 if (item ==
nullptr || !item->data(0, ErrorItemRole).toBool())
193 auto copyAction = menu.addAction(tr(
"Copy"));
194 auto chosenAction = menu.exec(ui.treeWidget->mapToGlobal(pos));
195 if (chosenAction ==
nullptr)
197 if (chosenAction == copyAction)
198 QGuiApplication::clipboard()->setText(item->text(0));
208#include "moc_plugindialog_p.cpp"
Combined button and popup list for selecting options.
Auxiliary methods to store/retrieve settings.