Plasma
declarativewidget.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2010 Marco Martin <mart@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this program; if not, write to the 00016 * Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "declarativewidget.h" 00021 00022 00023 #include <QtDeclarative/QDeclarativeComponent> 00024 #include <QtDeclarative/QDeclarativeItem> 00025 #include <QtDeclarative/QDeclarativeEngine> 00026 #include <QtDeclarative/QDeclarativeContext> 00027 #include <QScriptEngine> 00028 #include <QGraphicsLinearLayout> 00029 #include <QGraphicsScene> 00030 #include <QTimer> 00031 00032 #include <kdebug.h> 00033 #include <kdeclarative.h> 00034 #include <kglobal.h> 00035 #include <kstandarddirs.h> 00036 00037 #include "private/declarative/declarativenetworkaccessmanagerfactory_p.h" 00038 #include "private/dataenginebindings_p.h" 00039 00040 namespace Plasma 00041 { 00042 00043 class DeclarativeWidgetPrivate 00044 { 00045 public: 00046 DeclarativeWidgetPrivate(DeclarativeWidget *parent) 00047 : q(parent), 00048 engine(0), 00049 component(0), 00050 root(0), 00051 delay(false) 00052 { 00053 } 00054 00055 ~DeclarativeWidgetPrivate() 00056 { 00057 } 00058 00059 void errorPrint(); 00060 void execute(const QString &fileName); 00061 void finishExecute(); 00062 void scheduleExecutionEnd(); 00063 void minimumWidthChanged(); 00064 void minimumHeightChanged(); 00065 00066 00067 DeclarativeWidget *q; 00068 00069 QString qmlPath; 00070 QDeclarativeEngine* engine; 00071 QScriptEngine *scriptEngine; 00072 QDeclarativeComponent* component; 00073 QObject *root; 00074 bool delay : 1; 00075 }; 00076 00077 void DeclarativeWidgetPrivate::errorPrint() 00078 { 00079 QString errorStr = "Error loading QML file.\n"; 00080 if(component->isError()){ 00081 QList<QDeclarativeError> errors = component->errors(); 00082 foreach (const QDeclarativeError &error, errors) { 00083 errorStr += (error.line()>0?QString(QString::number(error.line()) + QLatin1String(": ")):QLatin1String("")) 00084 + error.description() + '\n'; 00085 } 00086 } 00087 kWarning() << component->url().toString() + '\n' + errorStr; 00088 } 00089 00090 void DeclarativeWidgetPrivate::execute(const QString &fileName) 00091 { 00092 if (fileName.isEmpty()) { 00093 kDebug() << "File name empty!"; 00094 return; 00095 } 00096 00097 KDeclarative kdeclarative; 00098 kdeclarative.setDeclarativeEngine(engine); 00099 kdeclarative.initialize(); 00100 //binds things like kconfig and icons 00101 kdeclarative.setupBindings(); 00102 00103 component->loadUrl(fileName); 00104 00105 scriptEngine = kdeclarative.scriptEngine(); 00106 registerDataEngineMetaTypes(scriptEngine); 00107 00108 if (delay) { 00109 QTimer::singleShot(0, q, SLOT(scheduleExecutionEnd())); 00110 } else { 00111 scheduleExecutionEnd(); 00112 } 00113 } 00114 00115 void DeclarativeWidgetPrivate::scheduleExecutionEnd() 00116 { 00117 if (component->isReady() || component->isError()) { 00118 finishExecute(); 00119 } else { 00120 QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), q, SLOT(finishExecute())); 00121 } 00122 } 00123 00124 void DeclarativeWidgetPrivate::finishExecute() 00125 { 00126 if (component->isError()) { 00127 errorPrint(); 00128 } 00129 00130 root = component->create(); 00131 00132 if (!root) { 00133 errorPrint(); 00134 } 00135 00136 kDebug() << "Execution of QML done!"; 00137 QGraphicsWidget *widget = dynamic_cast<QGraphicsWidget*>(root); 00138 QGraphicsObject *object = dynamic_cast<QGraphicsObject *>(root); 00139 00140 00141 if (object) { 00142 static_cast<QGraphicsItem *>(object)->setParentItem(q); 00143 if (q->scene()) { 00144 q->scene()->addItem(object); 00145 } 00146 } 00147 00148 if (widget) { 00149 q->setPreferredSize(-1,-1); 00150 QGraphicsLinearLayout *lay = static_cast<QGraphicsLinearLayout *>(q->layout()); 00151 if (!lay) { 00152 lay = new QGraphicsLinearLayout(q); 00153 lay->setContentsMargins(0, 0, 0, 0); 00154 } 00155 lay->addItem(widget); 00156 } else { 00157 q->setLayout(0); 00158 qreal minimumWidth = 0; 00159 qreal minimumHeight = 0; 00160 if (object) { 00161 minimumWidth = object->property("minimumWidth").toReal(); 00162 minimumHeight = object->property("minimumHeight").toReal(); 00163 object->setProperty("width", q->size().width()); 00164 object->setProperty("height", q->size().height()); 00165 QObject::connect(object, SIGNAL(minimumWidthChanged()), q, SLOT(minimumWidthChanged())); 00166 QObject::connect(object, SIGNAL(minimumHeightChanged()), q, SLOT(minimumHeightChanged())); 00167 } 00168 00169 if (minimumWidth > 0 && minimumHeight > 0) { 00170 q->setMinimumSize(minimumWidth, minimumHeight); 00171 } else { 00172 q->setMinimumSize(-1, -1); 00173 } 00174 } 00175 emit q->finished(); 00176 } 00177 00178 void DeclarativeWidgetPrivate::minimumWidthChanged() 00179 { 00180 qreal minimumWidth = root->property("minimumWidth").toReal(); 00181 q->setMinimumWidth(minimumWidth); 00182 } 00183 00184 void DeclarativeWidgetPrivate::minimumHeightChanged() 00185 { 00186 qreal minimumHeight = root->property("minimumHeight").toReal(); 00187 q->setMinimumHeight(minimumHeight); 00188 } 00189 00190 DeclarativeWidget::DeclarativeWidget(QGraphicsWidget *parent) 00191 : QGraphicsWidget(parent), 00192 d(new DeclarativeWidgetPrivate(this)) 00193 { 00194 setFlag(QGraphicsItem::ItemHasNoContents); 00195 00196 d->engine = new QDeclarativeEngine(this); 00197 d->engine->setNetworkAccessManagerFactory(new DeclarativeNetworkAccessManagerFactory); 00198 00199 d->component = new QDeclarativeComponent(d->engine, this); 00200 } 00201 00202 DeclarativeWidget::~DeclarativeWidget() 00203 { 00204 QDeclarativeNetworkAccessManagerFactory *factory = d->engine->networkAccessManagerFactory(); 00205 d->engine->setNetworkAccessManagerFactory(0); 00206 delete factory; 00207 delete d; 00208 } 00209 00210 void DeclarativeWidget::setQmlPath(const QString &path) 00211 { 00212 d->qmlPath = path; 00213 d->execute(path); 00214 } 00215 00216 QString DeclarativeWidget::qmlPath() const 00217 { 00218 return d->qmlPath; 00219 } 00220 00221 void DeclarativeWidget::setInitializationDelayed(const bool delay) 00222 { 00223 d->delay = delay; 00224 } 00225 00226 bool DeclarativeWidget::isInitializationDelayed() const 00227 { 00228 return d->delay; 00229 } 00230 00231 QDeclarativeEngine* DeclarativeWidget::engine() 00232 { 00233 return d->engine; 00234 } 00235 00236 QScriptEngine *DeclarativeWidget::scriptEngine() const 00237 { 00238 return d->scriptEngine; 00239 } 00240 00241 QObject *DeclarativeWidget::rootObject() const 00242 { 00243 return d->root; 00244 } 00245 00246 QDeclarativeComponent *DeclarativeWidget::mainComponent() const 00247 { 00248 return d->component; 00249 } 00250 00251 void DeclarativeWidget::resizeEvent(QGraphicsSceneResizeEvent *event) 00252 { 00253 QGraphicsWidget::resizeEvent(event); 00254 00255 if (d->root) { 00256 d->root->setProperty("width", size().width()); 00257 d->root->setProperty("height", size().height()); 00258 } 00259 } 00260 00261 00262 } // namespace Plasma 00263 00264 #include <declarativewidget.moc> 00265
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:36:04 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:36:04 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.