玉兔远程控制 0.1.0-bate6
载入中...
搜索中...
未找到
FrmManagePlugins.cpp
1#include <QLoggingCategory>
2#include <QVBoxLayout>
3#include <QHBoxLayout>
4#include <QHeaderView>
5#include <QPluginLoader>
6#include <QPushButton>
7#include <QFileDialog>
8#include "Plugin.h"
9#include "RabbitCommonDir.h"
10#include "FrmManagePlugins.h"
11#include "CheckBoxHeader.h"
12#include "ui_FrmManagePlugins.h"
13
14static Q_LOGGING_CATEGORY(log, "Manage")
15CFrmManagePlugins::CFrmManagePlugins(QWidget *parent) : CParameterUI(parent)
16 , m_pPara(nullptr)
17 , ui(new Ui::CFrmManagePluginsUI)
18 , m_pModelFilter(nullptr)
19{
20 ui->setupUi(this);
21 setWindowTitle(tr("Load Plugins"));
22
23 bool check = connect(ui->lvPluginsPath, SIGNAL(customContextMenuRequested(QPoint)),
24 this, SLOT(slotCustomContextPluginsPath(QPoint)));
25 Q_ASSERT(check);
26 m_pModelPluginPath = new QStandardItemModel(ui->lvPluginsPath);
27 ui->lvPluginsPath->setModel(m_pModelPluginPath);
28
29 ui->tvFilter->setSelectionMode(QAbstractItemView::SingleSelection);
30 ui->tvFilter->setSelectionBehavior(QAbstractItemView::SelectRows);
31 ui->tvFilter->setEditTriggers(QAbstractItemView::NoEditTriggers);
32
33 m_pModelFilter = new QStandardItemModel(ui->tvFilter);
34 ui->tvFilter->setModel(m_pModelFilter);
35 check = connect(m_pModelFilter, SIGNAL(itemChanged(QStandardItem*)),
36 this, SLOT(slotFilterItemChanged(QStandardItem*)));
37 Q_ASSERT(check);
38 SetFilterHeader();
39
40 /*必须在 setModel 后,才能应用
41 QHeaderView::Interactive :0 用户可设置,也可被程序设置成默认大小
42 QHeaderView::Fixed :2 用户不可更改列宽
43 QHeaderView::Stretch :1 根据空间,自动改变列宽,用户与程序不能改变列宽
44 QHeaderView::ResizeToContents:3 根据内容改变列宽,用户与程序不能改变列宽
45 */
46 /*
47 ui->tvFilter->horizontalHeader()->setSectionResizeMode(
48 QHeaderView::Interactive);//*/
49}
50
52{
53 m_pPara = qobject_cast<CParameterPlugin*>(pParameter);
54 bool checked = m_pPara->GetEnableSetPluginsPath();
55 ui->gbPluginsPath->setChecked(checked);
56 on_gbPluginsPath_clicked(checked);
57 ui->cbOnlyLoadInWhitelist->setChecked(m_pPara->GetOnlyLoadInWhitelist());
58 return 0;
59}
60
62{
63 QStringList lstPath;
64 m_pPara->SetEnableSetPluginsPath(ui->gbPluginsPath->isChecked());
65 for(int i = 0; i < m_pModelPluginPath->rowCount(); i++) {
66 lstPath << m_pModelPluginPath->item(i)->text();
67 }
68 m_pPara->SetPluginsPath(lstPath);
69 m_pPara->m_WhiteList.Clear();
70 m_pPara->m_BlackList.Clear();
71 for(int i = 0; i < m_pModelFilter->rowCount(); i++) {
72 QString szPath = m_pModelFilter->item(i, ColumnNo::File)->text();
73 if(szPath.isEmpty()) continue;
74 auto pWhitelist = m_pModelFilter->item(i, ColumnNo::Whitelist);
75 if(pWhitelist->checkState() == Qt::Checked)
76 m_pPara->m_WhiteList.AddKey(szPath);
77 auto pBlacklist = m_pModelFilter->item(i, ColumnNo::Blacklist);
78 if(pBlacklist->checkState() == Qt::Checked)
79 m_pPara->m_BlackList.AddKey(szPath);
80 }
81 m_pPara->SetOnlyLoadInWhitelist(ui->cbOnlyLoadInWhitelist->isChecked());
82 return 0;
83}
84
85int CFrmManagePlugins::AddPath(const QString &szPath)
86{
87 auto pFind = m_pModelPluginPath->findItems(szPath);
88 if(!pFind.isEmpty()) return 0;
89
90 auto pPath = new QStandardItem(szPath);
91 m_pModelPluginPath->appendRow(pPath);
92
93 QStringList filters;
94 if(filters.isEmpty())
95 {
96#if defined (Q_OS_WINDOWS) || defined(Q_OS_WIN)
97 filters << "*Plugin*.dll";
98#elif defined(Q_OS_MACOS) || defined(Q_OS_MAC)
99 filters << "*Plugin*.dylib";
100#else
101 filters << "*Plugin*.so";
102#endif
103 }
104 FindPlugins(szPath, filters);
105 slotFilterItemChanged(m_pModelFilter->item(0, ColumnNo::Whitelist));
106 slotFilterItemChanged(m_pModelFilter->item(0, ColumnNo::Blacklist));
107 return 0;
108}
109
110int CFrmManagePlugins::FindPlugins(QDir dir, QStringList filters, bool bAdd)
111{
112 QStringList files = dir.entryList(filters, QDir::Files | QDir::NoDotAndDotDot);
113
114 foreach (auto fileName, files) {
115 QString szPath = dir.absoluteFilePath(fileName);
116 if(!bAdd) {
117 RemoveItem(fileName);
118 continue;
119 }
120 auto pFind = m_pModelFilter->findItems(szPath, Qt::MatchExactly, ColumnNo::File);
121 if(!pFind.isEmpty()) continue;
122
123 QPluginLoader loader(szPath);
124 QObject *plugin = loader.instance();
125 if(plugin) {
126 CPlugin* p = qobject_cast<CPlugin*>(plugin);
127 if(p)
128 AddItem(p, fileName);
129 loader.unload();
130 }
131 }
132
133 foreach (auto d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
134 QDir pluginDir = dir;
135 if(pluginDir.cd(d))
136 FindPlugins(pluginDir, filters);
137 }
138
139 return 0;
140}
141
142int CFrmManagePlugins::AddItem(CPlugin* plugin, const QString& szPath)
143{
144 QList<QStandardItem*> lstItems;
145 auto pWhitelist = new QStandardItem();
146 pWhitelist->setCheckable(true);
147 if(m_pPara->m_WhiteList.contains(szPath))
148 pWhitelist->setCheckState(Qt::Checked);
149 lstItems << pWhitelist;
150 auto pBlacklist = new QStandardItem();
151 pBlacklist->setCheckable(true);
152 if(m_pPara->m_BlackList.contains(szPath))
153 pBlacklist->setCheckState(Qt::Checked);
154 lstItems << pBlacklist;
155 auto pName = new QStandardItem(plugin->Icon(), plugin->DisplayName());
156 lstItems << pName;
157 auto pType = new QStandardItem(plugin->TypeName(plugin->Type()));
158 lstItems << pType;
159 auto pPath = new QStandardItem(szPath);
160 lstItems << pPath;
161 m_pModelFilter->appendRow(lstItems);
162
163 //以下设置列宽函数必须要数据加载完成后使用,才能应用
164 ui->tvFilter->resizeColumnsToContents(); //设置所有列宽度自适应内容
165 return 0;
166}
167
168int CFrmManagePlugins::RemoveItem(const QString &szPath)
169{
170 auto pFind = m_pModelFilter->findItems(szPath, Qt::MatchExactly, ColumnNo::File);
171 if(pFind.isEmpty()) return 0;
172 foreach(auto item, pFind) {
173 m_pModelFilter->removeRow(item->index().row());
174 }
175 return 0;
176}
177
178void CFrmManagePlugins::on_pbAdd_clicked()
179{
180 QString szPath = QFileDialog::getExistingDirectory(
181 this, tr("Plugin path"),
182 RabbitCommon::CDir::Instance()->GetDirPlugins());
183 if(szPath.isEmpty()) return;
184 AddPath(szPath);
185}
186
187void CFrmManagePlugins::on_pbRemove_clicked()
188{
189 QModelIndex index = ui->lvPluginsPath->currentIndex();
190 if(!index.isValid())
191 return;
192
193 auto item = m_pModelPluginPath->item(index.row());
194 if(item) {
195 QString szPath = item->text();
196 if(!szPath.isEmpty()) {
197 QStringList filters;
198 if(filters.isEmpty())
199 {
200#if defined (Q_OS_WINDOWS) || defined(Q_OS_WIN)
201 filters << "*Plugin*.dll";
202#elif defined(Q_OS_MACOS) || defined(Q_OS_MAC)
203 filters << "*Plugin*.dylib";
204#else
205 filters << "*Plugin*.so";
206#endif
207 }
208 FindPlugins(szPath, filters, false);
209 }
210 }
211 m_pModelPluginPath->removeRow(index.row());
212 slotFilterItemChanged(m_pModelFilter->item(0, ColumnNo::Whitelist));
213 slotFilterItemChanged(m_pModelFilter->item(0, ColumnNo::Blacklist));
214}
215
216void CFrmManagePlugins::slotCustomContextPluginsPath(const QPoint &pos)
217{
218 QMenu m;
219 m.addAction(tr("Add"), this, SLOT(on_pbAdd_clicked()));
220 m.addAction(tr("Remove"), this, SLOT(on_pbRemove_clicked()));
221 m.exec(this->mapToGlobal(pos));
222}
223
224void CFrmManagePlugins::on_gbPluginsPath_clicked(bool checked)
225{
226 m_pModelPluginPath->clear();
227 m_pModelFilter->clear();
228 SetFilterHeader();
229
230 QStringList lstPaths;
231 if(checked)
232 lstPaths = m_pPara->GetPluginsPath();
233 else
234 lstPaths << RabbitCommon::CDir::Instance()->GetDirPlugins();
235 foreach(auto szPath, lstPaths) {
236 AddPath(szPath);
237 }
238}
239
240int CFrmManagePlugins::SetFilterHeader()
241{
242 if(!m_pModelFilter) return -1;
243 auto pWhitelist = new QStandardItem(tr("Whitelist"));
244 pWhitelist->setToolTip(pWhitelist->text());
245 pWhitelist->setCheckable(true);
246 m_pModelFilter->setHorizontalHeaderItem(ColumnNo::Whitelist, pWhitelist);
247 auto pBlacklist = new QStandardItem(tr("Blacklist"));
248 pBlacklist->setToolTip(pBlacklist->text());
249 pBlacklist->setCheckable(true);
250 m_pModelFilter->setHorizontalHeaderItem(ColumnNo::Blacklist, pBlacklist);
251 m_pModelFilter->setHorizontalHeaderItem(ColumnNo::Name, new QStandardItem(tr("Name")));
252 m_pModelFilter->setHorizontalHeaderItem(ColumnNo::Type, new QStandardItem(tr("Type")));
253 m_pModelFilter->setHorizontalHeaderItem(ColumnNo::File, new QStandardItem(tr("File")));
254
255 if(qobject_cast<CCheckBoxHeader*>(ui->tvFilter->horizontalHeader()))
256 return 0;
257
258 auto pHeader = new CCheckBoxHeader(Qt::Horizontal, ui->tvFilter);
259 if(pHeader) {
260 ui->tvFilter->setHorizontalHeader(pHeader);
261 bool check = false;
262 check = connect(pHeader, &CCheckBoxHeader::sigCheckStateChanged,
263 this, [this](int index, Qt::CheckState state) {
264 qDebug(log) << "CCheckBoxHeader::sigCheckStateChanged";
265 for(int row = 0; row < m_pModelFilter->rowCount(); row++) {
266 auto item = m_pModelFilter->item(row, index);
267 switch(state)
268 {
269 case Qt::PartiallyChecked: {
270 QString szPath = m_pModelFilter->item(row, ColumnNo::File)->text();
271 if(ColumnNo::Whitelist == index) {
272 if(m_pPara->m_WhiteList.contains(szPath))
273 item->setCheckState(Qt::Checked);
274 else
275 item->setCheckState(Qt::Unchecked);
276 }
277 if(ColumnNo::Blacklist == index) {
278 if(m_pPara->m_BlackList.contains(szPath))
279 item->setCheckState(Qt::Checked);
280 else
281 item->setCheckState(Qt::Unchecked);
282 }
283 break;
284 }
285 default:
286 item->setCheckState(state);
287 break;
288 }
289 }
290 });
291 Q_ASSERT(check);
292 }
293
294 return 0;
295}
296
297void CFrmManagePlugins::slotFilterItemChanged(QStandardItem *item)
298{
299 qDebug(log) << Q_FUNC_INFO;
300 if(!m_pModelFilter) return;
301 if(!item) return;
302 if(!item->isCheckable()) return;
303 for(int i = 0; i < m_pModelFilter->rowCount(); i++) {
304 if(i == item->row()) continue;
305 auto state = m_pModelFilter->item(i, item->column())->checkState();
306 if(state != item->checkState()) {
307 m_pModelFilter->horizontalHeaderItem(item->column())->setCheckState(Qt::PartiallyChecked);
308 return;
309 }
310 }
311 m_pModelFilter->horizontalHeaderItem(item->column())->setCheckState(item->checkState());
312}
包含复选框的表头
virtual int SetParameter(CParameter *pParameter) override
[override functions]
virtual int Accept() override
接受参数
参数界面接口
Definition ParameterUI.h:15
参数接口
Definition Parameter.h:209
插件接口
Definition Plugin.h:15
virtual const QString DisplayName() const
在界面上显示的名称
Definition Plugin.cpp:76