ccPluginUIManager.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. //##########################################################################
  2. //# #
  3. //# CLOUDCOMPARE #
  4. //# #
  5. //# This program is free software; you can redistribute it and/or modify #
  6. //# it under the terms of the GNU General Public License as published by #
  7. //# the Free Software Foundation; version 2 or later of the License. #
  8. //# #
  9. //# This program is distributed in the hope that it will be useful, #
  10. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  11. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  12. //# GNU General Public License for more details. #
  13. //# #
  14. //# COPYRIGHT: CloudCompare project #
  15. //# #
  16. //##########################################################################
  17. #include "ccPluginInfoDlg.h"
  18. #include "ccPluginUIManager.h"
  19. #include <ccConsole.h>
  20. #include <ccGLPluginInterface.h>
  21. #include <ccGLWindowInterface.h>
  22. #include <ccIOPluginInterface.h>
  23. #include <ccMainAppInterface.h>
  24. #include <ccPluginManager.h>
  25. #include <ccStdPluginInterface.h>
  26. // Qt
  27. #include <QAction>
  28. #include <QMenu>
  29. #include <QToolBar>
  30. #include <QWidget>
  31. ccPluginUIManager::ccPluginUIManager(ccMainAppInterface* appInterface, QWidget* parent)
  32. : QObject(parent)
  33. , m_parentWidget(parent)
  34. , m_appInterface(appInterface)
  35. , m_pluginMenu(nullptr)
  36. , m_glFilterMenu(nullptr)
  37. , m_actionRemoveFilter(nullptr)
  38. , m_glFilterActions(this)
  39. , m_mainPluginToolbar(nullptr)
  40. , m_showPluginToolbar(nullptr)
  41. , m_glFiltersToolbar(nullptr)
  42. , m_showGLFilterToolbar(nullptr)
  43. {
  44. setupActions();
  45. setupMenus();
  46. setupToolbars();
  47. }
  48. void ccPluginUIManager::init()
  49. {
  50. auto plugins = ccPluginManager::Get().pluginList();
  51. m_pluginMenu->setEnabled(false);
  52. m_glFilterMenu->setEnabled(false);
  53. m_mainPluginToolbar->setVisible(false);
  54. QVector<ccStdPluginInterface*> coreStdPlugins;
  55. QVector<ccStdPluginInterface*> thirdPartyStdPlugins;
  56. QVector<QAction*> coreGLActions;
  57. QVector<QAction*> thirdPartyGLActions;
  58. for (ccPluginInterface* plugin : plugins)
  59. {
  60. if (plugin == nullptr)
  61. {
  62. Q_ASSERT(false);
  63. continue;
  64. }
  65. if (!ccPluginManager::Get().isEnabled(plugin))
  66. {
  67. m_plugins.push_back(plugin);
  68. continue;
  69. }
  70. const QString pluginName = plugin->getName();
  71. Q_ASSERT(!pluginName.isEmpty());
  72. if (pluginName.isEmpty())
  73. {
  74. // should be unreachable - we have already checked for this in ccPlugins::Find()
  75. continue;
  76. }
  77. switch (plugin->getType())
  78. {
  79. case CC_STD_PLUGIN: //standard plugin
  80. {
  81. ccStdPluginInterface* stdPlugin = static_cast<ccStdPluginInterface*>(plugin);
  82. stdPlugin->setMainAppInterface(m_appInterface);
  83. if (stdPlugin->isCore())
  84. {
  85. coreStdPlugins.append(stdPlugin);
  86. }
  87. else
  88. {
  89. thirdPartyStdPlugins.append(stdPlugin);
  90. }
  91. m_plugins.push_back(stdPlugin);
  92. break;
  93. }
  94. case CC_GL_FILTER_PLUGIN: //GL filter
  95. {
  96. ccGLPluginInterface* glPlugin = static_cast<ccGLPluginInterface*>(plugin);
  97. QAction* action = new QAction(pluginName, this);
  98. action->setToolTip(glPlugin->getDescription());
  99. action->setIcon(glPlugin->getIcon());
  100. action->setCheckable(true);
  101. // store the plugin's interface pointer in the QAction data so we can access it in enableGLFilter()
  102. QVariant v;
  103. v.setValue(glPlugin);
  104. action->setData(v);
  105. connect(action, &QAction::triggered, this, &ccPluginUIManager::enableGLFilter);
  106. m_glFilterActions.addAction(action);
  107. if (glPlugin->isCore())
  108. {
  109. coreGLActions.append(action);
  110. }
  111. else
  112. {
  113. thirdPartyGLActions.append(action);
  114. }
  115. m_plugins.push_back(glPlugin);
  116. break;
  117. }
  118. case CC_IO_FILTER_PLUGIN:
  119. {
  120. ccIOPluginInterface* ioPlugin = static_cast<ccIOPluginInterface*>(plugin);
  121. // there are no menus or toolbars for I/O plugins
  122. m_plugins.push_back(ioPlugin);
  123. break;
  124. }
  125. }
  126. }
  127. // add core standard plugins to menu & tool bar
  128. for (ccStdPluginInterface* plugin : coreStdPlugins)
  129. {
  130. QList<QAction*> actions = plugin->getActions();
  131. addActionsToMenu(plugin, actions);
  132. addActionsToToolBar(plugin, actions);
  133. plugin->onNewSelection(m_appInterface->getSelectedEntities());
  134. }
  135. // add 3rd standard party plugins to menu & tool bar (if any )
  136. if (!thirdPartyStdPlugins.isEmpty())
  137. {
  138. m_pluginMenu->addSection("3rd Party");
  139. for (ccStdPluginInterface* plugin : thirdPartyStdPlugins)
  140. {
  141. QList<QAction*> actions = plugin->getActions();
  142. addActionsToMenu(plugin, actions);
  143. addActionsToToolBar(plugin, actions);
  144. plugin->onNewSelection(m_appInterface->getSelectedEntities());
  145. }
  146. }
  147. // add core GL plugins to menu & tool bar
  148. for (QAction* action : coreGLActions)
  149. {
  150. m_glFilterMenu->addAction(action);
  151. m_glFiltersToolbar->addAction(action);
  152. }
  153. // add 3rd GL party plugins to menu & tool bar (if any )
  154. if (!thirdPartyGLActions.isEmpty())
  155. {
  156. m_glFilterMenu->addSection("3rd Party");
  157. for (QAction* action : thirdPartyGLActions)
  158. {
  159. m_glFilterMenu->addAction(action);
  160. m_glFiltersToolbar->addAction(action);
  161. }
  162. }
  163. m_pluginMenu->setEnabled(!m_pluginMenu->isEmpty());
  164. if (m_mainPluginToolbar->isEnabled())
  165. {
  166. m_showPluginToolbar->setEnabled(true);
  167. }
  168. m_glFilterMenu->setEnabled(!m_glFilterMenu->isEmpty());
  169. m_glFiltersToolbar->setEnabled(!m_glFilterMenu->isEmpty()); // [sic] we have toolbar actions if we have them in the menu
  170. m_showPluginToolbar->setChecked(m_mainPluginToolbar->isEnabled());
  171. if (m_glFiltersToolbar->isEnabled())
  172. {
  173. m_showGLFilterToolbar->setEnabled(true);
  174. }
  175. m_showGLFilterToolbar->setChecked(m_glFiltersToolbar->isEnabled());
  176. }
  177. QMenu* ccPluginUIManager::pluginMenu() const
  178. {
  179. return m_pluginMenu;
  180. }
  181. QMenu* ccPluginUIManager::shaderAndFilterMenu() const
  182. {
  183. return m_glFilterMenu;
  184. }
  185. QToolBar* ccPluginUIManager::mainPluginToolbar()
  186. {
  187. return m_mainPluginToolbar;
  188. }
  189. QList<QToolBar*>& ccPluginUIManager::additionalPluginToolbars()
  190. {
  191. return m_additionalPluginToolbars;
  192. }
  193. QAction* ccPluginUIManager::actionShowMainPluginToolbar()
  194. {
  195. return m_showPluginToolbar;
  196. }
  197. QToolBar* ccPluginUIManager::glFiltersToolbar()
  198. {
  199. return m_glFiltersToolbar;
  200. }
  201. QAction* ccPluginUIManager::actionShowGLFilterToolbar()
  202. {
  203. return m_showGLFilterToolbar;
  204. }
  205. void ccPluginUIManager::updateMenus()
  206. {
  207. ccGLWindowInterface* active3DView = m_appInterface->getActiveGLWindow();
  208. const bool hasActiveView = (active3DView != nullptr);
  209. const QList<QAction*> actionList = m_glFilterActions.actions();
  210. for (QAction* action : actionList)
  211. {
  212. action->setEnabled(hasActiveView);
  213. }
  214. }
  215. void ccPluginUIManager::handleSelectionChanged()
  216. {
  217. const ccHObject::Container &selectedEntities = m_appInterface->getSelectedEntities();
  218. const auto& list = m_plugins;
  219. for (ccPluginInterface* plugin : list)
  220. {
  221. if (plugin->getType() == CC_STD_PLUGIN)
  222. {
  223. ccStdPluginInterface* stdPlugin = static_cast<ccStdPluginInterface*>(plugin);
  224. stdPlugin->onNewSelection(selectedEntities);
  225. }
  226. }
  227. }
  228. void ccPluginUIManager::showAboutDialog() const
  229. {
  230. ccPluginInfoDlg about;
  231. about.setPluginPaths(ccPluginManager::Get().pluginPaths());
  232. about.setPluginList(m_plugins);
  233. about.exec();
  234. }
  235. void ccPluginUIManager::setupActions()
  236. {
  237. m_actionRemoveFilter = new QAction(QIcon(":/CC/images/noFilter.png"), tr("Remove Filter"), this);
  238. m_actionRemoveFilter->setEnabled(false);
  239. connect(m_actionRemoveFilter, &QAction::triggered, this, &ccPluginUIManager::disableGLFilter);
  240. m_showPluginToolbar = new QAction(tr("Plugins"), this);
  241. m_showPluginToolbar->setCheckable(true);
  242. m_showPluginToolbar->setEnabled(false);
  243. m_showGLFilterToolbar = new QAction(tr("GL Filters"), this);
  244. m_showGLFilterToolbar->setCheckable(true);
  245. m_showGLFilterToolbar->setEnabled(false);
  246. }
  247. void ccPluginUIManager::setupMenus()
  248. {
  249. m_pluginMenu = new QMenu(tr("Plugins"), m_parentWidget);
  250. m_glFilterMenu = new QMenu(tr("Shaders && Filters"), m_parentWidget);
  251. m_glFilterMenu->addAction(m_actionRemoveFilter);
  252. m_glFilterActions.setExclusive(true);
  253. }
  254. void ccPluginUIManager::addActionsToMenu(ccStdPluginInterface* stdPlugin, const QList<QAction*> &actions)
  255. {
  256. // If the plugin has more than one action we create its own menu
  257. if (actions.size() > 1)
  258. {
  259. QMenu* menu = new QMenu(stdPlugin->getName(), m_parentWidget);
  260. menu->setIcon(stdPlugin->getIcon());
  261. menu->setEnabled(true);
  262. for (QAction* action : actions)
  263. {
  264. menu->addAction(action);
  265. }
  266. m_pluginMenu->addMenu(menu);
  267. }
  268. else // otherwise we just add it to the main menu
  269. {
  270. Q_ASSERT(actions.count() == 1);
  271. m_pluginMenu->addAction(actions.at(0));
  272. }
  273. }
  274. void ccPluginUIManager::setupToolbars()
  275. {
  276. m_mainPluginToolbar = new QToolBar(tr("Plugins"), m_parentWidget);
  277. m_mainPluginToolbar->setObjectName(QStringLiteral("Main Plugin Toolbar"));
  278. connect(m_showPluginToolbar, &QAction::toggled, m_mainPluginToolbar, &QToolBar::setVisible);
  279. m_glFiltersToolbar = new QToolBar(tr("GL Filters"), m_parentWidget);
  280. m_glFiltersToolbar->setObjectName(QStringLiteral("GL Plugin Toolbar"));
  281. m_glFiltersToolbar->addAction(m_actionRemoveFilter);
  282. connect(m_showGLFilterToolbar, &QAction::toggled, m_glFiltersToolbar, &QToolBar::setVisible);
  283. }
  284. void ccPluginUIManager::addActionsToToolBar(ccStdPluginInterface* stdPlugin, const QList<QAction*> &actions)
  285. {
  286. const QString pluginName = stdPlugin->getName();
  287. // If the plugin has more than one action we create its own tool bar
  288. if (actions.size() > 1)
  289. {
  290. QToolBar* toolBar = new QToolBar(pluginName + QStringLiteral(" toolbar"), m_parentWidget);
  291. if (toolBar != nullptr)
  292. {
  293. m_additionalPluginToolbars.push_back(toolBar);
  294. toolBar->setObjectName(pluginName);
  295. toolBar->setEnabled(true);
  296. for (QAction* action : actions)
  297. {
  298. toolBar->addAction(action);
  299. }
  300. }
  301. }
  302. else // otherwise we just add it to the main tool bar
  303. {
  304. Q_ASSERT(actions.count() == 1);
  305. m_mainPluginToolbar->addAction(actions.at(0));
  306. }
  307. }
  308. void ccPluginUIManager::enableGLFilter()
  309. {
  310. ccGLWindowInterface* win = m_appInterface->getActiveGLWindow();
  311. if (win == nullptr)
  312. {
  313. ccLog::Warning("[GL filter] No active 3D view");
  314. return;
  315. }
  316. QAction* action = qobject_cast<QAction*>(sender());
  317. Q_ASSERT(action != nullptr);
  318. ccGLPluginInterface* plugin = action->data().value<ccGLPluginInterface*>();
  319. if (plugin == nullptr)
  320. {
  321. return;
  322. }
  323. if (win->areGLFiltersEnabled())
  324. {
  325. ccGlFilter* filter = plugin->getFilter();
  326. if (filter != nullptr)
  327. {
  328. win->setGlFilter(filter);
  329. m_actionRemoveFilter->setEnabled(true);
  330. ccConsole::Print("Note: go to << Display > Shaders & Filters > No filter >> to disable GL filter");
  331. }
  332. else
  333. {
  334. ccConsole::Error("Can't load GL filter (an error occurred)!");
  335. }
  336. }
  337. else
  338. {
  339. ccConsole::Error("GL filters not supported!");
  340. }
  341. }
  342. void ccPluginUIManager::disableGLFilter()
  343. {
  344. ccGLWindowInterface* win = m_appInterface->getActiveGLWindow();
  345. if (win != nullptr)
  346. {
  347. win->setGlFilter(nullptr);
  348. win->redraw(false);
  349. m_actionRemoveFilter->setEnabled(false);
  350. m_glFilterActions.checkedAction()->setChecked(false);
  351. }
  352. }