Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkBaseApplication.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include <mitkBaseApplication.h>
14 
15 #include <mitkExceptionMacro.h>
16 #include <mitkLogMacros.h>
17 #include <mitkProvisioningInfo.h>
18 
19 #include <QmitkSafeApplication.h>
20 #include <QmitkSingleApplication.h>
21 
22 #include <Poco/Util/HelpFormatter.h>
23 
24 #include <ctkPluginFramework.h>
25 #include <ctkPluginFramework_global.h>
26 #include <ctkPluginFrameworkLauncher.h>
27 
28 #include <usModuleSettings.h>
29 
30 #include <vtkOpenGLRenderWindow.h>
31 #include <QVTKOpenGLWidget.h>
32 
33 #include <QCoreApplication>
34 #include <QDir>
35 #include <QFileInfo>
36 #include <QRunnable>
37 #include <QSplashScreen>
38 #include <QStandardPaths>
39 #include <QTime>
40 
41 namespace
42 {
43  void outputQtMessage(QtMsgType type, const QMessageLogContext&, const QString& msg)
44  {
45  auto message = msg.toStdString();
46 
47  switch (type)
48  {
49  case QtDebugMsg:
50  MITK_DEBUG << message;
51  break;
52 
53  case QtInfoMsg:
54  MITK_INFO << message;
55  break;
56 
57  case QtWarningMsg:
58  MITK_WARN << message;
59  break;
60 
61  case QtCriticalMsg:
62  MITK_ERROR << message;
63  break;
64 
65  case QtFatalMsg:
66  MITK_ERROR << message;
67  abort();
68 
69  default:
70  MITK_INFO << message;
71  break;
72  }
73  }
74 }
75 
76 namespace mitk
77 {
78  const QString BaseApplication::ARG_APPLICATION = "BlueBerry.application";
79  const QString BaseApplication::ARG_CLEAN = "BlueBerry.clean";
80  const QString BaseApplication::ARG_CONSOLELOG = "BlueBerry.consoleLog";
81  const QString BaseApplication::ARG_DEBUG = "BlueBerry.debug";
82  const QString BaseApplication::ARG_FORCE_PLUGIN_INSTALL = "BlueBerry.forcePlugins";
83  const QString BaseApplication::ARG_HOME = "BlueBerry.home";
84  const QString BaseApplication::ARG_NEWINSTANCE = "BlueBerry.newInstance";
85  const QString BaseApplication::ARG_NO_LAZY_REGISTRY_CACHE_LOADING = "BlueBerry.noLazyRegistryCacheLoading";
86  const QString BaseApplication::ARG_NO_REGISTRY_CACHE = "BlueBerry.noRegistryCache";
87  const QString BaseApplication::ARG_PLUGIN_CACHE = "BlueBerry.plugin_cache_dir";
88  const QString BaseApplication::ARG_PLUGIN_DIRS = "BlueBerry.plugin_dirs";
89  const QString BaseApplication::ARG_PRELOAD_LIBRARY = "BlueBerry.preloadLibrary";
90  const QString BaseApplication::ARG_PRODUCT = "BlueBerry.product";
91  const QString BaseApplication::ARG_PROVISIONING = "BlueBerry.provisioning";
92  const QString BaseApplication::ARG_REGISTRY_MULTI_LANGUAGE = "BlueBerry.registryMultiLanguage";
93  const QString BaseApplication::ARG_SPLASH_IMAGE = "BlueBerry.splashscreen";
94  const QString BaseApplication::ARG_STORAGE_DIR = "BlueBerry.storageDir";
95  const QString BaseApplication::ARG_XARGS = "xargs";
96 
97  const QString BaseApplication::PROP_APPLICATION = "blueberry.application";
102  const QString BaseApplication::PROP_PRODUCT = "blueberry.product";
104 
105  class SplashCloserCallback : public QRunnable
106  {
107  public:
108  SplashCloserCallback(QSplashScreen* splashscreen)
109  : m_Splashscreen(splashscreen)
110  {
111  }
112 
113  void run() override
114  {
115  this->m_Splashscreen->close();
116  }
117 
118  private:
119  QSplashScreen *m_Splashscreen; // Owned by BaseApplication::Impl
120  };
121 
122  struct BaseApplication::Impl
123  {
124  ctkProperties m_FWProps;
125 
126  QCoreApplication *m_QApp;
127 
128  int m_Argc;
129  char **m_Argv;
130 
131 #ifdef Q_OS_MAC
132  std::vector<char*> m_Argv_macOS;
133 #endif
134 
135  QString m_AppName;
136  QString m_OrgaName;
137  QString m_OrgaDomain;
138 
139  bool m_SingleMode;
140  bool m_SafeMode;
141 
142  QSplashScreen *m_Splashscreen;
143  SplashCloserCallback *m_SplashscreenClosingCallback;
144 
145  QStringList m_PreloadLibs;
146  QString m_ProvFile;
147 
148  Impl(int argc, char **argv)
149  : m_Argc(argc),
150  m_Argv(argv),
151 #ifdef Q_OS_MAC
152  m_Argv_macOS(),
153 #endif
154  m_SingleMode(false),
155  m_SafeMode(true),
156  m_Splashscreen(nullptr),
157  m_SplashscreenClosingCallback(nullptr)
158  {
159 #ifdef Q_OS_MAC
160  /* On macOS the process serial number is passed as an command line argument (-psn_<NUMBER>)
161  in certain circumstances. This option causes a Poco exception. We remove it, if present. */
162 
163  m_Argv_macOS.reserve(argc);
164 
165  const char psn[] = "-psn";
166 
167  for (decltype(argc) i = 0; i < argc; ++i)
168  {
169  if (0 == strncmp(argv[i], psn, sizeof(psn)))
170  continue;
171 
172  m_Argv_macOS.push_back(argv[i]);
173  }
174 
175  m_Argc = static_cast<decltype(m_Argc)>(m_Argv_macOS.size());
176  m_Argv = m_Argv_macOS.data();
177 #endif
178  }
179 
180  ~Impl()
181  {
182  delete m_SplashscreenClosingCallback;
183  delete m_Splashscreen;
184  delete m_QApp;
185  }
186 
187  QVariant getProperty(const QString &property) const
188  {
189  auto iter = m_FWProps.find(property);
190 
191  return m_FWProps.end() != iter
192  ? iter.value()
193  : QVariant();
194  }
195 
196  void handleBooleanOption(const std::string &name, const std::string &)
197  {
198  auto fwKey = QString::fromStdString(name);
199 
200  // Translate some keys to proper framework properties
201  if (ARG_CONSOLELOG == fwKey)
202  fwKey = ctkPluginFrameworkLauncher::PROP_CONSOLE_LOG;
203 
204  // For all other options we use the command line option name as the
205  // framework property key.
206  m_FWProps[fwKey] = true;
207  }
208 
209  void handlePreloadLibraryOption(const std::string &, const std::string &value)
210  {
211  m_PreloadLibs.push_back(QString::fromStdString(value));
212  }
213 
214  void handleClean(const std::string &, const std::string &)
215  {
216  m_FWProps[ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN] = ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT;
217  }
218 
219  void initializeCTKPluginFrameworkProperties(Poco::Util::LayeredConfiguration &configuration)
220  {
221  // Add all configuration key/value pairs as framework properties
222  Poco::Util::LayeredConfiguration::Keys keys;
223 
224  Poco::Util::LayeredConfiguration::Keys keyStack;
225  configuration.keys(keyStack);
226 
227  std::vector<std::string> keyChain;
228 
229  while (!keyStack.empty())
230  {
231  const auto currSubKey = keyStack.back();
232 
233  if (!keyChain.empty() && keyChain.back() == currSubKey)
234  {
235  keyChain.pop_back();
236  keyStack.pop_back();
237  continue;
238  }
239 
240  Poco::Util::LayeredConfiguration::Keys subKeys;
241  configuration.keys(currSubKey, subKeys);
242 
243  if (subKeys.empty())
244  {
245  std::string finalKey;
246  keyStack.pop_back();
247 
248  for (const auto key : keyChain)
249  finalKey += key + '.';
250 
251  finalKey += currSubKey;
252  keys.push_back(finalKey);
253  }
254  else
255  {
256  keyChain.push_back(currSubKey);
257 
258  for (const auto key : subKeys)
259  keyStack.push_back(key);
260  }
261  }
262 
263  for (const auto key : keys)
264  {
265  if (configuration.hasProperty(key))
266  {
267  // .ini and command line options overwrite already inserted keys
268  auto qKey = QString::fromStdString(key);
269  m_FWProps[qKey] = QString::fromStdString(configuration.getString(key));
270  }
271  }
272  }
273 
274  void parseProvisioningFile(const QString &filePath)
275  {
276  // Skip parsing if the file path is empty
277  if (filePath.isEmpty())
278  return;
279 
280  auto consoleLog = this->getProperty(ctkPluginFrameworkLauncher::PROP_CONSOLE_LOG).toBool();
281 
282  // Read initial plugins from a provisioning file
283  QFileInfo provFile(filePath);
284  QStringList pluginsToStart;
285 
286  if (provFile.exists())
287  {
288  MITK_INFO(consoleLog) << "Using provisioning file: " << qPrintable(provFile.absoluteFilePath());
289  ProvisioningInfo provInfo(provFile.absoluteFilePath());
290 
291  // It can still happen that the encoding is not compatible with the fromUtf8 function (i.e. when
292  // manipulating the LANG variable). The QStringList in provInfo is empty then.
293  if (provInfo.getPluginDirs().empty())
294  {
295  MITK_ERROR << "Cannot search for provisioning file, the retrieved directory list is empty.\n"
296  << "This can happen if there are some special non-ASCII characters in the install path.";
297  }
298  else
299  {
300  for(const auto pluginPath : provInfo.getPluginDirs())
301  ctkPluginFrameworkLauncher::addSearchPath(pluginPath);
302 
303  auto pluginUrlsToStart = provInfo.getPluginsToStart();
304 
305  for (const auto url : pluginUrlsToStart)
306  pluginsToStart.push_back(url.toString());
307  }
308  }
309  else
310  {
311  MITK_INFO(consoleLog) << "Provisionig file does not exist.";
312  }
313 
314  if (!pluginsToStart.isEmpty())
315  {
316  m_FWProps[ctkPluginFrameworkLauncher::PROP_PLUGINS] = pluginsToStart;
317 
318  // Use transient start with declared activation policy (this helps when the provisioning file
319  // changes and some plug-ins should not be installed in the application any more).
320  ctkPlugin::StartOptions startOptions(ctkPlugin::START_TRANSIENT | ctkPlugin::START_ACTIVATION_POLICY);
321  m_FWProps[ctkPluginFrameworkLauncher::PROP_PLUGINS_START_OPTIONS] = static_cast<int>(startOptions);
322  }
323  }
324  };
325 
326  BaseApplication::BaseApplication(int argc, char **argv)
327  : Application(),
328  d(new Impl(argc, argv))
329  {
330  }
331 
333  {
334  delete d;
335  }
336 
337  void BaseApplication::printHelp(const std::string &, const std::string &)
338  {
339  Poco::Util::HelpFormatter help(this->options());
340  help.setAutoIndent();
341  help.setCommand(this->commandName());
342  help.format(std::cout);
343 
344  exit(EXIT_OK);
345  }
346 
347  void BaseApplication::setApplicationName(const QString &name)
348  {
349  if (nullptr != qApp)
350  qApp->setApplicationName(name);
351 
352  d->m_AppName = name;
353  }
354 
356  {
357  return nullptr != qApp
358  ? qApp->applicationName()
359  : d->m_AppName;
360  }
361 
362  void BaseApplication::setOrganizationName(const QString &name)
363  {
364  if (nullptr != qApp)
365  qApp->setOrganizationName(name);
366 
367  d->m_OrgaName = name;
368  }
369 
371  {
372  return nullptr != qApp
373  ? qApp->organizationName()
374  : d->m_OrgaName;
375  }
376 
377  void BaseApplication::setOrganizationDomain(const QString &domain)
378  {
379  if (nullptr != qApp)
380  qApp->setOrganizationDomain(domain);
381 
382  d->m_OrgaDomain = domain;
383  }
384 
386  {
387  return nullptr != qApp
388  ? qApp->organizationDomain()
389  : d->m_OrgaDomain;
390  }
391 
392  void BaseApplication::setSingleMode(bool singleMode)
393  {
394  if (nullptr != qApp)
395  return;
396 
397  d->m_SingleMode = singleMode;
398  }
399 
401  {
402  return d->m_SingleMode;
403  }
404 
405  void BaseApplication::setSafeMode(bool safeMode)
406  {
407  if (nullptr != qApp && nullptr == d->m_QApp)
408  return;
409 
410  d->m_SafeMode = safeMode;
411 
412  nullptr == d->m_QApp && getSingleMode()
413  ? static_cast<QmitkSingleApplication *>(d->m_QApp)->setSafeMode(safeMode)
414  : static_cast<QmitkSafeApplication *>(d->m_QApp)->setSafeMode(safeMode);
415  }
416 
418  {
419  return d->m_SafeMode;
420  }
421 
422  void BaseApplication::setPreloadLibraries(const QStringList &libraryBaseNames)
423  {
424  d->m_PreloadLibs = libraryBaseNames;
425  }
426 
428  {
429  return d->m_PreloadLibs;
430  }
431 
432  void BaseApplication::setProvisioningFilePath(const QString &filePath)
433  {
434  d->m_ProvFile = filePath;
435  }
436 
438  {
439  auto provFilePath = d->m_ProvFile;
440 
441  // A null QString means look up a default provisioning file
442  if (provFilePath.isNull() && nullptr != qApp)
443  {
444  QFileInfo appFilePath(QCoreApplication::applicationFilePath());
445  QDir basePath(QCoreApplication::applicationDirPath());
446 
447  auto provFileName = appFilePath.baseName() + ".provisioning";
448 
449  QFileInfo provFile(basePath.absoluteFilePath(provFileName));
450 
451 #ifdef Q_OS_MAC
452  /*
453  * On macOS, if started from the build directory, the .provisioning file is located at:
454  * <MITK-build/bin/MitkWorkbench.provisioning>
455  * The executable path is:
456  * <MITK-build/bin/MitkWorkbench.app/Contents/MacOS/MitkWorkbench>
457  * In this case we have to cdUp threetimes.
458  *
459  * During packaging the MitkWorkbench.provisioning file is placed at the same
460  * level like the executable. Nothing has to be done.
461  */
462 
463  if (!provFile.exists())
464  {
465  basePath.cdUp();
466  basePath.cdUp();
467  basePath.cdUp();
468  provFile = basePath.absoluteFilePath(provFileName);
469  }
470 #endif
471 
472  if (provFile.exists())
473  {
474  provFilePath = provFile.absoluteFilePath();
475  }
476 #ifdef CMAKE_INTDIR
477  else
478  {
479  basePath.cdUp();
480  provFile.setFile(basePath.absoluteFilePath(provFileName));
481 
482  if (provFile.exists())
483  provFilePath = provFile.absoluteFilePath();
484  }
485 #endif
486  }
487 
488  return provFilePath;
489  }
490 
492  {
493  if (nullptr != qApp)
494  return;
495 
496  // If parameters have been set before, we have to store them to hand them
497  // through to the application
498  auto appName = this->getApplicationName();
499  auto orgName = this->getOrganizationName();
500  auto orgDomain = this->getOrganizationDomain();
501 
502  // Create a QCoreApplication instance
503  this->getQApplication();
504 
505  // Provide parameters to QCoreApplication
506  this->setApplicationName(appName);
507  this->setOrganizationName(orgName);
508  this->setOrganizationDomain(orgDomain);
509 
510  qInstallMessageHandler(outputQtMessage);
511  }
512 
513  void BaseApplication::initialize(Poco::Util::Application &self)
514  {
515  // 1. Call the super-class method
516  Poco::Util::Application::initialize(self);
517 
518  // 2. Initialize the Qt framework (by creating a QCoreApplication)
519  this->initializeQt();
520 
521  // 3. Seed the random number generator, once at startup.
522  QTime time = QTime::currentTime();
523  qsrand((uint)time.msec());
524 
525  // 4. Load the "default" configuration, which involves parsing
526  // an optional <executable-name>.ini file and parsing any
527  // command line arguments
528  this->loadConfiguration();
529 
530  // 5. Add configuration data from the command line and the
531  // optional <executable-name>.ini file as CTK plugin
532  // framework properties.
533  d->initializeCTKPluginFrameworkProperties(this->config());
534 
535  // 6. Initialize splash screen if an image path is provided
536  // in the .ini file
537  this->initializeSplashScreen(qApp);
538 
539  // 7. Set the custom CTK Plugin Framework storage directory
540  QString storageDir = this->getCTKFrameworkStorageDir();
541 
542  if (!storageDir.isEmpty())
543  d->m_FWProps[ctkPluginConstants::FRAMEWORK_STORAGE] = storageDir;
544 
545  // 8. Set the library search paths and the pre-load library property
546  this->initializeLibraryPaths();
547 
548  auto preloadLibs = this->getPreloadLibraries();
549 
550  if (!preloadLibs.isEmpty())
551  d->m_FWProps[ctkPluginConstants::FRAMEWORK_PRELOAD_LIBRARIES] = preloadLibs;
552 
553  // 9. Initialize the CppMicroServices library.
554  // The initializeCppMicroServices() method reuses the
555  // FRAMEWORK_STORAGE property, so we call it after the
556  // getCTKFrameworkStorageDir method.
557  this->initializeCppMicroServices();
558 
559  // 10. Parse the (optional) provisioning file and set the
560  // correct framework properties.
561  d->parseProvisioningFile(this->getProvisioningFilePath());
562 
563  // 11. Set the CTK Plugin Framework properties
564  ctkPluginFrameworkLauncher::setFrameworkProperties(d->m_FWProps);
565  }
566 
568  {
569  auto pfw = this->getFramework();
570 
571  if (pfw)
572  {
573  pfw->stop();
574  // Wait for up to 10 seconds for the CTK plugin framework to stop
575  pfw->waitForStop(10000);
576  }
577 
578  Poco::Util::Application::uninitialize();
579  }
580 
582  {
583  return d->m_Argc;
584  }
585 
587  {
588  return d->m_Argv;
589  }
590 
592  {
593  QString storageDir;
594 
595  if (this->getSingleMode())
596  {
597  // This function checks if an instance is already running and either sends a message to
598  // it containing the command line arguments or checks if a new instance was forced by
599  // providing the BlueBerry.newInstance command line argument. In the latter case, a path
600  // to a temporary directory for the new application's storage directory is returned.
601  storageDir = handleNewAppInstance(static_cast<QtSingleApplication *>(d->m_QApp),
602  d->m_Argc, d->m_Argv, ARG_NEWINSTANCE);
603  }
604 
605  if (storageDir.isEmpty())
606  {
607  // This is a new instance and no other instance is already running. We specify the
608  // storage directory here (this is the same code as in berryInternalPlatform.cpp)
609  // so that we can re-use the location for the persistent data location of the
610  // the CppMicroServices library.
611 
612  // Append a hash value of the absolute path of the executable to the data location.
613  // This allows to start the same application from different build or install trees.
614  storageDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/" +
615  this->getOrganizationName() + "/" + this->getApplicationName() + '_';
616  storageDir += QString::number(qHash(QCoreApplication::applicationDirPath())) + "/";
617  }
618 
619  return storageDir;
620  }
621 
623  {
624  auto storageDir = this->getProperty(ctkPluginConstants::FRAMEWORK_STORAGE).toString();
625 
626  if (!storageDir.isEmpty())
627  us::ModuleSettings::SetStoragePath((storageDir + "us" + QDir::separator()).toStdString());
628  }
629 
630  QCoreApplication *BaseApplication::getQApplication() const
631  {
632  if (nullptr == qApp)
633  {
634  vtkOpenGLRenderWindow::SetGlobalMaximumNumberOfMultiSamples(0);
635 
636  auto defaultFormat = QVTKOpenGLWidget::defaultFormat();
637  defaultFormat.setSamples(0);
638  QSurfaceFormat::setDefaultFormat(defaultFormat);
639 
640 #ifdef Q_OS_OSX
641  QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings);
642 #endif
643 
644  QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
645 
646  d->m_QApp = this->getSingleMode()
647  ? static_cast<QCoreApplication*>(new QmitkSingleApplication(d->m_Argc, d->m_Argv, this->getSafeMode()))
648  : static_cast<QCoreApplication*>(new QmitkSafeApplication(d->m_Argc, d->m_Argv, this->getSafeMode()));
649  }
650 
651  return qApp;
652  }
653 
655  {
656  QStringList suffixes;
657  suffixes << "plugins";
658 
659 #ifdef Q_OS_WINDOWS
660  suffixes << "bin/plugins";
661  #ifdef CMAKE_INTDIR
662  suffixes << "bin/" CMAKE_INTDIR "/plugins";
663  #endif
664 #else
665  suffixes << "lib/plugins";
666  #ifdef CMAKE_INTDIR
667  suffixes << "lib/" CMAKE_INTDIR "/plugins";
668  #endif
669 #endif
670 
671 #ifdef Q_OS_MAC
672  suffixes << "../../plugins";
673 #endif
674 
675  // We add a couple of standard library search paths for plug-ins
676  QDir appDir(QCoreApplication::applicationDirPath());
677 
678  // Walk one directory up and add bin and lib sub-dirs; this might be redundant
679  appDir.cdUp();
680 
681  for (const auto suffix : suffixes)
682  ctkPluginFrameworkLauncher::addSearchPath(appDir.absoluteFilePath(suffix));
683  }
684 
685  int BaseApplication::main(const std::vector<std::string> &args)
686  {
687  // Start the plugin framework and all installed plug-ins according to their auto-start setting
688  QStringList arguments;
689 
690  for (auto const &arg : args)
691  arguments.push_back(QString::fromStdString(arg));
692 
693  if (nullptr != d->m_Splashscreen)
694  {
695  // A splash screen is displayed. Create the closing callback.
696  d->m_SplashscreenClosingCallback = new SplashCloserCallback(d->m_Splashscreen);
697  }
698 
699  return ctkPluginFrameworkLauncher::run(d->m_SplashscreenClosingCallback, QVariant::fromValue(arguments)).toInt();
700  }
701 
702  void BaseApplication::defineOptions(Poco::Util::OptionSet &options)
703  {
704  Poco::Util::Option helpOption("help", "h", "print this help text");
705  helpOption.callback(Poco::Util::OptionCallback<BaseApplication>(this, &BaseApplication::printHelp));
706  options.addOption(helpOption);
707 
708  Poco::Util::Option newInstanceOption(ARG_NEWINSTANCE.toStdString(), "", "forces a new instance of this application");
709  newInstanceOption.callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handleBooleanOption));
710  options.addOption(newInstanceOption);
711 
712  Poco::Util::Option cleanOption(ARG_CLEAN.toStdString(), "", "cleans the plugin cache");
713  cleanOption.callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handleClean));
714  options.addOption(cleanOption);
715 
716  Poco::Util::Option productOption(ARG_PRODUCT.toStdString(), "", "the id of the product to be launched");
717  productOption.argument("<id>").binding(PROP_PRODUCT.toStdString());
718  options.addOption(productOption);
719 
720  Poco::Util::Option appOption(ARG_APPLICATION.toStdString(), "", "the id of the application extension to be executed");
721  appOption.argument("<id>").binding(PROP_APPLICATION.toStdString());
722  options.addOption(appOption);
723 
724  Poco::Util::Option provOption(ARG_PROVISIONING.toStdString(), "", "the location of a provisioning file");
725  provOption.argument("<prov file>").binding(ARG_PROVISIONING.toStdString());
726  options.addOption(provOption);
727 
728  Poco::Util::Option storageDirOption(ARG_STORAGE_DIR.toStdString(), "", "the location for storing persistent application data");
729  storageDirOption.argument("<dir>").binding(ctkPluginConstants::FRAMEWORK_STORAGE.toStdString());
730  options.addOption(storageDirOption);
731 
732  Poco::Util::Option consoleLogOption(ARG_CONSOLELOG.toStdString(), "", "log messages to the console");
733  consoleLogOption.callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handleBooleanOption));
734  options.addOption(consoleLogOption);
735 
736  Poco::Util::Option debugOption(ARG_DEBUG.toStdString(), "", "enable debug mode");
737  debugOption.argument("<options file>", false).binding(ctkPluginFrameworkLauncher::PROP_DEBUG.toStdString());
738  options.addOption(debugOption);
739 
740  Poco::Util::Option forcePluginOption(ARG_FORCE_PLUGIN_INSTALL.toStdString(), "", "force installing plug-ins with same symbolic name");
741  forcePluginOption.callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handleBooleanOption));
742  options.addOption(forcePluginOption);
743 
744  Poco::Util::Option preloadLibsOption(ARG_PRELOAD_LIBRARY.toStdString(), "", "preload a library");
745  preloadLibsOption.argument("<library>")
746  .repeatable(true)
747  .callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handlePreloadLibraryOption));
748  options.addOption(preloadLibsOption);
749 
750  Poco::Util::Option noRegistryCacheOption(ARG_NO_REGISTRY_CACHE.toStdString(), "", "do not use a cache for the registry");
751  noRegistryCacheOption.callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handleBooleanOption));
752  options.addOption(noRegistryCacheOption);
753 
754  Poco::Util::Option noLazyRegistryCacheLoadingOption(ARG_NO_LAZY_REGISTRY_CACHE_LOADING.toStdString(), "", "do not use lazy cache loading for the registry");
755  noLazyRegistryCacheLoadingOption.callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handleBooleanOption));
756  options.addOption(noLazyRegistryCacheLoadingOption);
757 
758  Poco::Util::Option registryMultiLanguageOption(ARG_REGISTRY_MULTI_LANGUAGE.toStdString(), "", "enable multi-language support for the registry");
759  registryMultiLanguageOption.callback(Poco::Util::OptionCallback<Impl>(d, &Impl::handleBooleanOption));
760  options.addOption(registryMultiLanguageOption);
761 
762  Poco::Util::Option splashScreenOption(ARG_SPLASH_IMAGE.toStdString(), "", "optional picture to use as a splash screen");
763  splashScreenOption.argument("<filename>").binding(ARG_SPLASH_IMAGE.toStdString());
764  options.addOption(splashScreenOption);
765 
766  Poco::Util::Option xargsOption(ARG_XARGS.toStdString(), "", "Extended argument list");
767  xargsOption.argument("<args>").binding(ARG_XARGS.toStdString());
768  options.addOption(xargsOption);
769 
770  Poco::Util::Application::defineOptions(options);
771  }
772 
774  {
775  return ctkPluginFrameworkLauncher::getPluginFramework();
776  }
777 
778  ctkPluginContext *BaseApplication::getFrameworkContext() const
779  {
780  auto framework = getFramework();
781 
782  return framework
783  ? framework->getPluginContext()
784  : nullptr;
785  }
786 
787  void BaseApplication::initializeSplashScreen(QCoreApplication * application) const
788  {
789  auto pixmapFileNameProp = d->getProperty(ARG_SPLASH_IMAGE);
790 
791  if (!pixmapFileNameProp.isNull())
792  {
793  auto pixmapFileName = pixmapFileNameProp.toString();
794  QFileInfo checkFile(pixmapFileName);
795 
796  if (checkFile.exists() && checkFile.isFile())
797  {
798  QPixmap pixmap(checkFile.absoluteFilePath());
799 
800  d->m_Splashscreen = new QSplashScreen(pixmap, Qt::WindowStaysOnTopHint);
801  d->m_Splashscreen->show();
802 
803  application->processEvents();
804  }
805  }
806  }
807 
808  QHash<QString, QVariant> BaseApplication::getFrameworkProperties() const
809  {
810  return d->m_FWProps;
811  }
812 
814  {
815  this->init(d->m_Argc, d->m_Argv);
816  return Application::run();
817  }
818 
819  void BaseApplication::setProperty(const QString &property, const QVariant &value)
820  {
821  d->m_FWProps[property] = value;
822  }
823 
824  QVariant BaseApplication::getProperty(const QString &property) const
825  {
826  return d->getProperty(property);
827  }
828 
829  void BaseApplication::installTranslator(QTranslator* translator)
830  {
831  this->getQApplication()->installTranslator(translator);
832  }
833 
835  {
836  auto app = dynamic_cast<QtSingleApplication*>(this->getQApplication());
837 
838  if (nullptr != app)
839  app->isRunning();
840 
841  mitkThrow() << "Method not implemented.";
842  }
843 
844  void BaseApplication::sendMessage(const QByteArray msg)
845  {
846  auto app = dynamic_cast<QtSingleApplication*>(this->getQApplication());
847 
848  if (nullptr != app)
849  app->sendMessage(msg);
850 
851  mitkThrow() << "Method not implemented.";
852  }
853 }
virtual QString getCTKFrameworkStorageDir() const
static const QString ARG_DEBUG
void setPreloadLibraries(const QStringList &libraryBaseNames)
void setOrganizationDomain(const QString &name)
void setSafeMode(bool safeMode)
#define MITK_INFO
Definition: mitkLogMacros.h:18
static const QString ARG_CONSOLELOG
void initializeSplashScreen(QCoreApplication *application) const
QString getApplicationName() const
QStringList getPreloadLibraries() const
#define MITK_ERROR
Definition: mitkLogMacros.h:20
static const QString ARG_REGISTRY_MULTI_LANGUAGE
static const QString ARG_CLEAN
static const QString ARG_PLUGIN_CACHE
#define MITK_DEBUG
Definition: mitkLogMacros.h:22
static const QString ARG_XARGS
DataCollection - Class to facilitate loading/accessing structured data.
QSharedPointer< ctkPluginFramework > getFramework() const
QVariant getProperty(const QString &property) const
static const QString PROP_REGISTRY_MULTI_LANGUAGE
static const QString PROP_APPLICATION
static const QString PROP_NO_REGISTRY_CACHE
static const QString ARG_SPLASH_IMAGE
static const QString ARG_NO_REGISTRY_CACHE
static const QString ARG_PRELOAD_LIBRARY
void setProperty(const QString &property, const QVariant &value)
The custom viewer plugin implements simple viewer functionality presented in a customized look and feel It was developed to demonstrate extensibility and customizability of the blueberry application framework As an example for the GUI customization capabilities provided by the BlueBerry application framework
ctkPluginContext * getFrameworkContext() const
static const QString ARG_NEWINSTANCE
#define MITK_WARN
Definition: mitkLogMacros.h:19
void initialize(Poco::Util::Application &self) override
static const QString ARG_HOME
void setOrganizationName(const QString &name)
void setSingleMode(bool singleMode)
void defineOptions(Poco::Util::OptionSet &options) override
#define mitkThrow()
static const QString ARG_PLUGIN_DIRS
void setProvisioningFilePath(const QString &filePath)
static const QString ARG_FORCE_PLUGIN_INSTALL
void sendMessage(const QByteArray)
unsigned int uint
static const QString ARG_PRODUCT
static const QString PROP_PRODUCT
static const QString ARG_APPLICATION
static const QString PROP_NEWINSTANCE
BaseApplication(int argc, char **argv)
void installTranslator(QTranslator *)
void setApplicationName(const QString &name)
static const QString PROP_NO_LAZY_REGISTRY_CACHE_LOADING
static const QString ARG_PROVISIONING
static const QString ARG_NO_LAZY_REGISTRY_CACHE_LOADING
virtual void initializeCppMicroServices()
QHash< QString, QVariant > getFrameworkProperties() const
QString getOrganizationName() const
QString getOrganizationDomain() const
virtual void initializeLibraryPaths()
virtual QCoreApplication * getQApplication() const
int main(const std::vector< std::string > &args) override
static const QString ARG_STORAGE_DIR
static void SetStoragePath(const std::string &path)
void printHelp(const std::string &name, const std::string &value)
QString getProvisioningFilePath() const
static const QString PROP_FORCE_PLUGIN_INSTALL
uint qHash(const berry::Object &o)