pluginDialog.cpp 10.3 KB
Newer Older
Pierre Kraemer's avatar
Pierre Kraemer committed
1
#include "pluginDialog.h"
2

3
//#include <libxml2/libxml/tree.h>
4
#include <QFile>
5
6
#include <QFileInfo>
#include <QDir>
7
#include <QFileDialog>
8
9
10
#include <QDomDocument>
#include <QDomElement>
#include <QDomNode>
11
12
#include <QDomText>
#include <QMessageBox>
Pierre Kraemer's avatar
Pierre Kraemer committed
13
//#include <QRegExp>
14
//#include <QTextBrowser>
15

Pierre Kraemer's avatar
Pierre Kraemer committed
16
#include "system.h"
17
#include "window.h"
18
#include "plugin.h"
19

20
21
PluginDialog::PluginDialog(Window* window) :
	m_window(window),
22
23
24
25
26
27
28
29
30
	init(true)
{
	this->setupUi(this);

	treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
	treeWidget->setSelectionMode(QAbstractItemView::SingleSelection);

	connect(addButton, SIGNAL(pressed()), this, SLOT(cb_addPlugins()));
	connect(removeButton, SIGNAL(pressed()), this, SLOT(cb_removePlugins()));
Pierre Kraemer's avatar
Pierre Kraemer committed
31
32
33
	connect(directoryButton, SIGNAL(pressed()), this, SLOT(cb_addPluginsDirectory()));

	connect(treeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(cb_togglePlugin(QTreeWidgetItem *, int)));
Pierre Kraemer's avatar
Pierre Kraemer committed
34
//	connect(treeWidget, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(customContextMenu(const QPoint &)));
35

Pierre Kraemer's avatar
Pierre Kraemer committed
36
//	connect(this, SIGNAL(accepted()), this, SLOT(cb_acceptDialog()));
37

Pierre Kraemer's avatar
Pierre Kraemer committed
38
//	restoreState();
39
40
41
42
43
44
45
46
47
48

	if (System::Error::code != System::Error::SUCCESS)
		System::Error::showError(this);

	init = false;
}

PluginDialog::~PluginDialog()
{}

Pierre Kraemer's avatar
Pierre Kraemer committed
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
//bool PluginDialog::restoreState()
//{
//	QFile xmlFile(System::app_path.toStdString().c_str() + QString("/state_save.xml"));
//
//	if (!xmlFile.exists())
//	{
//		System::Error::code = System::Error::NO_PLUGIN_PATH_FILE;
//		return false;
//	}
//
//	if (!xmlFile.open(QIODevice::ReadOnly))
//	{
//		System::Error::code = System::Error::ERROR_OPEN_PLUGIN_FILE;
//		return false;
//	}
//
//	QDomDocument doc;
//
//	if (!doc.setContent(&xmlFile))
//	{
//		System::Error::code = System::Error::BAD_PLUGIN_PATH_FILE;
//		xmlFile.close();
//		return false;
//	}
//
//	xmlFile.close();
//
//	QDomElement root = doc.documentElement();
//	QDomElement plugins_node = root.firstChildElement("PLUGINS");
//
//	const PluginHash& activePlugins = m_window->getPluginsHash();
//
//	if (!plugins_node.isNull())
//	{
//		QDomElement plugins_subNode = plugins_node.firstChildElement();
//
//		while (!plugins_subNode.isNull())
//		{
//			if (plugins_subNode.tagName() == "DIR")
//			{
//				QString pluginDirPath = plugins_subNode.attribute("path", "./plugins");
//				QFileInfo fi(pluginDirPath);
//
//				if (fi.exists() && fi.isDir())
//				{
//					QDir pluginDir(pluginDirPath);
//
//					QTreeWidgetItem *dirItem = new QTreeWidgetItem(treeWidget, DIR);
//					dirItem->setText(1, pluginDir.path());
//
//					QStringList filters, dirFiles;
//					filters << "lib*.so";
//					filters << "lib*.dylib";
//
//					dirFiles = pluginDir.entryList(filters, QDir::Files);
//					foreach(QString fileName, dirFiles)
//					{
//						QFileInfo pfi(fileName);
//						QString pluginName = pfi.baseName().remove(0, 3);
//
//						QTreeWidgetItem *item = new QTreeWidgetItem(dirItem, FILE_DIR);
//						item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
//
//						if (activePlugins.contains(pluginName))
//							item->setCheckState(0, Qt::Checked);
//						else
//							item->setCheckState(0, Qt::Unchecked);
//
//						item->setText(1, pluginDir.absoluteFilePath(fileName));
//					}
//				}
//			}
//			else if (plugins_subNode.tagName() == "FILE")
//			{
//				QString pluginPath = plugins_subNode.attribute("path");
//
//				if (!pluginPath.isEmpty())
//				{
//					QFileInfo fi(pluginPath);
//
//					if (fi.exists() && pluginPath.left(3) == "lib" && (fi.suffix() == "so" || fi.suffix() == "dylib"))
//					{
//						QString pluginName = fi.baseName().remove(0, 3);
//						QTreeWidgetItem *item =  new QTreeWidgetItem(treeWidget, FILE);
//						item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
//
//						if (activePlugins.contains(pluginName))
//							item->setCheckState(0, Qt::Checked);
//						else
//							item->setCheckState(0, Qt::Unchecked);
//
//						item->setText(1, pluginPath);
//					}
//				}
//			}
//
//			plugins_subNode = plugins_subNode.nextSiblingElement();
//		}
//	}
//
//	return true;
//}
151
152
153
154

