Medical Imaging Interaction Toolkit  2018.4.99-87d68d9f
Medical Imaging Interaction Toolkit
berryWorkbenchPlugin.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 "berryLog.h"
14 
15 #include "berryWorkbenchPlugin.h"
16 
17 #include "internal/berryWorkbenchRegistryConstants.h"
18 #include "internal/berryWorkbench.h"
19 #include "berryPlatform.h"
20 
21 #include "internal/intro/berryEditorIntroAdapterPart.h"
22 #include "internal/defaultpresentation/berryQtWorkbenchPresentationFactory.h"
23 
24 #include "berryQtStyleManager.h"
25 
26 #include "berryExtensionFactory.h"
27 #include "internal/berryQtWorkbenchTweaklet.h"
28 #include "internal/berryQtWorkbenchPageTweaklet.h"
29 #include "internal/berryQtWidgetsTweaklet.h"
30 #include "internal/dialogs/berryPerspectivesPreferencePage.h"
31 #include "internal/berryQtStylePreferencePage.h"
32 #include "internal/berryStatusUtil.h"
33 #include "internal/berryHandlerServiceFactory.h"
34 #include "internal/berryMenuServiceFactory.h"
35 #include "internal/berryCommandServiceFactory.h"
36 #include "internal/berryWorkbenchSourceProvider.h"
37 #include "berryObjectString.h"
38 #include "berryObjects.h"
39 #include "internal/berryPolicy.h"
40 #include "internal/berryHandlerAuthority.h"
41 
42 #include "internal/berryOpenPerspectivePropertyTester.h"
43 #include "internal/berryPerspectiveParameterValues.h"
44 
45 #include "internal/handlers/berryCloseAllPerspectivesHandler.h"
46 #include "internal/handlers/berryClosePerspectiveHandler.h"
47 #include "internal/handlers/berryDynamicHelpHandler.h"
48 #include "internal/handlers/berryHelpContentsHandler.h"
49 #include "internal/handlers/berryIntroHandler.h"
50 #include "internal/handlers/berryOpenInNewWindowHandler.h"
51 #include "internal/handlers/berryNewEditorHandler.h"
52 #include "internal/handlers/berryQuitHandler.h"
53 #include "internal/handlers/berryResetPerspectiveHandler.h"
54 #include "internal/handlers/berrySavePerspectiveHandler.h"
55 #include "internal/handlers/berryShowPerspectiveHandler.h"
56 #include "internal/handlers/berryShowViewHandler.h"
57 
58 #include "berryIQtStyleManager.h"
59 #include "berryIContributor.h"
60 #include "berryILog.h"
61 #include "berryIElementFactory.h"
62 
63 #include "berryIExtension.h"
64 
65 #include <QDebug>
66 #include <QPrinterInfo>
67 #include <QSvgGenerator>
68 
69 namespace berry
70 {
71 
72 bool WorkbenchPlugin::DEBUG = false;
73 
75 
76 WorkbenchPlugin* WorkbenchPlugin::inst = nullptr;
77 
80 {
81  inst = this;
82  presentationFactory = nullptr;
83  editorRegistry = nullptr;
84  viewRegistry = nullptr;
85  perspRegistry = nullptr;
86  introRegistry = nullptr;
87 }
88 
90 {
91  delete presentationFactory;
92  delete editorRegistry;
93  delete viewRegistry;
94  delete perspRegistry;
95  delete introRegistry;
96 
97  inst = nullptr;
98 }
99 
101  const IConfigurationElement::Pointer& element, const QString& extensionName)
102 {
103  if (!element->GetAttribute(extensionName).isNull()) return true;
104 
105  QString elementText = element->GetValue();
106  if (!elementText.isEmpty()) return true;
107 
108  QList<IConfigurationElement::Pointer> children(element->GetChildren(extensionName));
109  if (children.size() == 1)
110  {
111  if (!(children[0]->GetAttribute(WorkbenchRegistryConstants::ATT_CLASS).isNull()))
112  return true;
113  }
114  return false;
115 }
116 
118  const IConfigurationElement::Pointer& element, const QString& extensionName)
119 {
121 
122  if (plugin.isNull())
123  return true;
124  return plugin->getState() == ctkPlugin::ACTIVE;
125 }
126 
128  const IConfigurationElement::Pointer& element, const QString& extensionName)
129 {
130  // this code is derived heavily from
131  // ConfigurationElement.createExecutableExtension.
132  QString prop;
133  QString executable;
134  QString contributorName;
135  int i = 0;
136 
137  if (!extensionName.isNull())
138  prop = element->GetAttribute(extensionName);
139  else
140  {
141  // property not specified, try as element value
142  prop = element->GetValue();
143  if (!prop.isNull())
144  {
145  prop = prop.trimmed();
146  if (prop.isEmpty())
147  prop = QString();
148  }
149  }
150 
151  if (prop.isNull())
152  {
153  // property not defined, try as a child element
154  QList<IConfigurationElement::Pointer> exec(element->GetChildren(extensionName));
155  if (!exec.isEmpty())
156  contributorName = exec[0]->GetAttribute("plugin");
157  }
158  else
159  {
160  // simple property or element value, parse it into its components
161  i = prop.indexOf(':');
162  if (i != -1)
163  executable = prop.left(i).trimmed();
164  else
165  executable = prop;
166 
167  i = executable.indexOf('/');
168  if (i != -1)
169  contributorName = executable.left(i).trimmed();
170  }
171 
172  if (contributorName.isNull())
173  contributorName = element->GetContributor()->GetName();
174 
175  return Platform::GetPlugin(contributorName);
176 }
177 
179 {
180  return inst;
181 }
182 
184 {
185  // TODO BundleContext GetBundles
186  //return bundleContext->GetBundles().size();
187  return 0;
188 }
189 
191 {
192  if (perspRegistry == nullptr)
193  {
194  perspRegistry = new PerspectiveRegistry();
195 
196  // the load methods can touch on WorkbenchImages if an image is
197  // missing so we need to wrap the call in
198  // a startup block for the case where a custom descriptor exists on
199  // startup that does not have an image
200  // associated with it. See bug 196352.
201  //StartupThreading.runWithoutExceptions(new StartupRunnable() {
202  // public void runWithException() throws Throwable {
203  perspRegistry->Load();
204  // }
205  //});
206  }
207  return perspRegistry;
208 }
209 
210 // PreferenceManager getPreferenceManager() {
211 // if (preferenceManager == null) {
212 // preferenceManager = new WorkbenchPreferenceManager(
213 // PREFERENCE_PAGE_CATEGORY_SEPARATOR);
214 //
215 // //Get the pages from the registry
216 // PreferencePageRegistryReader registryReader = new PreferencePageRegistryReader(
217 // getWorkbench());
218 // registryReader
219 // .loadFromRegistry(Platform.getExtensionRegistry());
220 // preferenceManager.addPages(registryReader.getTopLevelNodes());
221 //
222 // }
223 // return preferenceManager;
224 // }
225 
227 {
228  if (introRegistry == nullptr)
229  {
230  introRegistry = new IntroRegistry();
231  }
232  return introRegistry;
233 }
234 
236 {
237  if (!viewRegistry)
238  viewRegistry = new ViewRegistry();
239 
240  return viewRegistry;
241 }
242 
244 {
245  if (!editorRegistry)
246  editorRegistry = new EditorRegistry();
247 
248  return editorRegistry;
249 }
250 
252 {
253  // Get the extension point registry.
256  WorkbenchRegistryConstants::PL_ELEMENT_FACTORY);
257 
258  IElementFactory* factory = nullptr;
259  if (!extensionPoint)
260  {
261  WorkbenchPlugin::Log("Unable to find element factory. Extension point: " +
262  WorkbenchRegistryConstants::PL_ELEMENT_FACTORY + " not found");
263  return factory;
264  }
265 
266  // Loop through the config elements.
267  IConfigurationElement::Pointer targetElement;
268  QList<IConfigurationElement::Pointer> configElements =
269  extensionPoint->GetConfigurationElements();
270  for (int j = 0; j < configElements.size(); j++)
271  {
272  QString strID = configElements[j]->GetAttribute("id");
273  if (targetID == strID)
274  {
275  targetElement = configElements[j];
276  break;
277  }
278  }
279  if (!targetElement)
280  {
281  // log it since we cannot safely display a dialog.
282  WorkbenchPlugin::Log("Unable to find element factory: " + targetID);
283  return factory;
284  }
285 
286  // Create the extension.
287  try
288  {
289  factory = targetElement->CreateExecutableExtension<IElementFactory>("class");
290  }
291  catch (const CoreException& e)
292  {
293  // log it since we cannot safely display a dialog.
294  WorkbenchPlugin::Log("Unable to create element factory.", e.GetStatus());
295  factory = nullptr;
296  }
297  return factory;
298 }
299 
301  if (presentationFactory != nullptr) return presentationFactory;
302 
303  QString targetID = Workbench::GetInstance()->GetPresentationId();
304  presentationFactory = this->CreateExtension<IPresentationFactory>(
305  WorkbenchRegistryConstants::PL_PRESENTATION_FACTORIES,
306  "factory", targetID);
307  if (presentationFactory == nullptr)
308  WorkbenchPlugin::Log("Error creating presentation factory: " +
309  targetID + " -- class is not an IPresentationFactory");
310 
311  return presentationFactory;
312 }
313 
314 void WorkbenchPlugin::Log(const QString& message)
315 {
316  BERRY_INFO << "LOG: " << message << std::endl;
317  //inst->GetLog().log(message);
318 }
319 
320 void WorkbenchPlugin::Log(const ctkException &exc)
321 {
322  QString str;
323  QDebug dbg(&str);
324  dbg << exc.printStackTrace();
325  BERRY_INFO << "LOG: " << str << std::endl;
326  //inst->GetLog().log(exc);
327 }
328 
329 
330 void WorkbenchPlugin::Log(const QString& message, const ctkException &t)
331 {
332  PlatformException exc(message, t);
334 }
335 
336 void WorkbenchPlugin::Log(const QString& clazz,
337  const QString& methodName, const ctkException &t)
338 {
339  QString msg = QString("Exception in ") + clazz + "." + methodName + ": "
340  + t.what();
341 
342  WorkbenchPlugin::Log(msg, t);
343 }
344 
345 void WorkbenchPlugin::Log(const QString& message, const SmartPointer<IStatus>& status)
346 {
347  //1FTUHE0: ITPCORE:ALL - API - Status & logging - loss of semantic info
348 
349  if (!message.isEmpty())
350  {
351  GetDefault()->GetLog()->Log(StatusUtil::NewStatus(IStatus::ERROR_TYPE, message, BERRY_STATUS_LOC));
352  }
353 
354  GetDefault()->GetLog()->Log(status);
355 }
356 
358 {
359  GetDefault()->GetLog()->Log(status);
360 }
361 
362 void WorkbenchPlugin::start(ctkPluginContext* context)
363 {
364  // Dummy code to force linkage to Qt5PrintSupport (issue with GCC 7.3)
365  QPrinterInfo forceQt5PrintSupportLinkage;
366  forceQt5PrintSupportLinkage.isNull();
367 
368  // Same for Qt5Svg
369  QSvgGenerator forceQt5SvgLinkage;
370  forceQt5SvgLinkage.title();
371 
372  //context.addBundleListener(getBundleListener());
374  bundleContext = context;
375 
376  AbstractSourceProvider::DEBUG = Policy::DEBUG_SOURCES();
377 
378  HandlerAuthority::DEBUG = Policy::DEBUG_HANDLERS();
379  HandlerAuthority::DEBUG_PERFORMANCE = Policy::DEBUG_HANDLERS_PERFORMANCE();
380  HandlerAuthority::DEBUG_VERBOSE = Policy::DEBUG_HANDLERS_VERBOSE();
381  HandlerAuthority::DEBUG_VERBOSE_COMMAND_ID = Policy::DEBUG_HANDLERS_VERBOSE_COMMAND_ID();
382 
383  BERRY_REGISTER_EXTENSION_CLASS(EditorIntroAdapterPart, context)
384 
386 
387  BERRY_REGISTER_EXTENSION_CLASS(QtWidgetsTweaklet, context)
388  BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchTweaklet, context)
389  BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchPageTweaklet, context)
390  BERRY_REGISTER_EXTENSION_CLASS(QtWorkbenchPresentationFactory, context)
391 
392  BERRY_REGISTER_EXTENSION_CLASS(PerspectivesPreferencePage, context)
393  BERRY_REGISTER_EXTENSION_CLASS(QtStylePreferencePage, context)
394 
395  BERRY_REGISTER_EXTENSION_CLASS(HandlerServiceFactory, context)
396  BERRY_REGISTER_EXTENSION_CLASS(MenuServiceFactory, context)
397  BERRY_REGISTER_EXTENSION_CLASS(CommandServiceFactory, context)
398 
399  BERRY_REGISTER_EXTENSION_CLASS(WorkbenchSourceProvider, context)
400 
401  BERRY_REGISTER_EXTENSION_CLASS(OpenPerspectivePropertyTester, context)
402  BERRY_REGISTER_EXTENSION_CLASS(PerspectiveParameterValues, context)
403 
404  BERRY_REGISTER_EXTENSION_CLASS(HelpContentsHandler, context)
405  BERRY_REGISTER_EXTENSION_CLASS(DynamicHelpHandler, context)
406  BERRY_REGISTER_EXTENSION_CLASS(IntroHandler, context)
407  BERRY_REGISTER_EXTENSION_CLASS(OpenInNewWindowHandler, context)
408  BERRY_REGISTER_EXTENSION_CLASS(NewEditorHandler, context)
409  BERRY_REGISTER_EXTENSION_CLASS(QuitHandler, context)
410  BERRY_REGISTER_EXTENSION_CLASS(ShowPerspectiveHandler, context)
411  BERRY_REGISTER_EXTENSION_CLASS(ShowViewHandler, context)
412  BERRY_REGISTER_EXTENSION_CLASS(SavePerspectiveHandler, context)
413  BERRY_REGISTER_EXTENSION_CLASS(ClosePerspectiveHandler, context)
414  BERRY_REGISTER_EXTENSION_CLASS(CloseAllPerspectivesHandler, context)
415  BERRY_REGISTER_EXTENSION_CLASS(ResetPerspectiveHandler, context)
416 
417  styleManager.reset(new QtStyleManager());
418  context->registerService<berry::IQtStyleManager>(styleManager.data());
419 
420  // The UI plugin needs to be initialized so that it can install the callback in PrefUtil,
421  // which needs to be done as early as possible, before the workbench
422  // accesses any API preferences.
423 // Bundle uiBundle = Platform.getBundle(PlatformUI.PLUGIN_ID);
424 // try
425 // {
426 // // Attempt to load the activator of the ui bundle. This will force lazy start
427 // // of the ui bundle. Using the bundle activator class here because it is a
428 // // class that needs to be loaded anyway so it should not cause extra classes
429 // // to be loaded.
430 // if(uiBundle != null)
431 // uiBundle.loadClass(UI_BUNDLE_ACTIVATOR);
432 // }
433 // catch (ClassNotFoundException e)
434 // {
435 // WorkbenchPlugin.log("Unable to load UI activator", e); //$NON-NLS-1$
436 // }
437  /*
438  * DO NOT RUN ANY OTHER CODE AFTER THIS LINE. If you do, then you are
439  * likely to cause a deadlock in class loader code. Please see Bug 86450
440  * for more information.
441  */
442 
443 }
444 
445 //const QList<IBundle::Pointer> WorkbenchPlugin::GetBundles()
446 //{
447 // return bundleContext.IsNull() ? QList<IBundle::Pointer>() : bundleContext->GetBundles();
448 //}
449 
451 {
452  return bundleContext;
453 }
454 
455 void WorkbenchPlugin::stop(ctkPluginContext* context)
456 {
457  AbstractUICTKPlugin::stop(context);
458 
459  styleManager.reset();
460 
461  delete perspRegistry;
462  // avoid possible crash, see bug #18399
463  perspRegistry = nullptr;
464 }
465 
467 {
468  QFileInfo fileInfo = bundleContext->getDataFile("");
469  if (!fileInfo.isWritable()) return QString();
470  return fileInfo.absoluteFilePath();
471 }
472 
473 }
static bool IsBundleLoadedForExecutableExtension(const IConfigurationElement::Pointer &element, const QString &extensionName)
static void Log(const QString &message)
ctkPluginContext * GetPluginContext()
virtual SmartPointer< IExtensionPoint > GetExtensionPoint(const QString &extensionPointId) const =0
static char PREFERENCE_PAGE_CATEGORY_SEPARATOR
static WorkbenchPlugin * GetDefault()
SmartPointer< IStatus > GetStatus() const
IIntroRegistry * GetIntroRegistry()
void stop(ctkPluginContext *context) override
static QSharedPointer< ctkPlugin > GetBundleForExecutableExtension(const IConfigurationElement::Pointer &element, const QString &extensionName)
#define BERRY_STATUS_LOC
Definition: berryStatus.h:253
ILog * GetLog() const
Definition: berryPlugin.cpp:38
IEditorRegistry * GetEditorRegistry()
std::vcl_size_t GetBundleCount()
#define BERRY_INFO
Definition: berryLog.h:20
void start(ctkPluginContext *context) override
static QString PLUGIN_ID()
static IExtensionRegistry * GetExtensionRegistry()
void stop(ctkPluginContext *context) override
static QSharedPointer< ctkPlugin > GetPlugin(const QString &symbolicName)
IElementFactory * GetElementFactory(const QString &targetID) const
IPresentationFactory * GetPresentationFactory()
#define BERRY_REGISTER_EXTENSION_CLASS(_ClassType, _PluginContext)
Definition: berryMacros.h:80
IPerspectiveRegistry * GetPerspectiveRegistry()
#define GetAttribute(name, type)
IViewRegistry * GetViewRegistry()
virtual void Log(const SmartPointer< IStatus > &status)=0
void start(ctkPluginContext *context) override
static bool HasExecutableExtension(const IConfigurationElement::Pointer &element, const QString &extensionName)