Création d'un compte pour un collaborateur extérieur au laboratoire depuis l'intranet ICube : https://intranet.icube.unistra.fr/fr/labs/member/profile

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

Pierre Kraemer's avatar
Pierre Kraemer committed
3
4
#include <QVBoxLayout>
#include <QSplitter>
5
6
7
#include <QMessageBox>
#include <QDockWidget>
#include <QPluginLoader>
8
#include <QFile>
9
#include <QFileInfo>
10
#include <QDir>
11
12
13
#include <QKeyEvent>
#include <QMouseEvent>
#include <QWheelEvent>
14

Pierre Kraemer's avatar
Pierre Kraemer committed
15
16
#include "plugin.h"
#include "view.h"
17
#include "texture.h"
18
19
#include "camera.h"
#include "mapHandler.h"
20

Pierre Kraemer's avatar
Pierre Kraemer committed
21
22
23
24
25
26
27
28
29
#include "dialogs/camerasDialog.h"
#include "dialogs/pluginsDialog.h"
#include "dialogs/mapsDialog.h"

namespace CGoGN
{

namespace SCHNApps
{
Pierre Kraemer's avatar
Pierre Kraemer committed
30

31
Window::Window(const QString& appPath, PythonQtObjectPtr& pythonContext, PythonQtScriptingConsole& pythonConsole) :
Pierre Kraemer's avatar
Pierre Kraemer committed
32
	QMainWindow(),
Pierre Kraemer's avatar
Pierre Kraemer committed
33
34
	m_appPath(appPath),
	m_pythonContext(pythonContext),
35
	m_pythonConsole(pythonConsole),
36
	m_firstView(NULL),
37
	m_currentView(NULL)
38
{
Pierre Kraemer's avatar
Pierre Kraemer committed
39
40
41
	m_camerasDialog = new CamerasDialog(this);
	m_pluginsDialog = new PluginsDialog(this);
	m_mapsDialog = new MapsDialog(this);
42

43
	this->setupUi(this);
44

Pierre Kraemer's avatar
Pierre Kraemer committed
45
	m_dock = new QDockWidget(tr("Plugins"), this);
46
47
	m_dock->setAllowedAreas(Qt::RightDockWidgetArea);
	m_dock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable);
48
49
50

	m_dockTabWidget = new QTabWidget(m_dock);
	m_dockTabWidget->setObjectName("DockTabWidget");
51
	m_dockTabWidget->setLayoutDirection(Qt::LeftToRight);
52
	m_dockTabWidget->setTabPosition(QTabWidget::East);
Pierre Kraemer's avatar
Pierre Kraemer committed
53
54
55

	addDockWidget(Qt::RightDockWidgetArea, m_dock);
	m_dock->setVisible(false);
56
57
	m_dock->setWidget(m_dockTabWidget);

58
59
	connect(actionShowHideDock, SIGNAL(triggered()), this, SLOT(cb_showHideDock()));

60
61
	m_pythonDock = new QDockWidget(tr("Python"), this);
	m_pythonDock->setAllowedAreas(Qt::BottomDockWidgetArea);
Pierre Kraemer's avatar
Pierre Kraemer committed
62
63
	m_pythonDock->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetClosable);

64
65
66
67
68
69
	addDockWidget(Qt::BottomDockWidgetArea, m_pythonDock);
	m_pythonDock->setVisible(false);
	m_pythonDock->setWidget(&m_pythonConsole);

	connect(actionShowHidePythonDock, SIGNAL(triggered()), this, SLOT(cb_showHidePythonDock()));

Pierre Kraemer's avatar
Pierre Kraemer committed
70
71
72
73
74
	m_centralLayout = new QVBoxLayout(centralwidget);

