editorwidget.cpp 8.71 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
7
8
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
9
** Commercial Usage
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
26
** If you are unsure which license is appropriate for your use, please
** contact the sales department at qt-sales@nokia.com.
con's avatar
con committed
27
**
28
**************************************************************************/
con's avatar
con committed
29
30
31
32

#include "editorwidget.h"
#include "formeditorw.h"

hjk's avatar
hjk committed
33
#include <coreplugin/minisplitter.h>
hjk's avatar
hjk committed
34
#include <utils/qtcassert.h>
hjk's avatar
hjk committed
35

con's avatar
con committed
36
37
38
39
40
41
42
43
#include <QtCore/QEvent>
#include <QtGui/QVBoxLayout>
#include <QtGui/QTabWidget>

using namespace Designer::Constants;

enum { ActionEditorTab, SignalSlotEditorTab };

con's avatar
con committed
44
enum { wantSignalSlotEditor = 1 };
con's avatar
con committed
45
46
47
48

namespace Designer {
namespace Internal {

hjk's avatar
hjk committed
49
50
51
52
53
SharedSubWindow::SharedSubWindow(QWidget *shared, QWidget *parent) :
   QWidget(parent),
   m_shared(shared),
   m_layout(new QVBoxLayout)
{
hjk's avatar
hjk committed
54
    QTC_ASSERT(m_shared, /**/);
hjk's avatar
hjk committed
55
56
57
    m_layout->setContentsMargins(0, 0, 0, 0);
    setLayout(m_layout);
}
con's avatar
con committed
58

hjk's avatar
hjk committed
59
60
61
void SharedSubWindow::activate()
{
    // Take the widget off the other parent
hjk's avatar
hjk committed
62
    QTC_ASSERT(m_shared, return);
hjk's avatar
hjk committed
63
64
65
    QWidget *currentParent = m_shared->parentWidget();
    if (currentParent == this)
        return;
con's avatar
con committed
66

hjk's avatar
hjk committed
67
68
    if (currentParent) {
        QVBoxLayout *lt = qobject_cast<QVBoxLayout *>(currentParent->layout());
hjk's avatar
hjk committed
69
        QTC_ASSERT(lt, return);
hjk's avatar
hjk committed
70
71
        m_shared->setParent(0);
        delete lt->takeAt(0);
con's avatar
con committed
72
    }
hjk's avatar
hjk committed
73
74
75
    m_layout->addWidget(m_shared);
    m_layout->invalidate();
}
con's avatar
con committed
76

hjk's avatar
hjk committed
77
78
79
80
81
82
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);
con's avatar
con committed
83
    }
hjk's avatar
hjk committed
84
}
con's avatar
con committed
85

hjk's avatar
hjk committed
86
87
// ---------- Global EditorState
Q_GLOBAL_STATIC(EditorWidgetState, editorWidgetState)
con's avatar
con committed
88

hjk's avatar
hjk committed
89
90
91
92
93
94
95
96
97
98
enum { Version = 1 };
// Simple conversion of an int list to QVariantList, size as leading element
static void intToVariantList(const QList<int> &il, QVariantList& vl)
{
    const int size = il.size();
    vl.push_back(size);
    if (size != 0) {
        const QList<int>::const_iterator cend = il.constEnd();
        for (QList<int>::const_iterator it = il.constBegin(); it != cend; ++it)
            vl.push_back(QVariant(*it));
con's avatar
con committed
99
    }
hjk's avatar
hjk committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
}
// Simple conversion of a QVariantList portion saved by the above function to int list
bool variantListToIntList(const QVariantList& vl, int &index, QList<int> &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());
con's avatar
con committed
114
    }
hjk's avatar
hjk committed
115
116
    return true;
}
con's avatar
con committed
117

hjk's avatar
hjk committed
118
119
120
121
122
123
124
125
126
127
// ------------------ EditorWidgetState
QVariant EditorWidgetState::toVariant() const
{
    QVariantList rc;
    rc.push_back(Version);
    intToVariantList(horizontalSizes, rc);
    intToVariantList(centerVerticalSizes, rc);
    intToVariantList(rightVerticalSizes, rc);
    return QVariant(rc);
}
con's avatar
con committed
128

hjk's avatar
hjk committed
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
bool EditorWidgetState::fromVariant(const QVariant &v)
{
    // Restore state. The weird thing is that QSettings might return
    // a QStringList although it was saved as QVariantList<int>.
    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);
}
con's avatar
con committed
148

hjk's avatar
hjk committed
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// ---------- 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<SharedSubWindow*>(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]);
con's avatar
con committed
166

hjk's avatar
hjk committed
167
168
    // center
    m_centerVertSplitter->addWidget(formWindow);
con's avatar
con committed
169

hjk's avatar
hjk committed
170
171
172
    if (wantSignalSlotEditor) {
        m_bottomTab = new QTabWidget;
        m_bottomTab->setTabPosition(QTabWidget::South);
173
        m_bottomTab->setDocumentMode(true);
hjk's avatar
hjk committed
174
175
176
177
178
        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]);
con's avatar
con committed
179
180
    }

hjk's avatar
hjk committed
181
    addWidget(m_centerVertSplitter);
con's avatar
con committed
182

hjk's avatar
hjk committed
183
184
185
186
    m_rightVertSplitter->addWidget(m_designerSubWindows[ObjectInspectorSubWindow]);
    m_rightVertSplitter->addWidget(m_designerSubWindows[PropertyEditorSubWindow]);
    addWidget(m_rightVertSplitter);
}
con's avatar
con committed
187

hjk's avatar
hjk committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
void EditorWidget::setInitialSizes()
{
    QList<int> 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);
}
con's avatar
con committed
214

hjk's avatar
hjk committed
215
216
217
218
219
220
221
222
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();
}
con's avatar
con committed
223

hjk's avatar
hjk committed
224
225
226
227
228
229
bool EditorWidget::event(QEvent * e)
{
    if (e->type() == QEvent::Hide)
        *editorWidgetState() = save();
    return QSplitter::event(e);
}
con's avatar
con committed
230

hjk's avatar
hjk committed
231
232
233
234
235
236
237
238
EditorWidgetState EditorWidget::save() const
{
    EditorWidgetState rc;
    rc.horizontalSizes = sizes();
    rc.centerVerticalSizes = m_centerVertSplitter->sizes();
    rc.rightVerticalSizes = m_rightVertSplitter->sizes();
    return rc;
}
con's avatar
con committed
239

hjk's avatar
hjk committed
240
241
242
243
244
245
246
247
248
249
250
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;
}
con's avatar
con committed
251

hjk's avatar
hjk committed
252
253
254
255
void EditorWidget::toolChanged(int i)
{
    if (m_bottomTab)
        m_bottomTab->setCurrentIndex(i == EditModeSignalsSlotEditor ? SignalSlotEditorTab : ActionEditorTab);
con's avatar
con committed
256
}
hjk's avatar
hjk committed
257
258
259
260
261
262
263
264
265

EditorWidgetState EditorWidget::state()
{
    return *editorWidgetState();
}

void EditorWidget::setState(const EditorWidgetState& st)
{
    *editorWidgetState() = st;
con's avatar
con committed
266
}
hjk's avatar
hjk committed
267
268
269

} // namespace Internal
} // namespace Designer