1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-02-20 10:54:14 +01:00

GCS: 'This file isn't big enough for the two of us!' Moved SplitterOrView to it's own files, makes stuff easier to figure out :)

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1752 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
cranphin 2010-09-25 18:56:57 +00:00 committed by cranphin
parent 9bf6bbcbeb
commit 467bb42b02
6 changed files with 605 additions and 483 deletions

View File

@ -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 \

View File

@ -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 <coreplugin/coreconstants.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <utils/qtcassert.h>
#include <utils/styledbar.h>
#include <QtCore/QDebug>
#include <QtGui/QApplication>
#include <QtGui/QComboBox>
#include <QtGui/QHBoxLayout>
#include <QtGui/QLabel>
#include <QtGui/QMouseEvent>
#include <QtGui/QPainter>
#include <QtGui/QStyle>
#include <QtGui/QStyleOption>
#include <QtGui/QToolButton>
#include <QtGui/QMenu>
#include <QtGui/QClipboard>
#ifdef Q_WS_MAC
#include <qmacstyle_mac.h>
#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<QMacStyle *>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<IUAVGadget*> SplitterOrView::gadgets()
{
QList<IUAVGadget*> g;
if (hasGadget())
g.append(gadget());
if (m_splitter) {
for (int i = 0; i < m_splitter->count(); ++i) {
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i))) {
QList<IUAVGadget*> 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<SplitterOrView*>(m_splitter->widget(i))) {
splitterOrView->unsplitAll_helper();
}
}
}
}
void SplitterOrView::unsplit()
{
if (!m_splitter)
return;
Q_ASSERT(m_splitter->count() == 1);
SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView*>(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<QVariant> sizesQVariant;
foreach (int value, m_sizes) {
sizesQVariant.append(value);
}
qSettings->setValue("splitterSizes", sizesQVariant);
qSettings->beginGroup("side0");
static_cast<SplitterOrView*>(m_splitter->widget(0))->saveState(qSettings);
qSettings->endGroup();
qSettings->beginGroup("side1");
static_cast<SplitterOrView*>(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<QVariant> 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<SplitterOrView*>(m_splitter->widget(0))->restoreState(qSettings);
qSettings->endGroup();
qSettings->beginGroup("side1");
static_cast<SplitterOrView*>(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<SplitterOrView*>(m_splitter->widget(0))->restoreState(first);
static_cast<SplitterOrView*>(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);
}
}

View File

@ -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 <QWidget>
#include <QtGui/QMouseEvent>
#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<Core::IUAVGadget*> 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<int> m_sizes;
};
}
}
#endif // SPLITTERORVIEW_H

View File

@ -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<Internal::SplitterOrView> m_splitterOrView;
// The gadget which is currently 'active'.
QPointer<IUAVGadget> m_currentGadget;
ICore *m_core;
Internal::UAVGadgetClosingCoreListener *m_coreListener;
QPointer<ICore> m_core;
QPointer<Internal::UAVGadgetClosingCoreListener> 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);

View File

@ -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<QMacStyle *>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<SplitterOrView*>(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<IUAVGadget*> SplitterOrView::gadgets()
{
QList<IUAVGadget*> g;
if (hasGadget())
g.append(gadget());
if (m_splitter) {
for (int i = 0; i < m_splitter->count(); ++i) {
if (SplitterOrView *splitterOrView = qobject_cast<SplitterOrView*>(m_splitter->widget(i))) {
QList<IUAVGadget*> 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<SplitterOrView*>(m_splitter->widget(i))) {
splitterOrView->unsplitAll_helper();
}
}
}
}
void SplitterOrView::unsplit()
{
if (!m_splitter)
return;
Q_ASSERT(m_splitter->count() == 1);
SplitterOrView *childSplitterOrView = qobject_cast<SplitterOrView*>(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<QVariant> sizesQVariant;
foreach (int value, m_sizes) {
sizesQVariant.append(value);
}
qSettings->setValue("splitterSizes", sizesQVariant);
qSettings->beginGroup("side0");
static_cast<SplitterOrView*>(m_splitter->widget(0))->saveState(qSettings);
qSettings->endGroup();
qSettings->beginGroup("side1");
static_cast<SplitterOrView*>(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<QVariant> 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<SplitterOrView*>(m_splitter->widget(0))->restoreState(qSettings);
qSettings->endGroup();
qSettings->beginGroup("side1");
static_cast<SplitterOrView*>(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<SplitterOrView*>(m_splitter->widget(0))->restoreState(first);
static_cast<SplitterOrView*>(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);
}
}

View File

@ -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<Core::IUAVGadget*> 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<int> m_sizes;
};
}
}
#endif // UAVGADGETVIEW_H