	m_rootSplitter = new QSplitter(centralwidget);
	b_rootSplitterInitialized = false;
	m_centralLayout->addWidget(m_rootSplitter);
75

76
77
	// add first view
	m_firstView = addView();
78
	setCurrentView(m_firstView);
Pierre Kraemer's avatar
Pierre Kraemer committed
79
	m_rootSplitter->addWidget(m_firstView);
80

81
82
	glewInit();

Pierre Kraemer's avatar
Pierre Kraemer committed
83
	// connect the basic actions
84
85
	connect(actionAboutSCHNApps, SIGNAL(triggered()), this, SLOT(cb_aboutSCHNApps()));
	connect(actionAboutCGoGN, SIGNAL(triggered()), this, SLOT(cb_aboutCGoGN()));
86

Pierre Kraemer's avatar
Pierre Kraemer committed
87
88
89
	connect(actionManageCameras, SIGNAL(triggered()), this, SLOT(cb_showCamerasDialog()));
	connect(actionManagePlugins, SIGNAL(triggered()), this, SLOT(cb_showPluginsDialog()));
	connect(actionManageMaps, SIGNAL(triggered()), this, SLOT(cb_showMapsDialog()));
90

91
	registerPluginsDirectory(m_appPath + QString("/../lib"));
Pierre Kraemer's avatar
Pierre Kraemer committed
92
93
}

94
95
96
97
Window::~Window()
{
}

Pierre Kraemer's avatar
Pierre Kraemer committed
98
99
100
101
/*********************************************************
 * MANAGE DOCK
 *********************************************************/

102
void Window::addTabInDock(QWidget* tabWidget, const QString& tabText, bool enable)
Pierre Kraemer's avatar
Pierre Kraemer committed
103
{
104
	if(tabWidget)
105
	{
106
107
		int currentTab = m_dockTabWidget->currentIndex();

108
		int idx = m_dockTabWidget->addTab(tabWidget, tabText);
Pierre Kraemer's avatar
Pierre Kraemer committed
109
		m_dock->setVisible(true);
110
		m_dockTabWidget->setTabEnabled(idx, enable);
111
112
113

		if(currentTab != -1)
			m_dockTabWidget->setCurrentIndex(currentTab);
114
	}
Pierre Kraemer's avatar
Pierre Kraemer committed
115
116
117
118
}

void Window::removeTabInDock(QWidget *tabWidget)
{
119
	if(tabWidget)
Pierre Kraemer's avatar
Pierre Kraemer committed
120
121
122
		m_dockTabWidget->removeTab(m_dockTabWidget->indexOf(tabWidget));
}

123
124
void Window::enablePluginTabWidgets(Plugin* plugin)
{
125
126
	int currentTab = m_dockTabWidget->currentIndex();

127
128
	const QList<QWidget*> tabWidgets = plugin->getTabWidgets();
	foreach(QWidget* w, tabWidgets)
129
130
131
		m_dockTabWidget->setTabEnabled(m_dockTabWidget->indexOf(w), true);

	m_dockTabWidget->setCurrentIndex(currentTab);
132
133
134
135
}

void Window::disablePluginTabWidgets(Plugin* plugin)
{
136
137
	int currentTab = m_dockTabWidget->currentIndex();

138
139
	const QList<QWidget*> tabWidgets = plugin->getTabWidgets();
	foreach(QWidget* w, tabWidgets)
140
141
142
		m_dockTabWidget->setTabEnabled(m_dockTabWidget->indexOf(w), false);

	m_dockTabWidget->setCurrentIndex(currentTab);
143
144
}

Pierre Kraemer's avatar
Pierre Kraemer committed
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*********************************************************
 * MANAGE MENU ACTIONS
 *********************************************************/

