diff --git a/applets/org.kde.active.connman/contents/ui/ExpandingBox.qml b/applets/org.kde.active.connman/contents/ui/ExpandingBox.qml index 6507c729..95c1181d 100644 --- a/applets/org.kde.active.connman/contents/ui/ExpandingBox.qml +++ b/applets/org.kde.active.connman/contents/ui/ExpandingBox.qml @@ -1,328 +1,328 @@ /* * Copyright 2011 Intel Corporation. * * This program is licensed under the terms and conditions of the - * LGPL, version 2.1. The full text of the LGPL Licence is at + * LGPL, version 2.1. The full text of the LGPL License is at * http://www.gnu.org/licenses/lgpl.html */ /*! \qmlclass ExpandingBox \title ExpandingBox \section1 ExpandingBox This is a box which can be given any content and adapts its size accordingly. The default state of the box only show a header line and an icon which indicates if the box is expanded or not. Clicking on the header expands the box and shows the content. The behaviour isn't final because detailed specifications are missing. \section2 API properties \qmlproperty bool expanded \qmlcm true if the box is currently expanded \qmlproperty Row iconRow \qmlcm area that can hold a set of icons \qmlproperty string titleText \qmlcm sets the text shown on the header \qmlproperty color titleTextColor \qmlcm sets the color of the text shown on the header \qmlproperty Component detailsComponent \qmlcm contains the content to be shown when the box is expanded \qmlproperty Item detailsItem \qmlcm stores the contents when created \qmlproperty int buttonHeight \qmlcm this defines how big the Expanding box is when it's not extended. If you change the orientation and the size, you have to set these too. \qmlproperty int buttonWidth \qmlcm this defines how big the Expanding box is when it's not extended. If you change the orientation and the size, you have to set these too. \qmlproperty Item headerContent \qmlcm this Item will appear in the header. It can be used to create complex custom headers. \qmlproperty string orientation \qmlcm this value defines how ExpandingBox is orientated. Possible values are: "horizontal" - expands to lower; "vertical" - expands to the right. Default is 'horizontal'. If you change the orientation and the size during runtime, make sure you change the buttonWidth and buttonHeight too. \qmlproperty bool lazyCreation \qmlcm this value defines how ExpandingBox is created. By default (false), content to expand is created when the ExpandingBox is first instantiated. Setting this property to true delays content created if and until the box is expanded. \section2 Signals \qmlproperty [signal] expandingChanged \qmlcm emitted if the box switches between expanded and not expanded \param bool expanded \qmlpcm indicates if the box is expanded or not \endparam \section2 Functions \qmlnone \section2 Example \qml ExpandingBox { id: expandingBox width: 200 height: 75 titleText: "ExpandingBox" titleTextColor: "black" anchors.centerIn: parent detailsComponent: expandingBoxComponent Component { id: expandingBoxComponent Rectangle { id: rect color: "blue" height: 50; width: 150 anchors.centerIn: parent Button { text: "Switch" // switches orientation to vertical onClicked: { expandingBox.width = 75 expandingBox.height = 200 expandingBox.buttonWidth = 75 expandingBox.buttonHeight = 200 expandingBox.orientation = "vertical" // this has to be last, since it triggers the changes } } } } } \endqml */ import Qt 4.7 import MeeGo.Ux.Kernel 0.1 import MeeGo.Ux.Components.Common 0.1 import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.plasma.components 0.1 as PlasmaComponents PlasmaComponents.ListItem { id: expandingBox enabled: true checked: expanded onClicked: expanded = !expanded property bool expanded: false property alias titleText: titleText.text property alias titleTextColor: titleText.color property Component detailsComponent: null property Item detailsItem: null property alias iconRow: iconArea.children property int buttonHeight: 13 property int buttonWidth: 13 property alias headerContent: headerContentArea.children property string orientation: "horizontal" property bool lazyCreation: false signal expandingChanged( bool expanded ) width: 250 height: 45// + ( ( titleText.font.pixelSize > expandButton.height ) ? titleText.font.pixelSize : expandButton.height ) clip: true // if new content is set, destroy any old content and create the new one onDetailsComponentChanged: { if( detailsItem ) { detailsItem.destroy() detailsItem = null } if (expanded || !lazyCreation) { //console.log("Creating expanding box!") detailsItem = detailsComponent.createObject( boxDetailsArea ) } pulldownImage.componentCompleted = true } // if content has been set, destroy any old content and create the new one Component.onCompleted: { buttonHeight = height buttonWidth = width pulldownImage.boxReady = true if( !lazyCreation && detailsComponent && !pulldownImage.componentCompleted ) { if ( detailsItem ) detailsItem.destroy() detailsItem = detailsComponent.boxDetailsArea( boxDetailsArea ) } } // if the expanded state changes, propagate the change via signal onExpandedChanged: { if (expanded) { if( !detailsItem ) { //console.log("Creating expanding box!") detailsItem = detailsComponent.createObject( boxDetailsArea ) } } expandingBox.expandingChanged( expanded ) } Item { id: pulldownImage property bool componentCompleted: false property int animationTime: 200 property bool boxReady: false height: expandingBox.height width: expandingBox.width // the header item contains the title, the image for the button which indicates // the expanded state and a GestreuArea to change the expanded state on click Item { id: header // the header adapts its height to the height of the title and the button plus some space height: ( expandingBox.orientation == "horizontal" ) ? buttonHeight : parent.height width: ( expandingBox.orientation == "horizontal" ) ? parent.width : buttonWidth anchors.top: parent.top Row { id: iconArea anchors { left: parent.left; margins: 5 } anchors.verticalCenter: expandButton.verticalCenter spacing: anchors.margins } PlasmaComponents.Label { id: titleText elide: Text.ElideRight anchors.left: iconArea.right anchors.right: expandButton.left anchors.leftMargin: 10 anchors.verticalCenter: expandButton.verticalCenter } Item { id: headerContentArea x: 5 y: 5 width: ( expandingBox.orientation == "horizontal" ) ? expandingBox.width - expandButton.width - 6 * 2 - 10 : parent.width - 10 height: ( expandingBox.orientation == "horizontal" ) ? parent.height -10 : expandingBox.height - expandButton.height - 6 * 2 - 10 clip: true } PlasmaCore.SvgItem { id: expandButton x: ( expandingBox.orientation == "horizontal" ) ? expandingBox.width - width - 6 : (header.width - width) / 2 y: ( expandingBox.orientation == "horizontal" ) ? (header.height - height) / 2 : expandingBox.height - height - 6 svg: PlasmaCore.Svg { imagePath: "widgets/arrows" } width: naturalSize.width height: naturalSize.height elementId: expandingBox.expanded ? "up-arrow" : "down-arrow" } } // this item is used when creating the content in the detailsItem to set some general properties Item { id: boxDetailsArea property int itemMargins: 3 opacity: 0 clip: true visible: expandingBox.expanded anchors { top: ( expandingBox.orientation == "horizontal" ) ? header.bottom : parent.top left: ( expandingBox.orientation == "horizontal" ) ? parent.left : header.right bottom: parent.bottom right: parent.right margins: itemMargins } } } onOrientationChanged: { if(!pulldownImage.boxReady) return var oldExpanded = expanded pulldownImage.animationTime = 0 expanded = false height = buttonHeight width = buttonWidth expanded = oldExpanded pulldownImage.animationTime = 200 } states: [ State { name: "expanded" PropertyChanges { target: expandingBox height: buttonHeight + detailsItem.height + boxDetailsArea.itemMargins * 2 } PropertyChanges { target: boxDetailsArea visible: true opacity: 1.0 } when: { expandingBox.expanded && expandingBox.orientation == "horizontal" } }, State { name: "expandedVertical" PropertyChanges { target: expandingBox width: buttonWidth + detailsItem.width + boxDetailsArea.itemMargins * 2 } PropertyChanges { target: boxDetailsArea visible: true opacity: 1.0 } when: { expandingBox.expanded && expandingBox.orientation == "vertical" } } ] transitions: [ Transition { SequentialAnimation { ParallelAnimation{ NumberAnimation { properties: "height" duration: pulldownImage.animationTime easing.type: Easing.InCubic } NumberAnimation { properties: "width" duration: pulldownImage.animationTime easing.type: Easing.InCubic } } NumberAnimation { properties: "opacity" duration: pulldownImage.animationTime easing.type: Easing.OutCubic } } } ] } diff --git a/applications/common/kdeclarativeview.h b/applications/common/kdeclarativeview.h index 55b55ec1..9eef46a6 100644 --- a/applications/common/kdeclarativeview.h +++ b/applications/common/kdeclarativeview.h @@ -1,86 +1,86 @@ /*************************************************************************** * * * Copyright 2011 Sebastian Kügler * * Copyright 2011 Marco Martin * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, 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 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 . * ***************************************************************************/ #ifndef KDECLARATIVEVIEW_H #define KDECLARATIVEVIEW_H #include namespace Plasma { class Package; } class QScriptEngine; class KDeclarativeViewPrivate; class KDeclarativeView : public QDeclarativeView { Q_OBJECT public: KDeclarativeView(QWidget *parent = 0); ~KDeclarativeView(); /** - * Sets wether the application uses opengl + * Sets whether the application uses opengl * @arg bool on if true the declarative view will use opengl for its viewport() */ void setUseGL(const bool on); /** * @returns true if the declarative view uses opengl */ bool useGL() const; /** * Sets the package from where load the application QML UI * The package must be of the type "Generic package" * it must provide a qml file as "mainscript" * @arg QString packageName the plugin name of the package */ void setPackageName(const QString &packageName); /** * @returns the plugin name of the package */ QString packageName() const; /** * Sets the package used for the application QML UI. * You usually don't need to use this, rather use setPackageName * @see setPackageName */ //FIXME: remove this function? void setPackage(Plasma::Package *package); /** * @returns the plugin name of the package that holds the application QML UI */ Plasma::Package *package() const; QSize sizeHint() const; QScriptEngine *scriptEngine() const; private: KDeclarativeViewPrivate *const d; }; #endif //KDECLARATIVEVIEW_H diff --git a/applications/webbrowser/package/contents/ui/content/LinkPopup.qml b/applications/webbrowser/package/contents/ui/content/LinkPopup.qml index af8a5f94..6ec5b09b 100644 --- a/applications/webbrowser/package/contents/ui/content/LinkPopup.qml +++ b/applications/webbrowser/package/contents/ui/content/LinkPopup.qml @@ -1,194 +1,194 @@ /* * Copyright 2011 by Sebastian Kügler * * 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. */ import QtQuick 1.1 import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.qtextracomponents 0.1 import org.kde.plasma.components 0.1 as PlasmaComponents PlasmaCore.FrameSvgItem { id: linkPopup objectName: "linkPopup" property Item linkRect: Item {} property int iconSize: 32 property int space: 12 property string url imagePath: "dialogs/background" //width: (iconSize*2) + iconSize width: space*30 height: space*10 //height: iconSize*2 //width: childrenRect.width //height: childrenRect.height z: 100000 state: "collapsed" MouseArea { id: hidePopup //anchors.fill: flickable x: -flickable.width; y: -flickable.height; width: flickable.width*2; height: flickable.height*2 onClicked: linkPopup.state = "collapsed" visible: linkPopup.state == "expanded" //Rectangle {color: "green"; opacity: 0.2; anchors.fill: parent; } } Item { id: buttonRow anchors.fill: parent anchors.margins: space*2 QIconItem { id: newWindowIcon icon: QIcon("window-new") width: linkPopup.iconSize height: width anchors { top: parent.top; left: parent.left; } MouseArea { anchors.fill: parent; } } PlasmaComponents.Label { id: newWindowLabel anchors { verticalCenter: newWindowIcon.verticalCenter; left: newWindowIcon.right; right: parent.right; leftMargin: space } text: i18n("Open link in new window") elide: Text.ElideMiddle } MouseArea { anchors { top: newWindowIcon.top; bottom: newWindowIcon.bottom; left: parent.left; right: parent.right; } onClicked: { flickable.newWindowRequested(url); print("open in new window " + url); linkPopup.state = "collapsed"; } onPressed: PropertyAnimation { target: newWindowIcon; properties: "scale"; from: 1.0; to: 0.75; duration: 175; easing.type: Easing.OutExpo; } onReleased: PropertyAnimation { target: newWindowIcon; properties: "scale"; from: 0.75; to: 1.0; duration: 175; easing.type: Easing.OutExpo; } } QIconItem { id: copyIcon icon: QIcon("edit-copy") width: linkPopup.iconSize height: linkPopup.iconSize anchors { top: newWindowIcon.bottom; left: parent.left; topMargin: space; } //enabled: textInput.selectedText != "" // MouseArea { // anchors.fill: parent; // } TextInput { id: textField; visible: false } } PlasmaComponents.Label { id: copyLabel anchors { verticalCenter: copyIcon.verticalCenter; left: copyIcon.right; right: parent.right; leftMargin: space } text: i18n("Copy link to clipboard"); elide: Text.ElideMiddle } MouseArea { anchors { top: copyIcon.top; bottom: copyIcon.bottom; left: parent.left; right: parent.right; } onClicked: { textField.text = url; textField.selectAll(); textField.copy(); textField.text = "" linkPopup.state = "collapsed"; } onPressed: PropertyAnimation { target: copyIcon; properties: "scale"; from: 1.0; to: 0.75; duration: 175; easing.type: Easing.OutExpo; } onReleased: PropertyAnimation { target: copyIcon; properties: "scale"; from: 0.75; to: 1.0; duration: 175; easing.type: Easing.OutExpo; } } } states: [ State { id: expanded name: "expanded"; PropertyChanges { target: linkPopup; opacity: 1.0; scale: 1.0 } }, State { id: collapsed name: "collapsed"; PropertyChanges { target: linkPopup; opacity: 0; scale: 0.9 } } ] transitions: [ Transition { from: "collapsed"; to: "expanded" ParallelAnimation { ScriptAction { script: { placePopup(); flickable.interactiveSuspended = true; } } PropertyAnimation { properties: "opacity"; duration: 175; easing.type: Easing.InExpo; } PropertyAnimation { properties: "scale"; duration: 175; easing.type: Easing.InExpo; } } }, Transition { from: "expanded"; to: "collapsed" ParallelAnimation { ScriptAction { script: { flickable.interactiveSuspended = false; } } PropertyAnimation { properties: "opacity"; duration: 175; easing.type: Easing.OutExpo; } PropertyAnimation { properties: "scale"; duration: 100; easing.type: Easing.OutExpo; } } } ] function placePopup () { // Smart placement of link popup. The popup sits on top horizontally // centered on the actived link or item in the webpage, never covering // it. If it doesn't fit within the webview, it's moved under or aligned // to the edges. // Check if we need to shift vertically if (linkRect.x < linkPopup.width/2) { // hitting the left edge, anchor to left border linkPopup.x = 0; } else { if (webView.width < linkRect.x + linkPopup.width ) { // hitting the right edge, anchoring right linkPopup.x = webView.width - linkPopup.width } else { // Not hitting any edge, align horizontally centered with link rect linkPopup.x = linkRect.x-(linkPopup.width/2)+linkRect.width/2 } } - // Check wether we need to reposition horizontally + // Check whether we need to reposition horizontally if (linkRect.y < linkPopup.height) { // move down under linkRect point linkPopup.y = linkRect.y + linkRect.height; } else { // Normally, the popup sits above the link rectangle linkPopup.y = linkRect.y - linkPopup.height; } } } diff --git a/applications/webbrowser/src/adblock/adblockmanager.cpp b/applications/webbrowser/src/adblock/adblockmanager.cpp index 6f7e5a40..46ce26ca 100644 --- a/applications/webbrowser/src/adblock/adblockmanager.cpp +++ b/applications/webbrowser/src/adblock/adblockmanager.cpp @@ -1,374 +1,374 @@ /* ============================================================ * * This file has been kindly borrowed and adapted from the rekonq project * * Copyright (C) 2010-2011 by Andrea Diamantini * Copyright 2011 Sebastian Kügler * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 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 14 of version 3 of the license. * * 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 General Public License * along with this program. If not, see . * * ============================================================ */ #define QL1S(x) QLatin1String(x) #define QL1C(x) QLatin1Char(x) // Self Includes #include "adblockmanager.h" // Local Includes #include "adblocknetworkreply.h" //#include "adblockwidget.h" //#include "webpage.h" // KDE Includes #include #include #include #include #include // Qt Includes #include #include #include #include QStringList defaultLocations() { return QStringList("https://easylist-downloads.adblockplus.org/easylist.txt"); } QStringList defaultTitles() { return QStringList("EasyList"); } AdBlockManager::AdBlockManager(QObject *parent) : QObject(parent) , _isAdblockEnabled(false) , _isHideAdsEnabled(false) , _index(0) { _dirWatch = new KDirWatch(this); QString configPath = KStandardDirs::locateLocal("config", "active-webbrowserrc"); _dirWatch->addFile(configPath); connect(_dirWatch, SIGNAL(dirty(QString)), SLOT(loadSettings())); connect(_dirWatch, SIGNAL(created(QString)), SLOT(loadSettings())); loadSettings(); } AdBlockManager::~AdBlockManager() { _whiteList.clear(); _blackList.clear(); _hideList.clear(); } void AdBlockManager::loadSettings(bool checkUpdateDate) { _index = 0; _buffer.clear(); _hostWhiteList.clear(); _hostBlackList.clear(); _whiteList.clear(); _blackList.clear(); _hideList.clear(); KSharedConfigPtr ptr = KSharedConfig::openConfig("active-webbrowserrc"); ptr->reparseConfiguration(); _config = KConfigGroup(ptr, "adblock"); _isAdblockEnabled = _config.readEntry("adBlockEnabled", true); kDebug() << "Adblock is now " << _isAdblockEnabled; // no need to load filters if adblock is not enabled :) if (!_isAdblockEnabled) return; // just to be sure.. _isHideAdsEnabled = _config.readEntry("hideAdsEnabled", true); // read settings KSharedConfig::Ptr config = KSharedConfig::openConfig("adblock", KConfig::SimpleConfig, "appdata"); KConfigGroup rulesGroup(config, "rules"); QStringList rules; rules = rulesGroup.readEntry("local-rules" , QStringList()); loadRules(rules); - // Checking wether to update the adblock filters, and doin' it + // Checking whether to update the adblock filters, and doin' it QDateTime today = QDateTime::currentDateTime(); QDateTime lastUpdate = _config.readEntry("lastUpdate", QDateTime(QDate(2001, 9, 11))); int days = _config.readEntry("updateInterval", 7); if (!checkUpdateDate || today > lastUpdate.addDays(days)) { _config.writeEntry("lastUpdate", QDateTime::currentDateTime()); updateNextSubscription(); return; } // else QStringList titles = _config.readEntry("adBlockEnabled", defaultTitles()); foreach(const QString & title, titles) { rules = rulesGroup.readEntry(title + "-rules" , QStringList()); loadRules(rules); } } void AdBlockManager::loadRules(const QStringList &rules) { foreach(const QString & stringRule, rules) { // ! rules are comments if (stringRule.startsWith('!')) continue; // [ rules are ABP info if (stringRule.startsWith('[')) continue; // empty rules are just dangerous.. // (an empty rule in whitelist allows all, in blacklist blocks all..) if (stringRule.isEmpty()) continue; // white rules if (stringRule.startsWith(QL1S("@@"))) { const QString filter = stringRule.mid(2); if (_hostWhiteList.tryAddFilter(filter)) continue; AdBlockRule rule(filter); _whiteList << rule; continue; } // hide (CSS) rules if (stringRule.startsWith(QL1S("##"))) { _hideList << stringRule.mid(2); continue; } // TODO implement domain-specific hiding if (stringRule.contains(QL1S("##"))) continue; if (_hostBlackList.tryAddFilter(stringRule)) continue; AdBlockRule rule(stringRule); _blackList << rule; } } QNetworkReply *AdBlockManager::block(const QNetworkRequest &request, QWebPage *page) { if (!_isAdblockEnabled) return 0; // we (ad)block just http traffic if (request.url().scheme() != QL1S("http")) return 0; QString urlString = request.url().toString(); // We compute a lowercase version of the URL so each rule does not // have to do it. const QString urlStringLowerCase = urlString.toLower(); const QString host = request.url().host(); // check white rules before :) if (_hostWhiteList.match(host)) { //kDebug() << " ****ADBLOCK: WHITE RULE (@@) Matched by host matcher: ***********"; //kDebug() << " UrlString: " << urlString; return 0; } foreach(const AdBlockRule & filter, _whiteList) { if (filter.match(request, urlString, urlStringLowerCase)) { //kDebug() << " ****ADBLOCK: WHITE RULE (@@) Matched: ***********"; //kDebug() << " UrlString: " << urlString; return 0; } } // then check the black ones :( if (_hostBlackList.match(host)) { //kDebug() << " ****ADBLOCK: BLACK RULE Matched by host matcher: ***********"; //kDebug() << " UrlString: " << urlString; AdBlockNetworkReply *reply = new AdBlockNetworkReply(request, urlString, this); return reply; } foreach(const AdBlockRule & filter, _blackList) { if (filter.match(request, urlString, urlStringLowerCase)) { //kDebug() << " ****ADBLOCK: BLACK RULE Matched: ***********"; //kDebug() << " UrlString: " << urlString; QWebElement document = page->mainFrame()->documentElement(); QWebElementCollection elements = document.findAll("*"); foreach(QWebElement el, elements) { const QString srcAttribute = el.attribute("src"); if (filter.match(request, srcAttribute, srcAttribute.toLower())) { //kDebug() << "MATCHES ATTRIBUTE!!!!!"; el.setStyleProperty(QL1S("visibility"), QL1S("hidden")); el.setStyleProperty(QL1S("width"), QL1S("0")); el.setStyleProperty(QL1S("height"), QL1S("0")); } } AdBlockNetworkReply *reply = new AdBlockNetworkReply(request, urlString, this); return reply; } } // no match return 0; } void AdBlockManager::applyHidingRules(QWebPage *page) { if (!page) return; if (!_isAdblockEnabled) return; if (!_isHideAdsEnabled) return; QWebElement document = page->mainFrame()->documentElement(); // HIDE RULES foreach(const QString & filter, _hideList) { QWebElementCollection elements = document.findAll(filter); foreach(QWebElement el, elements) { if (el.isNull()) continue; //kDebug() << "Hide element: " << el.localName(); el.setStyleProperty(QL1S("visibility"), QL1S("hidden")); el.removeFromDocument(); } } } void AdBlockManager::updateNextSubscription() { QStringList locations = _config.readEntry("subscriptionLocations", defaultLocations()); if (_index < locations.size()) { QString urlString = locations.at(_index); KUrl subUrl = KUrl(urlString); KIO::TransferJob* job = KIO::get(subUrl , KIO::Reload , KIO::HideProgressInfo); job->metaData().insert("ssl_no_client_cert", "TRUE"); job->metaData().insert("ssl_no_ui", "TRUE"); job->metaData().insert("UseCache", "false"); job->metaData().insert("cookies", "none"); job->metaData().insert("no-auth", "true"); connect(job, SIGNAL(data(KIO::Job*,QByteArray)), this, SLOT(subscriptionData(KIO::Job*,QByteArray))); connect(job, SIGNAL(result(KJob*)), this, SLOT(slotResult(KJob*))); connect(job, SIGNAL(finished(KJob*job)), this, SLOT(slotFinished())); return; } _index = 0; _buffer.clear(); } void AdBlockManager::slotResult(KJob *job) { if (job->error()) { kWarning() << "Fetching rules failed: " << job->errorString(); return; } QList list = _buffer.split('\n'); QStringList ruleList; foreach(const QByteArray & ba, list) { ruleList << QString(ba); } loadRules(ruleList); saveRules(ruleList); _index++; // last.. updateNextSubscription(); } void AdBlockManager::subscriptionData(KIO::Job* job, const QByteArray& data) { Q_UNUSED(job) if (data.isEmpty()) return; int oldSize = _buffer.size(); _buffer.resize(_buffer.size() + data.size()); memcpy(_buffer.data() + oldSize, data.data(), data.size()); } void AdBlockManager::saveRules(const QStringList &rules) { QStringList cleanedRules; foreach(const QString & r, rules) { if (!r.startsWith('!') && !r.startsWith('[') && !r.isEmpty()) cleanedRules << r; } QStringList titles = _config.readEntry("subscriptionTitles", defaultTitles()); QString title = titles.at(_index) + "-rules"; KSharedConfig::Ptr config = KSharedConfig::openConfig("adblock", KConfig::SimpleConfig, "appdata"); KConfigGroup cg(config , "rules"); cg.writeEntry(title, cleanedRules); } void AdBlockManager::addSubscription(const QString &title, const QString &location) { QStringList titles = _config.readEntry("subscriptionTitles", defaultTitles()); if (titles.contains(title)) return; QStringList locations = _config.readEntry("subscriptionLocations", defaultLocations()); if (locations.contains(location)) return; titles << title; locations << location; _config.writeEntry("subscriptionTitles", titles); _config.writeEntry("subscriptionLocations", locations); } #include "adblockmanager.moc" diff --git a/applications/webbrowser/src/kdeclarativewebview.cpp b/applications/webbrowser/src/kdeclarativewebview.cpp index f9d4a98a..12ce1f43 100644 --- a/applications/webbrowser/src/kdeclarativewebview.cpp +++ b/applications/webbrowser/src/kdeclarativewebview.cpp @@ -1,1338 +1,1338 @@ /* Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies) 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. */ #define QL1S(x) QLatin1String(x) #define QL1C(x) QLatin1Char(x) #include "kdeclarativewebview.h" #include "networkaccessmanager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class KDeclarativeWebViewPrivate { public: KDeclarativeWebViewPrivate(KDeclarativeWebView* qq) : q(qq) , preferredwidth(0) , preferredheight(0) , progress(1.0) , status(KDeclarativeWebView::Null) , wallet(0) , pending(PendingNone) , newWindowComponent(0) , newWindowParent(0) , rendering(true) { } KDeclarativeWebView* q; QUrl url; // page url might be different if it has not loaded yet GraphicsWebView* view; int preferredwidth, preferredheight; qreal progress; KDeclarativeWebView::Status status; KWebWallet *wallet; QString statusText; enum { PendingNone, PendingUrl, PendingHtml, PendingContent } pending; QUrl pendingUrl; QString pendingString; QByteArray pendingData; QStringList rssFeeds; mutable KDeclarativeWebSettings settings; QDeclarativeComponent* newWindowComponent; QDeclarativeItem* newWindowParent; static void windowObjectsAppend(QDeclarativeListProperty* prop, QObject* o) { static_cast(prop->data)->windowObjects.append(o); static_cast(prop->data)->updateWindowObjects(); } void updateWindowObjects(); QObjectList windowObjects; bool rendering; KDirWatch* dirWatch; }; GraphicsWebView::GraphicsWebView(KDeclarativeWebView* parent) : QGraphicsWebView(parent) , parent(parent) , pressTime(400) , flicking(true) { } void GraphicsWebView::mousePressEvent(QGraphicsSceneMouseEvent* event) { pressPoint = event->pos(); if (pressTime) { pressTimer.start(pressTime, this); parent->setKeepMouseGrab(false); } else { grabMouse(); parent->setKeepMouseGrab(true); } QGraphicsWebView::mousePressEvent(event); QWebHitTestResult hit = page()->mainFrame()->hitTestContent(pressPoint.toPoint()); if (hit.isContentEditable()) { parent->forceActiveFocus(); } // Comboboxes and flicking don't go together well, // disable flicking as long as the combo box is open setFlickingEnabled(hit.element().tagName() != "SELECT"); kDebug() << " - - > Hit element: " << hit.element().tagName() << hit.linkElement().geometry(); if (!hit.linkElement().geometry().isNull()) { kDebug() << "XXXXXXXXXX link pressed. .. "; emit linkPressed(hit.linkUrl(), hit.linkElement().geometry()); } //QMouseEvent* me = new QMouseEvent(QEvent::MouseButtonDblClick, (event->pos() / parent->contentsScale()).toPoint(), event->button(), event->buttons(), 0); emit click(event->pos().x(), event->pos().y()); setFocus(); } void GraphicsWebView::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { QGraphicsWebView::mouseReleaseEvent(event); pressTimer.stop(); parent->setKeepMouseGrab(false); ungrabMouse(); } void GraphicsWebView::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) { QMouseEvent* me = new QMouseEvent(QEvent::MouseButtonDblClick, (event->pos() / parent->contentsScale()).toPoint(), event->button(), event->buttons(), 0); emit doubleClick(event->pos().x(), event->pos().y()); delete me; } void GraphicsWebView::handleLinkClicked(const QUrl &link) { QUrl u(link); if (pressTimer.isActive()) { kDebug() << "timer is running, loading URL" << link; page()->mainFrame()->load(u); } else { kDebug() << "timer is not running, not loading url" << link; } } void GraphicsWebView::timerEvent(QTimerEvent* event) { if (event->timerId() == pressTimer.timerId()) { pressTimer.stop(); grabMouse(); parent->setKeepMouseGrab(true); kDebug() << "handle pressAndHold"; QWebHitTestResult hit = page()->mainFrame()->hitTestContent(pressPoint.toPoint()); if (!hit.linkElement().geometry().isNull()) { kDebug() << "XXXXXXXXXX link pressed AND HOLD. .. "; emit linkPressAndHold(hit.linkUrl(), hit.linkElement().geometry()); } } } void GraphicsWebView::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { if (pressTimer.isActive()) { if ((event->pos() - pressPoint).manhattanLength() > QApplication::startDragDistance()) pressTimer.stop(); } if (parent->keepMouseGrab()) QGraphicsWebView::mouseMoveEvent(event); } bool GraphicsWebView::sceneEvent(QEvent *event) { bool rv = QGraphicsWebView::sceneEvent(event); if (event->type() == QEvent::UngrabMouse) { pressTimer.stop(); parent->setKeepMouseGrab(false); } return rv; } bool GraphicsWebView::flickingEnabled() const { return flicking; } void GraphicsWebView::setFlickingEnabled(bool enabled) { if (flicking != enabled) { flicking = enabled; emit flickingEnabledChanged(); } } /*! \qmlclass WebView KDeclarativeWebView \ingroup qml-view-elements \since 4.7 \brief The WebView item allows you to add Web content to a canvas. \inherits Item A WebView renders Web content based on a URL. This type is made available by importing the \c QtWebKit module: \bold{import QtWebKit 1.0} The WebView item includes no scrolling, scaling, toolbars, or other common browser components. These must be implemented around WebView. See the \l{QML Web Browser} example for a demonstration of this. The page to be displayed by the item is specified using the \l url property, and this can be changed to fetch and display a new page. While the page loads, the \l progress property is updated to indicate how much of the page has been loaded. \section1 Appearance If the width and height of the item is not set, they will dynamically adjust to a size appropriate for the content. This width may be large for typical online web pages, typically greater than 800 by 600 pixels. If the \l{Item::}{width} or \l{Item::}{height} is explictly set, the rendered Web site will be clipped, not scaled, to fit into the set dimensions. If the preferredWidth property is set, the width will be this amount or larger, usually laying out the Web content to fit the preferredWidth. The appearance of the content can be controlled to a certain extent by changing the settings.standardFontFamily property and other settings related to fonts. The page can be zoomed by calling the heuristicZoom() method, which performs a series of tests to determine whether zoomed content will be displayed in an appropriate way in the space allocated to the item. \section1 User Interaction and Navigation By default, certain mouse and touch events are delivered to other items in preference to the Web content. For example, when a scrolling view is created by placing a WebView in a Flickable, move events are delivered to the Flickable so that the user can scroll the page. This prevents the user from accidentally selecting text in a Web page instead of scrolling. The pressGrabTime property defines the time the user must touch or press a mouse button over the WebView before the Web content will receive the move events it needs to select text and images. When this item has keyboard focus, all keyboard input will be sent directly to the Web page within. When the navigates by clicking on links, the item records the pages visited in its internal history Because this item is designed to be used as a component in a browser, it exposes \l{Action}{actions} for \l back, \l forward, \l reload and \l stop. These can be triggered to change the current page displayed by the item. \section1 Example Usage \beginfloatright \inlineimage webview.png \endfloat The following example displays a scaled down Web page at a fixed size. \snippet doc/src/snippets/declarative/webview/webview.qml document \clearfloat \sa {declarative/modelviews/webview}{WebView example}, {demos/declarative/webbrowser}{Web Browser demo} */ /*! \internal \class KDeclarativeWebView \brief The KDeclarativeWebView class allows you to add web content to a QDeclarativeView. A WebView renders web content base on a URL. \image webview.png The item includes no scrolling, scaling, toolbars, etc., those must be implemented around WebView. See the WebBrowser example for a demonstration of this. A KDeclarativeWebView object can be instantiated in Qml using the tag \l WebView. */ KDeclarativeWebView::KDeclarativeWebView(QDeclarativeItem *parent) : QDeclarativeItem(parent) { init(); } KDeclarativeWebView::~KDeclarativeWebView() { delete d; } void KDeclarativeWebView::init() { d = new KDeclarativeWebViewPrivate(this); if (QWebSettings::iconDatabasePath().isNull() && QWebSettings::globalSettings()->localStoragePath().isNull() && QWebSettings::offlineStoragePath().isNull() && QWebSettings::offlineWebApplicationCachePath().isNull()) QWebSettings::enablePersistentStorage(); setAcceptedMouseButtons(Qt::LeftButton); setFlag(QGraphicsItem::ItemHasNoContents, true); setClip(true); d->view = new GraphicsWebView(this); d->view->setResizesToContents(true); QWebPage* wp = new QDeclarativeWebPage(this); KWebPage* kwp = qobject_cast(wp); if (kwp) { WId wid = KWindowSystem::activeWindow(); d->wallet = new KWebWallet(this, wid); kwp->setWallet(d->wallet); - // TODO: hook in some dialog wether the user wants to save the form data + // TODO: hook in some dialog whether the user wants to save the form data // happens unconditionally right now for every form filled in connect(d->wallet, SIGNAL(saveFormDataRequested(QString,QUrl)), d->wallet, SLOT(acceptSaveFormDataRequest(QString)), Qt::UniqueConnection); } wp->setForwardUnsupportedContent(true); setPage(wp); initSettings(); #ifndef NO_KIO KIO::AccessManager *access = new NetworkAccessManager(page()); wp->setNetworkAccessManager(access); #endif connect(d->view, SIGNAL(geometryChanged()), this, SLOT(updateDeclarativeWebViewSize())); connect(d->view, SIGNAL(flickingEnabledChanged()), this, SLOT(updateFlickingEnabled())); connect(d->view, SIGNAL(click(int,int)), this, SIGNAL(click(int,int))); connect(d->view, SIGNAL(doubleClick(int,int)), this, SIGNAL(doubleClick(int,int))); //connect(d->view, SIGNAL(loadLink(QUrl,QRect)), SIGNAL(linkClicked(QUrl,QRect))); connect(d->view, SIGNAL(linkPressed(QUrl,QRect)), this, SIGNAL(linkPressed(QUrl,QRect))); connect(d->view, SIGNAL(linkPressAndHold(QUrl,QRect)), this, SIGNAL(linkPressAndHold(QUrl,QRect))); connect(d->view, SIGNAL(scaleChanged()), this, SIGNAL(contentsScaleChanged())); connect(access, SIGNAL(finished(QNetworkReply*)), page(), SLOT(handleNetworkErrors(QNetworkReply*))); wp->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); connect(wp, SIGNAL(linkClicked(QUrl)), d->view, SLOT(handleLinkClicked(QUrl))); d->dirWatch = new KDirWatch(this); QString configPath = KStandardDirs::locateLocal("config", "active-webbrowserrc"); d->dirWatch->addFile(configPath); connect(d->dirWatch, SIGNAL(dirty(QString)), SLOT(initSettings())); connect(d->dirWatch, SIGNAL(created(QString)), SLOT(initSettings())); } void KDeclarativeWebView::initSettings() { //kDebug() << "Settings up fonts and reading settings: " << KGlobalSettings::generalFont().family() << KGlobalSettings::generalFont().pointSize(); settings()->setFontFamily(QWebSettings::StandardFont, KGlobalSettings::generalFont().family()); settings()->setFontFamily(QWebSettings::SerifFont, KGlobalSettings::generalFont().family()); settings()->setFontFamily(QWebSettings::FixedFont, KGlobalSettings::generalFont().family()); settings()->setFontFamily(QWebSettings::CursiveFont, KGlobalSettings::generalFont().family()); settings()->setFontFamily(QWebSettings::SansSerifFont, KGlobalSettings::generalFont().family()); settings()->setFontFamily(QWebSettings::FantasyFont, KGlobalSettings::generalFont().family()); settings()->setFontSize(QWebSettings::DefaultFontSize, KGlobalSettings::generalFont().pointSize()); //settings()->setFontSize(QWebSettings::FontSize, KGlobalSettings::generalFont().pointSize()); settings()->setFontSize(QWebSettings::DefaultFixedFontSize, KGlobalSettings::fixedFont().pointSize()); settings()->setFontSize(QWebSettings::MinimumFontSize, KGlobalSettings::smallestReadableFont().pointSize()); settings()->setFontSize(QWebSettings::MinimumLogicalFontSize, KGlobalSettings::smallestReadableFont().pointSize()); // From configuration KSharedConfigPtr ptr = KSharedConfig::openConfig("active-webbrowserrc"); ptr->reparseConfiguration(); KConfigGroup cg(ptr, "webbrowser"); bool pluginsEnabled = cg.readEntry("pluginsEnabled", false); //kDebug() << " C++ Plugins on? " << pluginsEnabled; settings()->setAttribute(QWebSettings::PluginsEnabled, pluginsEnabled); settingsObject()->setPluginsEnabled(pluginsEnabled); } void KDeclarativeWebView::componentComplete() { QDeclarativeItem::componentComplete(); #ifdef NO_KIO page()->setNetworkAccessManager(qmlEngine(this)->networkAccessManager()); #endif switch (d->pending) { case KDeclarativeWebViewPrivate::PendingUrl: setUrl(d->pendingUrl); break; case KDeclarativeWebViewPrivate::PendingHtml: setHtml(d->pendingString, d->pendingUrl); break; case KDeclarativeWebViewPrivate::PendingContent: setContent(d->pendingData, d->pendingString, d->pendingUrl); break; default: break; } d->pending = KDeclarativeWebViewPrivate::PendingNone; d->updateWindowObjects(); } KDeclarativeWebView::Status KDeclarativeWebView::status() const { return d->status; } /*! \qmlproperty real WebView::progress This property holds the progress of loading the current URL, from 0 to 1. If you just want to know when progress gets to 1, use WebView::onLoadFinished() or WebView::onLoadFailed() instead. */ qreal KDeclarativeWebView::progress() const { return d->progress; } void KDeclarativeWebView::doLoadStarted() { if (!d->url.isEmpty()) { d->status = Loading; emit statusChanged(d->status); } setRssFeeds(QStringList()); emit loadStarted(); } void KDeclarativeWebView::doLoadProgress(int p) { if (d->progress == p / 100.0) return; d->progress = p / 100.0; emit progressChanged(); } void KDeclarativeWebView::pageUrlChanged() { updateContentsSize(); if ((d->url.isEmpty() && page()->mainFrame()->url() != QUrl(QLatin1String("about:blank"))) || (d->url != page()->mainFrame()->url() && !page()->mainFrame()->url().isEmpty())) { d->url = page()->mainFrame()->url(); if (d->url == QUrl(QLatin1String("about:blank"))) d->url = QUrl(); emit urlChanged(); } } void KDeclarativeWebView::doLoadFinished(bool ok) { if (ok) { d->status = d->url.isEmpty() ? Null : Ready; emit loadFinished(); if (d->status == Ready) { if (d->wallet) { d->wallet->fillFormData(page()->mainFrame()); } foreach (const QWebElement &el, page()->mainFrame()->findAllElements("LINK")) { if (el.attribute("type").contains("application/rss+xml")) { d->rssFeeds << el.attribute("href"); } } if (!rssFeeds().isEmpty()) { emit rssFeedsChanged(); } } } else { d->status = Error; emit loadFailed(); } emit statusChanged(d->status); } /*! \qmlproperty url WebView::url This property holds the URL to the page displayed in this item. It can be set, but also can change spontaneously (eg. because of network redirection). If the url is empty, the page is blank. The url is always absolute (QML will resolve relative URL strings in the context of the containing QML document). */ QUrl KDeclarativeWebView::url() const { return d->url; } void KDeclarativeWebView::setUrl(const QUrl& url) { if (url == d->url) return; if (isComponentComplete()) { d->url = url; updateContentsSize(); QUrl seturl = url; if (seturl.isEmpty()) seturl = QUrl(QLatin1String("about:blank")); Q_ASSERT(!seturl.isRelative()); page()->mainFrame()->load(seturl); emit urlChanged(); } else { d->pending = d->PendingUrl; d->pendingUrl = url; } } QStringList KDeclarativeWebView::rssFeeds() const { return d->rssFeeds; } void KDeclarativeWebView::setRssFeeds(const QStringList &feeds) { if (d->rssFeeds != feeds) { d->rssFeeds = feeds; emit rssFeedsChanged(); }; } /*! \qmlproperty int WebView::preferredWidth This property holds the ideal width for displaying the current URL. */ int KDeclarativeWebView::preferredWidth() const { return d->preferredwidth; } void KDeclarativeWebView::setPreferredWidth(int width) { if (d->preferredwidth == width) return; d->preferredwidth = width; updateContentsSize(); emit preferredWidthChanged(); } /*! \qmlproperty int WebView::preferredHeight This property holds the ideal height for displaying the current URL. This only affects the area zoomed by heuristicZoom(). */ int KDeclarativeWebView::preferredHeight() const { return d->preferredheight; } void KDeclarativeWebView::setPreferredHeight(int height) { if (d->preferredheight == height) return; d->preferredheight = height; updateContentsSize(); emit preferredHeightChanged(); } /*! \qmlmethod bool WebView::evaluateJavaScript(string scriptSource) Evaluates the \a scriptSource JavaScript inside the context of the main web frame, and returns the result of the last executed statement. Note that this JavaScript does \e not have any access to QML objects except as made available as windowObjects. */ QVariant KDeclarativeWebView::evaluateJavaScript(const QString& scriptSource) { return this->page()->mainFrame()->evaluateJavaScript(scriptSource); } void KDeclarativeWebView::updateDeclarativeWebViewSize() { QSizeF size = d->view->geometry().size() * contentsScale(); setImplicitWidth(size.width()); setImplicitHeight(size.height()); } void KDeclarativeWebView::initialLayout() { // nothing useful to do at this point } void KDeclarativeWebView::updateContentsSize() { if (page()) { page()->setPreferredContentsSize(QSize( d->preferredwidth>0 ? d->preferredwidth : width(), d->preferredheight>0 ? d->preferredheight : height())); } } void KDeclarativeWebView::geometryChanged(const QRectF& newGeometry, const QRectF& oldGeometry) { QWebPage* webPage = page(); if (newGeometry.size() != oldGeometry.size() && webPage) { QSize contentSize = webPage->preferredContentsSize(); if (widthValid()) contentSize.setWidth(width()); if (heightValid()) contentSize.setHeight(height()); if (contentSize != webPage->preferredContentsSize()) webPage->setPreferredContentsSize(contentSize); } QDeclarativeItem::geometryChanged(newGeometry, oldGeometry); } /*! \qmlproperty list WebView::javaScriptWindowObjects A list of QML objects to expose to the web page. Each object will be added as a property of the web frame's window object. The property name is controlled by the value of \c WebView.windowObjectName attached property. Exposing QML objects to a web page allows JavaScript executing in the web page itself to communicate with QML, by reading and writing properties and by calling methods of the exposed QML objects. This example shows how to call into a QML method using a window object. \qml WebView { javaScriptWindowObjects: QtObject { WebView.windowObjectName: "qml" function qmlCall() { console.log("This call is in QML!"); } } html: "" } \endqml The output of the example will be: \code This is in WebKit! This call is in QML! \endcode If Javascript is not enabled for the page, then this property does nothing. */ QDeclarativeListProperty KDeclarativeWebView::javaScriptWindowObjects() { return QDeclarativeListProperty(this, d, &KDeclarativeWebViewPrivate::windowObjectsAppend); } KDeclarativeWebViewAttached* KDeclarativeWebView::qmlAttachedProperties(QObject* o) { return new KDeclarativeWebViewAttached(o); } void KDeclarativeWebViewPrivate::updateWindowObjects() { if (!q->isComponentCompletePublic() || !q->page()) return; for (int i = 0; i < windowObjects.count(); ++i) { QObject* object = windowObjects.at(i); KDeclarativeWebViewAttached* attached = static_cast(qmlAttachedPropertiesObject(object)); if (attached && !attached->windowObjectName().isEmpty()) q->page()->mainFrame()->addToJavaScriptWindowObject(attached->windowObjectName(), object); } } bool KDeclarativeWebView::renderingEnabled() const { return d->rendering; } void KDeclarativeWebView::setRenderingEnabled(bool enabled) { if (d->rendering == enabled) return; d->rendering = enabled; emit renderingEnabledChanged(); d->view->setTiledBackingStoreFrozen(!enabled); } /*! \qmlsignal WebView::onDoubleClick(int clickx, int clicky) The WebView does not pass double-click events to the web engine, but rather emits this signals. */ /*! \qmlmethod bool WebView::heuristicZoom(int clickX, int clickY, real maxzoom) Finds a zoom that: \list \i shows a whole item \i includes (\a clickX, \a clickY) \i fits into the preferredWidth and preferredHeight \i zooms by no more than \a maxZoom \i is more than 10% above the current zoom \endlist If such a zoom exists, emits zoomTo(zoom,centerX,centerY) and returns true; otherwise, no signal is emitted and returns false. */ bool KDeclarativeWebView::heuristicZoom(int clickX, int clickY, qreal maxZoom) { if (contentsScale() >= maxZoom / scale()) return false; qreal ozf = contentsScale(); QRect showArea = elementAreaAt(clickX, clickY, d->preferredwidth / maxZoom, d->preferredheight / maxZoom); qreal z = qMin(qreal(d->preferredwidth) / showArea.width(), qreal(d->preferredheight) / showArea.height()); if (z > maxZoom / scale()) z = maxZoom / scale(); if (z / ozf > 1.2) { QRectF r(showArea.left() * z, showArea.top() * z, showArea.width() * z, showArea.height() * z); emit zoomTo(z, r.x() + r.width() / 2, r.y() + r.height() / 2); return true; } return false; } /*! \qmlproperty int WebView::pressGrabTime The number of milliseconds the user must press before the WebView starts passing move events through to the Web engine (rather than letting other QML elements such as a Flickable take them). Defaults to 400ms. Set to 0 to always grab and pass move events to the Web engine. */ int KDeclarativeWebView::pressGrabTime() const { return d->view->pressTime; } void KDeclarativeWebView::setPressGrabTime(int millis) { if (d->view->pressTime == millis) return; d->view->pressTime = millis; emit pressGrabTimeChanged(); } bool KDeclarativeWebView::flickingEnabled() const { return d->view->flickingEnabled(); } void KDeclarativeWebView::setFlickingEnabled(bool enabled) { d->view->setFlickingEnabled(enabled); emit flickingEnabledChanged(); } void KDeclarativeWebView::updateFlickingEnabled() { setFlickingEnabled(d->view->flickingEnabled()); } #ifndef QT_NO_ACTION /*! \qmlproperty action WebView::back This property holds the action for causing the previous URL in the history to be displayed. */ QAction* KDeclarativeWebView::backAction() const { return page()->action(QWebPage::Back); } /*! \qmlproperty action WebView::forward This property holds the action for causing the next URL in the history to be displayed. */ QAction* KDeclarativeWebView::forwardAction() const { return page()->action(QWebPage::Forward); } /*! \qmlproperty action WebView::reload This property holds the action for reloading with the current URL */ QAction* KDeclarativeWebView::reloadAction() const { return page()->action(QWebPage::Reload); } /*! \qmlproperty action WebView::stop This property holds the action for stopping loading with the current URL */ QAction* KDeclarativeWebView::stopAction() const { return page()->action(QWebPage::Stop); } #endif // QT_NO_ACTION /*! \qmlproperty string WebView::title This property holds the title of the web page currently viewed By default, this property contains an empty string. */ QString KDeclarativeWebView::title() const { return page()->mainFrame()->title(); } /*! \qmlproperty pixmap WebView::icon This property holds the icon associated with the web page currently viewed */ QPixmap KDeclarativeWebView::icon() const { return page()->mainFrame()->icon().pixmap(QSize(256, 256)); } /*! \qmlproperty string WebView::statusText This property is the current status suggested by the current web page. In a web browser, such status is often shown in some kind of status bar. */ void KDeclarativeWebView::setStatusText(const QString& text) { d->statusText = text; emit statusTextChanged(); } void KDeclarativeWebView::windowObjectCleared() { d->updateWindowObjects(); } QString KDeclarativeWebView::statusText() const { return d->statusText; } QWebPage* KDeclarativeWebView::page() const { return d->view->page(); } // The QObject interface to settings(). /*! \qmlproperty string WebView::settings.standardFontFamily \qmlproperty string WebView::settings.fixedFontFamily \qmlproperty string WebView::settings.serifFontFamily \qmlproperty string WebView::settings.sansSerifFontFamily \qmlproperty string WebView::settings.cursiveFontFamily \qmlproperty string WebView::settings.fantasyFontFamily \qmlproperty int WebView::settings.minimumFontSize \qmlproperty int WebView::settings.minimumLogicalFontSize \qmlproperty int WebView::settings.defaultFontSize \qmlproperty int WebView::settings.defaultFixedFontSize \qmlproperty bool WebView::settings.autoLoadImages \qmlproperty bool WebView::settings.javascriptEnabled \qmlproperty bool WebView::settings.javaEnabled \qmlproperty bool WebView::settings.pluginsEnabled \qmlproperty bool WebView::settings.privateBrowsingEnabled \qmlproperty bool WebView::settings.javascriptCanOpenWindows \qmlproperty bool WebView::settings.javascriptCanAccessClipboard \qmlproperty bool WebView::settings.developerExtrasEnabled \qmlproperty bool WebView::settings.linksIncludedInFocusChain \qmlproperty bool WebView::settings.zoomTextOnly \qmlproperty bool WebView::settings.printElementBackgrounds \qmlproperty bool WebView::settings.offlineStorageDatabaseEnabled \qmlproperty bool WebView::settings.offlineWebApplicationCacheEnabled \qmlproperty bool WebView::settings.localStorageDatabaseEnabled \qmlproperty bool WebView::settings.localContentCanAccessRemoteUrls These properties give access to the settings controlling the web view. See QWebSettings for details of these properties. \qml WebView { settings.pluginsEnabled: true settings.standardFontFamily: "Arial" // ... } \endqml */ KDeclarativeWebSettings* KDeclarativeWebView::settingsObject() const { d->settings.s = page()->settings(); return &d->settings; } void KDeclarativeWebView::setPage(QWebPage* page) { if (d->view->page() == page) return; d->view->setPage(page); updateContentsSize(); page->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); page->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); connect(page->mainFrame(), SIGNAL(urlChanged(QUrl)), this, SLOT(pageUrlChanged())); connect(page->mainFrame(), SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString))); connect(page->mainFrame(), SIGNAL(titleChanged(QString)), this, SIGNAL(iconChanged())); connect(page->mainFrame(), SIGNAL(iconChanged()), this, SIGNAL(iconChanged())); connect(page->mainFrame(), SIGNAL(initialLayoutCompleted()), this, SLOT(initialLayout())); connect(page->mainFrame(), SIGNAL(contentsSizeChanged(QSize)), this, SIGNAL(contentsSizeChanged(QSize))); connect(page, SIGNAL(loadStarted()), this, SLOT(doLoadStarted())); connect(page, SIGNAL(loadProgress(int)), this, SLOT(doLoadProgress(int))); connect(page, SIGNAL(loadFinished(bool)), this, SLOT(doLoadFinished(bool))); connect(page, SIGNAL(statusBarMessage(QString)), this, SLOT(setStatusText(QString))); connect(page->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(windowObjectCleared())); page->settings()->setAttribute(QWebSettings::TiledBackingStoreEnabled, true); } /*! \qmlsignal WebView::onLoadStarted() This handler is called when the web engine begins loading a page. Later, WebView::onLoadFinished() or WebView::onLoadFailed() will be emitted. */ /*! \qmlsignal WebView::onLoadFinished() This handler is called when the web engine \e successfully finishes loading a page, including any component content (WebView::onLoadFailed() will be emitted otherwise). \sa progress */ /*! \qmlsignal WebView::onLoadFailed() This handler is called when the web engine fails loading a page or any component content (WebView::onLoadFinished() will be emitted on success). */ void KDeclarativeWebView::load(const QNetworkRequest& request, QNetworkAccessManager::Operation operation, const QByteArray& body) { page()->mainFrame()->load(request, operation, body); } QString KDeclarativeWebView::html() const { return page()->mainFrame()->toHtml(); } /*! \qmlproperty string WebView::html This property holds HTML text set directly The html property can be set as a string. \qml WebView { html: "

This is HTML." } \endqml */ void KDeclarativeWebView::setHtml(const QString& html, const QUrl& baseUrl) { updateContentsSize(); if (isComponentComplete()) page()->mainFrame()->setHtml(html, baseUrl); else { d->pending = d->PendingHtml; d->pendingUrl = baseUrl; d->pendingString = html; } emit htmlChanged(); } void KDeclarativeWebView::setContent(const QByteArray& data, const QString& mimeType, const QUrl& baseUrl) { updateContentsSize(); if (isComponentComplete()) page()->mainFrame()->setContent(data, mimeType, qmlContext(this)->resolvedUrl(baseUrl)); else { d->pending = d->PendingContent; d->pendingUrl = baseUrl; d->pendingString = mimeType; d->pendingData = data; } } QWebHistory* KDeclarativeWebView::history() const { return page()->history(); } QWebSettings* KDeclarativeWebView::settings() const { return page()->settings(); } KDeclarativeWebView* KDeclarativeWebView::createWindow(QWebPage::WebWindowType type) { switch (type) { case QWebPage::WebBrowserWindow: { if (!d->newWindowComponent && d->newWindowParent) qWarning("WebView::newWindowComponent not set - WebView::newWindowParent ignored"); else if (d->newWindowComponent && !d->newWindowParent) qWarning("WebView::newWindowParent not set - WebView::newWindowComponent ignored"); else if (d->newWindowComponent && d->newWindowParent) { KDeclarativeWebView* webview = 0; QDeclarativeContext* windowContext = new QDeclarativeContext(qmlContext(this)); QObject* newObject = d->newWindowComponent->create(windowContext); if (newObject) { windowContext->setParent(newObject); QDeclarativeItem* item = qobject_cast(newObject); if (!item) delete newObject; else { webview = item->findChild(); if (!webview) delete item; else { newObject->setParent(d->newWindowParent); static_cast(item)->setParentItem(d->newWindowParent); } } } else delete windowContext; return webview; } } break; case QWebPage::WebModalDialog: { // Not supported } } return 0; } /*! \qmlproperty component WebView::newWindowComponent This property holds the component to use for new windows. The component must have a WebView somewhere in its structure. When the web engine requests a new window, it will be an instance of this component. The parent of the new window is set by newWindowParent. It must be set. */ QDeclarativeComponent* KDeclarativeWebView::newWindowComponent() const { return d->newWindowComponent; } void KDeclarativeWebView::setNewWindowComponent(QDeclarativeComponent* newWindow) { if (newWindow == d->newWindowComponent) return; d->newWindowComponent = newWindow; emit newWindowComponentChanged(); } /*! \qmlproperty item WebView::newWindowParent The parent item for new windows. \sa newWindowComponent */ QDeclarativeItem* KDeclarativeWebView::newWindowParent() const { return d->newWindowParent; } void KDeclarativeWebView::setNewWindowParent(QDeclarativeItem* parent) { if (parent == d->newWindowParent) return; if (d->newWindowParent && parent) { QList children = d->newWindowParent->childItems(); for (int i = 0; i < children.count(); ++i) children.at(i)->setParentItem(parent); } d->newWindowParent = parent; emit newWindowParentChanged(); } QSize KDeclarativeWebView::contentsSize() const { return page()->mainFrame()->contentsSize() * contentsScale(); } qreal KDeclarativeWebView::contentsScale() const { return d->view->scale(); } void KDeclarativeWebView::setContentsScale(qreal scale) { if (scale == d->view->scale()) return; d->view->setScale(scale); updateDeclarativeWebViewSize(); emit contentsScaleChanged(); } /*! Returns the area of the largest element at position (\a x,\a y) that is no larger than \a maxWidth by \a maxHeight pixels. May return an area larger in the case when no smaller element is at the position. */ QRect KDeclarativeWebView::elementAreaAt(int x, int y, int maxWidth, int maxHeight) const { QWebHitTestResult hit = page()->mainFrame()->hitTestContent(QPoint(x, y)); QRect hitRect = hit.boundingRect(); QWebElement element = hit.enclosingBlockElement(); if (maxWidth <= 0) maxWidth = INT_MAX; if (maxHeight <= 0) maxHeight = INT_MAX; while (!element.parent().isNull() && element.geometry().width() <= maxWidth && element.geometry().height() <= maxHeight) { hitRect = element.geometry(); element = element.parent(); } return hitRect; } /*! \internal \class QDeclarativeWebPage \brief The QDeclarativeWebPage class is a QWebPage that can create QML plugins. \sa KDeclarativeWebView */ QDeclarativeWebPage::QDeclarativeWebPage(KDeclarativeWebView* parent) : KWebPage(parent, KWalletIntegration) { connect(this, SIGNAL(unsupportedContent(QNetworkReply*)), this, SLOT(handleUnsupportedContent(QNetworkReply*))); // //TODO: move this in the webbrowser implementation m_nepomukHelper = new NepomukHelper(this); } QDeclarativeWebPage::~QDeclarativeWebPage() { } QString QDeclarativeWebPage::chooseFile(QWebFrame* originatingFrame, const QString& oldFile) { Q_UNUSED(originatingFrame) Q_UNUSED(oldFile) return KFileDialog::getOpenFileName(); } /*! \qmlsignal WebView::onAlert(string message) The handler is called when the web engine sends a JavaScript alert. The \a message is the text to be displayed in the alert to the user. */ void QDeclarativeWebPage::javaScriptAlert(QWebFrame* originatingFrame, const QString& msg) { // FIXME: implement alert Q_UNUSED(originatingFrame) emit viewItem()->alert(msg); } bool QDeclarativeWebPage::javaScriptConfirm(QWebFrame* originatingFrame, const QString& msg) { // FIXME: Not supported (it's modal) Q_UNUSED(originatingFrame) Q_UNUSED(msg) return false; } bool QDeclarativeWebPage::javaScriptPrompt(QWebFrame* originatingFrame, const QString& msg, const QString& defaultValue, QString* result) { // FIXME: Not supported (it's modal) Q_UNUSED(originatingFrame) Q_UNUSED(msg) Q_UNUSED(defaultValue) Q_UNUSED(result) return false; } KDeclarativeWebView* QDeclarativeWebPage::viewItem() { return static_cast(parent()); } QWebPage* QDeclarativeWebPage::createWindow(WebWindowType type) { KDeclarativeWebView* newView = viewItem()->createWindow(type); if (newView) return newView->page(); return 0; } void QDeclarativeWebPage::handleUnsupportedContent(QNetworkReply *reply) { if (!reply) { return; } QUrl replyUrl = reply->url(); if (replyUrl.scheme() == QLatin1String("abp")) return; if (reply->error() == QNetworkReply::NoError && reply->header(QNetworkRequest::ContentTypeHeader).isValid()) { downloadUrl(replyUrl); } } bool QDeclarativeWebPage::downloadResource (const KUrl& srcUrl, const QString& suggestedName, QWidget* parent, const KIO::MetaData& metaData) { const QString fileName ((suggestedName.isEmpty() ? srcUrl.fileName() : suggestedName)); const KUrl &destUrl(QString("file://%1/%2").arg(QDir::homePath()).arg(fileName)); if (!destUrl.isValid()) { return false; } KIO::CopyJob *job = KIO::copy(srcUrl, destUrl); if (!metaData.isEmpty()) { job->setMetaData(metaData); } job->setAutoRename(true); job->addMetaData(QLatin1String("MaxCacheSize"), QLatin1String("0")); // Don't store in http cache. job->addMetaData(QLatin1String("cache"), QLatin1String("cache")); // Use entry from cache if available. job->ui()->setWindow((parent ? parent->window() : 0)); job->ui()->setAutoErrorHandlingEnabled(true); connect(job, SIGNAL(result(KJob*)), this, SLOT(downloadFinished(KJob*))); return true; } void QDeclarativeWebPage::downloadFinished(KJob *job) { KIO::CopyJob *cj = qobject_cast(job); if (cj && job->error() == KJob::NoError) { KUrl localUrl = cj->destUrl(); KUrl remoteUrl; foreach (const KUrl &_u, cj->srcUrls()) { remoteUrl = _u; } // add file to current activity, store remote url as metadata m_nepomukHelper->storeDownloadMetaData(remoteUrl, localUrl); } else { // TODO: handle download errors. kError() << "Error downloading file: " << job->errorString(); } } void QDeclarativeWebPage::downloadRequest(const QNetworkRequest &request) { downloadResource(request.url(), QString(), view(), request.attribute(static_cast(KIO::AccessManager::MetaData)).toMap()); } void QDeclarativeWebPage::downloadUrl(const KUrl &url) { downloadResource(url, QString(), view()); } #include "errorhandling.cpp" QT_END_NAMESPACE diff --git a/applications/webbrowser/src/nepomukhelper.cpp b/applications/webbrowser/src/nepomukhelper.cpp index ed93cd03..6fb73f4a 100644 --- a/applications/webbrowser/src/nepomukhelper.cpp +++ b/applications/webbrowser/src/nepomukhelper.cpp @@ -1,114 +1,114 @@ /*************************************************************************** * * * Copyright 2012 Sebastian Kügler * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, 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 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 "nepomukhelper.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include class NepomukHelperPrivate { public: QUrl localUrl; QUrl remoteUrl; KActivities::Consumer* activityConsumer; }; NepomukHelper::NepomukHelper(QObject *parent) : QObject(parent) { d = new NepomukHelperPrivate; d->activityConsumer = new KActivities::Consumer(this); } NepomukHelper::~NepomukHelper() { delete d; } void NepomukHelper::storeDownloadMetaData(const KUrl &remoteUrl, const KUrl &localUrl) { d->localUrl = localUrl; d->remoteUrl = remoteUrl; // Create resources for the remote and local file and website Nepomuk::SimpleResource remoteFile; remoteFile.addType(Nepomuk::Vocabulary::NFO::RemoteDataObject()); remoteFile.addType(Nepomuk::Vocabulary::NFO::WebDataObject()); remoteFile.addProperty(Nepomuk::Vocabulary::NIE::url(), d->remoteUrl); Nepomuk::SimpleResource file; file.addType(Nepomuk::Vocabulary::NFO::FileDataObject()); file.addProperty(Nepomuk::Vocabulary::NIE::url(), d->localUrl); file.addProperty(Nepomuk::Vocabulary::NDO::copiedFrom(), remoteFile); Nepomuk::SimpleResource website; website.addType(Nepomuk::Vocabulary::NFO::HtmlDocument()); website.addType(Nepomuk::Vocabulary::NFO::WebDataObject()); website.addProperty(Nepomuk::Vocabulary::NIE::url(), d->remoteUrl); // Record the download as event QDateTime dt = QDateTime::currentDateTime(); Nepomuk::SimpleResource event; event.addType(Nepomuk::Vocabulary::NDO::DownloadEvent()); event.addProperty(Nepomuk::Vocabulary::NUAO::start(), dt); event.addProperty(Nepomuk::Vocabulary::NUAO::end(), dt); event.addProperty(Nepomuk::Vocabulary::NUAO::involves(), file); event.addProperty(Nepomuk::Vocabulary::NDO::referrer(), website); //kDebug() << "storing Nepomuk meta: " << d->remoteUrl << " " << d->localUrl; // Store these resources Nepomuk::SimpleResourceGraph graph; graph << remoteFile << file << website << event; KJob* job = Nepomuk::storeResources(graph); connect(job, SIGNAL(finished(KJob*)), this, SLOT(storeResourcesFinished(KJob*))); // And link the downloaded file to the currently active Activity QString activityId = d->activityConsumer->currentActivity(); KActivities::Info aInfo(activityId); aInfo.linkResource(d->localUrl); } void NepomukHelper::storeResourcesFinished(KJob *job) { if( job->error() ) { kWarning() << "Error storing metadata for download: " << job->errorString(); return; } - //kDebug() << "Sucessfully pushed the data"; + //kDebug() << "Successfully pushed the data"; } #include "nepomukhelper.moc" diff --git a/components/metadatamodel/test/dynamictreemodel.h b/components/metadatamodel/test/dynamictreemodel.h index e2f73989..809b76a3 100644 --- a/components/metadatamodel/test/dynamictreemodel.h +++ b/components/metadatamodel/test/dynamictreemodel.h @@ -1,197 +1,197 @@ /**************************************************************************** ** ** Copyright (C) 2009 Stephen Kelly ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the test suite of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage ** This file contains pre-release code and may not be distributed. ** You may use this file in accordance with the terms and conditions ** contained in the Technology Preview License Agreement accompanying ** this package. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** ** ** ** ** ** ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef DYNAMICTREEMODEL_H #define DYNAMICTREEMODEL_H #include #include #include class DynamicTreeModel : public QAbstractItemModel { Q_OBJECT public: DynamicTreeModel(QObject *parent = 0); QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &index = QModelIndex()) const; int columnCount(const QModelIndex &index = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; void clear(); protected slots: /** Finds the parent id of the string with id @p searchId. Returns -1 if not found. */ qint64 findParentId(qint64 searchId) const; private: QHash m_items; QHash > > m_childItems; qint64 nextId; qint64 newId() { return nextId++; }; QModelIndex m_nextParentIndex; int m_nextRow; int m_depth; int maxDepth; friend class ModelInsertCommand; friend class ModelMoveCommand; friend class ModelResetCommand; friend class ModelResetCommandFixed; }; class ModelChangeCommand : public QObject { Q_OBJECT public: explicit ModelChangeCommand( DynamicTreeModel *model, QObject *parent = 0 ); virtual ~ModelChangeCommand() {} void setAncestorRowNumbers(QList rowNumbers) { m_rowNumbers = rowNumbers; } QModelIndex findIndex(QList rows); void setStartRow(int row) { m_startRow = row; } void setEndRow(int row) { m_endRow = row; } void setNumCols(int cols) { m_numCols = cols; } virtual void doCommand() = 0; protected: DynamicTreeModel* m_model; QList m_rowNumbers; int m_numCols; int m_startRow; int m_endRow; }; typedef QList ModelChangeCommandList; class ModelInsertCommand : public ModelChangeCommand { Q_OBJECT public: explicit ModelInsertCommand(DynamicTreeModel *model, QObject *parent = 0 ); virtual ~ModelInsertCommand() {} virtual void doCommand(); }; class ModelMoveCommand : public ModelChangeCommand { Q_OBJECT public: ModelMoveCommand(DynamicTreeModel *model, QObject *parent); virtual ~ModelMoveCommand() {} virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); virtual void doCommand(); virtual void emitPostSignal(); void setDestAncestors( QList rows ) { m_destRowNumbers = rows; } void setDestRow(int row) { m_destRow = row; } protected: QList m_destRowNumbers; int m_destRow; }; /** A command which does a move and emits a reset signal. */ class ModelResetCommand : public ModelMoveCommand { Q_OBJECT public: - explicity ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); + explicit ModelResetCommand(DynamicTreeModel* model, QObject* parent = 0); virtual ~ModelResetCommand(); virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); virtual void emitPostSignal(); }; /** A command which does a move and emits a beginResetModel and endResetModel signals. */ class ModelResetCommandFixed : public ModelMoveCommand { Q_OBJECT public: explicit ModelResetCommandFixed(DynamicTreeModel* model, QObject* parent = 0); virtual ~ModelResetCommandFixed(); virtual bool emitPreSignal(const QModelIndex &srcParent, int srcStart, int srcEnd, const QModelIndex &destParent, int destRow); virtual void emitPostSignal(); }; #endif diff --git a/components/mobilecomponents/ResourceDelegate.qml b/components/mobilecomponents/ResourceDelegate.qml index 505dbf85..32fe8ef9 100644 --- a/components/mobilecomponents/ResourceDelegate.qml +++ b/components/mobilecomponents/ResourceDelegate.qml @@ -1,119 +1,119 @@ /* * Copyright 2011 Marco Martin * * 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 Library 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. */ import QtQuick 1.1 import org.kde.plasma.mobilecomponents 0.1 as MobileComponents import org.kde.qtextracomponents 0.1 Item { id: delegateItem property string className: model["className"] ? model["className"] : "FileDataObject" property string genericClassName: model["genericClassName"] ? model["genericClassName"] : "FileDataObject" property bool infoLabelVisible implicitWidth: itemLoader.item.implicitWidth implicitHeight: itemLoader.item.implicitHeight signal clicked(variant mouse) signal pressed(variant mouse) signal released(variant mouse) signal pressAndHold(variant mouse) function roundToStandardSize(size) { if (size >= theme.enormousIconSize) { return theme.enormousIconSize } else if (size >= theme.hugeIconSize) { return theme.hugeIconSize } else if (size >= theme.largeIconSize) { return theme.largeIconSize } else if (size >= theme.mediumIconSize) { return theme.mediumIconSize } else if (size >= theme.smallMediumIconSize) { return theme.smallMediumIconSize } else { return theme.smallIconSize } } MobileComponents.FallbackComponent { id: fallback } Loader { id: itemLoader anchors { fill: parent margins: 4 } - //FIXME: assuming the view is parent.parent is bad, it should have the view attached property (it appears it doesnt, why?) + //FIXME: assuming the view is parent.parent is bad, it should have the view attached property (it appears it doesn't, why?) source: { if (!className && !genericClassName) { return "" } var view = delegateItem.parent if (view != undefined && view.orientation == undefined && view.flow == undefined) { view = view.parent } if (view != undefined && view.orientation == undefined && view.flow == undefined) { view = view.parent } if (!delegateItem.parent || !delegateItem.parent.parent || view == undefined || view.orientation == ListView.Horizontal || view.cellHeight != undefined) { return fallback.resolvePath("resourcedelegates", [(className + "/ItemHorizontal.qml"), (genericClassName + "/ItemHorizontal.qml"), "FileDataObject/ItemHorizontal.qml"]) } else { return fallback.resolvePath("resourcedelegates", [(className + "/Item.qml"), (genericClassName + "/Item.qml"), "FileDataObject/Item.qml"]) } } } //FIXME: this mess is due to mousearea not having screen coordinates MouseEventListener { anchors.fill: parent MouseArea { anchors.fill: parent onClicked: delegateItem.clicked(mouse) onPressed: delegateItem.pressed(mouse) onReleased: delegateItem.released(mouse) onPressAndHold: { delegateItem.pressAndHold(mouse) if (resourceInstance && contextMenu) { contextMenu.parentItem = delegateItem contextMenu.adjustPosition(); contextMenu.visible = true } } } onPositionChanged: { if (contextMenu) { contextMenu.mainItem.highlightItem(mouse.screenX, mouse.screenY) } } onReleased: { if (contextMenu) { contextMenu.mainItem.runItem(mouse.screenX, mouse.screenY) } } } } diff --git a/containments/activityscreen/contents/ui/PlasmoidGroup.qml b/containments/activityscreen/contents/ui/PlasmoidGroup.qml index a52caafe..b394bc03 100644 --- a/containments/activityscreen/contents/ui/PlasmoidGroup.qml +++ b/containments/activityscreen/contents/ui/PlasmoidGroup.qml @@ -1,107 +1,107 @@ /* * Copyright 2011 Marco Martin * * 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 Library 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. */ import QtQuick 1.0 import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.plasma.mobilecomponents 0.1 as MobileComponents import "plasmapackage:/code/LayoutManager.js" as LayoutManager ItemGroup { id: plasmoidGroup scale: plasmoid.scale canResizeHeight: true title: applet.name minimumWidth: Math.max(LayoutManager.cellSize.width, appletContainer.minimumWidth + plasmoidGroup.contents.anchors.leftMargin + plasmoidGroup.contents.anchors.rightMargin) minimumHeight: Math.max(LayoutManager.cellSize.height, appletContainer.minimumHeight + plasmoidGroup.contents.anchors.topMargin + plasmoidGroup.contents.anchors.bottomMargin) property alias applet: appletContainer.applet MobileComponents.AppletContainer { id: appletContainer anchors.fill: plasmoidGroup.contents onAppletChanged: { applet.appletDestroyed.connect(appletDestroyed) appletTimer.running = true } function appletDestroyed() { LayoutManager.setSpaceAvailable(plasmoidGroup.x, plasmoidGroup.y, plasmoidGroup.width, plasmoidGroup.height, true) plasmoidGroup.destroy() } } MobileComponents.ActionButton { svg: configIconsSvg elementId: "close" iconSize: Math.max(16, plasmoidGroup.titleHeight - 2) backgroundVisible: false visible: action.enabled action: applet.action("remove") anchors { right: plasmoidGroup.contents.right bottom: plasmoidGroup.contents.top bottomMargin: 4 } Component.onCompleted: { action.enabled = true } } MobileComponents.ActionButton { svg: configIconsSvg elementId: "configure" iconSize: Math.max(16, plasmoidGroup.titleHeight - 2) backgroundVisible: false visible: action.enabled action: applet.action("configure") anchors { left: plasmoidGroup.contents.left bottom: plasmoidGroup.contents.top bottomMargin: 4 } Component.onCompleted: { action.enabled = true } } - //FIXME: this delay is becuase backgroundHints gets updated only after a while in qml applets + //FIXME: this delay is because backgroundHints gets updated only after a while in qml applets Timer { id: appletTimer interval: 250 repeat: false running: false onTriggered: { if (applet.backgroundHints != 0) { plasmoidGroup.imagePath = "widgets/background" } else { plasmoidGroup.imagePath = "widgets/translucentbackground" } applet.backgroundHints = "NoBackground" } } } diff --git a/containments/appletstrip/contents/ui/PlasmoidContainer.qml b/containments/appletstrip/contents/ui/PlasmoidContainer.qml index e617ba02..0d3b22d0 100644 --- a/containments/appletstrip/contents/ui/PlasmoidContainer.qml +++ b/containments/appletstrip/contents/ui/PlasmoidContainer.qml @@ -1,116 +1,116 @@ /* * Copyright 2011 Marco Martin * * 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 Library 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. */ import QtQuick 1.0 import org.kde.plasma.core 0.1 as PlasmaCore import org.kde.plasma.mobilecomponents 0.1 as MobileComponents PlasmaCore.FrameSvgItem { id: plasmoidContainer anchors.top: appletsRow.top anchors.bottom: appletsRow.bottom //FIXME: this is due to the disappear anim managed by the applet itslef scale: applet.scale property QGraphicsWidget applet onAppletChanged: { applet.appletDestroyed.connect(appletDestroyed) applet.parent = plasmoidContainer appletTimer.running = true } - //FIXME: this delay is becuase backgroundHints gets updated only after a while in qml applets + //FIXME: this delay is because backgroundHints gets updated only after a while in qml applets Timer { id: appletTimer interval: 250 repeat: false running: false onTriggered: { if (applet.backgroundHints != 0) { plasmoidContainer.imagePath = "widgets/background" } else { plasmoidContainer.imagePath = "invalid" } applet.backgroundHints = "NoBackground" applet.x = plasmoidContainer.margins.left applet.y = plasmoidContainer.margins.top height = appletsRow.height width = Math.max(main.width/appletColumns, applet.minimumSize.width + plasmoidContainer.margins.left + plasmoidContainer.margins.right) applet.width = width - plasmoidContainer.margins.left - plasmoidContainer.margins.right applet.height = height - plasmoidContainer.margins.top - plasmoidContainer.margins.bottom - runButton.height } } function appletDestroyed() { plasmoidContainer.destroy() } PlasmaCore.Svg { id: iconsSvg imagePath: "widgets/configuration-icons" } MoveButton { anchors { left: parent.left bottom: parent.bottom leftMargin: plasmoidContainer.margins.left bottomMargin: plasmoidContainer.margins.bottom } } MobileComponents.ActionButton { id: runButton anchors { right: parent.right bottom: parent.bottom rightMargin: plasmoidContainer.margins.right bottomMargin: plasmoidContainer.margins.bottom } svg: iconsSvg elementId: "maximize" backgroundVisible: false z: applet.z + 1 action: applet.action("run associated application") } ExtraActions { anchors { bottom: parent.bottom horizontalCenter: parent.horizontalCenter bottomMargin: plasmoidContainer.margins.bottom } z: applet.z + 1 } onHeightChanged: { if (applet) { applet.height = height var ratio = applet.preferredSize.width/applet.preferredSize.height applet.width = main.width/appletColumns width = applet.width } } -} \ No newline at end of file +} diff --git a/shell/firstrun/firstrun.cpp b/shell/firstrun/firstrun.cpp index ea2340c2..885c28fa 100644 --- a/shell/firstrun/firstrun.cpp +++ b/shell/firstrun/firstrun.cpp @@ -1,174 +1,174 @@ /* * Copyright 2011 Sebastian Kügler * * 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 "firstrun.h" #include "kao.h" #include #include #include #include #include #include #include #include #include #include #include #include FirstRun::FirstRun(QObject* parent) : QObject(parent), m_activityController(0) { m_initialActivities << "Introduction" << "Vacation Planning" << "My First Activity"; // wait until the system has settled down // yep, hack, but needed to prevent race conditions when nepomuk is no up yet :/ if (Nepomuk::Query::QueryServiceClient::serviceAvailable()) { QTimer::singleShot(5000, this, SLOT(init())); } else { m_queryServiceWatcher = new QDBusServiceWatcher(QLatin1String("org.kde.nepomuk.services.nepomukqueryservice"), QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this); connect(m_queryServiceWatcher, SIGNAL(serviceRegistered(QString)), this, SLOT(serviceRegistered(QString))); } } void FirstRun::serviceRegistered(const QString &service) { if (service == "org.kde.nepomuk.services.nepomukqueryservice") { init(); } } void FirstRun::init() { KConfig* scfg = new KConfig("active-firstrunrc"); KConfigGroup grp = scfg->group("general"); bool hasRun = grp.readEntry("hasRun", false); delete scfg; kError() << "Starting first run ..." << !hasRun; if (!hasRun) { m_activityController = new KActivities::Controller(this); m_currentActivity = m_activityController->currentActivity(); QStringList activities = m_activityController->listActivities(); foreach (const QString &id, activities) { activityAdded(id); } connect(m_activityController, SIGNAL(activityAdded(QString)), this, SLOT(activityAdded(QString))); } else { kError() << "Already ran, doing nothing"; emit done(); } } FirstRun::~FirstRun() { } void FirstRun::activityAdded(const QString& source) { KActivities::Info* info = new KActivities::Info(source); kError() << "------> Source added: " << info->name() << source; - // Check if it's among the default activities and wether we've configured this actity already + // Check if it's among the default activities and whether we've configured this actity already if (!m_initialActivities.contains(info->name())) { //kError() << "noinit"; return; } if (m_completedActivities.contains(info->name())) { //kError() << "completed"; return; } m_completedActivities << info->name(); kError() << "------> Source added: " << info->name() << source; QString appPath = "/usr/share/applications/kde4/"; //kError() << "AAA: " << info->name(); if (info->name() == "Introduction") { // Bookmarks connectToActivity(source, "http://www.plasma-active.org", "Plasma Active"); connectToActivity(source, "http://community.kde.org/Plasma/Active/Info/FAQ", "FAQ"); connectToActivity(source, appPath + "adjust-time.desktop"); } else if (info->name() == "My First Activity") { // leaving it empty to invite creativity } else if (info->name() == "Vacation Planning") { // Bookmarks connectToActivity(source, "http://www.deutschebahn.com", "Deutsche Bahn"); connectToActivity(source, "http://wikitravel.org/en/Berlin", "Berlin Travel Guide"); connectToActivity(source, "http://osm.org/go/0MbEYhO8-", "OpenStreetMap Berlin"); // Apps connectToActivity(source, appPath + "active-image-viewer.desktop"); connectToActivity(source, appPath + "kwrite.desktop"); connectToActivity(source, appPath + "korganizer-mobile.desktop"); } if (m_completedActivities.size() == m_initialActivities.size()) { markDone(); kError() << "All done. Quitting."; emit done(); } } void FirstRun::connectToActivity(const QString &activityId, const QString &resourceUrl, const QString &description) { Nepomuk::Resource fileRes(resourceUrl); QUrl typeUrl; //Bookmark? if (QUrl(resourceUrl).scheme() == "http") { typeUrl = QUrl("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Bookmark"); fileRes.addType(typeUrl); fileRes.setDescription(description); fileRes.setProperty(QUrl::fromEncoded("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#bookmarks"), resourceUrl); // App? } else if (resourceUrl.endsWith(".desktop")) { typeUrl = QUrl("http://www.semanticdesktop.org/ontologies/2007/03/22/nfo#Application"); fileRes.addType(typeUrl); KService::Ptr service = KService::serviceByDesktopPath(QUrl(resourceUrl).path()); if (service) { fileRes.setLabel(service->name()); fileRes.setSymbols(QStringList() << service->icon()); } } kError() << " Added resource " << description << " to " << activityId; Nepomuk::Resource acRes(activityId, Nepomuk::Vocabulary::KAO::Activity()); acRes.addProperty(Soprano::Vocabulary::NAO::isRelated(), fileRes); } void FirstRun::markDone() { kError() << "Noting in kconfig that we've run once."; KConfig* scfg = new KConfig("active-firstrunrc"); KConfigGroup grp = scfg->group("general"); grp.writeEntry("hasRun", true); scfg->sync(); delete scfg; } #include "firstrun.moc" diff --git a/shell/mobcorona.cpp b/shell/mobcorona.cpp index 4f06139c..91311897 100644 --- a/shell/mobcorona.cpp +++ b/shell/mobcorona.cpp @@ -1,454 +1,454 @@ /*************************************************************************** * Copyright 2006-2008 Aaron Seigo * * Copyright 2009 Marco Martin * * Copyright 2010 Alexis Menard * * Copyright 2010 Artur Duque de Souza * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, 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 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 "mobcorona.h" #include "mobdialogmanager.h" #include "activity.h" #include "kao.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "plasmaapp.h" #include "mobview.h" #include #include #include #include #include #include #include static const char *DEFAUL_CONTAINMENT = "org.kde.active.activityscreen"; MobCorona::MobCorona(QObject *parent) : Plasma::Corona(parent), m_activityController(new KActivities::Controller(this)), m_package(0) { init(); } MobCorona::~MobCorona() { KConfigGroup cg(config(), "SavedContainments"); //stop everything, in order to restore them just on demand at next boot const QString currentActivity = m_activityController->currentActivity(); QHash::const_iterator i = m_activities.constBegin(); while (i != m_activities.constEnd()) { QString file = "activities/"+i.key(); KConfig external(file, KConfig::SimpleConfig, "appdata"); //copy the old config to the new location i.value()->save(external); if (i.key() != currentActivity) { i.value()->close(); } ++i; } //get rid of containments and their config groups foreach (Plasma::Containment *cont, containments()) { if (cont->context()->currentActivityId() != currentActivity && cont->formFactor() == Plasma::Planar) { cont->config().deleteGroup(); cont->destroy(false); } } } void MobCorona::init() { QString homeScreenPath = KGlobal::mainComponent().componentName() + "-homescreen"; KConfigGroup globalConfig(KGlobal::config(), "General"); homeScreenPath = globalConfig.readEntry("HomeScreenPackage", "org.kde.active.contour-tablet-homescreen"); kDebug()<<"Searching for the home screen"<isValid()) { kWarning()<<"Invalid home screen package:"<filePath("config", "plasma-default-layoutrc"); //kDebug() << "============================================================================"; //kDebug() << "layout HSP:" << homeScreenPath; //kDebug() << "layout RC :" << layoutRc; //kDebug() << "layout CFG:" << defaultConfig; if (!defaultConfig.isEmpty()) { kDebug() << "attempting to load the default layout from:" << defaultConfig; return KConfigGroup(new KConfig(defaultConfig), QString()); } kWarning() << "Invalid layout, could not locate plasma-default-layoutrc"; return KConfigGroup(); } void MobCorona::loadDefaultLayout() { KConfigGroup cg = defaultConfig(); if (cg.isValid()) { importLayout(cg); return; } kWarning() << "Invalid layout, could not locate plasma-default-layoutrc"; // FIXME: need to load the Mobile-specific containment // passing in an empty string will get us whatever the default // containment type is! Plasma::Containment* c = addContainmentDelayed(QString()); if (!c) { return; } c->init(); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); bool isDesktop = args->isSet("desktop"); if (isDesktop) { c->setScreen(0); } c->setWallpaper("image", "SingleImage"); c->setFormFactor(Plasma::Planar); c->updateConstraints(Plasma::StartupCompletedConstraint); c->flushPendingConstraintsEvents(); //cg is invalid here c->save(cg); // stacks all the containments at the same place c->setPos(0, 0); emit containmentAdded(c); requestConfigSync(); } void MobCorona::layoutContainments() { - // we dont need any layout for this as we are going to bind the position + // we don't need any layout for this as we are going to bind the position // of the containments to QML items to animate them. As soon as we don't // need the containment anymore we can just let it stay wherever it is as // long as it's offscreen (the view is not 'looking' at it). // As this method is called from containments resize event and itemChange // if we let the default implementation work here we could have bad surprises // of containments appearing in the view when putting them in the default // grid-like layout. return; } Plasma::Applet *MobCorona::loadDefaultApplet(const QString &pluginName, Plasma::Containment *c) { QVariantList args; Plasma::Applet *applet = Plasma::Applet::load(pluginName, 0, args); if (applet) { c->addApplet(applet); } return applet; } Plasma::Containment *MobCorona::findFreeContainment() const { foreach (Plasma::Containment *cont, containments()) { if ((cont->containmentType() == Plasma::Containment::DesktopContainment || cont->containmentType() == Plasma::Containment::CustomContainment) && cont->screen() == -1 && !offscreenWidgets().contains(cont)) { return cont; } } return 0; } int MobCorona::numScreens() const { return QApplication::desktop()->screenCount(); } void MobCorona::setScreenGeometry(const QRect &geometry) { m_screenGeometry = geometry; } QRect MobCorona::screenGeometry(int id) const { Q_UNUSED(id) return m_screenGeometry; } void MobCorona::setAvailableScreenRegion(const QRegion &r) { m_availableScreenRegion = r; emit availableScreenRegionChanged(); } QRegion MobCorona::availableScreenRegion(int id) const { QRegion r(screenGeometry(id)); return m_availableScreenRegion; foreach (Plasma::Containment *cont, PlasmaApp::self()->panelContainments()) { if (cont->location() == Plasma::TopEdge || cont->location() == Plasma::BottomEdge || cont->location() == Plasma::LeftEdge || cont->location() == Plasma::RightEdge) { r = r.subtracted(cont->mapToScene(cont->boundingRect()).toPolygon()); } } return r; } void MobCorona::currentActivityChanged(const QString &newActivity) { if (newActivity.isEmpty()) { return; } kDebug() << newActivity; Activity *act =activity(newActivity); if (act) { act->ensureActive(); } } Activity* MobCorona::activity(const QString &id) { if (!m_activities.contains(id)) { //the add signal comes late sometimes activityAdded(id); } return m_activities.value(id); } void MobCorona::activityAdded(const QString &id) { //TODO more sanity checks if (m_activities.contains(id)) { kDebug() << "you're late." << id; return; } Activity *a = new Activity(id, this); if (a->isCurrent()) { a->ensureActive(); } m_activities.insert(id, a); } void MobCorona::activityRemoved(const QString &id) { Activity *a = m_activities.take(id); a->deleteLater(); } void MobCorona::activateNextActivity() { QStringList list = m_activityController->listActivities(KActivities::Info::Running); if (list.isEmpty()) { return; } //FIXME: if the current activity is in transition the "next" will be the first int start = list.indexOf(m_activityController->currentActivity()); int i = (start + 1) % list.size(); m_activityController->setCurrentActivity(list.at(i)); } void MobCorona::activatePreviousActivity() { QStringList list = m_activityController->listActivities(KActivities::Info::Running); if (list.isEmpty()) { return; } //FIXME: if the current activity is in transition the "previous" will be the last int start = list.indexOf(m_activityController->currentActivity()); //fun fact: in c++, (-1 % foo) == -1 int i = start - 1; if (i < 0) { i = list.size() - 1; } m_activityController->setCurrentActivity(list.at(i)); } void MobCorona::checkActivities() { kDebug() << "containments to start with" << containments().count(); KActivities::Consumer::ServiceStatus status = m_activityController->serviceStatus(); //kDebug() << "$%$%$#%$%$%Status:" << status; if (status == KActivities::Consumer::NotRunning) { //panic and give up - better than causing a mess kDebug() << "No ActivityManager? Help, I've fallen and I can't get up!"; return; } QStringList existingActivities = m_activityController->listActivities(); foreach (const QString &id, existingActivities) { //ensure the activity resource exists //FIXME: shouldn't be done here Nepomuk::Resource activityResource(id, Nepomuk::Vocabulary::KAO::Activity()); activityResource.setProperty(Nepomuk::Vocabulary::KAO::activityIdentifier(), id); activityAdded(id); } QStringList newActivities; QString newCurrentActivity; //migration checks: //-containments with an invalid id are deleted. //-containments that claim they were on a screen are kept together, and are preferred if we //need to initialize the current activity. //-containments that don't know where they were or who they were with just get made into their //own activity. foreach (Plasma::Containment *cont, containments()) { bool excludeFromActivities = cont->config().readEntry("excludeFromActivities", false); if (!excludeFromActivities && (cont->containmentType() == Plasma::Containment::DesktopContainment || cont->containmentType() == Plasma::Containment::CustomContainment) && !offscreenWidgets().contains(cont)) { Plasma::Context *context = cont->context(); QString oldId = context->currentActivityId(); if (!oldId.isEmpty()) { if (existingActivities.contains(oldId)) { continue; //it's already claimed } kDebug() << "invalid id" << oldId; //byebye cont->destroy(false); continue; } if (cont->screen() > -1) { //it belongs on the current activity if (!newCurrentActivity.isEmpty()) { context->setCurrentActivityId(newCurrentActivity); continue; } } //discourage blank names if (context->currentActivity().isEmpty()) { context->setCurrentActivity(i18nc("Default name for a new activity", "New Activity")); } //create a new activity for the containment QString id = m_activityController->addActivity(context->currentActivity()); context->setCurrentActivityId(id); newActivities << id; if (cont->screen() > -1) { newCurrentActivity = id; } kDebug() << "migrated" << context->currentActivityId() << context->currentActivity(); QString activityIcon = cont->config().readEntry("activityIcon", QString()); if (!activityIcon.isEmpty()) { m_activityController->setActivityIcon(id, activityIcon); } } } kDebug() << "migrated?" << !newActivities.isEmpty() << containments().count(); if (!newActivities.isEmpty()) { requestConfigSync(); } //init the newbies foreach (const QString &id, newActivities) { activityAdded(id); } //ensure the current activity is initialized if (m_activityController->currentActivity().isEmpty()) { kDebug() << "guessing at current activity"; if (existingActivities.isEmpty()) { if (newCurrentActivity.isEmpty()) { if (newActivities.isEmpty()) { kDebug() << "no activities!?! Bad activitymanager, no cookie!"; QString id = m_activityController->addActivity(i18nc("Default name for a new activity", "New Activity")); activityAdded(id); m_activityController->setCurrentActivity(id); kDebug() << "created emergency activity" << id; } else { m_activityController->setCurrentActivity(newActivities.first()); } } else { m_activityController->setCurrentActivity(newCurrentActivity); } } else { m_activityController->setCurrentActivity(existingActivities.first()); } } } Plasma::Package *MobCorona::homeScreenPackage() const { return m_package; } #include "mobcorona.moc"