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