void PluginDialog::cb_addPlugins()
{
	init = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
155

156
157
	QStringList files = QFileDialog::getOpenFileNames(
		this,
Pierre Kraemer's avatar
Pierre Kraemer committed
158
		"Select one or more plugins",
159
		System::app_path + QString("/../Plugins/"),
160
161
162
163
164
		"Plugins (lib*.so lib*.dylib)"
	);

	if (!files.empty())
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
165
		foreach(QString pluginPath, files)
166
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
167
168
169
170
			QFileInfo pfi(pluginPath);
			QString pluginName = pfi.baseName().remove(0, 3);
			PluginInfo pinfo(pluginPath, pluginName);

171
172
173
			QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget, FILE);
			item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
			item->setCheckState(0, Qt::Unchecked);
Pierre Kraemer's avatar
Pierre Kraemer committed
174
175
176
			item->setText(1, pluginName);

			m_listedPlugins[item] = pinfo;
177
178
179
180
181
182
183
184
185
		}
	}

	if (System::Error::code != System::Error::SUCCESS)
		System::Error::showError(this);

	init = false;
}

Pierre Kraemer's avatar
Pierre Kraemer committed
186
void PluginDialog::cb_addPluginsDirectory()
187
188
{
	init = true;
Pierre Kraemer's avatar
Pierre Kraemer committed
189

190
191
	QString dir = QFileDialog::getExistingDirectory(
		this,
Pierre Kraemer's avatar
Pierre Kraemer committed
192
		tr("Select a directory"),
193
		System::app_path + QString("/../Plugins/"),
194
195
196
197
		QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
	);

	if (!dir.isEmpty())
Pierre Kraemer's avatar
Pierre Kraemer committed
198
199
200
201
202
203
204
205
206
	{
		QDir directory(dir);

		if (!directory.exists())
			System::Error::code = System::Error::BAD_PLUGIN_PATH_IN_FILE_f(directory.absolutePath());

		QTreeWidgetItem *dirItem = new QTreeWidgetItem(treeWidget, DIR);
		dirItem->setText(1, directory.path());

Pierre Kraemer's avatar
Pierre Kraemer committed
207
		QStringList filters;
Pierre Kraemer's avatar
Pierre Kraemer committed
208
209
210
		filters << "lib*.so";
		filters << "lib*.dylib";

Pierre Kraemer's avatar
Pierre Kraemer committed
211
		QStringList dirFiles;
Pierre Kraemer's avatar
Pierre Kraemer committed
212
213
		dirFiles = directory.entryList(filters, QDir::Files);

214
215
		const PluginHash& activePlugins = m_window->getPluginsHash();

Pierre Kraemer's avatar
Pierre Kraemer committed
216
		foreach(QString pluginPath, dirFiles)
Pierre Kraemer's avatar
Pierre Kraemer committed
217
		{
Pierre Kraemer's avatar
Pierre Kraemer committed
218
			QFileInfo pfi(pluginPath);
Pierre Kraemer's avatar
Pierre Kraemer committed
219
			QString pluginName = pfi.baseName().remove(0, 3);
Pierre Kraemer's avatar
Pierre Kraemer committed
220
			PluginInfo pinfo(directory.absoluteFilePath(pluginPath), pluginName);
Pierre Kraemer's avatar
Pierre Kraemer committed
221
222
223
224

			QTreeWidgetItem *item = new QTreeWidgetItem(dirItem, FILE_DIR);
			item->setFlags(item->flags() | Qt::ItemIsUserCheckable);

225
			if (activePlugins.contains(pluginName))
Pierre Kraemer's avatar
Pierre Kraemer committed
226
227
228
229
				item->setCheckState(0, Qt::Checked);
			else
				item->setCheckState(0, Qt::Unchecked);

Pierre Kraemer's avatar
Pierre Kraemer committed
230
231
232
			item->setText(1, pluginName);

			m_listedPlugins[item] = pinfo;
Pierre Kraemer's avatar
Pierre Kraemer committed
233
234
235
236
237
		}

		if (dirFiles.isEmpty())
			System::Error::code = System::Error::NO_PLUGIN_IN_DIR_f(directory.absolutePath());
	}
238
239
240
241
242
243
244
245
246

	if (System::Error::code != System::Error::SUCCESS)
		System::Error::showError(this);

	init = false;
}