bool Window::addMenuAction(const QString& menuPath, QAction* action)
{
	// if menu path = empty string: set error + failure
	if (menuPath.isEmpty())
		return false;

	if (!action)
		return false;

	// extracting all the substring separated by ';'
	QStringList stepNames = menuPath.split(";");
	stepNames.removeAll("");
	unsigned int nbStep = stepNames.count();

	// if only one substring: error + failure
	// No action directly in the menu bar
	if (nbStep < 1)
		return false;

	unsigned int i = 0;
169
	QMenu* lastMenu = NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
170
171
172
	foreach(QString step, stepNames)
	{
		++i;
173
		if (i < nbStep) // if not last substring (= menu)
Pierre Kraemer's avatar
Pierre Kraemer committed
174
		{
175
176
177
178
179
180
			// try to find an existing submenu with step name
			bool found = false;
			QList<QAction*> actions;
			if(i == 1) actions = menubar->actions();
			else actions = lastMenu->actions();
			foreach(QAction* action, actions)
Pierre Kraemer's avatar
Pierre Kraemer committed
181
			{
182
183
				QMenu* submenu = action->menu();
				if (submenu && submenu->title() == step)
Pierre Kraemer's avatar
Pierre Kraemer committed
184
				{
185
186
187
					lastMenu = submenu;
					found = true;
					break;
Pierre Kraemer's avatar
Pierre Kraemer committed
188
189
				}
			}
190
			if (!found)
Pierre Kraemer's avatar
Pierre Kraemer committed
191
			{
192
				QMenu* newMenu;
193
194
195
196
197
198
199
200
201
202
				if(i == 1)
				{
					newMenu = menubar->addMenu(step);
					newMenu->setParent(menubar);
				}
				else
				{
					newMenu = lastMenu->addMenu(step);
					newMenu->setParent(lastMenu);
				}
203
				lastMenu = newMenu;
Pierre Kraemer's avatar
Pierre Kraemer committed
204
205
			}
		}
206
		else // if last substring (= action name)
Pierre Kraemer's avatar
Pierre Kraemer committed
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
		{
			lastMenu->addAction(action);
			action->setText(step);
			action->setParent(lastMenu);
		}
	}

	return true;
}

