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 } 00149 00150 if (width > 0 && height > 0) { 00151 q->setPreferredSize(width, height); 00152 } else { 00153 q->setPreferredSize(-1, -1); 00154 } 00155 } 00156 emit q->finished(); 00157 } 00158 00159 00160 00161 DeclarativeWidget::DeclarativeWidget(QGraphicsWidget *parent) 00162 : QGraphicsWidget(parent), 00163 d(new DeclarativeWidgetPrivate(this)) 00164 { 00165 setFlag(QGraphicsItem::ItemHasNoContents); 00166 00167 d->engine = new QDeclarativeEngine(this); 00168 d->engine->setNetworkAccessManagerFactory(new DeclarativeNetworkAccessManagerFactory); 00169 foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "imports")) { 00170 d->engine->addImportPath(importPath); 00171 } 00172 00173 d->component = new QDeclarativeComponent(d->engine, this); 00174 } 00175 00176 DeclarativeWidget::~DeclarativeWidget() 00177 { 00178 delete d; 00179 } 00180 00181 void DeclarativeWidget::setQmlPath(const QString &path) 00182 { 00183 d->qmlPath = path; 00184 d->execute(path); 00185 } 00186 00187 QString DeclarativeWidget::qmlPath() const 00188 { 00189 return d->qmlPath; 00190 } 00191 00192 void DeclarativeWidget::setInitializationDelayed(const bool delay) 00193 { 00194 d->delay = delay; 00195 } 00196 00197 bool DeclarativeWidget::isInitializationDelayed() const 00198 { 00199 return d->delay; 00200 } 00201 00202 QDeclarativeEngine* DeclarativeWidget::engine() 00203 { 00204 return d->engine; 00205 } 00206 00207 QObject *DeclarativeWidget::rootObject() const 00208 { 00209 return d->root; 00210 } 00211 00212 QDeclarativeComponent *DeclarativeWidget::mainComponent() const 00213 { 00214 return d->component; 00215 } 00216 00217 void DeclarativeWidget::resizeEvent(QGraphicsSceneResizeEvent *event) 00218 { 00219 QGraphicsWidget::resizeEvent(event); 00220 00221 if (d->root) { 00222 d->root->setProperty("width", size().width()); 00223 d->root->setProperty("height", size().height()); 00224 } 00225 } 00226 00227 00228 } // namespace Plasma 00229 00230 #include <declarativewidget.moc> 00231
KDE 4.6 API Reference