/*************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** ** Non-Open Source Usage ** ** Licensees may use this file in accordance with the Qt Beta Version ** License Agreement, Agreement version 2.2 provided with the Software or, ** alternatively, in accordance with the terms contained in a written ** agreement between you and Nokia. ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU General ** Public License versions 2.0 or 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the packaging ** of this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and ** http://www.gnu.org/copyleft/gpl.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt GPL Exception ** version 1.3, included in the file GPL_EXCEPTION.txt in this package. ** ***************************************************************************/ #include "editorwidget.h" #include "formeditorw.h" #include #include #include #include #include using namespace Designer::Constants; enum { ActionEditorTab, SignalSlotEditorTab }; enum { wantSignalSlotEditor = 0 }; namespace Designer { namespace Internal { SharedSubWindow::SharedSubWindow(QWidget *shared, QWidget *parent) : QWidget(parent), m_shared(shared), m_layout(new QVBoxLayout) { QTC_ASSERT(m_shared, /**/); m_layout->setContentsMargins(0, 0, 0, 0); setLayout(m_layout); } void SharedSubWindow::activate() { // Take the widget off the other parent QTC_ASSERT(m_shared, return); QWidget *currentParent = m_shared->parentWidget(); if (currentParent == this) return; if (currentParent) { QVBoxLayout *lt = qobject_cast(currentParent->layout()); QTC_ASSERT(lt, return); m_shared->setParent(0); delete lt->takeAt(0); } m_layout->addWidget(m_shared); m_layout->invalidate(); } SharedSubWindow::~SharedSubWindow() { // Do not destroy the shared sub window if we currently own it if (m_layout->count()) { m_shared->setParent(0); delete m_layout->takeAt(0); } } // ---------- Global EditorState Q_GLOBAL_STATIC(EditorWidgetState, editorWidgetState) enum { Version = 1 }; // Simple conversion of an int list to QVariantList, size as leading element static void intToVariantList(const QList &il, QVariantList& vl) { const int size = il.size(); vl.push_back(size); if (size != 0) { const QList::const_iterator cend = il.constEnd(); for (QList::const_iterator it = il.constBegin(); it != cend; ++it) vl.push_back(QVariant(*it)); } } // Simple conversion of a QVariantList portion saved by the above function to int list bool variantListToIntList(const QVariantList& vl, int &index, QList &list) { list.clear(); if (index >= vl.size()) return false; const int size = vl.at(index++).toInt(); const int end = index + size; if (end > vl.size()) return false; if (size != 0) { for ( ; index < end; index++) list.push_back(vl.at(index).toInt()); } return true; } // ------------------ EditorWidgetState QVariant EditorWidgetState::toVariant() const { QVariantList rc; rc.push_back(Version); intToVariantList(horizontalSizes, rc); intToVariantList(centerVerticalSizes, rc); intToVariantList(rightVerticalSizes, rc); return QVariant(rc); } bool EditorWidgetState::fromVariant(const QVariant &v) { // Restore state. The weird thing is that QSettings might return // a QStringList although it was saved as QVariantList. if (v.type() != QVariant::List && v.type() != QVariant::StringList) return false; const QVariantList vl = v.toList(); if (vl.empty()) return false; int index = 0; const QVariant &versionV = vl.at(index++); if (versionV.type() != QVariant::Int && versionV.type() != QVariant::String) return false; if (versionV.toInt() > Version) return false; return variantListToIntList(vl, index, horizontalSizes) && variantListToIntList(vl, index, centerVerticalSizes) && variantListToIntList(vl, index, rightVerticalSizes); } // ---------- EditorWidget EditorWidget::EditorWidget(QWidget *formWindow) : Core::MiniSplitter(Qt::Horizontal), m_centerVertSplitter(new Core::MiniSplitter(Qt::Vertical)), m_bottomTab(0), m_rightVertSplitter(new Core::MiniSplitter(Qt::Vertical)) { // Get shared sub windows from Form Editor FormEditorW *few = FormEditorW::instance(); QWidget * const*subs = few->designerSubWindows(); // Create shared sub windows except SignalSlotEditor qFill(m_designerSubWindows, m_designerSubWindows + DesignerSubWindowCount, static_cast(0)); for (int i=0; i < DesignerSubWindowCount; i++) if (wantSignalSlotEditor || i != SignalSlotEditorSubWindow) m_designerSubWindows[i] = new SharedSubWindow(subs[i]); // Create splitter addWidget(m_designerSubWindows[WidgetBoxSubWindow]); // center m_centerVertSplitter->addWidget(formWindow); if (wantSignalSlotEditor) { m_bottomTab = new QTabWidget; m_bottomTab->setTabPosition(QTabWidget::South); m_bottomTab->addTab(m_designerSubWindows[ActionEditorSubWindow], tr("Action editor")); m_bottomTab->addTab(m_designerSubWindows[SignalSlotEditorSubWindow], tr("Signals and slots editor")); m_centerVertSplitter->addWidget(m_bottomTab); } else { m_centerVertSplitter->addWidget(m_designerSubWindows[ActionEditorSubWindow]); } addWidget(m_centerVertSplitter); m_rightVertSplitter->addWidget(m_designerSubWindows[ObjectInspectorSubWindow]); m_rightVertSplitter->addWidget(m_designerSubWindows[PropertyEditorSubWindow]); addWidget(m_rightVertSplitter); } void EditorWidget::setInitialSizes() { QList sizes; // center vertical. Either the tab containing signal slot editor/ // action editor or the action editor itself const QWidget *bottomWidget = m_bottomTab; if (!bottomWidget) bottomWidget = m_designerSubWindows[ActionEditorSubWindow]; const int tabHeight = bottomWidget->sizeHint().height(); sizes.push_back(height() - handleWidth() - tabHeight); sizes.push_back( tabHeight); m_centerVertSplitter->setSizes(sizes); // right vert sizes.clear(); sizes.push_back(height() /2 - (handleWidth() / 2)); sizes.push_back(height() / 2 - (handleWidth() / 2)); m_rightVertSplitter->setSizes(sizes); // horiz sizes sizes.clear(); const int wboxWidth = m_designerSubWindows[WidgetBoxSubWindow]->sizeHint().width(); const int vSplitterWidth = m_rightVertSplitter->sizeHint().width(); sizes.push_back(wboxWidth); sizes.push_back(width() - 2 * handleWidth() - wboxWidth - vSplitterWidth); sizes.push_back(vSplitterWidth); setSizes(sizes); } void EditorWidget::activate() { for (int i=0; i < DesignerSubWindowCount; i++) if (SharedSubWindow *sw = m_designerSubWindows[i]) // Signal slot might be deactivated sw->activate(); if (!restore(*editorWidgetState())) setInitialSizes(); } bool EditorWidget::event(QEvent * e) { if (e->type() == QEvent::Hide) *editorWidgetState() = save(); return QSplitter::event(e); } EditorWidgetState EditorWidget::save() const { EditorWidgetState rc; rc.horizontalSizes = sizes(); rc.centerVerticalSizes = m_centerVertSplitter->sizes(); rc.rightVerticalSizes = m_rightVertSplitter->sizes(); return rc; } bool EditorWidget::restore(const EditorWidgetState &s) { if (s.horizontalSizes.size() != count() || s.centerVerticalSizes.size() != m_centerVertSplitter->count() || s.rightVerticalSizes.size() != m_rightVertSplitter->count()) return false; m_centerVertSplitter->setSizes(s.centerVerticalSizes); m_rightVertSplitter->setSizes(s.rightVerticalSizes); setSizes(s.horizontalSizes); return true; } void EditorWidget::toolChanged(int i) { if (m_bottomTab) m_bottomTab->setCurrentIndex(i == EditModeSignalsSlotEditor ? SignalSlotEditorTab : ActionEditorTab); } EditorWidgetState EditorWidget::state() { return *editorWidgetState(); } void EditorWidget::setState(const EditorWidgetState& st) { *editorWidgetState() = st; } } // namespace Internal } // namespace Designer