void Window::removeMenuAction(QAction *action)
{
	if(action)
	{
		action->setEnabled(false);
		// parent of the action
		// which is an instance of QMenu if the action was created
		// using the addMenuActionMethod()
		QObject* parent = action->parent();
		delete action;

228
		while(parent != NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
229
		{
230
231
			QMenu* parentMenu = dynamic_cast<QMenu*>(parent);
			if(parentMenu && parentMenu->actions().empty())
Pierre Kraemer's avatar
Pierre Kraemer committed
232
233
			{
				parent = parent->parent();
234
				delete parentMenu;
Pierre Kraemer's avatar
Pierre Kraemer committed
235
			}
236
237
			else
				parent = NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
		}
	}
}

/*********************************************************
 * MANAGE TOOLBAR ACTIONS
 *********************************************************/

bool Window::addToolbarAction(QAction* action)
{
	if (action)
	{
		toolBar->addAction(action);
		return true;
	}
	return false;
}

void Window::removeToolbarAction(QAction* action)
{
	if (action)
		toolBar->removeAction(action);
}

/*********************************************************
263
 * MANAGE CAMERAS
Pierre Kraemer's avatar
Pierre Kraemer committed
264
265
 *********************************************************/

266
Camera* Window::addCamera(const QString& name)
Pierre Kraemer's avatar
Pierre Kraemer committed
267
{
268
	if (h_cameras.contains(name))
269
270
		return NULL;

271
272
	Camera* camera = new Camera(name, this);
	h_cameras.insert(name, camera);
Pierre Kraemer's avatar
Pierre Kraemer committed
273

274
	emit(cameraAdded(camera));
Pierre Kraemer's avatar
Pierre Kraemer committed
275

276
277
	return camera;
}
Pierre Kraemer's avatar
Pierre Kraemer committed
278

279
280
281
Camera* Window::addCamera()
{
	return addCamera(QString("camera_") + QString::number(Camera::cameraCount));
Pierre Kraemer's avatar
Pierre Kraemer committed
282
283
}

284
void Window::removeCamera(const QString& name)
Pierre Kraemer's avatar
Pierre Kraemer committed
285
{
286
	if (h_cameras.contains(name))
Pierre Kraemer's avatar
Pierre Kraemer committed
287
	{
288
289
		Camera* camera = h_cameras[name];
		h_cameras.remove(name);
Pierre Kraemer's avatar
Pierre Kraemer committed
290

291
		emit(cameraRemoved(camera));
Pierre Kraemer's avatar
Pierre Kraemer committed
292

293
		delete camera;
294
295
	}
}
Pierre Kraemer's avatar
Pierre Kraemer committed
296

297
Camera* Window::getCamera(const QString& name) const
Pierre Kraemer's avatar
Pierre Kraemer committed
298
{
299
300
	if (h_cameras.contains(name))
		return h_cameras[name];
Pierre Kraemer's avatar
Pierre Kraemer committed
301
302
303
304
	else
		return NULL;
}

305
306
307
/*********************************************************
 * MANAGE VIEWS
 *********************************************************/
Pierre Kraemer's avatar
Pierre Kraemer committed
308

309
View* Window::addView(const QString& name)
310
{
311
312
	if (h_views.contains(name))
		return NULL;
313

314
315
	View* view = NULL;
	if(m_firstView == NULL)
Pierre Kraemer's avatar
Pierre Kraemer committed
316
		view = new View(name, this);
317
	else
Pierre Kraemer's avatar
Pierre Kraemer committed
318
		view = new View(name, this, m_firstView);
319
	h_views.insert(name, view);
Pierre Kraemer's avatar
Pierre Kraemer committed
320

321
322
	emit(viewAdded(view));

323
	return view;
324
325
}

326
327
328
329
330
View* Window::addView()
{
	return addView(QString("view_") + QString::number(View::viewCount));
}

331
void Window::removeView(const QString& name)
332
{
333
	if (h_views.contains(name))
334
	{
Pierre Kraemer's avatar
Pierre Kraemer committed
335
336
337
		if(h_views.count() > 1)
		{
			View* view = h_views[name];
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
			if(view == m_firstView)
			{
				ViewHash::const_iterator i = h_views.constBegin();
				while (i != h_views.constEnd())
				{
					if(i.value() != view)
					{
						m_firstView = i.value();
						i = h_views.constEnd();
					}
					else
						++i;
				}
			}
//			if(view == m_currentView)
			setCurrentView(m_firstView);
Pierre Kraemer's avatar
Pierre Kraemer committed
354
			h_views.remove(name);
355
356
357

			emit(viewRemoved(view));

Pierre Kraemer's avatar
Pierre Kraemer committed
358
359
			delete view;
		}
360
361
362
	}
}

363
View* Window::getView(const QString& name) const
364
{
365
366
	if (h_views.contains(name))
		return h_views[name];
367
	else
368
		return NULL;
369
370
}

371
372
void Window::setCurrentView(View* view)
{
373
374
375
376
377
378
379
380
	if(m_currentView)
	{
		const QList<Plugin*>& oldPlugins = m_currentView->getLinkedPlugins();
		foreach(Plugin* p, oldPlugins)
			disablePluginTabWidgets(p);

		disconnect(m_currentView, SIGNAL(pluginLinked(Plugin*)), this, SLOT(enablePluginTabWidgets(Plugin*)));
	}
381
382
383
384
385
386
387
388

	View* oldCurrent = m_currentView;
	m_currentView = view;

	const QList<Plugin*>& newPlugins = m_currentView->getLinkedPlugins();
	foreach(Plugin* p, newPlugins)
		enablePluginTabWidgets(p);

389
390
391
392
393
394
	connect(m_currentView, SIGNAL(pluginLinked(Plugin*)), this, SLOT(enablePluginTabWidgets(Plugin*)));

	emit(currentViewChanged(m_currentView));

	if(oldCurrent)
		oldCurrent->updateGL();
395
396
397
	m_currentView->updateGL();
}

Pierre Kraemer's avatar
Pierre Kraemer committed
398
void Window::splitView(const QString& name, Qt::Orientation orientation)
399
{
Pierre Kraemer's avatar
Pierre Kraemer committed
400
	View* newView = addView();
401

Pierre Kraemer's avatar
Pierre Kraemer committed
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
	View* view = h_views[name];
	QSplitter* parent = (QSplitter*)(view->parentWidget());
	if(parent == m_rootSplitter && !b_rootSplitterInitialized)
	{
		m_rootSplitter->setOrientation(orientation);
		b_rootSplitterInitialized = true;
	}
	if(parent->orientation() == orientation)
		parent->insertWidget(parent->indexOf(view)+1, newView);
	else
	{
		int idx = parent->indexOf(view);
		view->setParent(NULL);
		QSplitter* spl = new QSplitter(orientation);
		spl->addWidget(view);
		spl->addWidget(newView);
		parent->insertWidget(idx, spl);
419
420
421
	}
}

422
/*********************************************************
423
 * MANAGE PLUGINS
424
425
 *********************************************************/

426
void Window::registerPluginsDirectory(const QString& path)
427
{
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
	QDir directory(path);
	if(directory.exists())
	{
		QStringList filters;
		filters << "lib*.so";
		filters << "lib*.dylib";
		filters << "*.dll";

		QStringList pluginFiles = directory.entryList(filters, QDir::Files);

		foreach(QString pluginFile, pluginFiles)
		{
			QFileInfo pfi(pluginFile);
			QString pluginName = pfi.baseName().remove(0, 3);
			QString pluginFilePath = directory.absoluteFilePath(pluginFile);

			m_availablePlugins[pluginName] = pluginFilePath;
		}

		m_pluginsDialog->refreshPluginsList();
	}
}
450

451
452
Plugin* Window::loadPlugin(const QString& pluginName)
{
453
	if (h_plugins.contains(pluginName))
454
		return NULL;
455

456
	if (m_availablePlugins.contains(pluginName))
457
	{
458
		QString pluginFilePath = m_availablePlugins[pluginName];
Pierre Kraemer's avatar
Pierre Kraemer committed
459

460
		QPluginLoader loader(pluginFilePath);
461

462
463
		// if the loader loads a plugin instance
		if (QObject* pluginObject = loader.instance())
464
		{
465
466
467
468
469
470
471
472
473
474
475
476
			Plugin* plugin = qobject_cast<Plugin*>(pluginObject);

			// set the plugin with correct parameters (name, filepath, window)
			plugin->setName(pluginName);
			plugin->setFilePath(pluginFilePath);
			plugin->setWindow(this);

			// then we call its enable() methods
			if (plugin->enable())
			{
				// if it succeeded we reference this plugin
				h_plugins.insert(pluginName, plugin);
477

478
479
				statusbar->showMessage(pluginName + QString(" successfully loaded."), 2000);
				emit(pluginLoaded(plugin));
480

481
482
483
484
485
486
487
488
				// method success
				return plugin;
			}
			else
			{
				delete plugin;
				return NULL;
			}
489
		}
490
		// if loading fails
491
492
		else
		{
493
			std::cout << "loadPlugin: loader.instance() failed" << std::endl << loader.errorString().toUtf8().constData() << std::endl;
494
495
496
497
			return NULL;
		}
	}
	else
Pierre Kraemer's avatar
Pierre Kraemer committed
498
	{
499
		std::cout << "loadPlugin: plugin not found (" << pluginName.toUtf8().constData() << ")" << std::endl;
500
		return NULL;
Pierre Kraemer's avatar
Pierre Kraemer committed
501
502
503
	}
}

504
void Window::unloadPlugin(const QString& pluginName)
505
{
506
507
508
509
510
511
512
513
	if (h_plugins.contains(pluginName))
	{
		Plugin* plugin = h_plugins[pluginName];

		// calling its disable() method and dereferencing it
		plugin->disable();
		h_plugins.remove(pluginName);

514
515
516
517
		QPluginLoader loader(plugin->getFilePath());
		loader.unload();

		statusbar->showMessage(pluginName + QString(" successfully unloaded."), 2000);
518
		emit(pluginUnloaded(plugin));
519
520
521
522

		// delete plugin
		delete plugin;
	}
523
524
}

525
Plugin* Window::getPlugin(const QString& name) const
526
{
527
528
529
530
	if (h_plugins.contains(name))
		return h_plugins[name];
	else
		return NULL;
531
532
}

533
534
535
/*********************************************************
 * MANAGE MAPS
 *********************************************************/
536

Pierre Kraemer's avatar
Pierre Kraemer committed
537
MapHandlerGen* Window::addMap(const QString& name, unsigned int dim)
538
{
Pierre Kraemer's avatar
Pierre Kraemer committed
539
540
541
	if (h_maps.contains(name))
		return NULL;

542
	MapHandlerGen* mh = NULL;
543
544
	switch(dim)
	{
545
546
547
		case 2 : {
			PFP2::MAP* map = new PFP2::MAP();
			mh = new MapHandler<PFP2>(name, this, map);
548
			break;
549
550
551
552
		}
		case 3 : {
			PFP3::MAP* map = new PFP3::MAP();
			mh = new MapHandler<PFP3>(name, this, map);
553
			break;
554
		}
555
556
	}

Pierre Kraemer's avatar
Pierre Kraemer committed
557
	h_maps.insert(name, mh);
558

Pierre Kraemer's avatar
Pierre Kraemer committed
559
	emit(mapAdded(mh));
560

Pierre Kraemer's avatar
Pierre Kraemer committed
561
	return mh;
562
563
}

564
void Window::removeMap(const QString& name)
565
{
566
	if (h_maps.contains(name))
567
	{
568
		MapHandlerGen* map = h_maps[name];
569
		h_maps.remove(name);
570
571
572

		emit(mapRemoved(map));

573
		delete map;
574
	}
575
576
}

577
MapHandlerGen* Window::getMap(const QString& name) const
578
579
580
{
	if (h_maps.contains(name))
		return h_maps[name];
581
582
583
584
	else
		return NULL;
}

585
586
587
588
/*********************************************************
 * MANAGE LINKS
 *********************************************************/

589
void Window::linkViewAndCamera(View* v, Camera* c)
590
{
591
592
593
	Camera* current = v->getCurrentCamera();
	current->unlinkView(v);
	emit(viewAndCameraUnlinked(v, current));
594

595
596
597
598
	v->setCurrentCamera(c);

	c->linkView(v);
	emit(viewAndCameraLinked(v, c));
599
600
}

601
void Window::linkViewAndCamera(const QString& viewName, const QString& cameraName)
602
{
603
604
605
606
	View* view = getView(viewName);
	Camera* camera = getCamera(cameraName);
	if(view && camera)
		linkViewAndCamera(view, camera);
607
608
609
610
611
612
}

void Window::linkViewAndMap(View* v, MapHandlerGen* m)
{
	v->linkMap(m);
	m->linkView(v);
613
614

	emit(viewAndMapLinked(v, m));
615
616

	v->updateGL();
617
618
}

619
620
621
622
623
624
625
626
void Window::linkViewAndMap(const QString& viewName, const QString& mapName)
{
	View* view = getView(viewName);
	MapHandlerGen* map = getMap(mapName);
	if(view && map)
		linkViewAndMap(view, map);
}

627
628
629
630
void Window::unlinkViewAndMap(View* v, MapHandlerGen* m)
{
	v->unlinkMap(m);
	m->unlinkView(v);
631
632

	emit(viewAndMapUnlinked(v, m));
633
634

	v->updateGL();
635
636
}

637
void Window::unlinkViewAndMap(const QString& viewName, const QString& mapName)
638
{
639
640
641
642
643
	View* view = getView(viewName);
	MapHandlerGen* map = getMap(mapName);
	if(view && map)
		unlinkViewAndMap(view, map);
}
644

645
646
647
648
649
650
void Window::linkViewAndPlugin(View* v, Plugin* p)
{
	v->linkPlugin(p);
	p->linkView(v);

	emit(viewAndPluginLinked(v, p));
651
652

	v->updateGL();
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
}

void Window::linkViewAndPlugin(const QString& viewName, const QString& pluginName)
{
	View* view = getView(viewName);
	Plugin* plugin = getPlugin(pluginName);
	if(view && plugin)
		linkViewAndPlugin(view, plugin);
}

void Window::unlinkViewAndPlugin(View* v, Plugin* p)
{
	v->unlinkPlugin(p);
	p->unlinkView(v);

	emit(viewAndPluginUnlinked(v, p));
669
670

	v->updateGL();
671
672
673
674
675
676
677
678
}

void Window::unlinkViewAndPlugin(const QString& viewName, const QString& pluginName)
{
	View* view = getView(viewName);
	Plugin* plugin = getPlugin(pluginName);
	if(view && plugin)
		unlinkViewAndPlugin(view, plugin);
679
680
}

681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
/*********************************************************
 * MANAGE TEXTURES
 *********************************************************/

Texture* Window::getTexture(const QString& image)
{
	if(h_textures.contains(image))
	{
		Texture* t = h_textures[image];
		t->ref++;
		return t;
	}
	else
	{
		Texture* t = NULL;
		QImage img(image);
		if(!img.isNull())
		{
			GLuint texID = m_firstView->bindTexture(img);
			t = new Texture(texID, img.size(), 1);
			h_textures.insert(image, t);
		}
		return t;
	}
}

void Window::releaseTexture(const QString& image)
{
	if(h_textures.contains(image))
	{
		Texture* t = h_textures[image];
		t->ref--;
		if(t->ref == 0)
		{
			m_firstView->deleteTexture(h_textures[image]->texID);
			h_textures.remove(image);
			delete t;
		}
	}
}

722
723
724
725
726
727
728
729
730
731
732


void Window::cb_aboutSCHNApps()
{
	QString str("SCHNApps:\nS... CGoGN Holder for Nice Applications\n"
	            "Web site: http://cgogn.unistra.fr \n"
	            "Contact information: cgogn@unistra.fr");
	QMessageBox::about(this, tr("About SCHNApps"), str);
}

void Window::cb_aboutCGoGN()
733
734
735
736
737
738
739
740
{
	QString str("CGoGN:\nCombinatorial and Geometric modeling\n"
	            "with Generic N-dimensional Maps\n"
	            "Web site: http://cgogn.unistra.fr \n"
	            "Contact information: cgogn@unistra.fr");
	QMessageBox::about(this, tr("About CGoGN"), str);
}

741
742
743
744
745
void Window::cb_showHideDock()
{
	m_dock->setVisible(m_dock->isHidden());
}

746
747
748
749
750
void Window::cb_showHidePythonDock()
{
	m_pythonDock->setVisible(m_pythonDock->isHidden());
}

Pierre Kraemer's avatar
Pierre Kraemer committed
751
void Window::cb_showCamerasDialog()
752
{
Pierre Kraemer's avatar
Pierre Kraemer committed
753
	m_camerasDialog->show();
754
755
}

Pierre Kraemer's avatar
Pierre Kraemer committed
756
void Window::cb_showPluginsDialog()
757
{
Pierre Kraemer's avatar
Pierre Kraemer committed
758
	m_pluginsDialog->show();
759
760
}

Pierre Kraemer's avatar
Pierre Kraemer committed
761
void Window::cb_showMapsDialog()
762
{
Pierre Kraemer's avatar
Pierre Kraemer committed
763
	m_mapsDialog->show();
764
}
Pierre Kraemer's avatar
Pierre Kraemer committed
765
766
767
768

} // namespace SCHNApps

} // namespace CGoGN