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 <QGraphicsLinearLayout> 00028 #include <QGraphicsScene> 00029 #include <QTimer> 00030 00031 #include <kdebug.h> 00032 #include <kglobal.h> 00033 #include <kstandarddirs.h> 00034 00035 #include "private/declarative/declarativenetworkaccessmanagerfactory_p.h" 00036 00037 namespace Plasma 00038 { 00039 00040 class DeclarativeWidgetPrivate 00041 { 00042 public: 00043 DeclarativeWidgetPrivate(DeclarativeWidget *parent) 00044 : q(parent), 00045 engine(0), 00046 component(0), 00047 root(0), 00048 delay(false) 00049 { 00050 } 00051 00052 ~DeclarativeWidgetPrivate() 00053 { 00054 } 00055 00056 void errorPrint(); 00057 void execute(const QString &fileName); 00058 void finishExecute(); 00059 void scheduleExecutionEnd(); 00060 00061 00062 DeclarativeWidget *q; 00063 00064 QString qmlPath; 00065 QDeclarativeEngine* engine; 00066 QDeclarativeComponent* component; 00067 QObject *root; 00068 bool delay : 1; 00069 }; 00070 00071 void DeclarativeWidgetPrivate::errorPrint() 00072 { 00073 QString errorStr = "Error loading QML file.\n"; 00074 if(component->isError()){ 00075 QList<QDeclarativeError> errors = component->errors(); 00076 foreach (const QDeclarativeError &error, errors) { 00077 errorStr += (error.line()>0?QString(QString::number(error.line()) + QLatin1String(": ")):QLatin1String("")) 00078 + error.description() + '\n'; 00079 } 00080 } 00081 kWarning() << component->url().toString() + '\n' + errorStr; 00082 } 00083 00084 void DeclarativeWidgetPrivate::execute(const QString &fileName) 00085 { 00086 if (fileName.isEmpty()) { 00087 kDebug() << "File name empty!"; 00088 return; 00089 } 00090 00091 component->loadUrl(fileName); 00092 00093 if (delay) { 00094 QTimer::singleShot(0, q, SLOT(scheduleExecutionEnd())); 00095 } else { 00096 scheduleExecutionEnd(); 00097 } 00098 } 00099 00100 void DeclarativeWidgetPrivate::scheduleExecutionEnd() 00101 { 00102 if (component->isReady() || component->isError()) { 00103 finishExecute(); 00104 } else { 00105 QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), q, SLOT(finishExecute())); 00106 } 00107 } 00108 00109 void DeclarativeWidgetPrivate::finishExecute() 00110 { 00111 if (component->isError()) { 00112 errorPrint(); 00113 } 00114 00115 root = component->create(); 00116 00117 if (!root) { 00118 errorPrint(); 00119 } 00120 00121 kDebug() << "Execution of QML done!"; 00122 QGraphicsWidget *widget = dynamic_cast<QGraphicsWidget*>(root); 00123 QGraphicsObject *object = dynamic_cast<QGraphicsObject *>(root); 00124 00125 00126 if (object) { 00127 static_cast<QGraphicsItem *>(object)->setParentItem(q); 00128 if (q->scene()) { 00129 q->scene()->addItem(object); 00130 } 00131 } 00132 00133 if (widget) { 00134 q->setPreferredSize(-1,-1); 00135 QGraphicsLinearLayout *lay = static_cast<QGraphicsLinearLayout *>(q->layout()); 00136 if (!lay) { 00137 lay = new QGraphicsLinearLayout(q); 00138 lay->setContentsMargins(0, 0, 0, 0); 00139 } 00140 lay->addItem(widget); 00141 } else { 00142 q->setLayout(0); 00143 qreal width = 0; 00144 qreal height = 0; 00145 if (object) { 00146 width = object->property("width").toReal(); 00147 height = object->property("height").toReal(); 00148 object->setProperty("width", q->size().width()); 00149 object->setProperty("height", q->size().height()); 00150 } 00151 00152 if (width > 0 && height > 0) { 00153 q->setPreferredSize(width, height); 00154 } else { 00155 q->setPreferredSize(-1, -1); 00156 } 00157 } 00158 emit q->finished(); 00159 } 00160 00161 00162 00163 DeclarativeWidget::DeclarativeWidget(QGraphicsWidget *parent) 00164 : QGraphicsWidget(parent), 00165 d(new DeclarativeWidgetPrivate(this)) 00166 { 00167 setFlag(QGraphicsItem::ItemHasNoContents); 00168 00169 d->engine = new QDeclarativeEngine(this); 00170 d->engine->setNetworkAccessManagerFactory(new DeclarativeNetworkAccessManagerFactory); 00171 foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "imports")) { 00172 d->engine->addImportPath(importPath); 00173 } 00174 00175 d->component = new QDeclarativeComponent(d->engine, this); 00176 } 00177 00178 DeclarativeWidget::~DeclarativeWidget() 00179 { 00180 delete d; 00181 } 00182 00183 void DeclarativeWidget::setQmlPath(const QString &path) 00184 { 00185 d->qmlPath = path; 00186 d->execute(path); 00187 } 00188 00189 QString DeclarativeWidget::qmlPath() const 00190 { 00191 return d->qmlPath; 00192 } 00193 00194 void DeclarativeWidget::setInitializationDelayed(const bool delay) 00195 { 00196 d->delay = delay; 00197 } 00198 00199 bool DeclarativeWidget::isInitializationDelayed() const 00200 { 00201 return d->delay; 00202 } 00203 00204 QDeclarativeEngine* DeclarativeWidget::engine() 00205 { 00206 return d->engine; 00207 } 00208 00209 QObject *DeclarativeWidget::rootObject() const 00210 { 00211 return d->root; 00212 } 00213 00214 QDeclarativeComponent *DeclarativeWidget::mainComponent() const 00215 { 00216 return d->component; 00217 } 00218 00219 void DeclarativeWidget::resizeEvent(QGraphicsSceneResizeEvent *event) 00220 { 00221 QGraphicsWidget::resizeEvent(event); 00222 00223 if (d->root) { 00224 d->root->setProperty("width", size().width()); 00225 d->root->setProperty("height", size().height()); 00226 } 00227 } 00228 00229 00230 } // namespace Plasma 00231 00232 #include <declarativewidget.moc> 00233
KDE 4.6 API Reference