Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
berryWindow.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 "berryWindow.h"
20 
21 #include "berryConstants.h"
22 #include "berrySameShellProvider.h"
23 #include "berryMenuManager.h"
24 
25 #include <QMainWindow>
26 
27 namespace berry
28 {
29 
30 const int Window::OK = 0;
31 const int Window::CANCEL = 1;
32 
33 QList<QIcon> Window::defaultImages = QList<QIcon>();
34 
35 Window::IExceptionHandler::Pointer Window::exceptionHandler(new DefaultExceptionHandler());
36 IShellProvider::Pointer Window::defaultModalParent(new DefaultModalParent());
37 
38 Window::WindowShellListener::WindowShellListener(Window* wnd)
39  : window(wnd)
40  {
41 
42  }
43 
44 void Window::WindowShellListener::ShellClosed(const ShellEvent::Pointer& event)
45 {
46  event->doit = false; // don't close now
47  if (window->CanHandleShellCloseEvent())
48  {
49  window->HandleShellCloseEvent();
50  }
51 }
52 
53 void Window::DefaultExceptionHandler::HandleException(const std::exception& t)
54 {
55  // Try to keep running.
56  std::cerr << t.what();
57 }
58 
59 Shell::Pointer Window::DefaultModalParent::GetShell() const
60 {
61  Shell::Pointer parent = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetActiveShell();
62 
63  // Make sure we don't pick a parent that has a modal child (this can lock the app)
64  if (parent == 0)
65  {
66  // If this is a top-level window, then there must not be any open modal windows.
67  parent = Window::GetModalChild(Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetShells());
68  }
69  else
70  {
71  // If we picked a parent with a modal child, use the modal child instead
72  Shell::Pointer modalChild = Window::GetModalChild(parent->GetShells());
73  if (modalChild != 0)
74  {
75  parent = modalChild;
76  }
77  }
78 
79  return parent;
80 }
81 
82 Shell::Pointer Window::GetModalChild(const QList<Shell::Pointer>& toSearch)
83 {
85 
86  int size = toSearch.size();
87  for (int i = size - 1; i < size; i--)
88  {
89  Shell::Pointer shell = toSearch[i];
90 
91  // Check if this shell has a modal child
92  QList<Shell::Pointer> children = shell->GetShells();
93  Shell::Pointer modalChild = GetModalChild(children);
94  if (modalChild != 0)
95  {
96  return modalChild;
97  }
98 
99  // If not, check if this shell is modal itself
100  if (shell->IsVisible() && (shell->GetStyle() & modal) != 0)
101  {
102  return shell;
103  }
104  }
105 
106  return Shell::Pointer(nullptr);
107 }
108 
109 //void Window::RunEventLoop()
110 //{
111 //
112 // //Use the display provided by the shell if possible
113 // Display display;
114 // if (shell == null)
115 // {
116 // display = Display.getCurrent();
117 // }
118 // else
119 // {
120 // display = loopShell.getDisplay();
121 // }
122 //
123 // while (loopShell != null && !loopShell.isDisposed())
124 // {
125 // try
126 // {
127 // if (!display.readAndDispatch())
128 // {
129 // display.sleep();
130 // }
131 // } catch (Throwable e)
132 // {
133 // exceptionHandler.handleException(e);
134 // }
135 // }
136 // display.update();
137 //}
138 
140 {
141  this->parentShell = new SameShellProvider(parentShell);
142  this->Init();
143 }
144 
146 {
147  poco_assert(shellProvider != 0);
148  this->parentShell = shellProvider;
149  this->Init();
150 }
151 
153 {
154 
155 }
156 
158 {
159  this->shellStyle = Constants::SHELL_TRIM;
160  this->returnCode = OK;
161  this->block = false;
162 }
163 
165 {
166  return true;
167 }
168 
170 {
171 
172  // The single image version of this code had a comment related to bug
173  // 46624,
174  // and some code that did nothing if the stored image was already
175  // disposed.
176  // The equivalent in the multi-image version seems to be to remove the
177  // disposed images from the array passed to the shell.
178  if (defaultImages.size() > 0)
179  {
180 // ArrayList nonDisposedImages = new ArrayList(defaultImages.length);
181 // for (int i = 0; i < defaultImages.length; ++i)
182 // {
183 // if (defaultImages[i] != null && !defaultImages[i].isDisposed())
184 // {
185 // nonDisposedImages.add(defaultImages[i]);
186 // }
187 // }
188 //
189 // if (nonDisposedImages.size() <= 0)
190 // {
191 // System.err.println("Window.configureShell: images disposed"); //$NON-NLS-1$
192 // }
193 // else
194 // {
195 // //Image[] array = new Image[nonDisposedImages.size()];
196 // nonDisposedImages.toArray(array);
197  newShell->SetImages(defaultImages);
198 // }
199  }
200 
201 // Layout layout = getLayout();
202 // if (layout != null)
203 // {
204 // newShell.setLayout(layout);
205 // }
206  CreateTrimWidgets(newShell);
207 }
208 
209 //voidWindow::ConstrainShellSize()
210 //{
211 // // limit the shell size to the display size
212 // QRect bounds = shell.getBounds();
213 // QRect constrained = getConstrainedShellBounds(bounds);
214 // if (!bounds.equals(constrained))
215 // {
216 // shell.setBounds(constrained);
217 // }
218 //}
219 
221 {
222  // by default, just create a composite
223  //return new Composite(parent, SWT.NONE);
224  return parent->GetControl();
225 }
226 
228 {
229 
230  Shell::Pointer newParent = this->GetParentShell();
231 // if (newParent != 0 && newParent.isDisposed())
232 // {
233 // parentShell = new SameShellProvider(null);
234 // newParent = getParentShell();//Find a better parent
235 // }
236 
237  //Create the shell
238  Shell::Pointer newShell = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->CreateShell(newParent, this->GetShellStyle());
239 
240  // resizeListener = new Listener() {
241  // public void handleEvent(Event e) {
242  // resizeHasOccurred = true;
243  // }
244  // };
245 
246  //newShell.addListener(SWT.Resize, resizeListener);
247  newShell->SetData(Object::Pointer(this));
248 
249  //Add a listener
250  newShell->AddShellListener(this->GetShellListener());
251 
252  //Set the layout
253  this->ConfigureShell(newShell);
254 
255 // //Register for font changes
256 // if (fontChangeListener == null)
257 // {
258 // fontChangeListener = new FontChangeListener();
259 // }
260 // JFaceResources.getFontRegistry().addListener(fontChangeListener);
261 
262  return newShell;
263 }
264 
266 {
267  return contents;
268 }
269 
270 QPoint Window::GetInitialLocation(const QPoint& initialSize)
271 {
272  QWidget* parent = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetParent(shell->GetControl());
273 
274  QPoint centerPoint(0,0);
275  QRect parentBounds(0,0,0,0);
276  if (parent != nullptr)
277  {
278  parentBounds = Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetBounds(parent);
279  centerPoint.setX(parentBounds.x() + parentBounds.width()/2);
280  centerPoint.setY(parentBounds.y() - parentBounds.height()/2);
281  }
282  else
283  {
284  parentBounds = Tweaklets::Get(GuiWidgetsTweaklet::KEY)
285  ->GetScreenSize(Tweaklets::Get(GuiWidgetsTweaklet::KEY)->GetPrimaryScreenNumber());
286  centerPoint.setX(parentBounds.width()/2);
287  centerPoint.setY(parentBounds.height()/2);
288  }
289 
290  return QPoint(centerPoint.x() - (initialSize.x() / 2),
291  std::max<int>(parentBounds.y(),
292  std::min<int>(centerPoint.y() - (initialSize.y() * 2 / 3),
293  parentBounds.y() + parentBounds.height() - initialSize.y())));
294 }
295 
297 {
298  return shell->ComputeSize(Constants::DEFAULT, Constants::DEFAULT, true);
299 }
300 
302 {
303  Shell::Pointer parent = parentShell->GetShell();
304 
306 
307  if ((this->GetShellStyle() & modal) != 0)
308  {
309  // If this is a modal shell with no parent, pick a shell using defaultModalParent.
310  if (parent == 0)
311  {
312  parent = defaultModalParent->GetShell();
313  }
314  }
315 
316  return parent;
317 }
318 
320 {
321  if (windowShellListener.isNull())
322  windowShellListener.reset(new WindowShellListener(this));
323 
324  return windowShellListener.data();
325 }
326 
328 {
329  return shellStyle;
330 }
331 
333 {
334  this->SetReturnCode(CANCEL);
335  this->Close();
336 }
337 
339 {
340 // if (resizeListener != null)
341 // {
342 // shell.removeListener(SWT.Resize, resizeListener);
343 // }
344 // if (resizeHasOccurred)
345 // { // Check if shell size has been set already.
346 // return;
347 // }
348 
349  QPoint size = this->GetInitialSize();
350  QPoint location = this->GetInitialLocation(size);
351  shell->SetBounds(this->GetConstrainedShellBounds(QRect(location.x(), location.y(), size.x(), size.y())));
352 }
353 
354 QRect Window::GetConstrainedShellBounds(const QRect& preferredSize)
355 {
356  QRect result(preferredSize);
357 
358  GuiWidgetsTweaklet* guiTweaklet(Tweaklets::Get(GuiWidgetsTweaklet::KEY));
359  int screenNum = guiTweaklet->GetClosestScreenNumber(result);
360  QRect bounds(guiTweaklet->GetAvailableScreenSize(screenNum));
361 
362  if (result.height() > bounds.height()) {
363  result.setHeight(bounds.height());
364  }
365 
366  if (result.width() > bounds.width()) {
367  result.setWidth(bounds.width());
368  }
369 
370  result.moveLeft( std::max<int>(bounds.x(), std::min<int>(result.x(), bounds.x()
371  + bounds.width() - result.width())));
372  result.moveTop(std::max<int>(bounds.y(), std::min<int>(result.y(), bounds.y()
373  + bounds.height() - result.height())));
374 
375  return result;
376 }
377 
379 {
380  poco_assert(shell == 0); // "There must not be an existing shell."; //$NON-NLS-1$
381  parentShell = new SameShellProvider(newParentShell);
382 }
383 
384 void Window::SetReturnCode(int code)
385 {
386  returnCode = code;
387 }
388 
389 void Window::SetShellStyle(int newShellStyle)
390 {
391  shellStyle = newShellStyle;
392 }
393 
395 {
396  if (GetShell().IsNull() && menuBarManager.IsNull())
397  {
398  menuBarManager = CreateMenuManager();
399  }
400 }
401 
403 {
404  MenuManager::Pointer manager(new MenuManager());
405  return manager;
406 }
407 
409 {
410  if (menuBarManager.IsNotNull())
411  {
412  QMainWindow* mw = qobject_cast<QMainWindow*>(shell->GetControl());
413  if (mw)
414  {
415  mw->setMenuBar(menuBarManager->CreateMenuBar(shell->GetControl()));
416  menuBarManager->UpdateAll(true);
417  }
418  }
419 
420 // if (showTopSeperator())
421 // {
422 // seperator1 = new Label(shell, SWT.SEPARATOR | SWT.HORIZONTAL);
423 // }
424 
425  //CreateToolBarControl(shell);
426  //CreateStatusLine(shell);
427 }
428 
430 {
431 
432 // BERRY_INFO << "Window::Close()";
433 
434 // // stop listening for font changes
435 // if (fontChangeListener != null)
436 // {
437 // JFaceResources.getFontRegistry().removeListener(fontChangeListener);
438 // fontChangeListener = null;
439 // }
440 
441  // remove this window from a window manager if it has one
442  if (windowManager != nullptr)
443  {
444  windowManager->Remove(Window::Pointer(this));
445  windowManager = nullptr;
446  }
447 
448  if (shell == 0)
449  {
450  return true;
451  }
452 
453  shell->RemoveShellListener(this->GetShellListener());
454  shell->SetData(Object::Pointer(nullptr));
455 
456  // If we "close" the shell recursion will occur.
457  // Instead, we need to "dispose" the shell to remove it from the
458  // display.
459  Tweaklets::Get(GuiWidgetsTweaklet::KEY)->DisposeShell(shell);
460  shell = nullptr;
461  contents = nullptr;
462 
463  return true;
464 }
465 
467 {
468  shell = this->CreateShell();
469  contents = this->CreateContents(shell);
470 
471  //initialize the bounds of the shell to that appropriate for the
472  // contents
473  this->InitializeBounds();
474 }
475 
477 {
478  return (defaultImages.size() < 1) ? QIcon() : defaultImages[0];
479 }
480 
482 {
483  return defaultImages;
484 }
485 
487 {
488  return returnCode;
489 }
490 
492 {
493  return shell;
494 }
495 
496 WindowManager* Window::GetWindowManager()
497 {
498  return windowManager;
499 }
500 
502 {
503  return menuBarManager.GetPointer();
504 }
505 
507 {
508 
509  if (shell == 0)
510  {
511  // create the window
512  this->Create();
513  }
514 
515  // limit the shell size to the display size
516  //constrainShellSize();
517 
518  // open the window
519  shell->Open(block);
520 
521 // // run the event loop if specified
522 // if (block)
523 // {
524 // this->RunEventLoop();
525 // }
526 
527  return returnCode;
528 }
529 
530 void Window::SetBlockOnOpen(bool shouldBlock)
531 {
532  block = shouldBlock;
533 }
534 
535 void Window::SetDefaultImage(const QIcon& image)
536 {
537  if (!image.isNull())
538  defaultImages.push_back(image);
539 }
540 
541 void Window::SetDefaultImages(const QList<QIcon>& images)
542 {
544 }
545 
546 void Window::SetWindowManager(WindowManager* manager)
547 {
548  windowManager = manager;
549 
550  // Code to detect invalid usage
551 
552  if (manager != nullptr)
553  {
554  QList<Window::Pointer> windows = manager->GetWindows();
555  for (int i = 0; i < windows.size(); i++)
556  {
557  if (windows[i] == this)
558  {
559  return;
560  }
561  }
562  manager->Add(Window::Pointer(this));
563  }
564 }
565 
567 {
568  if (exceptionHandler == 0)
569  {
570  exceptionHandler = handler;
571  }
572 }
573 
575 {
576  defaultModalParent = provider;
577 }
578 
579 }
virtual void Create()
static MsgHandler handler
Definition: usUtils.cpp:261
void SetParentShell(Shell::Pointer newParentShell)
itk::SmartPointer< Self > Pointer
virtual SmartPointer< MenuManager > CreateMenuManager()
void SetReturnCode(int code)
virtual void ConfigureShell(Shell::Pointer newShell)
void SetWindowManager(WindowManager *manager)
virtual IShellListener * GetShellListener()
static const int CANCEL
Definition: berryWindow.h:107
virtual bool CanHandleShellCloseEvent()
MenuManager * GetMenuBarManager() const
WindowManager * GetWindowManager()
static QIcon GetDefaultImage()
virtual void CreateTrimWidgets(SmartPointer< Shell > shell)
Shell::Pointer GetParentShell()
static const int SHELL_TRIM
static void SetDefaultModalParent(IShellProvider::Pointer provider)
static void SetDefaultImage(const QIcon &image)
virtual void Init()
Shell::Pointer GetShell() const override
virtual void InitializeBounds()
virtual QRect GetAvailableScreenSize(int i=-1)=0
void SetShellStyle(int newShellStyle)
#define OK
QRect GetConstrainedShellBounds(const QRect &preferredSize)
berry::SmartPointer< Self > Pointer
Definition: berryObject.h:88
virtual void HandleShellCloseEvent()
virtual bool Close()
static const int SYSTEM_MODAL
virtual QWidget * CreateContents(Shell::Pointer parent)
virtual QPoint GetInitialLocation(const QPoint &initialSize)
Window(Shell::Pointer parentShell)
virtual QPoint GetInitialSize()
static const int PRIMARY_MODAL
static QList< QIcon > GetDefaultImages()
static Tweaklets::TweakKey< GuiWidgetsTweaklet > KEY
static const int DEFAULT
static QList< QIcon > defaultImages
Definition: berryWindow.h:113
virtual Shell::Pointer CreateShell()
void SetBlockOnOpen(bool shouldBlock)
static const int APPLICATION_MODAL
virtual int GetClosestScreenNumber(const QRect &)=0
section MAP_FRAME_Mapper_Settings Mapper settings For the mapping of corrected images
virtual QWidget * GetContents()
static void SetDefaultImages(const QList< QIcon > &images)
static void SetExceptionHandler(IExceptionHandler::Pointer handler)