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