Skip to content
Snippets Groups Projects
ApplicationWindow.cpp 579 KiB
Newer Older
{
  FloatingWindow* fw = w->getFloatingWindow();
  if (!fw) return;
  fw->removeMdiSubWindow();
  removeFloatingWindow(fw);
  // main window must be closed or application will freeze 
  fw->close();
  addMdiSubWindowAsDocked(w);
  //activateWindow(w);
  w->setNormal();
  return;
}

/**
 * Remove a closed floating window from internal lists.
 * @param w :: Pointer to the closed window.
 */
void ApplicationWindow::removeFloatingWindow(FloatingWindow* w)
{
  if (m_floatingWindows.contains(w))
  {
    m_floatingWindows.remove(w);
    if (w->mdiSubWindow())
    {
      closeWindow(w->mdiSubWindow());
    }
    // Make the FloatingWindow delete itself
    w->deleteLater();
  }
}

/**
 * Return a pointer to the active FloatingWindow if the active window is floating
 * or NULL otherwise.
 */
FloatingWindow* ApplicationWindow::getActiveFloating() const
{
  MdiSubWindow* w = getActiveWindow();
  if (!w) return NULL;
  return w->getFloatingWindow();
}

/**
 * Filter out the WindowActivate event and set the active subwindow correctly.
 * @param e :: An event.
 */
bool ApplicationWindow::event(QEvent * e)
{
  if (e->type() == QEvent::WindowActivate)
  {
    bool needToActivate = true;

    // check if old active window is a floating one and this window was activated by clicking
    // on a tool bar - in this case we shouldn't actvate another window
    if (getActiveFloating())
    {

      QPoint cur_pos = this->mapFromGlobal(QCursor::pos());
      const QWidget* clickedWidget = NULL;
      
      if (rect().contains(cur_pos))
      {
        clickedWidget = childAt(cur_pos);
      }

      if (clickedWidget)
      {
        QString class_name = clickedWidget->className();
        if (class_name == "QToolButton" || class_name == "QToolBar" || class_name == "QMenuBar")
        {
          needToActivate = false;
        }
      }
    }

    if (needToActivate)
    {// activate current MDI subwindow
      QMdiSubWindow* qCurrent = d_workspace->currentSubWindow();
      if (qCurrent)
      {
        MdiSubWindow* sw = dynamic_cast<MdiSubWindow*>(qCurrent->widget());
        if (!sw)
        {// this should never happen - all MDI subwindow widgets must inherit from MdiSubwindow
          throw std::runtime_error("Non-MdiSubwindow widget found in MDI area");
        }
        activateWindow(sw);
      }
    }
  }
  return QMainWindow::event(e);
}

/**
 * Necessary steps to activate a floating window.
 * @param w :: Activated window
 */
void ApplicationWindow::mdiWindowActivated(MdiSubWindow* w)
{
  if (!w) return;
  setActiveWindow(w);
}

/**
 * Activate a subwindow (docked or floating) other than current active one.
 * This is required when the current window is closing.
 */
void ApplicationWindow::activateNewWindow()
{
  MdiSubWindow* current = getActiveWindow();
  MdiSubWindow* newone = NULL;
  Folder* folder = currentFolder();
  
  // try the docked windows first
  QList<QMdiSubWindow*> wl = d_workspace->subWindowList();
  foreach(QMdiSubWindow* w,wl)
  {
    if (w->widget() != static_cast<QWidget*>(current))
    {
      MdiSubWindow* sw = dynamic_cast<MdiSubWindow*>(w->widget());
        if (sw && 
            sw->status() != MdiSubWindow::Minimized && 
            sw->status() != MdiSubWindow::Hidden && 
            folder->hasWindow(sw))
    }
  }

  // if unsuccessful try the floating windows
  if (!newone)
  {
    foreach(FloatingWindow* w, m_floatingWindows)
    {
      MdiSubWindow* sw = w->mdiSubWindow();
      if (sw != current)
      {
        if (sw && 
            sw->status() != MdiSubWindow::Minimized && 
            sw->status() != MdiSubWindow::Hidden && 
            folder->hasWindow(sw))
  // activate a new sub-window or pass NULL if no window can be activated
  activateWindow(newone);
}

/**
 * The slot to change the active window from docked to floating.
 */
void ApplicationWindow::changeActiveToFloating()
{
  MdiSubWindow* activeWin = activeWindow();
  changeToFloating(activeWin);
}

/**
 * The slot to change the active window from floating to docked.
 */
void ApplicationWindow::changeActiveToDocked()
{
  MdiSubWindow* activeWin = activeWindow();
  changeToDocked(activeWin);
}

/**
 * Returns if a window should be made floating by default.
 * @param w :: Pointer to a MdiSubWindow.
 */
bool ApplicationWindow::isDefaultFloating(const MdiSubWindow* w) const
{
  QString wClassName = w->className();
  return isDefaultFloating(wClassName);
}

/**
 * Returns if a window should be made floating by default.
 * @param aClassName :: Class name of a MdiSubWindow or its internal widget in case of custom interfaces.
 */
bool ApplicationWindow::isDefaultFloating(const QString& aClassName) const
{
  bool theDefault = false;
  if (aClassName == "MultiLayer" || aClassName =="InstrumentWindow" || aClassName == "MdiSubWindow")
  {
    theDefault = true;
  }
  return settings.value("/General/FloatingWindows/"+aClassName,theDefault).toBool();
}


/**
 * Check that a widow will be visible if moved to these coordinates and
 * set them to default values otherwise.
 * @param w :: Pointer to a sub-window.
 * @param x :: Tested x coordinate
 * @param y :: Tested y coordinate
 */
void ApplicationWindow::validateWindowPos(MdiSubWindow* w, int& x, int& y)
{
  QSize sz = w->size();
  if ( w->getFloatingWindow() )
  {
    QWidget* desktop = QApplication::desktop()->screen();
    QPoint pos(x, y);
    pos += desktopTopLeft();
    if ( pos.x() < 0 || pos.y() < 0 ||
      pos.x() + sz.width() > desktop->width() ||
      pos.y() + sz.height() > desktop->height() )
    {
      pos = positionNewFloatingWindow(sz);
    }
    x = pos.x();
    y = pos.y();
    return;
  }
  else if ( x < 0 || y < 0 || 
    x + sz.width() > d_workspace->width() ||
    y + sz.height() > d_workspace->height() )
  {
    x = y = 0;
  }
}