diff --git a/ground/src/plugins/coreplugin/coreplugin.pro b/ground/src/plugins/coreplugin/coreplugin.pro index 0941fe627..7c2593068 100644 --- a/ground/src/plugins/coreplugin/coreplugin.pro +++ b/ground/src/plugins/coreplugin/coreplugin.pro @@ -30,6 +30,7 @@ SOURCES += mainwindow.cpp \ uavgadgetmode.cpp \ uavgadgetmanager/uavgadgetmanager.cpp \ uavgadgetmanager/uavgadgetview.cpp \ + uavgadgetmanager/splitterorview.cpp \ actionmanager/actionmanager.cpp \ actionmanager/command.cpp \ actionmanager/actioncontainer.cpp \ @@ -77,6 +78,7 @@ HEADERS += mainwindow.h \ iuavgadgetfactory.h \ uavgadgetmanager/uavgadgetmanager.h \ uavgadgetmanager/uavgadgetview.h \ + uavgadgetmanager/splitterorview.h \ actionmanager/actioncontainer.h \ actionmanager/actionmanager.h \ actionmanager/command.h \ diff --git a/ground/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp b/ground/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp new file mode 100644 index 000000000..8199c7208 --- /dev/null +++ b/ground/src/plugins/coreplugin/uavgadgetmanager/splitterorview.cpp @@ -0,0 +1,487 @@ +/** + ****************************************************************************** + * + * @file splitterorview.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup CorePlugin Core Plugin + * @{ + * @brief The Core GCS plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "splitterorview.h" +#include "uavgadgetview.h" +#include "uavgadgetmanager.h" +#include "uavgadgetinstancemanager.h" +#include "iuavgadget.h" +#include "coreimpl.h" +#include "minisplitter.h" +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef Q_WS_MAC +#include +#endif + +using namespace Core; +using namespace Core::Internal; + +SplitterOrView::SplitterOrView(Core::UAVGadgetManager *uavGadgetManager, Core::IUAVGadget *uavGadget, bool isRoot) : + m_uavGadgetManager(uavGadgetManager), + m_isRoot(isRoot), + m_splitter(0) +{ + m_view = new UAVGadgetView(m_uavGadgetManager, uavGadget, this); + m_layout = new QStackedLayout(this); + m_layout->addWidget(m_view); +} + +SplitterOrView::~SplitterOrView() +{ + if(m_view) { + delete m_view; + m_view = 0; + } + if(m_splitter) { + delete m_splitter; + m_splitter = 0; + } +} + +void SplitterOrView::mousePressEvent(QMouseEvent *e) +{ + if (e->button() != Qt::LeftButton) + return; + if (gadget()) { + setFocus(Qt::MouseFocusReason); + m_uavGadgetManager->setCurrentGadget(this->gadget()); + } +} + +//void SplitterOrView::paintEvent(QPaintEvent *event) +//{ +// if (m_uavGadgetManager->currentSplitterOrView() != this) +// return; +// +// if (!m_view) +// return; +// +// if (hasGadget()) +// return; +// +// if (m_uavGadgetManager->toolbarsShown()) +// return; +// +// // Discreet indication where an uavGadget would be if there is none +// QPainter painter(this); +// painter.setRenderHint(QPainter::Antialiasing, true); +// painter.setPen(Qt::NoPen); +// QColor shadeBrush(Qt::black); +// shadeBrush.setAlpha(25); +// painter.setBrush(shadeBrush); +// const int r = 3; +// painter.drawRoundedRect(rect().adjusted(r, r, -r, -r), r * 2, r * 2); +// +//#if 0 +// if (hasFocus()) { +//#ifdef Q_WS_MAC +// // With QMacStyle, we have to draw our own focus rect, since I didn't find +// // a way to draw the nice mac focus rect _inside_ this widget +// if (qobject_cast(style())) { +// painter.setPen(Qt::DotLine); +// painter.setBrush(Qt::NoBrush); +// painter.setOpacity(0.75); +// painter.drawRect(rect()); +// } else { +//#endif +// QStyleOptionFocusRect option; +// option.initFrom(this); +// option.backgroundColor = palette().color(QPalette::Background); +// +// // Some styles require a certain state flag in order to draw the focus rect +// option.state |= QStyle::State_KeyboardFocusChange; +// +// style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter); +//#ifdef Q_WS_MAC +// } +//#endif +// } +//#endif +//} + +/* Contract: return SplitterOrView that is not splitter, or 0 if not found. + * Implications: must not return SplitterOrView that is splitter. + */ +SplitterOrView *SplitterOrView::findFirstView() +{ + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) + if (SplitterOrView *result = splitterOrView->findFirstView()) + return result; + } + return 0; + } + return this; +} + +/* Contract: return SplitterOrView that has 'uavGadget', or 0 if not found. + * Implications: must not return SplitterOrView that is splitter. + */ +SplitterOrView *SplitterOrView::findView(Core::IUAVGadget *uavGadget) +{ + if (!uavGadget || hasGadget(uavGadget)) + return this; + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) + if (SplitterOrView *result = splitterOrView->findView(uavGadget)) + return result; + } + } + return 0; +} + +/* Contract: return SplitterOrView that has 'view', or 0 if not found. + * Implications: must not return SplitterOrView that is splitter. + */ +SplitterOrView *SplitterOrView::findView(UAVGadgetView *view) +{ + if (view == m_view) + return this; + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) + if (SplitterOrView *result = splitterOrView->findView(view)) + return result; + } + } + return 0; +} + +/* Contract: return SplitterOrView that is splitter that has as child SplitterOrView containing 'uavGadget', + * or 0 if not found. + * Implications: must return SplitterOrView that is splitter. + */ +SplitterOrView *SplitterOrView::findSplitter(Core::IUAVGadget *uavGadget) +{ + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { + if (splitterOrView->hasGadget(uavGadget)) + return this; + if (SplitterOrView *result = splitterOrView->findSplitter(uavGadget)) + return result; + } + } + } + return 0; +} + +/* Contract: return SplitterOrView that is splitter that has as child SplitterOrView 'child', + * or 0 if not found. + * Implications: must return SplitterOrView that is splitter. + */ +SplitterOrView *SplitterOrView::findSplitter(SplitterOrView *child) +{ + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { + if (splitterOrView == child) + return this; + if (SplitterOrView *result = splitterOrView->findSplitter(child)) + return result; + } + } + } + return 0; +} + +/* Contract: return SplitterOrView that follows SplitterOrView 'view' in tree structure, + * or 0 if not found. + * Implications: must not return SplitterOrView that is splitter. + */ +SplitterOrView *SplitterOrView::findNextView(SplitterOrView *view) +{ + bool found = false; + return findNextView_helper(view, &found); +} + +SplitterOrView *SplitterOrView::findNextView_helper(SplitterOrView *view, bool *found) +{ + if (*found && m_view) { + return this; + } + + if (this == view) { + *found = true; + return 0; + } + + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { + if (SplitterOrView *result = splitterOrView->findNextView_helper(view, found)) + return result; + } + } + } + return 0; +} + +QSize SplitterOrView::minimumSizeHint() const +{ + if (m_splitter) + return m_splitter->minimumSizeHint(); + return QSize(64, 64); +} + +QSplitter *SplitterOrView::takeSplitter() +{ + QSplitter *oldSplitter = m_splitter; + if (m_splitter) + m_layout->removeWidget(m_splitter); + m_splitter = 0; + return oldSplitter; +} + +UAVGadgetView *SplitterOrView::takeView() +{ + UAVGadgetView *oldView = m_view; + if (m_view) + m_layout->removeWidget(m_view); + m_view = 0; + return oldView; +} + +QList SplitterOrView::gadgets() +{ + QList g; + if (hasGadget()) + g.append(gadget()); + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { + QList result = splitterOrView->gadgets(); + g.append(result); + } + } + } + return g; +} + +void SplitterOrView::split(Qt::Orientation orientation) +{ + Q_ASSERT(m_view && (m_splitter == 0)); + m_splitter = new MiniSplitter(this); + m_splitter->setOrientation(orientation); + connect(m_splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(onSplitterMoved(int,int))); + m_layout->addWidget(m_splitter); + Core::IUAVGadget *ourGadget = m_view->gadget(); + + SplitterOrView *view = 0; + SplitterOrView *otherView = 0; + if (ourGadget) { + // Give our gadget to the new left or top SplitterOrView. + m_view->removeGadget(); + m_splitter->addWidget((view = new SplitterOrView(m_uavGadgetManager, ourGadget))); + m_splitter->addWidget((otherView = new SplitterOrView(m_uavGadgetManager))); + } else { + m_splitter->addWidget((otherView = new SplitterOrView(m_uavGadgetManager))); + m_splitter->addWidget((view = new SplitterOrView(m_uavGadgetManager))); + } + + m_layout->setCurrentWidget(m_splitter); + + if (m_view && !m_isRoot) { + m_uavGadgetManager->emptyView(m_view); + delete m_view; + m_view = 0; + } +} + +void SplitterOrView::onSplitterMoved( int pos, int index ) { + Q_UNUSED(pos); + Q_UNUSED(index); + // Update when the splitter is actually moved. + m_sizes = m_splitter->sizes(); +} + +void SplitterOrView::unsplitAll() +{ + Q_ASSERT(m_splitter); + m_splitter->hide(); + m_layout->removeWidget(m_splitter); // workaround Qt bug + unsplitAll_helper(); + delete m_splitter; + m_splitter = 0; +} + +void SplitterOrView::unsplitAll_helper() +{ + if (!m_isRoot && m_view) + m_uavGadgetManager->emptyView(m_view); + if (m_splitter) { + for (int i = 0; i < m_splitter->count(); ++i) { + if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { + splitterOrView->unsplitAll_helper(); + } + } + } +} + +void SplitterOrView::unsplit() +{ + if (!m_splitter) + return; + Q_ASSERT(m_splitter->count() == 1); + SplitterOrView *childSplitterOrView = qobject_cast(m_splitter->widget(0)); + QSplitter *oldSplitter = m_splitter; + m_splitter = 0; + + if (childSplitterOrView->isSplitter()) { + Q_ASSERT(childSplitterOrView->view() == 0); + m_splitter = childSplitterOrView->takeSplitter(); + m_layout->addWidget(m_splitter); + m_layout->setCurrentWidget(m_splitter); + } else { + UAVGadgetView *childView = childSplitterOrView->view(); + Q_ASSERT(childView); + if (m_view) { + if (IUAVGadget *e = childView->gadget()) { + childView->removeGadget(); + m_view->setGadget(e); + } + m_uavGadgetManager->emptyView(childView); + } else { + m_view = childSplitterOrView->takeView(); + m_layout->addWidget(m_view); + } + m_layout->setCurrentWidget(m_view); + } + delete oldSplitter; + m_uavGadgetManager->setCurrentGadget(findFirstView()->gadget()); +} + +void SplitterOrView::saveState(QSettings* qSettings) const { + if (m_splitter) { + qSettings->setValue("type", "splitter"); + qSettings->setValue("splitterOrientation", (qint32)m_splitter->orientation()); + QList sizesQVariant; + foreach (int value, m_sizes) { + sizesQVariant.append(value); + } + qSettings->setValue("splitterSizes", sizesQVariant); + qSettings->beginGroup("side0"); + static_cast(m_splitter->widget(0))->saveState(qSettings); + qSettings->endGroup(); + qSettings->beginGroup("side1"); + static_cast(m_splitter->widget(1))->saveState(qSettings); + qSettings->endGroup(); + } else if (gadget()) { + qSettings->setValue("type", "uavGadget"); + qSettings->setValue("classId", gadget()->classId()); + qSettings->beginGroup("gadget"); + gadget()->saveState(qSettings); + qSettings->endGroup(); + } +} + +void SplitterOrView::restoreState(QSettings* qSettings) +{ + QString mode = qSettings->value("type").toString(); + if (mode == "splitter") { + qint32 orientation = qSettings->value("splitterOrientation").toInt(); + QList sizesQVariant = qSettings->value("splitterSizes").toList(); + m_sizes.clear(); + foreach (QVariant value, sizesQVariant) { + m_sizes.append(value.toInt()); + } + split((Qt::Orientation)orientation); + m_splitter->setSizes(m_sizes); + qSettings->beginGroup("side0"); + static_cast(m_splitter->widget(0))->restoreState(qSettings); + qSettings->endGroup(); + qSettings->beginGroup("side1"); + static_cast(m_splitter->widget(1))->restoreState(qSettings); + qSettings->endGroup(); + } else if (mode == "uavGadget") { + QString classId = qSettings->value("classId").toString(); + int index = m_view->indexOfClassId(classId); + m_view->listSelectionActivated(index); + if(qSettings->childGroups().contains("gadget")) { + qSettings->beginGroup("gadget"); + gadget()->restoreState(qSettings); + qSettings->endGroup(); + } + } +} + +void SplitterOrView::restoreState(const QByteArray &state) +{ + QDataStream stream(state); + QByteArray mode; + stream >> mode; + if (mode == "splitter") { + qint32 orientation; + QByteArray splitter, first, second; + stream >> orientation >> splitter >> first >> second; + split((Qt::Orientation)orientation); + m_splitter->restoreState(splitter); + + // TODO: Lots of ugly, but this whole method should dissapear ASAP, + // It's here only for temporary backwards compatability. + m_sizes.clear(); + QDataStream stream(&splitter, QIODevice::ReadOnly); + qint32 marker; + qint32 v; + stream >> marker; + stream >> v; + stream >> m_sizes; + + + static_cast(m_splitter->widget(0))->restoreState(first); + static_cast(m_splitter->widget(1))->restoreState(second); + } else if (mode == "uavGadget") { + QString classId; + QByteArray uavGadgetState; + stream >> classId >> uavGadgetState; + int index = m_view->indexOfClassId(classId); + m_view->listSelectionActivated(index); + gadget()->restoreState(uavGadgetState); + } +} diff --git a/ground/src/plugins/coreplugin/uavgadgetmanager/splitterorview.h b/ground/src/plugins/coreplugin/uavgadgetmanager/splitterorview.h new file mode 100644 index 000000000..89967d952 --- /dev/null +++ b/ground/src/plugins/coreplugin/uavgadgetmanager/splitterorview.h @@ -0,0 +1,102 @@ +/** + ****************************************************************************** + * + * @file splitterorview.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup CorePlugin Core Plugin + * @{ + * @brief The Core GCS plugin + *****************************************************************************/ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef SPLITTERORVIEW_H +#define SPLITTERORVIEW_H + +#include +#include +#include "uavgadgetmanager.h" +#include "uavgadgetview.h" + +namespace Core { + +namespace Internal { + +class SplitterOrView : public QWidget +{ + Q_OBJECT +public: + SplitterOrView(UAVGadgetManager *uavGadgetManager, Core::IUAVGadget *uavGadget = 0, bool root = false); + ~SplitterOrView(); + + void split(Qt::Orientation orientation); + void unsplit(); + + inline bool isView() const { return m_view != 0; } + inline bool isRoot() const { return m_isRoot; } + + inline bool isSplitter() const { return m_splitter != 0; } + inline Core::IUAVGadget *gadget() const { return m_view ? m_view->gadget() : 0; } + inline bool hasGadget(Core::IUAVGadget *uavGadget) const { return m_view && m_view->hasGadget(uavGadget); } + inline bool hasGadget() const { return m_view && (m_view->gadget() != 0); } + inline UAVGadgetView *view() const { return m_view; } + inline QSplitter *splitter() const { return m_splitter; } + QList gadgets(); + QSplitter *takeSplitter(); + UAVGadgetView *takeView(); + + void saveState(QSettings*) const; + void restoreState(const QByteArray &); + void restoreState(QSettings*); + + SplitterOrView *findView(Core::IUAVGadget *uavGadget); + SplitterOrView *findView(UAVGadgetView *view); + SplitterOrView *findFirstView(); + SplitterOrView *findSplitter(Core::IUAVGadget *uavGadget); + SplitterOrView *findSplitter(SplitterOrView *child); + + SplitterOrView *findNextView(SplitterOrView *view); + + QSize sizeHint() const { return minimumSizeHint(); } + QSize minimumSizeHint() const; + + void unsplitAll(); + +protected: +// void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent *e); + +private slots: + void onSplitterMoved( int pos, int index ); + +private: + void unsplitAll_helper(); + SplitterOrView *findNextView_helper(SplitterOrView *view, bool *found); + UAVGadgetManager *m_uavGadgetManager; + bool m_isRoot; + QStackedLayout *m_layout; + UAVGadgetView *m_view; + QSplitter *m_splitter; + QList m_sizes; +}; + + +} +} +#endif // SPLITTERORVIEW_H diff --git a/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetmanager.cpp b/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetmanager.cpp index daa21f014..d01630325 100644 --- a/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetmanager.cpp +++ b/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetmanager.cpp @@ -28,6 +28,7 @@ #include "uavgadgetmanager.h" #include "uavgadgetview.h" +#include "splitterorview.h" #include "uavgadgetmode.h" #include "uavgadgetinstancemanager.h" #include "iuavgadgetfactory.h" @@ -126,11 +127,16 @@ namespace Core { struct UAVGadgetManagerPrivate { explicit UAVGadgetManagerPrivate(ICore *core, QWidget *parent); ~UAVGadgetManagerPrivate(); - Internal::SplitterOrView *m_splitterOrView; + + // The root splitter or view. + QPointer m_splitterOrView; + + // The gadget which is currently 'active'. QPointer m_currentGadget; - ICore *m_core; - Internal::UAVGadgetClosingCoreListener *m_coreListener; + QPointer m_core; + + QPointer m_coreListener; // actions static QAction *m_showToolbarsAction; @@ -151,6 +157,7 @@ QAction *UAVGadgetManagerPrivate::m_gotoOtherSplitAction = 0; UAVGadgetManagerPrivate::UAVGadgetManagerPrivate(ICore *core, QWidget *parent) : m_splitterOrView(0), + m_currentGadget(0), m_core(core), m_coreListener(0) { @@ -260,6 +267,10 @@ UAVGadgetManager::UAVGadgetManager(ICore *core, QWidget *parent) : // other setup m_d->m_splitterOrView = new SplitterOrView(this, 0, true); + // SplitterOrView with 0 as gadget calls our setCurrentGadget, which relies on currentSplitterOrView(), + // which needs our m_splitterorView to be set, which isn't set yet at that time. + // So directly set our currentGadget to 0, and do it again. + m_d->m_currentGadget = 0; setCurrentGadget(m_d->m_splitterOrView->view()->gadget()); QHBoxLayout *layout = new QHBoxLayout(this); diff --git a/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp b/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp index 6f5f4386b..a86b52d17 100644 --- a/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp +++ b/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.cpp @@ -61,8 +61,6 @@ Q_DECLARE_METATYPE(Core::IUAVGadget *) using namespace Core; using namespace Core::Internal; -// ================UAVGadgetView==================== - UAVGadgetView::UAVGadgetView(Core::UAVGadgetManager *uavGadgetManager, IUAVGadget *uavGadget, QWidget *parent) : QWidget(parent), m_uavGadgetManager(uavGadgetManager), @@ -252,423 +250,3 @@ void UAVGadgetView::currentGadgetChanged(IUAVGadget *gadget) { m_activeLabel->setVisible(m_uavGadget == gadget); } - -SplitterOrView::SplitterOrView(Core::UAVGadgetManager *uavGadgetManager, Core::IUAVGadget *uavGadget, bool isRoot) : - m_uavGadgetManager(uavGadgetManager), - m_isRoot(isRoot) -{ - m_view = new UAVGadgetView(m_uavGadgetManager, uavGadget, this); - m_layout = new QStackedLayout(this); - m_splitter = 0; - m_layout->addWidget(m_view); -} - -SplitterOrView::~SplitterOrView() -{ - delete m_view; - m_view = 0; - delete m_splitter; - m_splitter = 0; -} - -void SplitterOrView::mousePressEvent(QMouseEvent *e) -{ - if (e->button() != Qt::LeftButton) - return; - if (gadget()) { - setFocus(Qt::MouseFocusReason); - m_uavGadgetManager->setCurrentGadget(this->gadget()); - } -} - -//void SplitterOrView::paintEvent(QPaintEvent *event) -//{ -// if (m_uavGadgetManager->currentSplitterOrView() != this) -// return; -// -// if (!m_view) -// return; -// -// if (hasGadget()) -// return; -// -// if (m_uavGadgetManager->toolbarsShown()) -// return; -// -// // Discreet indication where an uavGadget would be if there is none -// QPainter painter(this); -// painter.setRenderHint(QPainter::Antialiasing, true); -// painter.setPen(Qt::NoPen); -// QColor shadeBrush(Qt::black); -// shadeBrush.setAlpha(25); -// painter.setBrush(shadeBrush); -// const int r = 3; -// painter.drawRoundedRect(rect().adjusted(r, r, -r, -r), r * 2, r * 2); -// -//#if 0 -// if (hasFocus()) { -//#ifdef Q_WS_MAC -// // With QMacStyle, we have to draw our own focus rect, since I didn't find -// // a way to draw the nice mac focus rect _inside_ this widget -// if (qobject_cast(style())) { -// painter.setPen(Qt::DotLine); -// painter.setBrush(Qt::NoBrush); -// painter.setOpacity(0.75); -// painter.drawRect(rect()); -// } else { -//#endif -// QStyleOptionFocusRect option; -// option.initFrom(this); -// option.backgroundColor = palette().color(QPalette::Background); -// -// // Some styles require a certain state flag in order to draw the focus rect -// option.state |= QStyle::State_KeyboardFocusChange; -// -// style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &painter); -//#ifdef Q_WS_MAC -// } -//#endif -// } -//#endif -//} - -/* Contract: return SplitterOrView that is not splitter, or 0 if not found. - * Implications: must not return SplitterOrView that is splitter. - */ -SplitterOrView *SplitterOrView::findFirstView() -{ - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) - if (SplitterOrView *result = splitterOrView->findFirstView()) - return result; - } - return 0; - } - return this; -} - -/* Contract: return SplitterOrView that has 'uavGadget', or 0 if not found. - * Implications: must not return SplitterOrView that is splitter. - */ -SplitterOrView *SplitterOrView::findView(Core::IUAVGadget *uavGadget) -{ - if (!uavGadget || hasGadget(uavGadget)) - return this; - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) - if (SplitterOrView *result = splitterOrView->findView(uavGadget)) - return result; - } - } - return 0; -} - -/* Contract: return SplitterOrView that has 'view', or 0 if not found. - * Implications: must not return SplitterOrView that is splitter. - */ -SplitterOrView *SplitterOrView::findView(UAVGadgetView *view) -{ - if (view == m_view) - return this; - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) - if (SplitterOrView *result = splitterOrView->findView(view)) - return result; - } - } - return 0; -} - -/* Contract: return SplitterOrView that is splitter that has as child SplitterOrView containing 'uavGadget', - * or 0 if not found. - * Implications: must return SplitterOrView that is splitter. - */ -SplitterOrView *SplitterOrView::findSplitter(Core::IUAVGadget *uavGadget) -{ - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { - if (splitterOrView->hasGadget(uavGadget)) - return this; - if (SplitterOrView *result = splitterOrView->findSplitter(uavGadget)) - return result; - } - } - } - return 0; -} - -/* Contract: return SplitterOrView that is splitter that has as child SplitterOrView 'child', - * or 0 if not found. - * Implications: must return SplitterOrView that is splitter. - */ -SplitterOrView *SplitterOrView::findSplitter(SplitterOrView *child) -{ - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { - if (splitterOrView == child) - return this; - if (SplitterOrView *result = splitterOrView->findSplitter(child)) - return result; - } - } - } - return 0; -} - -/* Contract: return SplitterOrView that follows SplitterOrView 'view' in tree structure, - * or 0 if not found. - * Implications: must not return SplitterOrView that is splitter. - */ -SplitterOrView *SplitterOrView::findNextView(SplitterOrView *view) -{ - bool found = false; - return findNextView_helper(view, &found); -} - -SplitterOrView *SplitterOrView::findNextView_helper(SplitterOrView *view, bool *found) -{ - if (*found && m_view) { - return this; - } - - if (this == view) { - *found = true; - return 0; - } - - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { - if (SplitterOrView *result = splitterOrView->findNextView_helper(view, found)) - return result; - } - } - } - return 0; -} - -QSize SplitterOrView::minimumSizeHint() const -{ - if (m_splitter) - return m_splitter->minimumSizeHint(); - return QSize(64, 64); -} - -QSplitter *SplitterOrView::takeSplitter() -{ - QSplitter *oldSplitter = m_splitter; - if (m_splitter) - m_layout->removeWidget(m_splitter); - m_splitter = 0; - return oldSplitter; -} - -UAVGadgetView *SplitterOrView::takeView() -{ - UAVGadgetView *oldView = m_view; - if (m_view) - m_layout->removeWidget(m_view); - m_view = 0; - return oldView; -} - -QList SplitterOrView::gadgets() -{ - QList g; - if (hasGadget()) - g.append(gadget()); - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { - QList result = splitterOrView->gadgets(); - g.append(result); - } - } - } - return g; -} - -void SplitterOrView::split(Qt::Orientation orientation) -{ - Q_ASSERT(m_view && (m_splitter == 0)); - m_splitter = new MiniSplitter(this); - m_splitter->setOrientation(orientation); - connect(m_splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(onSplitterMoved(int,int))); - m_layout->addWidget(m_splitter); - Core::IUAVGadget *e = m_view->gadget(); - - SplitterOrView *view = 0; - SplitterOrView *otherView = 0; - if (e) { - m_view->removeGadget(); - m_splitter->addWidget((view = new SplitterOrView(m_uavGadgetManager, e))); - m_splitter->addWidget((otherView = new SplitterOrView(m_uavGadgetManager))); - } else { - m_splitter->addWidget((otherView = new SplitterOrView(m_uavGadgetManager))); - m_splitter->addWidget((view = new SplitterOrView(m_uavGadgetManager))); - } - - m_layout->setCurrentWidget(m_splitter); - - if (m_view && !m_isRoot) { - m_uavGadgetManager->emptyView(m_view); - delete m_view; - m_view = 0; - } -} - -void SplitterOrView::onSplitterMoved( int pos, int index ) { - Q_UNUSED(pos); - Q_UNUSED(index); - // Update when the splitter is actually moved. - m_sizes = m_splitter->sizes(); -} - -void SplitterOrView::unsplitAll() -{ - m_splitter->hide(); - m_layout->removeWidget(m_splitter); // workaround Qt bug - unsplitAll_helper(); - delete m_splitter; - m_splitter = 0; -} - -void SplitterOrView::unsplitAll_helper() -{ - if (!m_isRoot && m_view) - m_uavGadgetManager->emptyView(m_view); - if (m_splitter) { - for (int i = 0; i < m_splitter->count(); ++i) { - if (SplitterOrView *splitterOrView = qobject_cast(m_splitter->widget(i))) { - splitterOrView->unsplitAll_helper(); - } - } - } -} - -void SplitterOrView::unsplit() -{ - if (!m_splitter) - return; - Q_ASSERT(m_splitter->count() == 1); - SplitterOrView *childSplitterOrView = qobject_cast(m_splitter->widget(0)); - QSplitter *oldSplitter = m_splitter; - m_splitter = 0; - - if (childSplitterOrView->isSplitter()) { - Q_ASSERT(childSplitterOrView->view() == 0); - m_splitter = childSplitterOrView->takeSplitter(); - m_layout->addWidget(m_splitter); - m_layout->setCurrentWidget(m_splitter); - } else { - UAVGadgetView *childView = childSplitterOrView->view(); - Q_ASSERT(childView); - if (m_view) { - if (IUAVGadget *e = childView->gadget()) { - childView->removeGadget(); - m_view->setGadget(e); - } - m_uavGadgetManager->emptyView(childView); - } else { - m_view = childSplitterOrView->takeView(); - m_layout->addWidget(m_view); - } - m_layout->setCurrentWidget(m_view); - } - delete oldSplitter; - m_uavGadgetManager->setCurrentGadget(findFirstView()->gadget()); -} - -void SplitterOrView::saveState(QSettings* qSettings) const { - if (m_splitter) { - qSettings->setValue("type", "splitter"); - qSettings->setValue("splitterOrientation", (qint32)m_splitter->orientation()); - QList sizesQVariant; - foreach (int value, m_sizes) { - sizesQVariant.append(value); - } - qSettings->setValue("splitterSizes", sizesQVariant); - qSettings->beginGroup("side0"); - static_cast(m_splitter->widget(0))->saveState(qSettings); - qSettings->endGroup(); - qSettings->beginGroup("side1"); - static_cast(m_splitter->widget(1))->saveState(qSettings); - qSettings->endGroup(); - } else if (gadget()) { - qSettings->setValue("type", "uavGadget"); - qSettings->setValue("classId", gadget()->classId()); - qSettings->beginGroup("gadget"); - gadget()->saveState(qSettings); - qSettings->endGroup(); - } -} - -void SplitterOrView::restoreState(QSettings* qSettings) -{ - QString mode = qSettings->value("type").toString(); - if (mode == "splitter") { - qint32 orientation = qSettings->value("splitterOrientation").toInt(); - QList sizesQVariant = qSettings->value("splitterSizes").toList(); - m_sizes.clear(); - foreach (QVariant value, sizesQVariant) { - m_sizes.append(value.toInt()); - } - split((Qt::Orientation)orientation); - m_splitter->setSizes(m_sizes); - qSettings->beginGroup("side0"); - static_cast(m_splitter->widget(0))->restoreState(qSettings); - qSettings->endGroup(); - qSettings->beginGroup("side1"); - static_cast(m_splitter->widget(1))->restoreState(qSettings); - qSettings->endGroup(); - } else if (mode == "uavGadget") { - QString classId = qSettings->value("classId").toString(); - int index = m_view->indexOfClassId(classId); - m_view->listSelectionActivated(index); - if(qSettings->childGroups().contains("gadget")) { - qSettings->beginGroup("gadget"); - gadget()->restoreState(qSettings); - qSettings->endGroup(); - } - } -} - -void SplitterOrView::restoreState(const QByteArray &state) -{ - QDataStream stream(state); - QByteArray mode; - stream >> mode; - if (mode == "splitter") { - qint32 orientation; - QByteArray splitter, first, second; - stream >> orientation >> splitter >> first >> second; - split((Qt::Orientation)orientation); - m_splitter->restoreState(splitter); - - // TODO: Lots of ugly, but this whole method should dissapear ASAP, - // It's here only for temporary backwards compatability. - m_sizes.clear(); - QDataStream stream(&splitter, QIODevice::ReadOnly); - qint32 marker; - qint32 v; - stream >> marker; - stream >> v; - stream >> m_sizes; - - - static_cast(m_splitter->widget(0))->restoreState(first); - static_cast(m_splitter->widget(1))->restoreState(second); - } else if (mode == "uavGadget") { - QString classId; - QByteArray uavGadgetState; - stream >> classId >> uavGadgetState; - int index = m_view->indexOfClassId(classId); - m_view->listSelectionActivated(index); - gadget()->restoreState(uavGadgetState); - } -} diff --git a/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h b/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h index 65a75d15d..874e775fb 100644 --- a/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h +++ b/ground/src/plugins/coreplugin/uavgadgetmanager/uavgadgetview.h @@ -98,64 +98,6 @@ private: QLabel *m_activeLabel; }; -class SplitterOrView : public QWidget -{ - Q_OBJECT -public: - SplitterOrView(UAVGadgetManager *uavGadgetManager, Core::IUAVGadget *uavGadget = 0, bool root = false); - ~SplitterOrView(); - - void split(Qt::Orientation orientation); - void unsplit(); - - inline bool isView() const { return m_view != 0; } - inline bool isRoot() const { return m_isRoot; } - - inline bool isSplitter() const { return m_splitter != 0; } - inline Core::IUAVGadget *gadget() const { return m_view ? m_view->gadget() : 0; } - inline bool hasGadget(Core::IUAVGadget *uavGadget) const { return m_view && m_view->hasGadget(uavGadget); } - inline bool hasGadget() const { return m_view && (m_view->gadget() != 0); } - inline UAVGadgetView *view() const { return m_view; } - inline QSplitter *splitter() const { return m_splitter; } - QList gadgets(); - QSplitter *takeSplitter(); - UAVGadgetView *takeView(); - - void saveState(QSettings*) const; - void restoreState(const QByteArray &); - void restoreState(QSettings*); - - SplitterOrView *findView(Core::IUAVGadget *uavGadget); - SplitterOrView *findView(UAVGadgetView *view); - SplitterOrView *findFirstView(); - SplitterOrView *findSplitter(Core::IUAVGadget *uavGadget); - SplitterOrView *findSplitter(SplitterOrView *child); - - SplitterOrView *findNextView(SplitterOrView *view); - - QSize sizeHint() const { return minimumSizeHint(); } - QSize minimumSizeHint() const; - - void unsplitAll(); - -protected: -// void paintEvent(QPaintEvent *); - void mousePressEvent(QMouseEvent *e); - -private slots: - void onSplitterMoved( int pos, int index ); - -private: - void unsplitAll_helper(); - SplitterOrView *findNextView_helper(SplitterOrView *view, bool *found); - UAVGadgetManager *m_uavGadgetManager; - bool m_isRoot; - QStackedLayout *m_layout; - UAVGadgetView *m_view; - QSplitter *m_splitter; - QList m_sizes; -}; - } } #endif // UAVGADGETVIEW_H