[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [kdelibs/frameworks] /: Merge remote-tracking branch 'origin/KDE/4.10' into frameworks
From: David Faure <faure+bluesystems () kde ! org>
Date: 2012-11-30 23:58:08
Message-ID: 20121130235808.0D1E7A6091 () git ! kde ! org
[Download RAW message or body]
Git commit 71e5e17968c934f0e761adffddf489afd8dde44b by David Faure.
Committed on 01/12/2012 at 00:57.
Pushed by dfaure into branch 'frameworks'.
Merge remote-tracking branch 'origin/KDE/4.10' into frameworks
Conflicts:
CMakeLists.txt [version]
README [version]
cmake/modules/CMakeLists.txt
cmake/modules/FindKDE4Internal.cmake
cmake/modules/FindNepomuk.cmake [git replaying an old conflict!]
cmake/modules/KDE4Macros.cmake [automoc4 stuff, reverted]
interfaces/ktexteditor/* [moved out]
kdecore/services/kmimetype.cpp [hand-merged into kio/global.cpp]
kdeui/util/kkeyserver.h
kdeui/widgets/ktextedit.cpp
kdewebkit/kwebwallet.cpp
khtml/misc/enum.h [git got confused, me thinks]
kio/kio/accessmanager.cpp
kio/kio/hostinfo.cpp
kio/kio/kprotocolmanager.cpp
kio/kio/kprotocolmanager.h
kioslave/http/http.cpp
kioslave/http/http.h
kioslave/http/tests/CMakeLists.txt
kioslave/http/tests/httpheaderdispositiontest.cpp
nepomuk/core/* [moved out]
plasma/CMakeLists.txt
plasma/applet.cpp
plasma/applet.h
plasma/dialog.cpp
plasma/packagestructure.cpp
plasma/popupapplet.cpp
plasma/private/applethandle.cpp
plasma/private/packages.cpp
plasma/private/tooltip.cpp
plasma/tooltipmanager.cpp
plasma/widgets/videowidget.h
staging/ki18n/src/klocalizedstring.cpp
staging/kservice/autotests/kservicetest.cpp
staging/kwidgets/src/utils/kglobalsettings.cpp
tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp
tier1/solid/src/solid/backends/upower/upoweracadapter.cpp
tier1/solid/src/solid/backends/upower/upowerbattery.cpp
M +1 -1 CMakeLists.txt
M +7 -7 kdecore/localization/klocale.h
M +1 -1 kdeui/tests/kmessagewidgettest.cpp
M +1 -1 kdeui/util/kkeyserver.h
M +22 -6 kdeui/widgets/kmessagewidget.cpp
M +6 -1 kdeui/widgets/krichtextedit.cpp
M +6 -6 kdeui/widgets/krichtextwidget.cpp
M +11 -6 kdeui/widgets/ktextedit.cpp
M +9 -0 kdeui/widgets/ktextedit.h
M +2 -0 kdewebkit/CMakeLists.txt
M +23 -10 kdewebkit/kwebwallet.cpp
M +6 -0 kfile/kfileplacesitem.cpp
M +2 -0 kfile/kfileplacesitem_p.h
M +11 -2 kfile/kfileplacesmodel.cpp
M +6 -2 kfile/kfilewidget.cpp
M +7 -5 khtml/rendering/render_box.cpp
M +1 -1 kimgio/xcf.cpp
M +7 -1 kio/kio/kfileitem.cpp
M +1 -1 kio/kio/kprotocolmanager.h
M +5 -0 kio/kio/krun.cpp
M +6 -0 kio/kio/krun.h
M +3 -2 kio/kio/slaveinterface_p.h
M +14 -0 kio/tests/jobtest.cpp
M +2 -0 kioslave/ftp/ftp.cpp
M +9 -3 kioslave/http/http.cpp
M +4 -4 kioslave/http/http_cache_cleaner.cpp
M +7 -7 kjsembed/kjsembed/qobject_binding.cpp
M +5 -3 kparts/browserrun.cpp
M +3 -3 kparts/browserrun.h
M +1 -0 plasma/CMakeLists.txt
A +26 -14 plasma/intoDeclarativeEngine/declarativewidget.cpp \
[License: LGPL (v2+)] M +3 -1 plasma/plasma.h
M +31 -0 plasma/runnercontext.cpp
M +14 -2 plasma/runnercontext.h
A +23 -0 staging/kio/src/core/global.cpp [License: LGPL (v2)]
A +1 -1 staging/kservice/src/sycoca/ksycoca.cpp [License: LGPL \
(v2)] A +1 -9 \
tier1/solid/src/solid/backends/udisks/udisksopticaldrive.cpp [License: \
LGPL] R +3 -2 tier1/solid/src/solid/backends/udisks2/udisksblock.cpp
R +1 -0 tier1/solid/src/solid/backends/udisks2/udisksblock.h
R +19 -19 tier1/solid/src/solid/backends/udisks2/udisksdevice.cpp
R +2 -0 tier1/solid/src/solid/backends/udisks2/udisksdevice.h
R +5 -35 tier1/solid/src/solid/backends/udisks2/udisksmanager.cpp
R +1 -0 tier1/solid/src/solid/backends/udisks2/udisksmanager.h
R +1 -1 tier1/solid/src/solid/backends/udisks2/udisksopticaldrive.cpp
A +53 -25 tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp \
[License: LGPL] R +1 -1 \
tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.h A +9 -7 \
tier1/solid/src/solid/backends/upower/upoweracadapter.cpp [License: \
LGPL] A +37 -41 \
tier1/solid/src/solid/backends/upower/upowerbattery.cpp [License: LGPL] \
R +2 -1 tier1/solid/src/solid/backends/upower/upowerdeviceinterface.h
A +3 -3 tier1/solid/src/solid/backends/upower/upowergenericinterface.cpp \
[License: LGPL] R +6 -7 tier1/solid/src/solid/networking.h
R +2 -13 tier1/threadweaver/Mainpage.dox
A +1 -1 tier1/threadweaver/src/Weaver/Job.h [License: LGPL \
(v2+)] A +3 -3 tier1/threadweaver/src/Weaver/WeaverInterface.h \
[License: LGPL (v2+)]
http://commits.kde.org/kdelibs/71e5e17968c934f0e761adffddf489afd8dde44b
diff --cc CMakeLists.txt
index 15ed359,893f00e..35310fe
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@@ -21,13 -9,10 +21,13 @@@ endif(
################# set KDE specific information #################
set (KDE_VERSION_MAJOR 4)
-set (KDE_VERSION_MINOR 9)
-set (KDE_VERSION_RELEASE 80)
+set (KDE_VERSION_MINOR 90)
+set (KDE_VERSION_RELEASE 00)
set (KDE_VERSION "${KDE_VERSION_MAJOR}.${KDE_VERSION_MINOR}.${KDE_VERSION_RELEASE}" \
)
-set (KDE_VERSION_STRING "${KDE_VERSION}")
+# For git master, use this:
- set (KDE_VERSION_STRING "${KDE_VERSION} (KDE Frameworks >= 20120113)")
++set (KDE_VERSION_STRING "${KDE_VERSION} (KDE Frameworks >= 20121130)")
+# For a stable release, use this:
+#set (KDE_VERSION_STRING "${KDE_VERSION}")
set (KDE_DISTRIBUTION_TEXT "compiled sources" CACHE STRING "Indicate the \
distribution in bug reports" )
diff --cc kdeui/widgets/ktextedit.cpp
index 42a0303,dfaf5b8..71d2a9f
--- a/kdeui/widgets/ktextedit.cpp
+++ b/kdeui/widgets/ktextedit.cpp
@@@ -1169,4 -1166,14 +1164,14 @@@ void KTextEdit::showAutoCorrectButton(b
d->showAutoCorrectionButton = show;
}
+ void KTextEdit::mousePopupMenuImplementation(const QPoint& pos)
+ {
+ QMenu *popup = mousePopupMenu();
+ if ( popup ) {
+ aboutToShowContextMenu(popup);
+ popup->exec( pos );
+ delete popup;
+ }
+ }
+
-#include "ktextedit.moc"
+#include "moc_ktextedit.cpp"
diff --cc kfile/kfileplacesmodel.cpp
index 4160075,0192926..06cd069
--- a/kfile/kfileplacesmodel.cpp
+++ b/kfile/kfileplacesmodel.cpp
@@@ -56,8 -55,8 +57,9 @@@
#include <solid/storagevolume.h>
#include <solid/opticaldrive.h>
#include <solid/opticaldisc.h>
+ #include <solid/portablemediaplayer.h>
#include <solid/predicate.h>
+#include <qstandardpaths.h>
class KFilePlacesModel::Private
{
diff --cc kfile/kfilewidget.cpp
index 55497d8,e755aae..c83df3a
--- a/kfile/kfilewidget.cpp
+++ b/kfile/kfilewidget.cpp
@@@ -2611,8 -2593,12 +2611,12 @@@ QUrl KFileWidget::getStartUrl(const QUr
}
else // not special "kfiledialog" URL
{
- if (!startDir.isRelative()) // has directory, maybe with \
filename
- {
+ // We can use startDir as the starting directory if either:
+ // (a) it has a directory part, or
+ // (b) there is a scheme (protocol), and it is not just \
"file".
- if (!startDir.directory().isEmpty() ||
++ if (!QUrlPathInfo(startDir).directory().isEmpty() ||
+ (!startDir.scheme().isEmpty() && \
!startDir.isLocalFile())) + { // can use start directory
ret = startDir; // will be checked by stat later
// If we won't be able to list it (e.g. http), then use \
default if ( !KProtocolManager::supportsListing( ret ) ) {
diff --cc kio/kio/kprotocolmanager.h
index cf06c0e,d9dca11..274adab
--- a/kio/kio/kprotocolmanager.h
+++ b/kio/kio/kprotocolmanager.h
@@@ -679,9 -678,9 +679,9 @@@ public
/**
* Returns the charset to use for the specified @ref url.
*
- * @since 5.0
+ * @since 4.10
*/
- static QString charsetFor(const KUrl& url);
+ static QString charsetFor(const QUrl& url);
private:
friend class KIO::SlaveConfigPrivate;
diff --cc kio/kio/slaveinterface_p.h
index 30e9981,e31ec5e..3c289c6
--- a/kio/kio/slaveinterface_p.h
+++ b/kio/kio/slaveinterface_p.h
@@@ -20,8 -20,10 +20,10 @@@
#define KIO_SLAVEINTERFACEPRIVATE_H
#include "global.h"
-#include "connection.h"
+#include "connection_p.h"
#include <QtCore/QTimer>
-#include <QtGui/QWidget>
++#include <QWidget>
+ #include <QtCore/QPointer>
#include <QtNetwork/QHostInfo>
static const unsigned int max_nums = 8;
diff --cc kioslave/http/http.cpp
index cbd6234,b7f8e8d..9d834da
--- a/kioslave/http/http.cpp
+++ b/kioslave/http/http.cpp
@@@ -596,9 -592,9 +596,9 @@@ void HTTPProtocol::setHost( const QStri
<< "(" << m_request.encoded_hostname << ")";
}
-bool HTTPProtocol::maybeSetRequestUrl(const KUrl &u)
+bool HTTPProtocol::maybeSetRequestUrl(const QUrl &u)
{
- kDebug (7113) << u;
+ kDebug(7113) << u;
m_request.url = u;
m_request.url.setPort(u.port(defaultPort()) != defaultPort() ? u.port() \
: -1);
diff --cc plasma/CMakeLists.txt
index b2300fb,674550d..a95cb57
--- a/plasma/CMakeLists.txt
+++ b/plasma/CMakeLists.txt
@@@ -121,11 -129,20 +121,12 @@@ set(plasma_LIB_SRC
private/associatedapplicationmanager.cpp
private/componentinstaller.cpp
private/datacontainer_p.cpp
- private/dataenginebindings.cpp
- private/dataengineconsumer.cpp
+ private/dataenginemanager.cpp
private/dataengineservice.cpp
- private/denyallauthorization.cpp
+ private/effects/halopainter.cpp
+ private/dialogshadows.cpp
- private/effectwatcher.cpp
- private/extenderapplet.cpp
- private/extenderitemmimedata.cpp
- private/focusindicator.cpp
private/getsource.cpp
- private/nativetabbar.cpp
private/packages.cpp
- private/pinpairingauthorization.cpp
- private/pinpairingdialog.cpp
private/plasmoidservice.cpp
private/remotedataengine.cpp
private/remoteservice.cpp
diff --cc plasma/intoDeclarativeEngine/declarativewidget.cpp
index 37f648e,0000000..c5fe651
mode 100644,000000..100644
--- a/plasma/intoDeclarativeEngine/declarativewidget.cpp
+++ b/plasma/intoDeclarativeEngine/declarativewidget.cpp
@@@ -1,326 -1,0 +1,338 @@@
+/*
+ * Copyright 2010 Marco Martin <mart@kde.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "declarativewidget.h"
+
+
+#include <QDeclarativeComponent>
+#include <QDeclarativeItem>
+#include <QDeclarativeEngine>
+#include <QDeclarativeContext>
+#include <QScriptEngine>
+#include <QGraphicsLinearLayout>
+#include <QGraphicsScene>
+#include <QTimer>
+
+#include <kdebug.h>
+#include <kdeclarative.h>
+
+
+#include "private/declarative/declarativenetworkaccessmanagerfactory_p.h"
+#include "private/declarative/dataenginebindings_p.h"
+
+namespace Plasma
+{
+
+class DeclarativeWidgetPrivate
+{
+public:
+ DeclarativeWidgetPrivate(DeclarativeWidget *parent)
+ : q(parent),
+ engine(0),
+ scriptEngine(0),
+ component(0),
+ root(0),
+ delay(false)
+ {
+ }
+
+ ~DeclarativeWidgetPrivate()
+ {
+ }
+
+ void errorPrint();
+ void execute(const QString &fileName);
+ void finishExecute();
+ void scheduleExecutionEnd();
+ void minimumWidthChanged();
+ void minimumHeightChanged();
+ void maximumWidthChanged();
+ void maximumHeightChanged();
+ void preferredWidthChanged();
+ void preferredHeightChanged();
+
+
+ DeclarativeWidget *q;
+
+ QString qmlPath;
+ QDeclarativeEngine* engine;
+ QScriptEngine *scriptEngine;
+ QDeclarativeComponent* component;
+ QObject *root;
+ bool delay : 1;
+};
+
+void DeclarativeWidgetPrivate::errorPrint()
+{
+ QString errorStr = "Error loading QML file.\n";
+ if(component->isError()){
+ QList<QDeclarativeError> errors = component->errors();
+ foreach (const QDeclarativeError &error, errors) {
+ errorStr += \
(error.line()>0?QString(QString::number(error.line()) + QLatin1String(": \
")):QLatin1String("")) + + error.description() + '\n';
+ }
+ }
+ kWarning() << component->url().toString() + '\n' + errorStr;
+}
+
+void DeclarativeWidgetPrivate::execute(const QString &fileName)
+{
+ if (fileName.isEmpty()) {
+#ifndef NDEBUG
+ kDebug() << "File name empty!";
+#endif
+ return;
+ }
+
+ KDeclarative kdeclarative;
+ kdeclarative.setDeclarativeEngine(engine);
+ kdeclarative.initialize();
+ //binds things like kconfig and icons
+ kdeclarative.setupBindings();
+
+ component->loadUrl(QUrl::fromLocalFile(fileName));
+
+ scriptEngine = kdeclarative.scriptEngine();
+ registerDataEngineMetaTypes(scriptEngine);
+
+ if (delay) {
+ QTimer::singleShot(0, q, SLOT(scheduleExecutionEnd()));
+ } else {
+ scheduleExecutionEnd();
+ }
+}
+
+void DeclarativeWidgetPrivate::scheduleExecutionEnd()
+{
+ if (component->isReady() || component->isError()) {
+ finishExecute();
+ } else {
+ QObject::connect(component, \
SIGNAL(statusChanged(QDeclarativeComponent::Status)), q, \
SLOT(finishExecute())); + }
+}
+
+void DeclarativeWidgetPrivate::finishExecute()
+{
+ if (component->isError()) {
+ errorPrint();
+ }
+
+ root = component->create();
+
+ if (!root) {
+ errorPrint();
+ }
+
+#ifndef NDEBUG
+ kDebug() << "Execution of QML done!";
+#endif
+ QGraphicsWidget *widget = dynamic_cast<QGraphicsWidget*>(root);
+ QGraphicsObject *object = dynamic_cast<QGraphicsObject *>(root);
+
+
+ if (object) {
+ static_cast<QGraphicsItem *>(object)->setParentItem(q);
+ if (q->scene()) {
+ q->scene()->addItem(object);
+ }
+ }
+
+ if (widget) {
+ q->setPreferredSize(-1,-1);
+ QGraphicsLinearLayout *lay = static_cast<QGraphicsLinearLayout \
*>(q->layout()); + if (!lay) {
+ lay = new QGraphicsLinearLayout(q);
+ lay->setContentsMargins(0, 0, 0, 0);
+ }
+ lay->addItem(widget);
+ } else {
+ q->setLayout(0);
+ qreal minimumWidth = 0;
+ qreal minimumHeight = 0;
+ qreal maximumWidth = 0;
+ qreal maximumHeight = 0;
+ qreal preferredWidth = 0;
+ qreal preferredHeight = 0;
+ if (object) {
+ object->setProperty("width", q->size().width());
+ object->setProperty("height", q->size().height());
+
- minimumWidth = object->property("minimumWidth").toReal();
- minimumHeight = object->property("minimumHeight").toReal();
- QObject::connect(object, SIGNAL(minimumWidthChanged()), q, \
SLOT(minimumWidthChanged()));
- QObject::connect(object, SIGNAL(minimumHeightChanged()), q, \
SLOT(minimumHeightChanged()));
-
- maximumWidth = object->property("maximumWidth").toReal();
- maximumHeight = object->property("maximumHeight").toReal();
- QObject::connect(object, SIGNAL(maximumWidthChanged()), q, \
SLOT(maximumWidthChanged()));
- QObject::connect(object, SIGNAL(maximumHeightChanged()), q, \
SLOT(maximumHeightChanged()));
-
- preferredWidth = object->property("preferredWidth").toReal();
- preferredHeight = \
object->property("preferredHeight").toReal();
- QObject::connect(object, SIGNAL(preferredWidthChanged()), q, \
SLOT(preferredWidthChanged()));
- QObject::connect(object, SIGNAL(preferredHeightChanged()), q, \
SLOT(preferredHeightChanged())); ++ if \
(object->metaObject()->indexOfProperty("minimumWidth")>=0) { ++ \
minimumWidth = object->property("minimumWidth").toReal(); ++ \
QObject::connect(object, SIGNAL(minimumWidthChanged()), q, \
SLOT(minimumWidthChanged())); ++ }
++ if (object->metaObject()->indexOfProperty("minimumHeight")>=0) \
{ ++ minimumHeight = \
object->property("minimumHeight").toReal(); ++ \
QObject::connect(object, SIGNAL(minimumHeightChanged()), q, \
SLOT(minimumHeightChanged())); ++ }
++
++ if (object->metaObject()->indexOfProperty("maximumWidth")>=0) \
{ ++ maximumWidth = \
object->property("maximumWidth").toReal(); ++ \
QObject::connect(object, SIGNAL(maximumWidthChanged()), q, \
SLOT(maximumWidthChanged())); ++ }
++ if (object->metaObject()->indexOfProperty("maximumHeight")>=0) \
{ ++ maximumHeight = \
object->property("maximumHeight").toReal(); ++ \
QObject::connect(object, SIGNAL(maximumHeightChanged()), q, \
SLOT(maximumHeightChanged())); ++ }
++
++ if (object->metaObject()->indexOfProperty("preferredWidth")>=0) \
{ ++ preferredWidth = \
object->property("preferredWidth").toReal(); ++ \
QObject::connect(object, SIGNAL(preferredWidthChanged()), q, \
SLOT(preferredWidthChanged())); ++ }
++ if (object->metaObject()->indexOfProperty("preferredHeight")>=0) \
{ ++ preferredHeight = \
object->property("preferredHeight").toReal(); ++ \
QObject::connect(object, SIGNAL(preferredHeightChanged()), q, \
SLOT(preferredHeightChanged())); ++ }
+ }
+
+ if (minimumWidth > 0 && minimumHeight > 0) {
+ q->setMinimumSize(minimumWidth, minimumHeight);
+ } else {
+ q->setMinimumSize(-1, -1);
+ }
+
+ if (maximumWidth > 0 && maximumHeight > 0) {
+ q->setMaximumSize(maximumWidth, maximumHeight);
+ } else {
+ q->setMaximumSize(-1, -1);
+ }
+
+ if (preferredWidth > 0 && preferredHeight > 0) {
+ q->setPreferredSize(preferredWidth, preferredHeight);
+ } else {
+ q->setPreferredSize(-1, -1);
+ }
+ }
+ emit q->finished();
+}
+
+void DeclarativeWidgetPrivate::minimumWidthChanged()
+{
+ qreal minimumWidth = root->property("minimumWidth").toReal();
+ q->setMinimumWidth(minimumWidth);
+}
+
+void DeclarativeWidgetPrivate::minimumHeightChanged()
+{
+ qreal minimumHeight = root->property("minimumHeight").toReal();
+ q->setMinimumHeight(minimumHeight);
+}
+
+void DeclarativeWidgetPrivate::maximumWidthChanged()
+{
+ qreal maximumWidth = root->property("maximumWidth").toReal();
+ q->setMaximumWidth(maximumWidth);
+}
+
+void DeclarativeWidgetPrivate::maximumHeightChanged()
+{
+ qreal maximumHeight = root->property("maximumHeight").toReal();
+ q->setMaximumHeight(maximumHeight);
+}
+
+void DeclarativeWidgetPrivate::preferredWidthChanged()
+{
+ qreal preferredWidth = root->property("preferredWidth").toReal();
+ q->setPreferredWidth(preferredWidth);
+}
+
+void DeclarativeWidgetPrivate::preferredHeightChanged()
+{
+ qreal preferredHeight = root->property("preferredHeight").toReal();
+ q->setPreferredHeight(preferredHeight);
+}
+
+DeclarativeWidget::DeclarativeWidget(QGraphicsWidget *parent)
+ : QGraphicsWidget(parent),
+ d(new DeclarativeWidgetPrivate(this))
+{
+ setFlag(QGraphicsItem::ItemHasNoContents);
+
+ d->engine = new QDeclarativeEngine(this);
+ d->engine->setNetworkAccessManagerFactory(new \
DeclarativeNetworkAccessManagerFactory); +
+ d->component = new QDeclarativeComponent(d->engine, this);
+}
+
+DeclarativeWidget::~DeclarativeWidget()
+{
+ QDeclarativeNetworkAccessManagerFactory *factory = \
d->engine->networkAccessManagerFactory(); + \
d->engine->setNetworkAccessManagerFactory(0); + delete factory;
+ delete d;
+}
+
+void DeclarativeWidget::setQmlPath(const QString &path)
+{
+ d->qmlPath = path;
+ d->execute(path);
+}
+
+QString DeclarativeWidget::qmlPath() const
+{
+ return d->qmlPath;
+}
+
+void DeclarativeWidget::setInitializationDelayed(const bool delay)
+{
+ d->delay = delay;
+}
+
+bool DeclarativeWidget::isInitializationDelayed() const
+{
+ return d->delay;
+}
+
+QDeclarativeEngine* DeclarativeWidget::engine()
+{
+ return d->engine;
+}
+
+QScriptEngine *DeclarativeWidget::scriptEngine() const
+{
+ return d->scriptEngine;
+}
+
+QObject *DeclarativeWidget::rootObject() const
+{
+ return d->root;
+}
+
+QDeclarativeComponent *DeclarativeWidget::mainComponent() const
+{
+ return d->component;
+}
+
+void DeclarativeWidget::resizeEvent(QGraphicsSceneResizeEvent *event)
+{
+ QGraphicsWidget::resizeEvent(event);
+
+ if (d->root) {
+ d->root->setProperty("width", size().width());
+ d->root->setProperty("height", size().height());
+ }
+}
+
+
+} // namespace Plasma
+
+
+
+
+#include "moc_declarativewidget.cpp"
diff --cc staging/kio/src/core/global.cpp
index 742102f,0000000..41bfb04
mode 100644,000000..100644
--- a/staging/kio/src/core/global.cpp
+++ b/staging/kio/src/core/global.cpp
@@@ -1,229 -1,0 +1,252 @@@
+/* This file is part of the KDE libraries
+ Copyright (C) 2000 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License version 2 as published by the Free Software Foundation.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public \
License + along with this library; see the file COPYING.LIB. If not, \
write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth \
Floor, + Boston, MA 02110-1301, USA.
+*/
+
+#include "global.h"
+
+#include <kprotocolinfo.h>
+#include <kconfiggroup.h>
+#include <klocale.h>
+#include <qmimedatabase.h>
+#include <QtDBus/QtDBus>
++#include <QHash>
+
+// If someone wants the SI-standard prefixes kB/MB/GB/TB, I would \
recommend +// a hidden kconfig option and getting the code from #57240 \
into the same +// method, so that all KDE apps use the same unit, instead \
of letting each app decide. +
+KIOCORE_EXPORT QString KIO::convertSize( KIO::filesize_t size )
+{
+ return KLocale::global()->formatByteSize(size);
+}
+
+KIOCORE_EXPORT QString KIO::convertSizeFromKiB( KIO::filesize_t kibSize )
+{
+ return KLocale::global()->formatByteSize(kibSize * 1024);
+}
+
+KIOCORE_EXPORT QString KIO::number( KIO::filesize_t size )
+{
+ char charbuf[256];
+ sprintf(charbuf, "%lld", size);
+ return QLatin1String(charbuf);
+}
+
+KIOCORE_EXPORT unsigned int KIO::calculateRemainingSeconds( \
KIO::filesize_t totalSize, + \
KIO::filesize_t processedSize, KIO::filesize_t speed ) +{
+ if ( (speed != 0) && (totalSize != 0) )
+ return ( totalSize - processedSize ) / speed;
+ else
+ return 0;
+}
+
+KIOCORE_EXPORT QString KIO::convertSeconds( unsigned int seconds )
+{
+ unsigned int days = seconds / 86400;
+ unsigned int hours = (seconds - (days * 86400)) / 3600;
+ unsigned int mins = (seconds - (days * 86400) - (hours * 3600)) / 60;
+ seconds = (seconds - (days * 86400) - (hours * 3600) - (mins \
* 60)); +
+ const QTime time(hours, mins, seconds);
+ const QString timeStr( KLocale::global()->formatTime(time, true /*with \
seconds*/, true /*duration*/) ); + if ( days > 0 )
+ return i18np("1 day %2", "%1 days %2", days, timeStr);
+ else
+ return timeStr;
+}
+
+#ifndef KDE_NO_DEPRECATED
+KIOCORE_EXPORT QTime KIO::calculateRemaining( KIO::filesize_t totalSize, \
KIO::filesize_t processedSize, KIO::filesize_t speed ) +{
+ QTime remainingTime;
+
+ if ( speed != 0 ) {
+ KIO::filesize_t secs;
+ if ( totalSize == 0 ) {
+ secs = 0;
+ } else {
+ secs = ( totalSize - processedSize ) / speed;
+ }
+ if (secs >= (24*60*60)) // Limit to 23:59:59
+ secs = (24*60*60)-1;
+ int hr = secs / ( 60 * 60 );
+ int mn = ( secs - hr * 60 * 60 ) / 60;
+ int sc = ( secs - hr * 60 * 60 - mn * 60 );
+
+ remainingTime.setHMS( hr, mn, sc );
+ }
+
+ return remainingTime;
+}
+#endif
+
+KIOCORE_EXPORT QString KIO::itemsSummaryString(uint items, uint files, \
uint dirs, KIO::filesize_t size, bool showSize) +{
+ if ( files == 0 && dirs == 0 && items == 0 ) {
+ return i18np( "%1 Item", "%1 Items", 0 );
+ }
+
+ QString summary;
+ const QString foldersText = i18np( "1 Folder", "%1 Folders", dirs );
+ const QString filesText = i18np( "1 File", "%1 Files", files );
+ if ( files > 0 && dirs > 0 ) {
+ summary = showSize ?
+ i18nc( "folders, files (size)", "%1, %2 (%3)", \
foldersText, filesText, KIO::convertSize( size ) ) : + \
i18nc( "folders, files", "%1, %2", foldersText, filesText ); + } else \
if ( files > 0 ) { + summary = showSize ? i18nc( "files (size)", \
"%1 (%2)", filesText, KIO::convertSize( size ) ) : filesText; + } else \
if ( dirs > 0 ) { + summary = foldersText;
+ }
+
+ if ( items > dirs + files ) {
+ const QString itemsText = i18np( "%1 Item", "%1 Items", items );
+ summary = summary.isEmpty() ? itemsText : i18nc( "items: folders, \
files (size)", "%1: %2", itemsText, summary ); + }
+
+ return summary;
+}
+
+KIOCORE_EXPORT QString KIO::encodeFileName( const QString & _str )
+{
+ QString str( _str );
+ str.replace('/', QChar(0x2044)); // "Fraction slash"
+ return str;
+}
+
+KIOCORE_EXPORT QString KIO::decodeFileName( const QString & _str )
+{
+ // Nothing to decode. "Fraction slash" is fine in filenames.
+ return _str;
+}
+
+/***************************************************************
+ *
+ * Utility functions
+ *
+ ***************************************************************/
+
+KIO::CacheControl KIO::parseCacheControl(const QString &cacheControl)
+{
+ QString tmp = cacheControl.toLower();
+
+ if (tmp == "cacheonly")
+ return KIO::CC_CacheOnly;
+ if (tmp == "cache")
+ return KIO::CC_Cache;
+ if (tmp == "verify")
+ return KIO::CC_Verify;
+ if (tmp == "refresh")
+ return KIO::CC_Refresh;
+ if (tmp == "reload")
+ return KIO::CC_Reload;
+
+ qDebug() << "unrecognized Cache control option:"<<cacheControl;
+ return KIO::CC_Verify;
+}
+
+QString KIO::getCacheControlString(KIO::CacheControl cacheControl)
+{
+ if (cacheControl == KIO::CC_CacheOnly)
+ return "CacheOnly";
+ if (cacheControl == KIO::CC_Cache)
+ return "Cache";
+ if (cacheControl == KIO::CC_Verify)
+ return "Verify";
+ if (cacheControl == KIO::CC_Refresh)
+ return "Refresh";
+ if (cacheControl == KIO::CC_Reload)
+ return "Reload";
+ qDebug() << "unrecognized Cache control enum value:"<<cacheControl;
+ return QString();
+}
+
+static bool useFavIcons()
+{
+ // this method will be called quite often, so better not read the \
config + // again and again.
+ static bool s_useFavIconsChecked = false;
+ static bool s_useFavIcons = false;
+ if (!s_useFavIconsChecked) {
+ s_useFavIconsChecked = true;
+ KConfigGroup cg( KSharedConfig::openConfig(), "HTML Settings" );
+ s_useFavIcons = cg.readEntry("EnableFavicon", true);
+ }
+ return s_useFavIcons;
+}
+
+QString KIO::favIconForUrl(const QUrl& url)
+{
++ /* The kded module also caches favicons, for one week, without any \
way ++ * to clean up the cache meanwhile.
++ * On the other hand, this QHash will get cleaned up after 5000 \
request ++ * (a selection in konsole of 80 chars generates around 500 \
requests) ++ * or by simply restarting the application (or the whole \
desktop, ++ * more likely, for the case of konqueror or konsole).
++ */
++ static QHash<QUrl, QString> iconNameCache;
++ static int autoClearCache = 0;
++ const QString notFound = QLatin1String("NOTFOUND");
++
+ if (url.isLocalFile()
+ || !url.scheme().startsWith(QLatin1String("http"))
+ || !useFavIcons())
+ return QString();
+
++ QString iconNameFromCache = iconNameCache.value(url, notFound);
++ if (iconNameFromCache != notFound) {
++ if ((++autoClearCache) < 5000) {
++ return iconNameFromCache;
++ } else {
++ iconNameCache.clear();
++ autoClearCache = 0;
++ }
++ }
++
+ QDBusInterface kded( QString::fromLatin1("org.kde.kded5"),
+ QString::fromLatin1("/modules/favicons"),
+ QString::fromLatin1("org.kde.FavIcon") );
+ QDBusReply<QString> result = kded.call( \
QString::fromLatin1("iconForUrl"), url.toString() ); ++ \
iconNameCache.insert(url, result.value()); + return result; \
// default is QString() +}
+
+QString KIO::iconNameForUrl(const QUrl& url)
+{
+ QMimeDatabase db;
+ const QMimeType mt = db.mimeTypeForUrl(url);
+ const QLatin1String unknown("unknown");
+ const QString mimeTypeIcon = mt.iconName();
+ QString i = mimeTypeIcon;
+
+ // if we don't find an icon, maybe we can use the one for the \
protocol + if (i == unknown || i.isEmpty() || mt.isDefault()
+ // and for the root of the protocol (e.g. trash:/) the protocol \
icon has priority over the mimetype icon + || url.path().length() \
<= 1) + {
+ i = favIconForUrl(url); // maybe there is a favicon?
+
+ if (i.isEmpty())
+ i = KProtocolInfo::icon(url.scheme());
+
+ // root of protocol: if we found nothing, revert to mimeTypeIcon \
(which is usually "folder") + if (url.path().length() <= 1 && (i == \
unknown || i.isEmpty())) + i = mimeTypeIcon;
+ }
+ return !i.isEmpty() ? i : unknown;
+}
diff --cc staging/kservice/src/sycoca/ksycoca.cpp
index ea5df3f,0000000..b75e2ce
mode 100644,000000..100644
--- a/staging/kservice/src/sycoca/ksycoca.cpp
+++ b/staging/kservice/src/sycoca/ksycoca.cpp
@@@ -1,626 -1,0 +1,626 @@@
+/* This file is part of the KDE libraries
+ * Copyright (C) 1999-2000 Waldo Bastian <bastian@kde.org>
+ * Copyright (C) 2005-2009 David Faure <faure@kde.org>
+ * Copyright (C) 2008 Hamish Rodda <rodda@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public \
License + * along with this library; see the file COPYING.LIB. If not, \
write to + * the Free Software Foundation, Inc., 51 Franklin Street, \
Fifth Floor, + * Boston, MA 02110-1301, USA.
+ **/
+
+#include "ksycoca.h"
+#include "ksycoca_p.h"
+#include "ksycocatype.h"
+#include "ksycocafactory.h"
+#include "kmemfile_p.h"
+#include "kconfiggroup.h"
+#include "ksharedconfig.h"
+
+#include <qstandardpaths.h>
+#include <QtCore/QDataStream>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+#include <QtCore/QBuffer>
+#include <QProcess>
+#include <QtDBus/QtDBus>
+
+#include <stdlib.h>
+#include <fcntl.h>
+
+#include "ksycocadevices_p.h"
+
+// TODO: remove mmap() from kdewin32 and use QFile::mmap() when needed
+#ifdef Q_OS_WIN
+#undef HAVE_MMAP
+#endif
+/**
+ * Sycoca file version number.
+ * If the existing file is outdated, it will not get read
+ * but instead we'll ask kded to regenerate a new one...
+ */
- #define KSYCOCA_VERSION 209
++#define KSYCOCA_VERSION 210
+
+/**
+ * Sycoca file name, used internally (by kbuildsycoca)
+ */
+#define KSYCOCA_FILENAME "ksycoca5"
+
+#if HAVE_MADVISE || HAVE_MMAP
+#include <sys/mman.h> // This #include was checked when looking for \
posix_madvise +#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+
+static bool s_autoRebuild = true;
+
+// The following limitations are in place:
+// Maximum length of a single string: 8192 bytes
+// Maximum length of a string list: 1024 strings
+// Maximum number of entries: 8192
+//
+// The purpose of these limitations is to limit the impact
+// of database corruption.
+
+
+Q_DECLARE_OPERATORS_FOR_FLAGS(KSycocaPrivate::BehaviorsIfNotFound)
+
+KSycocaPrivate::KSycocaPrivate()
+ : databaseStatus( DatabaseNotOpen ),
+ readError( false ),
+ timeStamp( 0 ),
+ m_databasePath(),
+ updateSig( 0 ),
+ sycoca_size(0),
+ sycoca_mmap(0),
+ m_mmapFile(0),
+ m_device(0)
+{
+#ifdef Q_OS_WIN
+ /*
+ on windows we use KMemFile (QSharedMemory) to avoid problems
+ with mmap (can't delete a mmap'd file)
+ */
+ m_sycocaStrategy = StrategyMemFile;
+#else
+ m_sycocaStrategy = StrategyMmap;
+#endif
+ KConfigGroup config(KSharedConfig::openConfig(), "KSycoca");
+ setStrategyFromString(config.readEntry("strategy"));
+}
+
+void KSycocaPrivate::setStrategyFromString(const QString& strategy) {
+ if (strategy == QLatin1String("mmap"))
+ m_sycocaStrategy = StrategyMmap;
+ else if (strategy == QLatin1String("file"))
+ m_sycocaStrategy = StrategyFile;
+ else if (strategy == QLatin1String("sharedmem"))
+ m_sycocaStrategy = StrategyMemFile;
+ else if (!strategy.isEmpty())
+ qWarning() << "Unknown sycoca strategy:" << strategy;
+}
+
+bool KSycocaPrivate::tryMmap()
+{
+#if HAVE_MMAP
+ Q_ASSERT(!m_databasePath.isEmpty());
+ m_mmapFile = new QFile(m_databasePath);
+ const bool canRead = m_mmapFile->open(QIODevice::ReadOnly);
+ Q_ASSERT(canRead);
+ if (!canRead)
+ return false;
+ fcntl(m_mmapFile->handle(), F_SETFD, FD_CLOEXEC);
+ sycoca_size = m_mmapFile->size();
+ sycoca_mmap = (const char *) mmap(0, sycoca_size,
+ PROT_READ, MAP_SHARED,
+ m_mmapFile->handle(), 0);
+ /* POSIX mandates only MAP_FAILED, but we are paranoid so check for
+ null pointer too. */
+ if (sycoca_mmap == (const char*) MAP_FAILED || sycoca_mmap == 0) {
+ qDebug().nospace() << "mmap failed. (length = " << sycoca_size << \
")"; + sycoca_mmap = 0;
+ return false;
+ } else {
+#if HAVE_MADVISE
+ (void) posix_madvise((void*)sycoca_mmap, sycoca_size, \
POSIX_MADV_WILLNEED); +#endif // HAVE_MADVISE
+ return true;
+ }
+#endif // HAVE_MMAP
+ return false;
+}
+
+int KSycoca::version()
+{
+ return KSYCOCA_VERSION;
+}
+
+class KSycocaSingleton
+{
+public:
+ KSycocaSingleton() { }
+ ~KSycocaSingleton() { }
+
+ bool hasSycoca() const {
+ return m_threadSycocas.hasLocalData();
+ }
+ KSycoca* sycoca() {
+ if (!m_threadSycocas.hasLocalData())
+ m_threadSycocas.setLocalData(new KSycoca);
+ return m_threadSycocas.localData();
+ }
+ void setSycoca(KSycoca* s) {
+ m_threadSycocas.setLocalData(s);
+ }
+
+private:
+ QThreadStorage<KSycoca*> m_threadSycocas;
+};
+
+Q_GLOBAL_STATIC(KSycocaSingleton, ksycocaInstance)
+
+// Read-only constructor
+KSycoca::KSycoca()
+ : d(new KSycocaPrivate)
+{
+ QDBusConnection::sessionBus().connect(QString(), QString(),
+ \
QString::fromLatin1("org.kde.KSycoca"), + \
QString::fromLatin1("notifyDatabaseChanged"), + \
this, SLOT(notifyDatabaseChanged(QStringList))); +}
+
+bool KSycocaPrivate::openDatabase(bool openDummyIfNotFound)
+{
+ Q_ASSERT(databaseStatus == DatabaseNotOpen);
+
+ delete m_device; m_device = 0;
+ QString path = KSycoca::absoluteFilePath();
+
+ bool canRead = QFileInfo(path).isReadable();
+ qDebug() << "Trying to open ksycoca from" << path;
+ if (!canRead) {
+ path = KSycoca::absoluteFilePath(KSycoca::GlobalDatabase);
+ if (!path.isEmpty()) {
+ qDebug() << "Trying to open global ksycoca from " << path;
+ canRead = QFileInfo(path).isReadable();
+ }
+ }
+
+ bool result = true;
+ if (canRead) {
+ m_databasePath = path;
+ checkVersion();
+ } else { // No database file
+ //qDebug() << "Could not open ksycoca";
+ m_databasePath.clear();
+ databaseStatus = NoDatabase;
+ if (openDummyIfNotFound) {
+ // We open a dummy database instead.
+ //qDebug() << "No database, opening a dummy one.";
+
+ m_sycocaStrategy = StrategyDummyBuffer;
+ QDataStream* str = stream();
+ *str << qint32(KSYCOCA_VERSION);
+ *str << qint32(0);
+ } else {
+ result = false;
+ }
+ }
+ return result;
+}
+
+KSycocaAbstractDevice* KSycocaPrivate::device()
+{
+ if (m_device)
+ return m_device;
+
+ Q_ASSERT(!m_databasePath.isEmpty());
+
+ KSycocaAbstractDevice* device = m_device;
+ if (m_sycocaStrategy == StrategyDummyBuffer) {
+ device = new KSycocaBufferDevice;
+ device->device()->open(QIODevice::ReadOnly); // can't fail
+ } else {
+#if HAVE_MMAP
+ if (m_sycocaStrategy == StrategyMmap && tryMmap()) {
+ device = new KSycocaMmapDevice(sycoca_mmap,
+ sycoca_size);
+ if (!device->device()->open(QIODevice::ReadOnly)) {
+ delete device; device = 0;
+ }
+ }
+#endif
+#ifndef QT_NO_SHAREDMEMORY
+ if (!device && m_sycocaStrategy == StrategyMemFile) {
+ device = new KSycocaMemFileDevice(m_databasePath);
+ if (!device->device()->open(QIODevice::ReadOnly)) {
+ delete device; device = 0;
+ }
+ }
+#endif
+ if (!device) {
+ device = new KSycocaFileDevice(m_databasePath);
+ if (!device->device()->open(QIODevice::ReadOnly)) {
+ qWarning() << "Couldn't open" << m_databasePath << "even \
though it is readable? Impossible."; + //delete device; \
device = 0; // this would crash in the return statement... + }
+ }
+ }
+ if (device) {
+ m_device = device;
+ }
+ return m_device;
+}
+
+QDataStream*& KSycocaPrivate::stream()
+{
+ if (!m_device) {
+ if (databaseStatus == DatabaseNotOpen) {
+ checkDatabase(KSycocaPrivate::IfNotFoundRecreate | \
KSycocaPrivate::IfNotFoundOpenDummy); + }
+
+ device(); // create m_device
+ }
+
+ return m_device->stream();
+}
+
+// Read-write constructor - only for KBuildSycoca
+KSycoca::KSycoca( bool /* dummy */ )
+ : d(new KSycocaPrivate)
+{
+ // This instance was not created by the singleton, but by a direct \
call to new! + ksycocaInstance()->setSycoca(this);
+}
+
+KSycoca * KSycoca::self()
+{
+ KSycoca* s = ksycocaInstance()->sycoca();
+ Q_ASSERT(s);
+ return s;
+}
+
+KSycoca::~KSycoca()
+{
+ d->closeDatabase();
+ delete d;
+ //if (ksycocaInstance.exists()
+ // && ksycocaInstance->self == this)
+ // ksycocaInstance->self = 0;
+}
+
+bool KSycoca::isAvailable()
+{
+ return self()->d->checkDatabase(KSycocaPrivate::IfNotFoundDoNothing/* \
don't open dummy db if not found */); +}
+
+void KSycocaPrivate::closeDatabase()
+{
+ delete m_device;
+ m_device = 0;
+
+ // It is very important to delete all factories here
+ // since they cache information about the database file
+ // But other threads might be using them, so this class is
+ // refcounted, and deleted when the last thread is done with them
+ qDeleteAll(m_factories);
+ m_factories.clear();
+#if HAVE_MMAP
+ if (sycoca_mmap) {
+ //QBuffer *buf = static_cast<QBuffer*>(device);
+ //buf->buffer().clear();
+ // Solaris has munmap(char*, size_t) and everything else should
+ // be happy with a char* for munmap(void*, size_t)
+ munmap(const_cast<char*>(sycoca_mmap), sycoca_size);
+ sycoca_mmap = 0;
+ }
+ delete m_mmapFile; m_mmapFile = 0;
+#endif
+
+ databaseStatus = DatabaseNotOpen;
+ timeStamp = 0;
+}
+
+void KSycoca::addFactory( KSycocaFactory *factory )
+{
+ d->addFactory(factory);
+}
+
+#ifndef KDE_NO_DEPRECATED
+bool KSycoca::isChanged(const char *type)
+{
+ return self()->d->changeList.contains(QString::fromLatin1(type));
+}
+#endif
+
+void KSycoca::notifyDatabaseChanged(const QStringList &changeList)
+{
+ d->changeList = changeList;
+ //qDebug() << QThread::currentThread() << "got a \
notifyDatabaseChanged signal" << changeList; + // kbuildsycoca tells us \
the database file changed + // Close the database and forget all about \
what we knew + // The next call to any public method will recreate
+ // everything that's needed.
+ d->closeDatabase();
+
+ // Now notify applications
+#ifndef KDE_NO_DEPRECATED
+ emit databaseChanged();
+#endif
+ emit databaseChanged(changeList);
+}
+
+QDataStream * KSycoca::findEntry(int offset, KSycocaType &type)
+{
+ QDataStream* str = stream();
+ Q_ASSERT(str);
+ //qDebug() << QString("KSycoca::_findEntry(offset=%1)").arg(offset,8,16);
+ str->device()->seek(offset);
+ qint32 aType;
+ *str >> aType;
+ type = KSycocaType(aType);
+ //qDebug() << QString("KSycoca::found type %1").arg(aType);
+ return str;
+}
+
+KSycocaFactoryList* KSycoca::factories()
+{
+ return d->factories();
+}
+
+// Warning, checkVersion rewinds to the beginning of stream().
+bool KSycocaPrivate::checkVersion()
+{
+ QDataStream *m_str = device()->stream();
+ Q_ASSERT(m_str);
+ m_str->device()->seek(0);
+ qint32 aVersion;
+ *m_str >> aVersion;
+ if ( aVersion < KSYCOCA_VERSION ) {
+ qDebug() << "Found version" << aVersion << ", expecting version" \
<< KSYCOCA_VERSION << "or higher."; + databaseStatus = BadVersion;
+ return false;
+ } else {
+ databaseStatus = DatabaseOK;
+ return true;
+ }
+}
+
+// If it returns true, we have a valid database and the stream has \
rewinded to the beginning +// and past the version number.
+bool KSycocaPrivate::checkDatabase(BehaviorsIfNotFound ifNotFound)
+{
+ if (databaseStatus == DatabaseOK) {
+ if (checkVersion()) // we know the version is ok, but we must \
rewind the stream anyway + return true;
+ }
+
+ closeDatabase(); // close the dummy one
+
+ // We can only use the installed ksycoca file if kded is running,
+ // since kded is what keeps the file uptodate.
+ QDBusConnectionInterface* bus = \
QDBusConnection::sessionBus().interface(); + const bool kdedRunning = \
bus->isServiceRegistered(QString::fromLatin1("org.kde.kded5")) || + \
qAppName() == "kbuildsycoca5"; +
+ // Check if new database already available
+ if (kdedRunning && openDatabase(ifNotFound & IfNotFoundOpenDummy)) {
+ if (checkVersion()) {
+ // Database exists, and version is ok.
+ return true;
+ }
+ }
+
+ if (ifNotFound & IfNotFoundRecreate) {
+ // Ask kded to rebuild ksycoca
+ // (so that it's not only built, but also kept up-to-date...)
+ bool justStarted = false;
+ if (!bus->isServiceRegistered(QLatin1String("org.kde.kded5"))) {
+ // kded isn't even running: start it
+ QDBusReply<void> reply = \
bus->startService(QLatin1String("org.kde.kded5")); + if \
(!reply.isValid()) { + qWarning() << "Couldn't start kded5 \
from org.kde.kded5.service:" << reply.error(); + }
+ //qDebug() << "kded5 registered";
+ justStarted = true;
+ } else {
+ //qDebug() << "kded5 found";
+ }
+
+ QDBusInterface sycoca(QLatin1String("org.kde.kded5"), \
QLatin1String("/kbuildsycoca")); +#if QT_VERSION >= QT_VERSION_CHECK(5, 0, \
0) + if (QStandardPaths::isTestModeEnabled()) {
+ if (!justStarted) {
+ const QDBusReply<bool> testMode = \
sycoca.call(QLatin1String("isTestModeEnabled")); + if \
(!testMode.value()) { + qWarning() << "This unit test \
uses ksycoca, it needs to be run in a separate DBus session, so that kded \
can be started in 'test mode'."; + qWarning() << \
"KSycoca updates will very likely fail unless you do that."; + \
qWarning() << "`eval dbus-launch` ; make test"; + // \
Idea for the future: move kbuildsycoca stuff to its own kded module, and \
use + // the same module with a different name, for \
test mode. + // On the other hand, the use of other \
kded modules (cookies, timezone, etc.) + // is also \
better separated from the user's kded anyway. + }
+ }
+ sycoca.call(QLatin1String("enableTestMode"));
+ Q_ASSERT(QDBusReply<bool>(sycoca.call(QLatin1String("isTestModeEnabled"))).value());
+ }
+#else
+ Q_UNUSED(justStarted);
+#endif
+
+ //qDebug() << "We have no database.... asking kded to create it";
+ sycoca.call(QLatin1String("recreate"));
+
+ closeDatabase(); // close the dummy one
+
+ // Ok, the new database should be here now, open it.
+ if (!openDatabase(ifNotFound & IfNotFoundOpenDummy)) {
+ qDebug() << "Still no database...";
+ return false; // Still no database - uh oh
+ }
+ if (!checkVersion()) {
+ qDebug() << "Still outdated...";
+ return false; // Still outdated - uh oh
+ }
+ return true;
+ }
+
+ return false;
+}
+
+QDataStream * KSycoca::findFactory(KSycocaFactoryId id)
+{
+ // Ensure we have a valid database (right version, and rewinded to \
beginning) + if (!d->checkDatabase(KSycocaPrivate::IfNotFoundRecreate)) \
{ + return 0;
+ }
+
+ QDataStream* str = stream();
+ Q_ASSERT(str);
+
+ qint32 aId;
+ qint32 aOffset;
+ while(true) {
+ *str >> aId;
+ if (aId == 0) {
+ qWarning() << "Error, KSycocaFactory (id =" << int(id) << ") \
not found!"; + break;
+ }
+ *str >> aOffset;
+ if (aId == id) {
+ //qDebug() << "KSycoca::findFactory(" << id << ") offset " << \
aOffset; + str->device()->seek(aOffset);
+ return str;
+ }
+ }
+ return 0;
+}
+
+QString KSycoca::kfsstnd_prefixes()
+{
+ // do not try to launch kbuildsycoca from here; this code is also \
called by kbuildsycoca. + if \
(!d->checkDatabase(KSycocaPrivate::IfNotFoundDoNothing)) + return \
QString(); + QDataStream* str = stream();
+ Q_ASSERT(str);
+ qint32 aId;
+ qint32 aOffset;
+ // skip factories offsets
+ while(true)
+ {
+ *str >> aId;
+ if ( aId )
+ *str >> aOffset;
+ else
+ break; // just read 0
+ }
+ // We now point to the header
+ QString prefixes;
+ KSycocaEntry::read(*str, prefixes);
+ *str >> d->timeStamp;
+ KSycocaEntry::read(*str, d->language);
+ *str >> d->updateSig;
+ KSycocaEntry::read(*str, d->allResourceDirs);
+ return prefixes;
+}
+
+quint32 KSycoca::timeStamp()
+{
+ if (!d->timeStamp)
+ (void) kfsstnd_prefixes();
+ return d->timeStamp;
+}
+
+quint32 KSycoca::updateSignature()
+{
+ if (!d->timeStamp)
+ (void) kfsstnd_prefixes();
+ return d->updateSig;
+}
+
+QString KSycoca::absoluteFilePath(DatabaseType type)
+{
+ if (type == GlobalDatabase) {
+ QString path = \
QStandardPaths::locate(QStandardPaths::GenericDataLocation, \
QString::fromLatin1("kde5/services/" KSYCOCA_FILENAME)); + if \
(path.isEmpty()) + return \
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + \
QString::fromLatin1("/kde5/services/" KSYCOCA_FILENAME); + return \
path; + }
+
+ const QByteArray ksycoca_env = qgetenv("KDESYCOCA");
+ if (ksycoca_env.isEmpty()) {
+ return QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) \
+ QLatin1Char('/') + QString::fromLatin1(KSYCOCA_FILENAME); + } else {
+ return QFile::decodeName(ksycoca_env);
+ }
+}
+
+QString KSycoca::language()
+{
+ if (d->language.isEmpty())
+ (void) kfsstnd_prefixes();
+ return d->language;
+}
+
+QStringList KSycoca::allResourceDirs()
+{
+ if (!d->timeStamp)
+ (void) kfsstnd_prefixes();
+ return d->allResourceDirs;
+}
+
+void KSycoca::flagError()
+{
+ qWarning() << "ERROR: KSycoca database corruption!";
+ KSycocaPrivate* d = ksycocaInstance()->sycoca()->d;
+ if (d->readError)
+ return;
+ d->readError = true;
+ if (s_autoRebuild) {
+ // Rebuild the damned thing.
+ if (QProcess::execute(QStandardPaths::findExecutable(QString::fromLatin1(KBUILDSYCOCA_EXENAME))) \
!= 0) + qWarning("ERROR: Running %s failed", \
KBUILDSYCOCA_EXENAME); + // Old comment, maybe not true anymore:
+ // Do not wait until the DBUS signal from kbuildsycoca here.
+ // It deletes m_str which is a problem when flagError is called \
during the KSycocaFactory ctor... + }
+}
+
+bool KSycoca::isBuilding()
+{
+ return false;
+}
+
+void KSycoca::disableAutoRebuild()
+{
+ s_autoRebuild = false;
+}
+
+QDataStream*& KSycoca::stream()
+{
+ return d->stream();
+}
+
+void KSycoca::clearCaches()
+{
+#if QT_VERSION >= QT_VERSION_CHECK(5,1,0)
+ if (ksycocaInstance.exists() && ksycocaInstance()->hasSycoca())
+#else
+ if (ksycocaInstance() && ksycocaInstance()->hasSycoca())
+#endif
+ ksycocaInstance()->sycoca()->d->closeDatabase();
+}
+
+#include "ksycoca.moc"
diff --cc tier1/solid/src/solid/backends/udisks/udisksopticaldrive.cpp
index 1acaddd,0000000..d3e2f93
mode 100644,000000..100644
--- a/tier1/solid/src/solid/backends/udisks/udisksopticaldrive.cpp
+++ b/tier1/solid/src/solid/backends/udisks/udisksopticaldrive.cpp
@@@ -1,197 -1,0 +1,189 @@@
+/*
+ Copyright 2010 Michael Zanetti <mzanetti@kde.org>
+ Copyright 2010-2011 Lukas Tinkl <ltinkl@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see \
<http://www.gnu.org/licenses/>. +*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <QtCore/QFile>
+#include <QtCore/QDebug>
+
+#include "udisksopticaldrive.h"
+#include "udisks.h"
+#include "udisksdevice.h"
+
+using namespace Solid::Backends::UDisks;
+
+UDisksOpticalDrive::UDisksOpticalDrive(UDisksDevice *device)
+ : UDisksStorageDrive(device), m_ejectInProgress(false), \
m_readSpeed(0), m_writeSpeed(0), m_speedsInit(false) +{
+ m_device->registerAction("eject", this,
+ SLOT(slotEjectRequested()),
+ SLOT(slotEjectDone(int,QString)));
+
+ connect(m_device, SIGNAL(changed()), this, SLOT(slotChanged()));
+}
+
+UDisksOpticalDrive::~UDisksOpticalDrive()
+{
+
+}
+
+bool UDisksOpticalDrive::eject()
+{
+ if (m_ejectInProgress)
+ return false;
+ m_ejectInProgress = true;
+ m_device->broadcastActionRequested("eject");
+
+ QDBusConnection c = QDBusConnection::systemBus();
+
+ QString path = m_device->udi();
+
- // check if the device is mounted and call umount if needed
- if (m_device->prop("DeviceIsMounted").toBool())
- {
- QDBusMessage msg = \
QDBusMessage::createMethodCall(UD_DBUS_SERVICE, path, \
UD_DBUS_INTERFACE_DISKS_DEVICE, "FilesystemUnmount");
- msg << QStringList(); // options, unused now
- c.call(msg, QDBus::NoBlock);
- }
-
+ QDBusMessage msg = QDBusMessage::createMethodCall(UD_DBUS_SERVICE, \
path, UD_DBUS_INTERFACE_DISKS_DEVICE, "DriveEject");
- msg << QStringList();
++ msg << "unmount"; // unmount parameter
+ return c.callWithCallback(msg, this, \
SLOT(slotDBusReply(QDBusMessage)), SLOT(slotDBusError(QDBusError))); +}
+
+void UDisksOpticalDrive::slotDBusReply(const QDBusMessage &/*reply*/)
+{
+ m_ejectInProgress = false;
+ m_device->broadcastActionDone("eject");
+}
+
+void UDisksOpticalDrive::slotDBusError(const QDBusError &error)
+{
+ m_ejectInProgress = false;
+ m_device->broadcastActionDone("eject", \
m_device->errorToSolidError(error.name()), + \
m_device->errorToString(error.name()) + ": " +error.message()); +}
+
+void UDisksOpticalDrive::slotEjectRequested()
+{
+ m_ejectInProgress = true;
+ Q_EMIT ejectRequested(m_device->udi());
+}
+
+void UDisksOpticalDrive::slotEjectDone(int error, const QString \
&errorString) +{
+ m_ejectInProgress = false;
+ Q_EMIT ejectDone(static_cast<Solid::ErrorType>(error), errorString, \
m_device->udi()); +}
+
+void UDisksOpticalDrive::initReadWriteSpeeds() const
+{
+#if 0
+ int read_speed, write_speed;
+ char *write_speeds = 0;
+ QByteArray device_file = \
QFile::encodeName(m_device->property("DeviceFile").toString()); +
+ //qDebug("Doing open (\"%s\", O_RDONLY | O_NONBLOCK)", \
device_file.constData()); + int fd = open(device_file, O_RDONLY | \
O_NONBLOCK); + if (fd < 0) {
+ qWarning("Cannot open %s: %s", device_file.constData(), strerror \
(errno)); + return;
+ }
+
+ if (get_read_write_speed(fd, &read_speed, &write_speed, \
&write_speeds) >= 0) { + m_readSpeed = read_speed;
+ m_writeSpeed = write_speed;
+
+ QStringList list = QString::fromLatin1(write_speeds).split(',', \
QString::SkipEmptyParts); + Q_FOREACH (const QString & speed, list)
+ m_writeSpeeds.append(speed.toInt());
+
+ free(write_speeds);
+
+ m_speedsInit = true;
+ }
+
+ close(fd);
+#endif
+}
+
+QList<int> UDisksOpticalDrive::writeSpeeds() const
+{
+ if (!m_speedsInit)
+ initReadWriteSpeeds();
+ //qDebug() << "solid write speeds:" << m_writeSpeeds;
+ return m_writeSpeeds;
+}
+
+int UDisksOpticalDrive::writeSpeed() const
+{
+ if (!m_speedsInit)
+ initReadWriteSpeeds();
+ return m_writeSpeed;
+}
+
+int UDisksOpticalDrive::readSpeed() const
+{
+ if (!m_speedsInit)
+ initReadWriteSpeeds();
+ return m_readSpeed;
+}
+
+Solid::OpticalDrive::MediumTypes UDisksOpticalDrive::supportedMedia() \
const +{
+ const QStringList mediaTypes = \
m_device->prop("DriveMediaCompatibility").toStringList(); + \
Solid::OpticalDrive::MediumTypes supported; +
+ QMap<Solid::OpticalDrive::MediumType, QString> map;
+ map[Solid::OpticalDrive::Cdr] = "optical_cd_r";
+ map[Solid::OpticalDrive::Cdrw] = "optical_cd_rw";
+ map[Solid::OpticalDrive::Dvd] = "optical_dvd";
+ map[Solid::OpticalDrive::Dvdr] = "optical_dvd_r";
+ map[Solid::OpticalDrive::Dvdrw] ="optical_dvd_rw";
+ map[Solid::OpticalDrive::Dvdram] ="optical_dvd_ram";
+ map[Solid::OpticalDrive::Dvdplusr] ="optical_dvd_plus_r";
+ map[Solid::OpticalDrive::Dvdplusrw] ="optical_dvd_plus_rw";
+ map[Solid::OpticalDrive::Dvdplusdl] ="optical_dvd_plus_r_dl";
+ map[Solid::OpticalDrive::Dvdplusdlrw] ="optical_dvd_plus_rw_dl";
+ map[Solid::OpticalDrive::Bd] ="optical_bd";
+ map[Solid::OpticalDrive::Bdr] ="optical_bd_r";
+ map[Solid::OpticalDrive::Bdre] ="optical_bd_re";
+ map[Solid::OpticalDrive::HdDvd] ="optical_hddvd";
+ map[Solid::OpticalDrive::HdDvdr] ="optical_hddvd_r";
+ map[Solid::OpticalDrive::HdDvdrw] ="optical_hddvd_rw";
+ // TODO add these to Solid
+ //map[Solid::OpticalDrive::Mo] ="optical_mo";
+ //map[Solid::OpticalDrive::Mr] ="optical_mrw";
+ //map[Solid::OpticalDrive::Mrw] ="optical_mrw_w";
+
+ Q_FOREACH ( const Solid::OpticalDrive::MediumType & type, map.keys() \
) + {
+ if ( mediaTypes.contains( map[type] ) )
+ {
+ supported |= type;
+ }
+ }
+
+ return supported;
+}
+
+void UDisksOpticalDrive::slotChanged()
+{
+ m_speedsInit = false; // reset the read/write speeds, changes eg. \
with an inserted media +}
diff --cc tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp
index df63aa6,0000000..537c1a7
mode 100644,000000..100644
--- a/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp
+++ b/tier1/solid/src/solid/backends/udisks2/udisksstorageaccess.cpp
@@@ -1,362 -1,0 +1,390 @@@
+/*
+ Copyright 2009 Pino Toscano <pino@kde.org>
+ Copyright 2009-2012 Lukáš Tinkl <ltinkl@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see \
<http://www.gnu.org/licenses/>. +*/
+
+#include "udisksstorageaccess.h"
+#include "udisks2.h"
+
- #include <QProcess>
++#include <QDomDocument>
+#include <QtDBus/QtDBus>
+#include <QApplication>
+#include <QWidget>
+
+using namespace Solid::Backends::UDisks2;
+
+StorageAccess::StorageAccess(Device *device)
+ : DeviceInterface(device), m_setupInProgress(false), \
m_teardownInProgress(false), m_passphraseRequested(false) +{
+ connect(device, SIGNAL(changed()), this, SLOT(checkAccessibility()));
+ updateCache();
+
+ // Delay connecting to DBus signals to avoid the related time penalty
+ // in hot paths such as predicate matching
+ QTimer::singleShot(0, this, SLOT(connectDBusSignals()));
+}
+
+StorageAccess::~StorageAccess()
+{
+}
+
+void StorageAccess::connectDBusSignals()
+{
+ m_device->registerAction("setup", this,
+ SLOT(slotSetupRequested()),
+ SLOT(slotSetupDone(int, const QString&)));
+
+ m_device->registerAction("teardown", this,
+ SLOT(slotTeardownRequested()),
+ SLOT(slotTeardownDone(int, const \
QString&))); +}
+
+bool StorageAccess::isLuksDevice() const
+{
+ return m_device->isEncryptedContainer(); // encrypted device
+}
+
+bool StorageAccess::isAccessible() const
+{
+ if (isLuksDevice()) { // check if the cleartext slave is mounted
- if (m_clearTextPath.isEmpty() || m_clearTextPath == "/")
++ const QString path = clearTextPath();
++ //qDebug() << Q_FUNC_INFO << "CLEARTEXT device path: " << path;
++ if (path.isEmpty() || path == "/")
+ return false;
- Device holderDevice(m_clearTextPath);
++ Device holderDevice(path);
+ return holderDevice.isMounted();
+ }
+
+ return m_device->isMounted();
+}
+
+QString StorageAccess::filePath() const
+{
- if (!isAccessible())
- return QString();
-
+ QByteArrayList mntPoints;
+
+ if (isLuksDevice()) { // encrypted (and unlocked) device
- if (m_clearTextPath.isEmpty() || m_clearTextPath == "/")
++ const QString path = clearTextPath();
++ if (path.isEmpty() || path == "/")
+ return QString();
- Device holderDevice(m_clearTextPath);
++ Device holderDevice(path);
+ mntPoints = \
qdbus_cast<QByteArrayList>(holderDevice.prop("MountPoints")); + if \
(!mntPoints.isEmpty()) + return \
QFile::decodeName(mntPoints.first()); // FIXME Solid doesn't support \
multiple mount points + else
+ return QString();
+ }
+
+ mntPoints = qdbus_cast<QByteArrayList>(m_device->prop("MountPoints"));
+
+ if (!mntPoints.isEmpty())
+ return QFile::decodeName(mntPoints.first()); // FIXME Solid \
doesn't support multiple mount points + else
+ return QString();
+}
+
+bool StorageAccess::isIgnored() const
+{
- return m_device->prop("HintIgnore").toBool(); // FIXME tune
++ return m_device->prop("HintIgnore").toBool();
+}
+
+bool StorageAccess::setup()
+{
+ if ( m_teardownInProgress || m_setupInProgress )
+ return false;
+ m_setupInProgress = true;
+ m_device->broadcastActionRequested("setup");
+
- if (m_device->isEncryptedContainer())
++ if (m_device->isEncryptedContainer() && clearTextPath().isEmpty())
+ return requestPassphrase();
+ else
+ return mount();
+}
+
+bool StorageAccess::teardown()
+{
+ if ( m_teardownInProgress || m_setupInProgress )
+ return false;
+ m_teardownInProgress = true;
+ m_device->broadcastActionRequested("teardown");
+
+ return unmount();
+}
+
+void StorageAccess::updateCache()
+{
+ m_isAccessible = isAccessible();
+}
+
+void StorageAccess::checkAccessibility()
+{
+ const bool old_isAccessible = m_isAccessible;
+ updateCache();
+
+ if (old_isAccessible != m_isAccessible) {
- Q_EMIT accessibilityChanged(m_isAccessible, isLuksDevice() ? \
m_clearTextPath : m_device->udi()); ++ Q_EMIT \
accessibilityChanged(m_isAccessible, m_device->udi()); + }
+}
+
- void StorageAccess::slotDBusReply( const QDBusMessage & reply )
++void StorageAccess::slotDBusReply( const QDBusMessage & /*reply*/ )
+{
++ const QString ctPath = clearTextPath();
+ if (m_setupInProgress)
+ {
+ if (isLuksDevice() && !isAccessible()) { // unlocked device, now \
mount it
- if (reply.type() == QDBusMessage::ReplyMessage) // we've got \
a response from Unlock
- m_clearTextPath = \
reply.arguments().value(0).value<QDBusObjectPath>().path(); + \
mount(); + }
+ else // Don't broadcast setupDone unless the setup is really \
done. (Fix kde#271156) + {
+ m_setupInProgress = false;
+ m_device->broadcastActionDone("setup");
+
+ checkAccessibility();
+ }
+ }
+ else if (m_teardownInProgress) // FIXME
+ {
- if (isLuksDevice() && !m_clearTextPath.isEmpty() && \
m_clearTextPath != "/") // unlocked device, lock it ++ if \
(isLuksDevice() && !ctPath.isEmpty() && ctPath != "/") // unlocked device, \
lock it + {
+ callCryptoTeardown();
+ }
- else if (!m_clearTextPath.isEmpty() && m_clearTextPath != "/") {
++ else if (!ctPath.isEmpty() && ctPath != "/") {
+ callCryptoTeardown(true); // Lock crypted parent
+ }
+ else
+ {
+ // try to "eject" (aka safely remove) from the (parent) \
drive, e.g. SD card from a reader
- QString drivePath = \
m_device->prop("Drive").value<QDBusObjectPath>().path(); ++ \
QString drivePath = m_device->drivePath(); + if \
(!drivePath.isEmpty() || drivePath != "/") + {
+ Device drive(drivePath);
+ if (drive.prop("Ejectable").toBool() &&
+ drive.prop("MediaAvailable").toBool() &&
+ !m_device->isOpticalDisc()) // optical drives \
have their Eject method + {
+ QDBusConnection c = QDBusConnection::systemBus();
+ QDBusMessage msg = \
QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, drivePath, \
UD2_DBUS_INTERFACE_DRIVE, "Eject"); + msg << \
QVariantMap(); // options, unused now + c.call(msg, \
QDBus::NoBlock); + }
+ }
+
+ m_teardownInProgress = false;
+ m_device->broadcastActionDone("teardown");
+
+ checkAccessibility();
+ }
+ }
+}
+
+void StorageAccess::slotDBusError( const QDBusError & error )
+{
++ //qDebug() << Q_FUNC_INFO << "DBUS ERROR:" << error.name() << \
error.message(); ++
+ if (m_setupInProgress)
+ {
+ m_setupInProgress = false;
+ m_device->broadcastActionDone("setup", \
m_device->errorToSolidError(error.name()), + \
m_device->errorToString(error.name()) + ": " +error.message()); +
+ checkAccessibility();
+ }
+ else if (m_teardownInProgress)
+ {
+ m_teardownInProgress = false;
- m_clearTextPath.clear();
+ m_device->broadcastActionDone("teardown", \
m_device->errorToSolidError(error.name()), + \
m_device->errorToString(error.name()) + ": " + error.message()); + \
checkAccessibility(); + }
+}
+
+void StorageAccess::slotSetupRequested()
+{
+ m_setupInProgress = true;
+ //qDebug() << "SETUP REQUESTED:" << m_device->udi();
+ Q_EMIT setupRequested(m_device->udi());
+}
+
+void StorageAccess::slotSetupDone(int error, const QString &errorString)
+{
+ m_setupInProgress = false;
+ //qDebug() << "SETUP DONE:" << m_device->udi();
+ Q_EMIT setupDone(static_cast<Solid::ErrorType>(error), errorString, \
m_device->udi()); +
+ checkAccessibility();
+}
+
+void StorageAccess::slotTeardownRequested()
+{
+ m_teardownInProgress = true;
+ Q_EMIT teardownRequested(m_device->udi());
+}
+
+void StorageAccess::slotTeardownDone(int error, const QString \
&errorString) +{
+ m_teardownInProgress = false;
- m_clearTextPath.clear();
+ Q_EMIT teardownDone(static_cast<Solid::ErrorType>(error), \
errorString, m_device->udi()); +
+ checkAccessibility();
+}
+
+bool StorageAccess::mount()
+{
+ QString path = m_device->udi();
++ const QString ctPath = clearTextPath();
+
- if (isLuksDevice()) { // mount options for the cleartext volume
- path = m_clearTextPath;
++ if (isLuksDevice() && !ctPath.isEmpty()) { // mount options for the \
cleartext volume ++ path = ctPath;
+ }
+
+ QDBusConnection c = QDBusConnection::systemBus();
+ QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, \
path, UD2_DBUS_INTERFACE_FILESYSTEM, "Mount"); + QVariantMap options;
+
+ if (m_device->prop("IdType").toString() == "vfat")
+ options.insert("options", "flush");
+
+ msg << options;
+
+ return c.callWithCallback(msg, this,
+ SLOT(slotDBusReply(const QDBusMessage &)),
+ SLOT(slotDBusError(const QDBusError &)));
+}
+
+bool StorageAccess::unmount()
+{
+ QString path = m_device->udi();
++ const QString ctPath = clearTextPath();
+
- if (isLuksDevice()) { // unmount options for the cleartext volume
- path = m_clearTextPath;
++ if (isLuksDevice() && !ctPath.isEmpty()) { // unmount options for the \
cleartext volume ++ path = ctPath;
+ }
+
+ QDBusConnection c = QDBusConnection::systemBus();
+ QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, \
path, UD2_DBUS_INTERFACE_FILESYSTEM, "Unmount"); +
+ msg << QVariantMap(); // options, unused now
+
+ return c.callWithCallback(msg, this,
+ SLOT(slotDBusReply(const QDBusMessage &)),
+ SLOT(slotDBusError(const QDBusError &)),
+ s_unmountTimeout);
+}
+
+QString StorageAccess::generateReturnObjectPath()
+{
+ static int number = 1;
+
+ return "/org/kde/solid/UDisks2StorageAccess_"+QString::number(number++);
+}
+
++QString StorageAccess::clearTextPath() const
++{
++ const QString prefix = "/org/freedesktop/UDisks2/block_devices";
++ QDBusMessage call = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, \
prefix, ++ \
DBUS_INTERFACE_INTROSPECT, "Introspect"); ++ QDBusPendingReply<QString> \
reply = QDBusConnection::systemBus().asyncCall(call); ++ \
reply.waitForFinished(); ++
++ if (reply.isValid()) {
++ QDomDocument dom;
++ dom.setContent(reply.value());
++ QDomNodeList nodeList = \
dom.documentElement().elementsByTagName("node"); ++ for (int i = 0; \
i < nodeList.count(); i++) { ++ QDomElement nodeElem = \
nodeList.item(i).toElement(); ++ if (!nodeElem.isNull() && \
nodeElem.hasAttribute("name")) { ++ const QString udi = \
prefix + "/" + nodeElem.attribute("name"); ++ Device \
holderDevice(udi); ++
++ if (m_device->udi() == \
holderDevice.prop("CryptoBackingDevice").value<QDBusObjectPath>().path()) { \
++ //qDebug() << Q_FUNC_INFO << "CLEARTEXT device path: \
" << udi; ++ return udi;
++ }
++ }
++ }
++ }
++
++ return QString();
++}
++
+bool StorageAccess::requestPassphrase()
+{
+ QString udi = m_device->udi();
+ QString returnService = QDBusConnection::sessionBus().baseService();
+ m_lastReturnObject = generateReturnObjectPath();
+
+ QDBusConnection::sessionBus().registerObject(m_lastReturnObject, \
this, QDBusConnection::ExportScriptableSlots); +
+ QWidget *activeWindow = QApplication::activeWindow();
+ uint wId = 0;
+ if (activeWindow!=0)
+ wId = (uint)activeWindow->winId();
+
+ QString appId = QCoreApplication::applicationName();
+
+ QDBusInterface soliduiserver("org.kde.kded5", \
"/modules/soliduiserver", "org.kde.SolidUiServer"); + QDBusReply<void> \
reply = soliduiserver.call("showPassphraseDialog", udi, returnService, + \
m_lastReturnObject, wId, appId); + m_passphraseRequested = \
reply.isValid(); + if (!m_passphraseRequested)
+ qWarning() << "Failed to call the SolidUiServer, D-Bus said:" << \
reply.error(); +
+ return m_passphraseRequested;
+}
+
+void StorageAccess::passphraseReply(const QString & passphrase)
+{
+ if (m_passphraseRequested)
+ {
+ QDBusConnection::sessionBus().unregisterObject(m_lastReturnObject);
+ m_passphraseRequested = false;
+ if (!passphrase.isEmpty())
+ callCryptoSetup(passphrase);
+ else
+ {
+ m_setupInProgress = false;
+ m_device->broadcastActionDone("setup");
+ }
+ }
+}
+
+void StorageAccess::callCryptoSetup(const QString & passphrase)
+{
+ QDBusConnection c = QDBusConnection::systemBus();
+ QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE, \
m_device->udi(), UD2_DBUS_INTERFACE_ENCRYPTED, "Unlock"); +
+ msg << passphrase;
+ msg << QVariantMap(); // options, unused now
+
+ c.callWithCallback(msg, this,
+ SLOT(slotDBusReply(const QDBusMessage &)),
+ SLOT(slotDBusError(const QDBusError &)));
+}
+
+bool StorageAccess::callCryptoTeardown(bool actOnParent)
+{
+ QDBusConnection c = QDBusConnection::systemBus();
+ QDBusMessage msg = QDBusMessage::createMethodCall(UD2_DBUS_SERVICE,
+ actOnParent ? \
(m_device->prop("CryptoBackingDevice").value<QDBusObjectPath>().path()) : \
m_device->udi(), + \
UD2_DBUS_INTERFACE_ENCRYPTED, "Lock"); + msg << QVariantMap(); // \
options, unused now +
- m_clearTextPath.clear();
-
+ return c.callWithCallback(msg, this,
+ SLOT(slotDBusReply(const QDBusMessage &)),
+ SLOT(slotDBusError(const QDBusError &)));
+}
diff --cc tier1/solid/src/solid/backends/upower/upoweracadapter.cpp
index f21606e,0000000..19e8987
mode 100644,000000..100644
--- a/tier1/solid/src/solid/backends/upower/upoweracadapter.cpp
+++ b/tier1/solid/src/solid/backends/upower/upoweracadapter.cpp
@@@ -1,58 -1,0 +1,60 @@@
+/*
+ Copyright 2009 Pino Toscano <pino@kde.org>
+ Copyright 2010 Lukas Tinkl <ltinkl@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see \
<http://www.gnu.org/licenses/>. +*/
+
+#include "upoweracadapter.h"
+
+using namespace Solid::Backends::UPower;
+
+AcAdapter::AcAdapter(UPowerDevice *device)
+ : DeviceInterface(device)
+{
+ connect(device, SIGNAL(changed()), this, SLOT(slotChanged()));
+
+ updateCache();
+}
+
+AcAdapter::~AcAdapter()
+{
+}
+
+bool AcAdapter::isPlugged() const
+{
- return m_device->prop("Online").toBool();
++ return m_device.data()->prop("Online").toBool();
+}
+
+void AcAdapter::slotChanged()
+{
- const bool old_isPlugged = m_isPlugged;
- updateCache();
-
- if (old_isPlugged != m_isPlugged)
- {
- Q_EMIT plugStateChanged(m_isPlugged, m_device->udi());
++ if (m_device) {
++ const bool old_isPlugged = m_isPlugged;
++ updateCache();
++
++ if (old_isPlugged != m_isPlugged)
++ {
++ Q_EMIT plugStateChanged(m_isPlugged, m_device.data()->udi());
++ }
+ }
+}
+
+void AcAdapter::updateCache()
+{
+ m_isPlugged = isPlugged();
+}
+
diff --cc tier1/solid/src/solid/backends/upower/upowerbattery.cpp
index 6e2ef6c,0000000..3d5819a
mode 100644,000000..100644
--- a/tier1/solid/src/solid/backends/upower/upowerbattery.cpp
+++ b/tier1/solid/src/solid/backends/upower/upowerbattery.cpp
@@@ -1,198 -1,0 +1,194 @@@
+/*
+ Copyright 2009 Pino Toscano <pino@kde.org>
+ Copyright 2010, 2012 Lukas Tinkl <ltinkl@redhat.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see \
<http://www.gnu.org/licenses/>. +*/
+
+#include "upowerbattery.h"
+
+using namespace Solid::Backends::UPower;
+
+Battery::Battery(UPowerDevice *device)
+ : DeviceInterface(device)
+{
+ connect(device, SIGNAL(changed()), this, SLOT(slotChanged()));
+
+ updateCache();
+}
+
+Battery::~Battery()
+{
+}
+
+bool Battery::isPlugged() const
+{
- return m_device->prop("IsPresent").toBool();
++ return m_device.data()->prop("IsPresent").toBool();
+}
+
+Solid::Battery::BatteryType Battery::type() const
+{
+ Solid::Battery::BatteryType result = Solid::Battery::UnknownBattery;
- const uint t = m_device->prop("Type").toUInt();
++ const uint t = m_device.data()->prop("Type").toUInt();
+ switch (t)
+ {
+ case 1: // TODO "Line Power"
+ break;
+ case 2:
+ result = Solid::Battery::PrimaryBattery;
+ break;
+ case 3:
+ result = Solid::Battery::UpsBattery;
+ break;
+ case 4:
+ result = Solid::Battery::MonitorBattery;
+ break;
+ case 5:
+ result = Solid::Battery::MouseBattery;
+ break;
+ case 6:
+ result = Solid::Battery::KeyboardBattery;
+ break;
+ case 7:
+ result = Solid::Battery::PdaBattery;
+ break;
+ case 8:
+ result = Solid::Battery::PhoneBattery;
+ break;
+ }
+ return result;
+}
+
+int Battery::chargePercent() const
+{
- return qRound(m_device->prop("Percentage").toDouble());
++ return qRound(m_device.data()->prop("Percentage").toDouble());
+}
+
+int Battery::capacity() const
+{
- return qRound(m_device->prop("Capacity").toDouble());
++ return qRound(m_device.data()->prop("Capacity").toDouble());
+}
+
+bool Battery::isRechargeable() const
+{
- return m_device->prop("IsRechargeable").toBool();
++ return m_device.data()->prop("IsRechargeable").toBool();
+}
+
+Solid::Battery::ChargeState Battery::chargeState() const
+{
+ Solid::Battery::ChargeState result = Solid::Battery::NoCharge;
- const uint state = m_device->prop("State").toUInt();
++ const uint state = m_device.data()->prop("State").toUInt();
+ switch (state)
+ {
+ case 0:
+ result = Solid::Battery::NoCharge; // stable or unknown
+ break;
+ case 1:
+ result = Solid::Battery::Charging;
+ break;
+ case 2:
+ result = Solid::Battery::Discharging;
+ break;
+ case 3: // TODO "Empty"
+ break;
+ case 4: // TODO "Fully charged"
+ break;
+ case 5: // TODO "Pending charge"
+ break;
+ case 6: // TODO "Pending discharge"
+ break;
+ }
+ return result;
+}
+
+Solid::Battery::Technology Battery::technology() const
+{
- const uint tech = m_device->prop("Technology").toUInt();
++ const uint tech = m_device.data()->prop("Technology").toUInt();
+ switch (tech)
+ {
+ case 1:
+ return Solid::Battery::LithiumIon;
+ case 2:
+ return Solid::Battery::LithiumPolymer;
+ case 3:
+ return Solid::Battery::LithiumIronPhosphate;
+ case 4:
+ return Solid::Battery::LeadAcid;
+ case 5:
+ return Solid::Battery::NickelCadmium;
+ case 6:
+ return Solid::Battery::NickelMetalHydride;
+ default:
+ return Solid::Battery::UnknownTechnology;
+ }
+}
+
+double Battery::energy() const
+{
- return m_device->prop("Energy").toDouble();
++ return m_device.data()->prop("Energy").toDouble();
+}
+
+double Battery::energyRate() const
+{
- return m_device->prop("EnergyRate").toDouble();
++ return m_device.data()->prop("EnergyRate").toDouble();
+}
+
+double Battery::voltage() const
+{
- return m_device->prop("Voltage").toDouble();
++ return m_device.data()->prop("Voltage").toDouble();
+}
+
+void Battery::slotChanged()
+{
- if (!m_device)
- return;
-
- const bool old_isPlugged = m_isPlugged;
- const int old_chargePercent = m_chargePercent;
- const Solid::Battery::ChargeState old_chargeState = m_chargeState;
- const double old_energy = m_energy;
- const double old_energyRate = m_energyRate;
- updateCache();
-
- if (old_chargePercent != m_chargePercent)
- {
- Q_EMIT chargePercentChanged(m_chargePercent, m_device->udi());
- }
-
- if (old_chargeState != m_chargeState)
- {
- Q_EMIT chargeStateChanged(m_chargeState, m_device->udi());
- }
-
- if (old_isPlugged != m_isPlugged)
- {
- Q_EMIT plugStateChanged(m_isPlugged, m_device->udi());
- }
-
- if (old_energy != m_energy) {
- Q_EMIT energyChanged(m_energy, m_device->udi());
- }
-
- if (old_energyRate != m_energyRate) {
- Q_EMIT energyRateChanged(m_energyRate, m_device->udi());
++ if (m_device) {
++ const bool old_isPlugged = m_isPlugged;
++ const int old_chargePercent = m_chargePercent;
++ const Solid::Battery::ChargeState old_chargeState = \
m_chargeState; ++ const double old_energy = m_energy;
++ const double old_energyRate = m_energyRate;
++ updateCache();
++
++ if (old_chargePercent != m_chargePercent) {
++ Q_EMIT chargePercentChanged(m_chargePercent, \
m_device.data()->udi()); ++ }
++
++ if (old_chargeState != m_chargeState) {
++ Q_EMIT chargeStateChanged(m_chargeState, \
m_device.data()->udi()); ++ }
++
++ if (old_isPlugged != m_isPlugged) {
++ Q_EMIT plugStateChanged(m_isPlugged, m_device.data()->udi());
++ }
++
++ if (old_energy != m_energy) {
++ Q_EMIT energyChanged(m_energy, m_device.data()->udi());
++ }
++
++ if (old_energyRate != m_energyRate) {
++ Q_EMIT energyRateChanged(m_energyRate, \
m_device.data()->udi()); ++ }
+ }
+}
+
+void Battery::updateCache()
+{
+ m_isPlugged = isPlugged();
+ m_chargePercent = chargePercent();
+ m_chargeState = chargeState();
+ m_energy = energy();
+ m_energyRate = energyRate();
+}
diff --cc tier1/solid/src/solid/backends/upower/upowergenericinterface.cpp
index 3a2e944,0000000..97cd10b
mode 100644,000000..100644
--- a/tier1/solid/src/solid/backends/upower/upowergenericinterface.cpp
+++ b/tier1/solid/src/solid/backends/upower/upowergenericinterface.cpp
@@@ -1,50 -1,0 +1,50 @@@
+/*
+ Copyright 2009 Pino Toscano <pino@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) version 3, or any
+ later version accepted by the membership of KDE e.V. (or its
+ successor approved by the membership of KDE e.V.), which shall
+ act as a proxy defined in Section 6 of version 3 of the license.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library. If not, see \
<http://www.gnu.org/licenses/>. +*/
+
+#include "upowergenericinterface.h"
+
+#include "upowerdevice.h"
+
+using namespace Solid::Backends::UPower;
+
+GenericInterface::GenericInterface(UPowerDevice *device)
+ : DeviceInterface(device)
+{
+}
+
+GenericInterface::~GenericInterface()
+{
+}
+
+QVariant GenericInterface::property(const QString &key) const
+{
- return m_device->prop(key);
++ return m_device.data()->prop(key);
+}
+
+QMap<QString, QVariant> GenericInterface::allProperties() const
+{
- return m_device->allProperties();
++ return m_device.data()->allProperties();
+}
+
+bool GenericInterface::propertyExists(const QString &key) const
+{
- return m_device->propertyExists(key);
++ return m_device.data()->propertyExists(key);
+}
+
diff --cc tier1/threadweaver/src/Weaver/Job.h
index 5729942,0000000..af78557
mode 100644,000000..100644
--- a/tier1/threadweaver/src/Weaver/Job.h
+++ b/tier1/threadweaver/src/Weaver/Job.h
@@@ -1,240 -1,0 +1,240 @@@
+/* -*- C++ -*-
+
+This file declares the Job class.
+
+$ Author: Mirko Boehm $
+$ Copyright: (C) 2004, 2005, 2006 Mirko Boehm $
+$ Contact: mirko@kde.org
+http://www.kde.org
+http://www.hackerbuero.org $
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public \
License + along with this library; see the file COPYING.LIB. If not, \
write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth \
Floor, + Boston, MA 02110-1301, USA.
+
+$Id: Job.h 32 2005-08-17 08:38:01Z mirko $
+*/
+
+#ifndef THREADWEAVER_JOB_H
+#define THREADWEAVER_JOB_H
+
+#include <QtCore/QObject>
+
+#include <threadweaver_export.h>
+
+class QMutex;
+class QWaitCondition;
+
+namespace ThreadWeaver {
+
+ class Thread;
+ class QueuePolicy;
+ class JobRunHelper;
+ class WeaverInterface;
+ class QueuePolicyList;
+
+ /** A Job is a simple abstraction of an action that is to be
+ executed in a thread context.
+ It is essential for the ThreadWeaver library that as a kind of
+ convention, the different creators of Job objects do not touch \
the + protected data members of the Job until somehow notified by \
the + Job.
+
+ Also, please note that Jobs may not be executed twice. Create two
+ different objects to perform two consecutive or parallel runs.
+
+ Jobs may declare dependencies. If Job B depends on Job A, B may not be
+ executed before A is finished. To learn about dependencies, see
+ DependencyPolicy.
+
+ Job objects finish by emitting the done(Job*) signal. Once this has \
been emitted, + ThreadWeaver is no longer using the Job which may then be \
deleted. + */
+
+ class THREADWEAVER_EXPORT Job : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ friend class JobRunHelper;
+
+ /** Construct a Job.
+
+ @param parent the parent QObject
+ */
+ explicit Job ( QObject* parent = 0 );
+
+ /** Destructor. */
+ virtual ~Job();
+
+ /** Perform the job. The thread in which this job is executed
+ is given as a parameter.
+ Do not overload this method to create your own Job
+ implementation, overload run(). */
+ virtual void execute(Thread*);
+
+ /** The queueing priority of the job.
+ Jobs will be sorted by their queueing priority when
+ enqueued. A higher queueing priority will place the job in
+ front of all lower-priority jobs in the queue.
+
+ Note: A higher or lower priority does not influence queue
+ policies. For example, a high-priority job that has an
+ unresolved dependency will not be executed, which means an
+ available lower-priority job will take precedence.
+
+ The default implementation returns zero. Only if this method
+ is overloaded for some job classes, priorities will
+ influence the execution order of jobs.
+ */
+ virtual int priority() const;
+
+ /** Return whether the Job finished successfully or not.
+ The default implementation simply returns true. Overload in
+ derived classes if the derived Job class can fail.
+
+ If a job fails (success() returns false), it will *NOT* \
resolve + its dependencies when it finishes. This will make \
sure that Jobs + that depend on the failed job will not be \
started. +
+ There is an important gotcha: When a Job object is deleted, \
it + will always resolve its dependencies. If dependent jobs \
should + not be executed after a failure, it is important to \
dequeue those + before deleting the failed Job.
+
+ A JobSequence may be helpful for that purpose.
+ */
+ virtual bool success () const;
+
+ /** Abort the execution of the job.
+ Call this method to ask the Job to abort if it is currently \
executed. + Please note that the default implementation of the \
method does + nothing (!). This is due to the fact that there \
is no generic + method to abort a processing Job. Not even a \
default boolean flag + makes sense, as Job could, for example, \
be in an event loop and + will need to create an exit event.
+ You have to reimplement the method to actually initiate an \
abort + action.
+ The method is not pure virtual because users are not supposed \
to + be forced to always implement requestAbort().
- Also, this method is supposed to return immidiately, not \
after the ++ Also, this method is supposed to return \
immediately, not after the + abort has completed. It requests \
the abort, the Job has to act on + the request. */
+ // FIXME (Mirko) this should be private, I guess?
+ virtual void requestAbort () {}
+
+ /** The job is about to be added to the weaver's job queue.
+ The job will be added right after this method finished. The
+ default implementation does nothing.
+ Use this method to, for example, queue sub-operations as jobs
+ before the job itself is queued.
+
+ Note: When this method is called, the associated Weaver \
object's + thread holds a lock on the weaver's queue. \
Therefore, it is save + to assume that recursive queueing is \
atomic from the queues + perspective.
+
+ @param weaver the Weaver object the job will be queued in
+ */
+ virtual void aboutToBeQueued ( WeaverInterface *weaver );
+
+ /** This Job is about the be dequeued from the weaver's job \
queue. + The job will be removed from the queue right after \
this method + returns.
+ Use this method to dequeue, if necessary, sub-operations \
(jobs) that this job + has enqueued.
+
+ Note: When this method is called, the associated Weaver \
object's + thread does hold a lock on the weaver's queue.
+
+ Note: The default implementation does nothing.
+
+ @param weaver the Weaver object from which the job will be \
dequeued + */
+ virtual void aboutToBeDequeued ( WeaverInterface *weaver );
+
+ /** canBeExecuted() returns true if all the jobs queue policies \
agree to it. + If it returns true, it expects that the job is \
executed right + after that. The done() methods of the queue \
policies will be + automatically called when the job is \
finished. +
+ If it returns false, all queue policy resources have been \
freed, + and the method can be called again at a later time.
+ */
+ virtual bool canBeExecuted();
+
+ /** Returns true if the jobs's execute method finished. */
+ bool isFinished() const;
+
+ /** Assign a queue policy.
+ Queue Policies customize the queueing (running) behaviour of \
sets + of jobs. Examples for queue policies are dependencies \
and resource + restrictions.
+ Every queue policy object can only be assigned once to a job,
+ multiple assignments will be IGNORED.
+ */
+ void assignQueuePolicy ( QueuePolicy* );
+
+ /** Remove a queue policy from this job.
+ */
+ void removeQueuePolicy ( QueuePolicy* );
+
+ Q_SIGNALS:
+ /** This signal is emitted when this job is being processed by a
+ thread. */
+ void started ( ThreadWeaver::Job* );
+ /**
+ * This signal is emitted when the job has been finished (no matter if \
it succeeded or not). + * After this signal has been emitted, \
ThreadWeaver no longer references the Job internally + * and the Job can \
be deleted. + */
+ void done ( ThreadWeaver::Job* );
+
+ /** This job has failed.
+ This signal is emitted when success() returns false after the \
job + is executed.
+ */
+ void failed( ThreadWeaver::Job* );
+
+ protected:
+ class Private;
+ Private* d;
+
+ /** Free the queue policies acquired before this job has been
+ executed. */
+ void freeQueuePolicyResources();
+
+ /** The method that actually performs the job. It is called from
+ execute(). This method is the one to overload it with the
+ job's task. */
+ virtual void run () = 0;
+ /** Return the thread that executes this job.
+ Returns zero of the job is not currently executed.
+
+ Do not confuse with QObject::thread() const !
+ // @todo rename to executingThread()
+ */
+ Thread *thread();
+
+ /** Call with status = true to mark this job as done. */
+ void setFinished ( bool status );
+
+ /** The mutex used to protect this job. */
+ // QMutex& mutex();
+
+ };
+}
+
+#endif // THREADWEAVER_JOB_H
+
diff --cc tier1/threadweaver/src/Weaver/WeaverInterface.h
index d79f7f1,0000000..0ed66ac
mode 100644,000000..100644
--- a/tier1/threadweaver/src/Weaver/WeaverInterface.h
+++ b/tier1/threadweaver/src/Weaver/WeaverInterface.h
@@@ -1,193 -1,0 +1,193 @@@
+/* -*- C++ -*-
+
+ This file declares the WeaverInterface class.
+
+ $ Author: Mirko Boehm $
+ $ Copyright: (C) 2005, 2006 Mirko Boehm $
+ $ Contact: mirko@kde.org
+ http://www.kde.org
+ http://www.hackerbuero.org $
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public \
License + along with this library; see the file COPYING.LIB. If not, \
write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth \
Floor, + Boston, MA 02110-1301, USA.
+
+ $Id: WeaverImpl.h 29 2005-08-14 19:04:30Z mirko $
+*/
+
+#ifndef WeaverInterface_H
+#define WeaverInterface_H
+
+#include <QtCore/QObject>
+
+#include <threadweaver_export.h>
+
+namespace ThreadWeaver {
+
+ class Job;
+ class State;
+ class WeaverObserver;
+
+ /** WeaverInterface provides a common interface for weaver \
implementations. +
+ In most cases, it is sufficient for an application to hold \
exactly one + ThreadWeaver job queue. To execute jobs in a specific \
order, use job + dependencies. To limit the number of jobs of a \
certain type that can + be executed at the same time, use resource \
restrictions. To handle + special requirements of the application \
when it comes to the order of + execution of jobs, implement a \
special queue policy and apply it to + the jobs.
+
+ Users of the ThreadWeaver API are encouraged to program to this
+ interface, instead of the implementation. This way, \
implementation + changes will not affect user programs.
+
+ This interface can be used for example to implement adapters and
+ decorators. The member documentation is provided in the Weaver \
and + WeaverImpl classes.
+ */
+
+ class THREADWEAVER_EXPORT WeaverInterface : public QObject {
+ Q_OBJECT
+
+ public:
+ /** A ThreadWeaver object manages a queue of Jobs.
+ It inherits QObject.
+ */
+ explicit WeaverInterface ( QObject* parent = 0 );
+ virtual ~WeaverInterface() {}
+ /** Return the state of the weaver object. */
+ virtual const State& state() const = 0;
+
+ /** Set the maximum number of threads this Weaver object may start. \
*/ + virtual void setMaximumNumberOfThreads( int cap ) = 0;
+
+ /** Get the maximum number of threads this Weaver may start. */
+ virtual int maximumNumberOfThreads() const = 0;
+
+ /** Returns the current number of threads in the inventory. */
+ virtual int currentNumberOfThreads () const = 0;
+
+ /** Register an observer.
+
+ Observers provides signals on different weaver events that \
are + otherwise only available through objects of different \
classes + (threads, jobs). Usually, access to the signals of \
those objects + is not provided through the weaver API. Use an \
observer to reveice + notice, for example, on thread activity.
+
+ To unregister, simply delete the observer.
+ */
+ virtual void registerObserver ( WeaverObserver* ) = 0;
+ /** Add a job to be executed.
+
+ It depends on the state if execution of the job will be \
attempted
- immidiately. In suspended state, jobs can be added to the \
queue, ++ immediately. In suspended state, jobs can be added to \
the queue, + but the threads remain suspended. In WorkongHard \
state, an idle
- thread may immidiately execute the job, or it might be queued \
if ++ thread may immediately execute the job, or it might be \
queued if + all threads are busy.
+ */
+ virtual void enqueue ( Job* ) = 0;
+ /** Remove a job from the queue.
+ If the job was queued but not started so far, it is simply
+ removed from the queue. For now, it is unsupported to
+ dequeue a job once its execution has started.
+ For that case, you will have to provide a method to interrupt your
+ job's execution (and receive the done signal).
+ Returns true if the job has been dequeued, false if the
+ job has already been started or is not found in the
+ queue. */
+ virtual bool dequeue ( Job* ) = 0;
+ /** Remove all queued jobs.
+ Please note that this will not kill the threads, therefore
+ all jobs that are being processed will be continued. */
+ virtual void dequeue () = 0;
+ /** Finish all queued operations, then return.
+
+ This method is used in imperative (not event driven) programs that
+ cannot react on events to have the controlling (main) thread wait
+ wait for the jobs to finish. The call will block the calling
+ thread and return when all queued jobs have been processed.
+
+ Warning: This will suspend your thread!
+ Warning: If one of your jobs enters an infinite loop, this
+ will never return! */
+ virtual void finish () = 0;
+ /** Suspend job execution.
+ When suspending, all threads are allowed to finish the
+ currently assigned job but will not receive a new
+ assignment.
+ When all threads are done processing the assigned job, the
+ signal suspended will() be emitted.
+ If you call suspend() and there are no jobs left to
- be done, you will immidiately receive the suspended()
++ be done, you will immediately receive the suspended()
+ signal. */
+ virtual void suspend () = 0;
+ /** Resume job queueing.
+ @see suspend
+ */
+ virtual void resume () = 0;
+ /** Is the queue empty?
+ The queue is empty if no more jobs are queued. */
+ virtual bool isEmpty () const = 0;
+ /** Is the weaver idle?
+ The weaver is idle if no jobs are queued and no jobs are processed
+ by the threads. */
+ virtual bool isIdle () const = 0;
+ /** Returns the number of pending jobs.
+ This will return the number of queued jobs. Jobs that are
+ currently being executed are not part of the queue. All jobs in
+ the queue are waiting to be executed.
+ */
+ virtual int queueLength () const = 0;
+
+ /** Request aborts of the currently executed jobs.
+ It is important to understand that aborts are requested, but
+ cannot be guaranteed, as not all Job classes support it. It is up
+ to the application to decide if and how job aborts are
+ necessary. */
+ virtual void requestAbort() = 0;
+
+ Q_SIGNALS:
+ /** This signal is emitted when the Weaver has finished ALL currently
+ queued jobs.
+ If a number of jobs is enqueued sequentially, this signal might be
+ emitted a couple of times (what happens is that all already queued
+ jobs have been processed while you still add new ones). This is
+ not a bug, but the intended behaviour. */
+ void finished ();
+
+ /** Thread queueing has been suspended.
+ When suspend is called with state = true, all threads are
+ allowed to finish their job. When the last thread
+ finished, this signal is emitted. */
+ void suspended ();
+
+ /** This signal is emitted when a job is finished. In addition,
+ the Job itself emits a done() signal just before the jobDone() \
signal + is emitted.
+ */
+
+ void jobDone ( ThreadWeaver::Job* );
+ // FIXME (0.7) test if signal is emitted properly
+ // FIXME (0.7) provide jobStarted and jobFailed signals
+ // FIXME (0.7) or remove all these, and add them to \
WeaverObserver +
+ /** The Weaver's state has changed. */
+ void stateChanged ( ThreadWeaver::State* );
+ };
+
+}
+
+#endif
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic