Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
berryCommandContributionItem.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 BlueBerry Platform
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include "berryIMenuService.h"
20 #include "berryICommandService.h"
23 #include "berryIElementReference.h"
24 #include "berryIElementUpdater.h"
25 #include "berryUIElement.h"
26 
27 #include <berryICommandListener.h>
29 #include <berryIHandler.h>
30 #include <berryCommand.h>
31 #include <berryCommandEvent.h>
33 #include <berryCommandExceptions.h>
35 
36 #include "../berryDisplay.h"
37 #include "../berryAsyncRunnable.h"
38 
39 #include "../handlers/berryIHandlerService.h"
40 #include "../services/berryIServiceLocator.h"
41 
42 #include "../internal/berryWorkbenchPlugin.h"
43 
44 #include <QMenu>
45 #include <QMenuBar>
46 #include <QToolBar>
47 #include <QApplication>
48 
49 #include <QMetaMethod>
50 
51 namespace berry
52 {
53 
54 ContributionItem::Modes CommandContributionItem::modes = ContributionItem::MODE_FORCE_TEXT;
55 
56 
57 //class CommandUIElementListener : public IUIElementListener
58 //{
59 //private:
60 // CommandContributionItem* item;
61 
62 // public:
63 
64 // CommandUIElementListener(CommandContributionItem* item);
65 
66 // void UIElementDisposed(UIElement* item);
67 
68 //void UIElementSelected(SmartPointer<UIElement> item);
69 //};
70 
71 
73  const SmartPointer<CommandContributionItemParameter>& contributionParameters)
74  : ContributionItem(contributionParameters->id)
75  , action(nullptr)
76  , checkedState(false)
77 {
78  this->icon = contributionParameters->icon;
79  this->label = contributionParameters->label;
80  this->mnemonic = contributionParameters->mnemonic;
81  this->shortcut = contributionParameters->shortcut;
82  this->tooltip = contributionParameters->tooltip;
83  this->style = contributionParameters->style;
84  this->helpContextId = contributionParameters->helpContextId;
85  this->visibleEnabled = contributionParameters->visibleEnabled;
86  this->mode = contributionParameters->mode;
87 
88  menuService = contributionParameters->serviceLocator->GetService<IMenuService>();
89  commandService = contributionParameters->serviceLocator->GetService<ICommandService>();
90  handlerService = contributionParameters->serviceLocator->GetService<IHandlerService>();
91  // bindingService = (IBindingService) contributionParameters.serviceLocator
92  // .getService(IBindingService.class);
93 
94  this->CreateCommand(contributionParameters->commandId,
95  contributionParameters->parameters);
96 
97  if (command)
98  {
99  try
100  {
101  class CommandUIElement : public UIElement
102  {
103 
104  private:
106 
107  public:
108 
109  CommandUIElement(CommandContributionItem* item, IServiceLocator* serviceLocator)
110  : UIElement(serviceLocator), item(item) {}
111 
112  void SetText(const QString& text) override
113  {
114  item->SetText(text);
115  }
116 
117  void SetToolTip(const QString& text) override
118  {
119  item->SetToolTip(text);
120  }
121 
122  void SetIcon(const QIcon& icon) override
123  {
124  item->SetIcon(icon);
125  }
126 
127  void SetChecked(bool checked) override
128  {
129  item->SetChecked(checked);
130  }
131 
132  void SetDropDownId(const QString& id) override
133  {
134  item->dropDownMenuOverride = id;
135  }
136 
137  };
138 
139  UIElement::Pointer callback(new CommandUIElement(this,
140  contributionParameters->serviceLocator));
141 
142  elementRef = commandService->RegisterElementForCommand(command, callback);
143  command->GetCommand()->AddCommandListener(this->GetCommandListener());
144  this->SetImages(contributionParameters->serviceLocator,
145  contributionParameters->iconStyle);
146 
147  if (contributionParameters->helpContextId.isEmpty())
148  {
149  try
150  {
151  this->helpContextId = commandService->GetHelpContextId(
152  contributionParameters->commandId);
153  }
154  catch (const NotDefinedException& /*e*/)
155  {
156  // it's OK to not have a helpContextId
157  }
158  }
159  // IWorkbenchLocationService::Pointer wls = contributionParameters.serviceLocator
160  // ->GetService(IWorkbenchLocationService::GetManifestName()).Cast<IWorkbenchLocationService>();
161  // const IWorkbench* workbench = wls->GetWorkbench();;
162  // if (workbench != 0 && !helpContextId.empty()) {
163  // this->workbenchHelpSystem = workbench->GetHelpSystem();
164  // }
165  }
166  catch (const NotDefinedException& /*e*/)
167  {
168  WorkbenchPlugin::Log(QString("Unable to register menu item \"") + this->GetId()
169  + "\", command \"" + contributionParameters->commandId
170  + "\" not defined");
171  }
172  }
173 }
174 
175 void CommandContributionItem::Fill(QMenu* parent, QAction* before)
176 {
177  if (!command || action || parent == nullptr)
178  {
179  return;
180  }
181 
182  // Menus don't support the pulldown style
183  Style tmpStyle = style;
184  if (tmpStyle == STYLE_PULLDOWN)
185  tmpStyle = STYLE_PUSH;
186 
187  QAction* item = nullptr;
188  if (before)
189  {
190  item = new QAction(icon, label, parent);
191  parent->insertAction(before, item);
192  }
193  else
194  {
195  item = parent->addAction(icon, label);
196  }
197 
198  // Remove this when key binding support is fully implemented
199  if (!shortcut.isEmpty())
200  {
201  item->setShortcut(shortcut);
202  }
203  item->setData(QVariant::fromValue(Object::Pointer(this)));
204  item->setProperty("contributionItem", QVariant::fromValue(Object::Pointer(this)));
205 
206  // if (workbenchHelpSystem != null)
207  // {
208  // workbenchHelpSystem.setHelp(item, helpContextId);
209  // }
210 
211  connect(item, SIGNAL(triggered()), SLOT(HandleWidgetSelection()));
212  connect(item, SIGNAL(destroyed()), SLOT(HandleActionDestroyed()));
213  action = item;
214 
215  this->Update();
216  this->UpdateIcons();
217 
218  //bindingService.addBindingManagerListener(bindingManagerListener);
219 }
220 
221 void CommandContributionItem::Fill(QToolBar *parent, QAction *before)
222 {
223  if (!command || action || parent == nullptr)
224  {
225  return;
226  }
227 
228  QAction* item = nullptr;
229  if (before)
230  {
231  item = parent->addAction(icon, label);
232  }
233  else
234  {
235  item = new QAction(icon, label, parent);
236  parent->insertAction(before, item);
237  }
238  item->setData(QVariant::fromValue(Object::Pointer(this)));
239  item->setProperty("contributionItem", QVariant::fromValue(Object::Pointer(this)));
240 
241  connect(item, SIGNAL(triggered()), SLOT(HandleWidgetSelection()));
242  connect(item, SIGNAL(destroyed()), SLOT(HandleActionDestroyed()));
243  action = item;
244 
245  this->Update();
246  this->UpdateIcons();
247 
248  //bindingService.addBindingManagerListener(bindingManagerListener);
249 }
250 
252 {
253  this->Update(QString::null);
254 }
255 
256 void CommandContributionItem::Update(const QString& /*id*/)
257 {
258  if (action)
259  {
260  QWidget* parent = action->parentWidget();
261  if(qobject_cast<QMenu*>(parent))
262  {
263  this->UpdateMenuItem();
264  }
265  else if (qobject_cast<QMenuBar*>(parent))
266  {
267  this->UpdateMenuItem();
268  }
269  else if (qobject_cast<QToolBar*>(parent))
270  {
271  this->UpdateToolItem();
272  }
273  }
274 
275 }
276 
277 void CommandContributionItem::UpdateMenuItem()
278 {
279  QString text = label;
280  if (text.isEmpty())
281  {
282  if (command.IsNotNull())
283  {
284  try
285  {
286  text = command->GetCommand()->GetName();
287  }
288  catch (const NotDefinedException& e)
289  {
290 // StatusManager.getManager().handle(
291 // StatusUtil.newStatus(IStatus.ERROR,
292 // "Update item failed "
293 // + getId(), e));
294  BERRY_ERROR << "Update item failed " << GetId() << e.what();
295  }
296  }
297  }
298  text = UpdateMnemonic(text);
299 
300 // String keyBindingText = null;
301 // if (command != null)
302 // {
303 // TriggerSequence binding = bindingService
304 // .getBestActiveBindingFor(command);
305 // if (binding != null)
306 // {
307 // keyBindingText = binding.format();
308 // }
309 // }
310 // if (text != null)
311 // {
312 // if (keyBindingText == null)
313 // {
314 // item.setText(text);
315 // }
316 // else
317 // {
318 // item.setText(text + '\t' + keyBindingText);
319 // }
320 // }
321 
322  if (action->isChecked() != checkedState)
323  {
324  action->setChecked(checkedState);
325  }
326 
327  // allow the handler update its enablement
328  bool shouldBeEnabled = IsEnabled();
329  if (action->isEnabled() != shouldBeEnabled)
330  {
331  action->setEnabled(shouldBeEnabled);
332  }
333 }
334 
335 void CommandContributionItem::UpdateToolItem()
336 {
337  QString text = label;
338  QString tooltip = label;
339  if (text.isNull())
340  {
341  if (command.IsNotNull())
342  {
343  try
344  {
345  text = command->GetCommand()->GetName();
346  tooltip = command->GetCommand()->GetDescription();
347  if (tooltip.trimmed().isEmpty())
348  {
349  tooltip = text;
350  }
351  }
352  catch (const NotDefinedException& e)
353  {
354 // StatusManager.getManager().handle(
355 // StatusUtil.newStatus(IStatus.ERROR,
356 // "Update item failed "
357 // + getId(), e));
358  BERRY_ERROR << "Update item failed " << GetId() << e.what();
359  }
360  }
361  }
362 
363  if ((icon.isNull() || (mode & MODE_FORCE_TEXT) == MODE_FORCE_TEXT)
364  && !text.isNull())
365  {
366  action->setText(text);
367  }
368 
369  QString toolTipText = GetToolTipText(tooltip);
370  action->setToolTip(toolTipText);
371 
372  if (action->isChecked() != checkedState)
373  {
374  action->setChecked(checkedState);
375  }
376 
377  // allow the handler update its enablement
378  bool shouldBeEnabled = IsEnabled();
379  if (action->isEnabled() != shouldBeEnabled)
380  {
381  action->setEnabled(shouldBeEnabled);
382  }
383 }
384 
386 {
387  if (elementRef)
388  {
389  commandService->UnregisterElement(elementRef);
390  }
391  if (commandListener)
392  {
393  command->GetCommand()->RemoveCommandListener(commandListener.data());
394  }
395 }
396 
398 {
399  if (command)
400  {
401  command->GetCommand()->SetEnabled(menuService->GetCurrentState());
402  return command->GetCommand()->IsEnabled();
403  }
404  return false;
405 }
406 
408 {
409  if (visibleEnabled)
410  {
411  return ContributionItem::IsVisible() && this->IsEnabled();
412  }
414 }
415 
416 void CommandContributionItem::SetImages(IServiceLocator* locator,
417  const QString& iconStyle)
418 {
419  if (icon.isNull())
420  {
422  if (service)
423  {
424  icon = service->GetImage(command->GetId(), iconStyle);
425  }
426  }
427 }
428 
429 ICommandListener* CommandContributionItem::GetCommandListener()
430 {
431  if (!commandListener)
432  {
433  class MyCommandListener : public ICommandListener
434  {
435 
436  private:
438 
439  public:
440 
441  MyCommandListener(CommandContributionItem* item)
442  : item(item)
443  {}
444 
445  void CommandChanged(const SmartPointer<const CommandEvent>& commandEvent) override
446  {
447  if (commandEvent->IsHandledChanged() || commandEvent->IsEnabledChanged()
448  || commandEvent->IsDefinedChanged())
449  {
450  item->UpdateCommandProperties(commandEvent);
451  }
452  }
453 
454  };
455 
456  commandListener.reset(new MyCommandListener(this));
457  }
458  return commandListener.data();
459 }
460 
461 void CommandContributionItem::UpdateCommandProperties(const SmartPointer<
462  const CommandEvent> commandEvent)
463 {
464  if (commandEvent->IsHandledChanged())
465  {
466  dropDownMenuOverride = "";
467  }
468  if (!action)
469  {
470  return;
471  }
472  Display* display = Display::GetDefault();
473  typedef AsyncRunnable<SmartPointer<const CommandEvent>, CommandContributionItem > UpdateRunnable;
474  Poco::Runnable* update = new UpdateRunnable(this, &CommandContributionItem::UpdateCommandPropertiesInUI, commandEvent);
475  if (display->InDisplayThread())
476  {
477  update->run();
478  }
479  else
480  {
481  display->AsyncExec(update);
482  }
483 }
484 
486  const CommandEvent>& commandEvent)
487 {
488  if (commandEvent->GetCommand()->IsDefined())
489  {
490  this->Update();
491  }
492  if (commandEvent->IsEnabledChanged()
493  || commandEvent->IsHandledChanged())
494  {
495  if (visibleEnabled)
496  {
497  IContributionManager* parent = this->GetParent();
498  if (parent)
499  {
500  parent->Update(true);
501  }
502  }
503  }
504 }
505 
506 void CommandContributionItem::HandleActionDestroyed()
507 {
508  this->action = nullptr;
509 }
510 
511 bool CommandContributionItem::ShouldRestoreAppearance(const SmartPointer<IHandler>& handler)
512 {
513  // if no handler or handler doesn't implement IElementUpdater,
514  // restore the contributed elements
515  if (handler.IsNull())
516  return true;
517 
518  if (!(handler.Cast<IElementUpdater>()))
519  return true;
520 
521  // special case, if its HandlerProxy, then check the actual handler
522 // if (handler instanceof HandlerProxy) {
523 // HandlerProxy handlerProxy = (HandlerProxy) handler;
524 // IHandler actualHandler = handlerProxy.getHandler();
525 // return shouldRestoreAppearance(actualHandler);
526 // }
527  return false;
528 }
529 
530 SmartPointer<ParameterizedCommand> CommandContributionItem::GetCommand() const
531 {
532  return command;
533 }
534 
535 void CommandContributionItem::CreateCommand(const QString &commandId,
536  const QHash<QString,Object::Pointer> &parameters)
537 {
538  if (commandId.isEmpty())
539  {
540 // StatusManager.getManager().handle(StatusUtil.newStatus(IStatus.ERROR,
541 // "Unable to create menu item \"" + getId()
542 // + "\", no command id", null));
543  BERRY_ERROR << "Unable to create menu item \"" << this->GetId().toStdString()
544  << "\", no command id";
545  return;
546  }
547  Command::Pointer cmd = commandService->GetCommand(commandId);
548  if (!cmd->IsDefined())
549  {
550 // StatusManager.getManager().handle(StatusUtil.newStatus(
551 // IStatus.ERROR, "Unable to create menu item \"" + getId()
552 // + "\", command \"" + commandId + "\" not defined", null));
553  BERRY_ERROR << "Unable to create menu item \"" << this->GetId().toStdString()
554  << "\", command \"" << commandId.toStdString() << "\" not defined";
555  return;
556  }
557 
558  command = ParameterizedCommand::GenerateCommand(cmd, parameters);
559 }
560 
561 QString CommandContributionItem::GetToolTipText(const QString& text) const
562 {
563  QString tooltipText = tooltip;
564  if (tooltip.isNull())
565  {
566  if (!text.isNull())
567  {
568  tooltipText = text;
569  }
570  else
571  {
572  tooltipText = "";
573  }
574  }
575 
576 // TriggerSequence activeBinding = bindingService
577 // .getBestActiveBindingFor(command);
578 // if (activeBinding != null && !activeBinding.isEmpty())
579 // {
580 // String acceleratorText = activeBinding.format();
581 // if (acceleratorText != null
582 // && acceleratorText.length() != 0)
583 // {
584 // tooltipText = NLS.bind(CommandMessages.Tooltip_Accelerator,
585 // tooltipText, acceleratorText);
586 // }
587 // }
588 
589  return tooltipText;
590 }
591 
592 QString CommandContributionItem::UpdateMnemonic(const QString &s)
593 {
594  if (mnemonic.isNull() || s.isEmpty())
595  {
596  return s;
597  }
598 
599  int idx = s.indexOf(mnemonic);
600  if (idx == -1)
601  {
602  return s;
603  }
604 
605  return s.left(idx) + '&' + s.mid(idx);
606 }
607 
608 //SmartPointer<IUIElementListener> CommandContributionItem::GetItemListener()
609 //{
610 // if (!itemListener)
611 // {
612 // itemListener = new CommandUIElementListener(this);
613 // }
614 // return itemListener;
615 //}
616 
617 void CommandContributionItem::HandleWidgetSelection()
618 {
619 // // Special check for ToolBar dropdowns...
620 // if (this->OpenDropDownMenu(event))
621 // //return;
622 
623  if ((style & STYLE_CHECK) != 0)
624  {
625  checkedState = action->isChecked();
626  }
627 
628  try
629  {
630  handlerService->ExecuteCommand(command, UIElement::Pointer(nullptr));
631  }
632  catch (const ExecutionException& e)
633  {
634  WorkbenchPlugin::Log("Failed to execute item " + GetId(), e);
635  }
636  catch (const NotDefinedException& e)
637  {
638  WorkbenchPlugin::Log("Failed to execute item " + GetId(), e);
639  }
640  catch (const NotEnabledException& e)
641  {
642  WorkbenchPlugin::Log("Failed to execute item " + GetId(), e);
643  }
644  catch (const NotHandledException& e)
645  {
646  WorkbenchPlugin::Log("Failed to execute item " + GetId(), e);
647  }
648 }
649 
650 //TODO Tool item drop down menu contributions
651 //bool CommandContributionItem::OpenDropDownMenu(SmartPointer<GuiTk::Event> event)
652 //{
653 //Widget item = event.widget;
654 //if (item != null)
655 //{
656 // int style = item.getStyle();
657 // if ((style & SWT.DROP_DOWN) != 0)
658 // {
659 // if (event.detail == 4)
660 // { // on drop-down button
661 // ToolItem ti = (ToolItem) item;
662 //
663 // final MenuManager menuManager = new MenuManager();
664 // Menu menu = menuManager.createContextMenu(ti.getParent());
665 // if (workbenchHelpSystem != null)
666 // {
667 // workbenchHelpSystem.setHelp(menu, helpContextId);
668 // }
669 // menuManager.addMenuListener(new IMenuListener()
670 // {
671 // public void menuAboutToShow(IMenuManager manager)
672 // {
673 // String id = getId();
674 // if (dropDownMenuOverride != null)
675 // {
676 // id = dropDownMenuOverride;
677 // }
678 // menuService.populateContributionManager(
679 // menuManager, "menu:" + id); //$NON-NLS-1$
680 // }
681 // });
682 //
683 // // position the menu below the drop down item
684 // Point point = ti.getParent().toDisplay(
685 // new Point(event.x, event.y));
686 // menu.setLocation(point.x, point.y); // waiting for SWT
687 // // 0.42
688 // menu.setVisible(true);
689 // return true; // we don't fire the action
690 // }
691 // }
692 //}
693 //
694 //return false;
695 //}
696 
697 void CommandContributionItem::SetIcon(const QIcon &icon)
698 {
699  this->icon = icon;
700  this->UpdateIcons();
701 }
702 
703 void CommandContributionItem::UpdateIcons()
704 {
705  action->setIcon(icon);
706 }
707 
708 void CommandContributionItem::SetText(const QString &text)
709 {
710  label = text;
711  this->Update();
712 }
713 
714 void CommandContributionItem::SetChecked(bool checked)
715 {
716  if (checkedState == checked)
717  {
718  return;
719  }
720  checkedState = checked;
721  action->setChecked(checkedState);
722 }
723 
724 void CommandContributionItem::SetToolTip(const QString &text)
725 {
726  tooltip = text;
727  action->setToolTip(text);
728 }
729 
730 }
static MsgHandler handler
Definition: usUtils.cpp:261
virtual void Update(bool force)=0
bool IsVisible() const override
virtual void UnregisterElement(const SmartPointer< IElementReference > &elementReference)=0
void UpdateCommandPropertiesInUI(const SmartPointer< const CommandEvent > &commandEvent)
virtual QIcon GetImage(const QString &commandId)=0
void Fill(QMenu *parent, QAction *before) override
static Display * GetDefault()
Implements transparent reference counting.
virtual Object::Pointer ExecuteCommand(const QString &commandId, const SmartPointer< const UIElement > &uielement)=0
static ParameterizedCommand::Pointer GenerateCommand(const SmartPointer< Command > command, const QHash< QString, Object::Pointer > &parameters)
#define BERRY_ERROR
Definition: berryLog.h:26
IContributionManager * GetParent() const
berry::SmartPointer< Self > Pointer
Definition: berryObject.h:88
virtual SmartPointer< Command > GetCommand(const QString &commandId) const =0
CommandContributionItem(const SmartPointer< CommandContributionItemParameter > &contributionParameters)
virtual SmartPointer< IEvaluationContext > GetCurrentState() const =0
QString GetId() const override