void PluginDialog::cb_removePlugins()
{
Pierre Kraemer's avatar
Pierre Kraemer committed
247
	QList<QTreeWidgetItem*> itemList = treeWidget->selectedItems();
248
249
250

	if (!itemList.isEmpty())
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
251
		foreach(QTreeWidgetItem* item, itemList)
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
		{
			if (item->type() == FILE)
			{
				if (item->checkState(0) == Qt::Checked)
				{
					QMessageBox msgBox;
					msgBox.setText("Le plugin\n"
					               "\t" + item->text(1) +
					               " doit être désactivé avant de pouvoir être\n"
					               "supprimé.");
					msgBox.exec();
				}
				else
				{
					item = treeWidget->takeTopLevelItem(treeWidget->indexOfTopLevelItem(item));
					delete item;
Pierre Kraemer's avatar
Pierre Kraemer committed
268
269

					m_listedPlugins.remove(item);
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
				}
			}
			else if (item->type() == FILE_DIR)
			{
				QMessageBox msgBox;
				msgBox.setText("Le plugin\n"
				               "\t" + item->text(1) +
				               " fait partit d'un paquet/directory.\n"
				               "Il ne peut être supprimé séparément.");
				msgBox.exec();
			}
			else if (item->type() == DIR)
			{
				bool isAnyPluginActive = false;
				QTreeWidgetItem *fileItem;

				for (int i = 0; (i < item->childCount() && !isAnyPluginActive); ++i)
				{
					fileItem = item->child(i);
					if (fileItem->checkState(0) == Qt::Checked)
						isAnyPluginActive = true;
				}

				if (isAnyPluginActive)
				{
					QMessageBox msgBox;
					msgBox.setText("Un ou plusieurs plugins du dossier sont actifs\n"
					               "Veuillez désactiver tous les plugins du paquet avant de supprimer celui-ci.");
					msgBox.exec();
				}
				else
				{
Pierre Kraemer's avatar
Pierre Kraemer committed
302
303
304
305
306
307
					for (int i = 0; i < item->childCount(); ++i)
					{
						fileItem = item->child(i);
						m_listedPlugins.remove(fileItem);
					}

308
309
310
311
312
313
314
315
316
317
318
					item = treeWidget->takeTopLevelItem(treeWidget->indexOfTopLevelItem(item));
					delete item;
				}
			}
		}
	}

	if (System::Error::code != System::Error::SUCCESS)
		System::Error::showError(this);
}

