1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the Qt Designer of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28
29 #include "qdesigneraxwidget.h"
30
31 #include <QtCore/qmetaobject.h>
32 #include <QtCore/qdebug.h>
33 #include <QtGui/qicon.h>
34 #include <QtGui/qpainter.h>
35 #include <QtGui/qevent.h>
36
37 #include <ActiveQt/QAxWidget>
38
39 #include <qt_windows.h>
40 #include <olectl.h>
41 #include <qaxtypes.h>
42
43 enum { debugAxWidget = 0 };
44
45 QT_BEGIN_NAMESPACE
46
47 /* XPM */
48 const char *widgetIconXPM[]={
49 "22 22 6 1",
50 "a c #000000",
51 "# c #808080",
52 "+ c #aaa5a0",
53 "b c #dddddd",
54 "* c #d4d0c8",
55 ". c none",
56 ".........#aa#...#aa#..",
57 ".........abba...abba..",
58 ".........abba...abba..",
59 ".........#aa#...#aa#..",
60 "..........aa.....aa...",
61 "..........aa.....aa...",
62 "..........aa.....aa...",
63 ".......aaaaaaaaaaaaaaa",
64 ".......a*************a",
65 ".......a************#a",
66 ".......a***********+#a",
67 ".......a***********+#a",
68 ".......a***********+#a",
69 "#aa#...a***********+#a",
70 "abbaaaaa***********+#a",
71 "abbaaaaa***********+#a",
72 "#aa#...a***********+#a",
73 ".......a***********+#a",
74 ".......a***********+#a",
75 ".......a**++++++++++#a",
76 ".......a*############a",
77 ".......aaaaaaaaaaaaaaa"};
78
QDesignerAxWidget(QWidget * parent)79 QDesignerAxWidget::QDesignerAxWidget(QWidget *parent) :
80 QWidget(parent),
81 m_axImage(widgetIcon())
82 {
83 }
84
~QDesignerAxWidget()85 QDesignerAxWidget::~QDesignerAxWidget()
86 {
87 delete m_axobject;
88 }
89
widgetIcon()90 QPixmap QDesignerAxWidget::widgetIcon()
91 {
92 return QPixmap(widgetIconXPM);
93 }
94
control() const95 QString QDesignerAxWidget::control() const
96 {
97 if (m_axobject)
98 return m_axobject->control();
99 return QString();
100 }
101
setControl(const QString & clsid)102 void QDesignerAxWidget::setControl(const QString &clsid)
103 {
104 if (clsid == control())
105 return;
106 if (clsid.isEmpty()) {
107 resetControl();
108 } else {
109 loadControl(clsid);
110 }
111 }
resetControl()112 void QDesignerAxWidget::resetControl()
113 {
114 if (!m_axobject)
115 return;
116 delete m_axobject;
117 m_axobject = nullptr;
118 update();
119 }
120
loadControl(const QString & clsid)121 bool QDesignerAxWidget::loadControl(const QString &clsid)
122 {
123 if (clsid.isEmpty())
124 return false;
125 if (m_axobject)
126 resetControl();
127 m_axobject = new QAxWidget();
128
129 if (!m_axobject->setControl(clsid)) {
130 delete m_axobject;
131 m_axobject = nullptr;
132 return false;
133 }
134 update();
135 return true;
136 }
137
sizeHint() const138 QSize QDesignerAxWidget::sizeHint() const
139 {
140 if (m_axobject)
141 return m_axobject->sizeHint();
142 return m_defaultSize;
143 }
144
minimumSizeHint() const145 QSize QDesignerAxWidget::minimumSizeHint() const
146 {
147 if (m_axobject)
148 return m_axobject->minimumSizeHint();
149 return QWidget::minimumSizeHint();
150 }
151
paintEvent(QPaintEvent *)152 void QDesignerAxWidget::paintEvent(QPaintEvent * /*event */)
153 {
154 QPainter p(this);
155 const QRect r = contentsRect();
156 const int contentsWidth = r.width();
157 const int contentsHeight= r.height();
158 if (m_axobject) { // QAxWidget has no concept of sizeHint()
159 if (m_drawFlags & DrawControl) {
160 m_axobject->resize(size());
161 m_axobject->render(&p, pos());
162 }
163 if (m_drawFlags & DrawIndicator) {
164 static const QString loaded = tr("Control loaded");
165 QColor patternColor(Qt::green);
166 if (m_drawFlags & DrawControl)
167 patternColor.setAlpha(80);
168 p.setBrush(QBrush(patternColor, Qt::BDiagPattern));
169 p.setPen(Qt::black);
170 if (r.height() > 5)
171 p.drawText(5,contentsHeight - 5, loaded);
172 }
173 }
174 if (m_drawFlags & DrawFrame) {
175 p.drawRect(r.adjusted(0, 0, -1, -1));
176 }
177 if (m_drawFlags & DrawIndicator) {
178 if (contentsWidth > m_axImage.width() && contentsHeight > m_axImage.height())
179 p.drawPixmap((contentsWidth - m_axImage.width()) / 2,
180 (contentsHeight-m_axImage.height()) / 2, m_axImage);
181 }
182 }
183
184 // --------- QDesignerAxPluginWidget
QDesignerAxPluginWidget(QWidget * parent)185 QDesignerAxPluginWidget::QDesignerAxPluginWidget(QWidget *parent) :
186 QDesignerAxWidget(parent)
187 {
188 }
189
190 QDesignerAxPluginWidget::~QDesignerAxPluginWidget() = default;
191
metaObject() const192 const QMetaObject *QDesignerAxPluginWidget::metaObject() const
193 {
194 if (const QAxWidget *aw = axobject())
195 return aw->metaObject();
196
197 return QDesignerAxWidget::metaObject();
198 }
199
200 #ifndef QT_NO_EXCEPTIONS
201
msgComException(const QObject * o,const QMetaObject::Call call,int index)202 static QString msgComException(const QObject *o, const QMetaObject::Call call, int index)
203 {
204 return QDesignerAxWidget::tr("A COM exception occurred when executing a meta call of type %1, index %2 of \"%3\".").
205 arg(call).arg(index).arg(o->objectName());
206 }
207
208 #endif // QT_NO_EXCEPTIONS
209
qt_metacall(QMetaObject::Call call,int signal,void ** argv)210 int QDesignerAxPluginWidget::qt_metacall(QMetaObject::Call call, int signal, void **argv)
211 {
212 QAxWidget *aw = axobject();
213 if (!aw)
214 return QDesignerAxWidget::qt_metacall(call,signal,argv);
215
216
217 const QMetaObject *mo = metaObject();
218 // Have base class handle inherited stuff (geometry, enabled...)
219 const bool inherited = call == QMetaObject::InvokeMetaMethod ?
220 (signal < mo->methodOffset()) : (signal < mo->propertyOffset());
221 if (inherited)
222 return QDesignerAxWidget::qt_metacall(call, signal, argv);
223
224 int rc = -1;
225 #ifndef QT_NO_EXCEPTIONS
226 try {
227 #endif
228 if (debugAxWidget)
229 if (call != QMetaObject::InvokeMetaMethod)
230 qDebug() << objectName() << call << signal << mo->property(signal).name();
231 switch (call) {
232 case QMetaObject::QueryPropertyStored: // Pretend all changed properties are stored for them to be saved
233 if (m_propValues.contains(signal))
234 if (argv[0])
235 *reinterpret_cast< bool*>(argv[0]) = true;
236 break;
237 case QMetaObject::ResetProperty:
238 rc = aw->qt_metacall(call, signal, argv);
239 update();
240 m_propValues.remove(signal);
241 break;
242 case QMetaObject::WriteProperty:
243 rc = aw->qt_metacall(call, signal, argv);
244 update();
245 m_propValues.insert(signal, true);
246 break;
247 default:
248 rc = aw->qt_metacall(call, signal, argv);
249 break;
250 }
251 #ifndef QT_NO_EXCEPTIONS
252 } catch(...) {
253 qWarning(msgComException(this, call, signal).toUtf8());
254 }
255 #endif
256 return rc;
257 }
258
259 QT_END_NAMESPACE
260