1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include "plugindialog_p.h"
31#include "pluginmanager_p.h"
32#include "iconloader_p.h"
33
34#include <QtDesigner/abstractformeditor.h>
35#include <QtDesigner/abstractintegration.h>
36#include <QtDesigner/abstractwidgetdatabase.h>
37
38#include <QtUiPlugin/customwidget.h>
39
40#include <QtWidgets/qstyle.h>
41#include <QtWidgets/qheaderview.h>
42#include <QtWidgets/qpushbutton.h>
43#include <QtCore/qfileinfo.h>
44#include <QtCore/qpluginloader.h>
45
46QT_BEGIN_NAMESPACE
47
48namespace qdesigner_internal {
49
50PluginDialog::PluginDialog(QDesignerFormEditorInterface *core, QWidget *parent)
51 : QDialog(parent
52#ifdef Q_OS_MACOS
53 , Qt::Tool
54#endif
55 ), m_core(core)
56{
57 ui.setupUi(this);
58
59 ui.message->hide();
60
61 const QStringList headerLabels(tr(s: "Components"));
62
63 ui.treeWidget->setAlternatingRowColors(false);
64 ui.treeWidget->setSelectionMode(QAbstractItemView::NoSelection);
65 ui.treeWidget->setHeaderLabels(headerLabels);
66 ui.treeWidget->header()->hide();
67
68 interfaceIcon.addPixmap(pixmap: style()->standardPixmap(standardPixmap: QStyle::SP_DirOpenIcon),
69 mode: QIcon::Normal, state: QIcon::On);
70 interfaceIcon.addPixmap(pixmap: style()->standardPixmap(standardPixmap: QStyle::SP_DirClosedIcon),
71 mode: QIcon::Normal, state: QIcon::Off);
72 featureIcon.addPixmap(pixmap: style()->standardPixmap(standardPixmap: QStyle::SP_FileIcon));
73
74 setWindowTitle(tr(s: "Plugin Information"));
75 populateTreeWidget();
76
77 QPushButton *updateButton = new QPushButton(tr(s: "Refresh"));
78 const QString tooltip = tr(s: "Scan for newly installed custom widget plugins.");
79 updateButton->setToolTip(tooltip);
80 updateButton->setWhatsThis(tooltip);
81 connect(sender: updateButton, signal: &QAbstractButton::clicked, receiver: this, slot: &PluginDialog::updateCustomWidgetPlugins);
82 ui.buttonBox->addButton(button: updateButton, role: QDialogButtonBox::ActionRole);
83
84}
85
86void PluginDialog::populateTreeWidget()
87{
88 ui.treeWidget->clear();
89 QDesignerPluginManager *pluginManager = m_core->pluginManager();
90 const QStringList fileNames = pluginManager->registeredPlugins();
91
92 if (!fileNames.isEmpty()) {
93 QTreeWidgetItem *topLevelItem = setTopLevelItem(tr(s: "Loaded Plugins"));
94 QFont boldFont = topLevelItem->font(column: 0);
95
96 for (const QString &fileName : fileNames) {
97 QPluginLoader loader(fileName);
98 const QFileInfo fileInfo(fileName);
99
100 QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, itemName: fileInfo.fileName(), font: boldFont);
101
102 if (QObject *plugin = loader.instance()) {
103 if (const QDesignerCustomWidgetCollectionInterface *c = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(object: plugin)) {
104 const auto &collCustomWidgets = c->customWidgets();
105 for (const QDesignerCustomWidgetInterface *p : collCustomWidgets)
106 setItem(pluginItem, name: p->name(), toolTip: p->toolTip(), whatsThis: p->whatsThis(), icon: p->icon());
107 } else {
108 if (const QDesignerCustomWidgetInterface *p = qobject_cast<QDesignerCustomWidgetInterface*>(object: plugin))
109 setItem(pluginItem, name: p->name(), toolTip: p->toolTip(), whatsThis: p->whatsThis(), icon: p->icon());
110 }
111 }
112 }
113 }
114
115 const QStringList notLoadedPlugins = pluginManager->failedPlugins();
116 if (!notLoadedPlugins.isEmpty()) {
117 QTreeWidgetItem *topLevelItem = setTopLevelItem(tr(s: "Failed Plugins"));
118 const QFont boldFont = topLevelItem->font(column: 0);
119 for (const QString &plugin : notLoadedPlugins) {
120 const QString failureReason = pluginManager->failureReason(pluginName: plugin);
121 QTreeWidgetItem *pluginItem = setPluginItem(topLevelItem, itemName: plugin, font: boldFont);
122 setItem(pluginItem, name: failureReason, toolTip: failureReason, whatsThis: QString(), icon: QIcon());
123 }
124 }
125
126 if (ui.treeWidget->topLevelItemCount() == 0) {
127 ui.label->setText(tr(s: "Qt Designer couldn't find any plugins"));
128 ui.treeWidget->hide();
129 } else {
130 ui.label->setText(tr(s: "Qt Designer found the following plugins"));
131 }
132}
133
134QTreeWidgetItem* PluginDialog::setTopLevelItem(const QString &itemName)
135{
136 QTreeWidgetItem *topLevelItem = new QTreeWidgetItem(ui.treeWidget);
137 topLevelItem->setText(column: 0, atext: itemName);
138 topLevelItem->setExpanded(true);
139 topLevelItem->setIcon(column: 0, aicon: style()->standardPixmap(standardPixmap: QStyle::SP_DirOpenIcon));
140
141 QFont boldFont = topLevelItem->font(column: 0);
142 boldFont.setBold(true);
143 topLevelItem->setFont(column: 0, afont: boldFont);
144
145 return topLevelItem;
146}
147
148QTreeWidgetItem* PluginDialog::setPluginItem(QTreeWidgetItem *topLevelItem,
149 const QString &itemName, const QFont &font)
150{
151 QTreeWidgetItem *pluginItem = new QTreeWidgetItem(topLevelItem);
152 pluginItem->setFont(column: 0, afont: font);
153 pluginItem->setText(column: 0, atext: itemName);
154 pluginItem->setExpanded(true);
155 pluginItem->setIcon(column: 0, aicon: style()->standardPixmap(standardPixmap: QStyle::SP_DirOpenIcon));
156
157 return pluginItem;
158}
159
160void PluginDialog::setItem(QTreeWidgetItem *pluginItem, const QString &name,
161 const QString &toolTip, const QString &whatsThis, const QIcon &icon)
162{
163 QTreeWidgetItem *item = new QTreeWidgetItem(pluginItem);
164 item->setText(column: 0, atext: name);
165 item->setToolTip(column: 0, atoolTip: toolTip);
166 item->setWhatsThis(column: 0, awhatsThis: whatsThis);
167 item->setIcon(column: 0, aicon: icon.isNull() ? qtLogoIcon() : icon);
168}
169
170void PluginDialog::updateCustomWidgetPlugins()
171{
172 const int before = m_core->widgetDataBase()->count();
173 m_core->integration()->updateCustomWidgetPlugins();
174 const int after = m_core->widgetDataBase()->count();
175 if (after > before) {
176 ui.message->setText(tr(s: "New custom widget plugins have been found."));
177 ui.message->show();
178 } else {
179 ui.message->setText(QString());
180 }
181 populateTreeWidget();
182}
183
184}
185
186QT_END_NAMESPACE
187

source code of qttools/src/designer/src/lib/shared/plugindialog.cpp