Pierre Kraemer's avatar
Pierre Kraemer committed
319
void PluginDialog::cb_togglePlugin(QTreeWidgetItem *item, int column)
320
321
322
{
	if (!init && column == 0)
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
323
		PluginInfo pinfo = m_listedPlugins[item];
324

Pierre Kraemer's avatar
Pierre Kraemer committed
325
326
		QString pluginPath = pinfo.pluginPath;
		QString pluginName = pinfo.pluginName;
327

328
329
		if (item->checkState(0) == Qt::Checked)
		{
330
			const PluginHash& activePlugins = m_window->getPluginsHash();
331

332
			if (activePlugins.contains(pluginName))
333
334
335
			{
				System::Error::code = System::Error::PLUGIN_EXISTS_f(pluginName);
				System::Error::showError(this);
336
337
338
				init = true;
				item->setCheckState(0, Qt::Unchecked);
				init = false;
339
340
341
				return;
			}

Pierre Kraemer's avatar
Pierre Kraemer committed
342
			Plugin* p = m_window->loadPlugin(pluginPath);
343
344

			if (p == NULL)
345
			{
346
347
348
				init = true;
				item->setCheckState(0, Qt::Unchecked);
				init = false;
349
350
351
			}
		}
		else if (item->checkState(0) == Qt::Unchecked)
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
		{
			Plugin* p = m_window->getPlugin(pluginName);

			if(!p->getLinkedViews().empty())
			{
				QMessageBox::warning(this, tr("Warning"), "Plugin is currently used");
				init = true;
				item->setCheckState(0, Qt::Checked);
				init = false;
				return;
			}
			else
			{
				m_window->unloadPlugin(pluginName);
			}
		}
Pierre Kraemer's avatar
Pierre Kraemer committed
368
369
	}
}
370

Pierre Kraemer's avatar
Pierre Kraemer committed
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
//void PluginDialog::customContextMenu(const QPoint &pos)
//{
//	QPoint globalPos = treeWidget->mapToGlobal(pos);
//
//	QTreeWidgetItem *item = treeWidget->itemAt(pos);
//
//	if (item && (item->type() == FILE || item->type() == FILE_DIR))
//	{
//		item->setSelected(true);
//
//		QMenu myMenu("Plus...", this);
//		QAction pluginInfo("Informations sur le plugin", this);
//		myMenu.addAction(&pluginInfo);
//		connect(&pluginInfo, SIGNAL(triggered()), this, SLOT(showPluginInfo()));
//
//		myMenu.exec(globalPos);
//	}
//}
389

Pierre Kraemer's avatar
Pierre Kraemer committed
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
//void PluginDialog::cb_acceptDialog()
//{
//	QStringList paths;
//
//	int t = treeWidget->topLevelItemCount();
//
//	for (int i = 0; i < t; ++i)
//	{
//		QTreeWidgetItem *item = treeWidget->topLevelItem(i);
//
//		if (item->type() == FILE || item->type() == DIR)
//		{
//			QString path = item->text(1);
//			paths.push_back(path);
//		}
//	}
//
407
408
//	if (!System::StateHandler::savePluginsInfo(m_window, activePlugins, paths))
//		System::Error::showError();
Pierre Kraemer's avatar
Pierre Kraemer committed
409
//}
410

411
412
413
414
415
416
417
//void PluginDialog::showPluginInfo()
//{
//	QTreeWidgetItem *item = treeWidget->currentItem();
//	QString strUrl = item->text(1);
//
//	System::Info::showPluginInfo(strUrl);
//}