diff --git a/declarativeimports/core/datamodel.cpp b/declarativeimports/core/datamodel.cpp index 0b260af4f..e4a2e0213 100644 --- a/declarativeimports/core/datamodel.cpp +++ b/declarativeimports/core/datamodel.cpp @@ -123,6 +123,18 @@ void SortFilterModel::setSortOrder(const Qt::SortOrder order) sort(0, order); } +QVariantHash SortFilterModel::get(int row) const +{ + QModelIndex idx = index(row, 0); + QVariantHash hash; + + QHash::const_iterator i; + for (i = roleNames().constBegin(); i != roleNames().constEnd(); ++i) { + hash[i.value()] = data(idx, i.key()); + } + + return hash; +} @@ -423,6 +435,19 @@ int DataModel::columnCount(const QModelIndex &parent) const return 1; } +QVariantHash DataModel::get(int row) const +{ + QModelIndex idx = index(row, 0); + QVariantHash hash; + + QHash::const_iterator i; + for (i = roleNames().constBegin(); i != roleNames().constEnd(); ++i) { + hash[i.value()] = data(idx, i.key()); + } + + return hash; +} + int DataModel::roleNameToId(const QString &name) { if (!m_roleIds.contains(name)) { diff --git a/declarativeimports/core/datamodel.h b/declarativeimports/core/datamodel.h index 744ec9e93..719500061 100644 --- a/declarativeimports/core/datamodel.h +++ b/declarativeimports/core/datamodel.h @@ -68,6 +68,8 @@ public: int count() const {return QSortFilterProxyModel::rowCount();} + Q_INVOKABLE QVariantHash get(int i) const; + Q_SIGNALS: void countChanged(); @@ -124,6 +126,8 @@ public: int count() const {return countItems();} + Q_INVOKABLE QVariantHash get(int i) const; + protected: void setItems(const QString &sourceName, const QVariantList &list); inline int countItems() const; diff --git a/declarativeimports/core/datasource.cpp b/declarativeimports/core/datasource.cpp index b29158809..b9f74a285 100644 --- a/declarativeimports/core/datasource.cpp +++ b/declarativeimports/core/datasource.cpp @@ -110,11 +110,22 @@ void DataSource::setupData() finishedWithEngine(m_dataEngine->pluginName()); } + /* + * It is due little explanation why this is a queued connection: + * If sourceAdded arrives immediately, in the case we have a datamodel + * with items at source level we connect too soon (before setData for + * all roles is done), having a dataupdated in the datamodel with only + * the first role, killing off the other roles. + * Besides causing a model reset more, unfortunately setRoleNames can be done a single time, so is not possible adding new roles after the + * first setRoleNames() is called. + * This fixes engines that have 1 item per source like the + * recommendations engine. + */ m_dataEngine = engine; - connect(m_dataEngine, SIGNAL(sourceAdded(const QString&)), this, SIGNAL(sourcesChanged())); + connect(m_dataEngine, SIGNAL(sourceAdded(const QString&)), this, SIGNAL(sourcesChanged()), Qt::QueuedConnection); connect(m_dataEngine, SIGNAL(sourceRemoved(const QString&)), this, SIGNAL(sourcesChanged())); - connect(m_dataEngine, SIGNAL(sourceAdded(const QString&)), this, SIGNAL(sourceAdded(const QString&))); + connect(m_dataEngine, SIGNAL(sourceAdded(const QString&)), this, SIGNAL(sourceAdded(const QString&)), Qt::QueuedConnection); connect(m_dataEngine, SIGNAL(sourceRemoved(const QString&)), this, SLOT(removeSource(const QString&))); connect(m_dataEngine, SIGNAL(sourceRemoved(const QString&)), this, SIGNAL(sourceRemoved(const QString&))); } diff --git a/declarativeimports/core/declarativeitemcontainer.cpp b/declarativeimports/core/declarativeitemcontainer.cpp index 4d5ed88e1..ef0eb77d0 100644 --- a/declarativeimports/core/declarativeitemcontainer.cpp +++ b/declarativeimports/core/declarativeitemcontainer.cpp @@ -59,6 +59,11 @@ void DeclarativeItemContainer::resizeEvent(QGraphicsSceneResizeEvent *event) } } +void DeclarativeItemContainer::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + event->ignore(); +} + void DeclarativeItemContainer::widthChanged() { if (!m_declarativeItem) { diff --git a/declarativeimports/core/declarativeitemcontainer_p.h b/declarativeimports/core/declarativeitemcontainer_p.h index a92ce19bb..d900fff94 100644 --- a/declarativeimports/core/declarativeitemcontainer_p.h +++ b/declarativeimports/core/declarativeitemcontainer_p.h @@ -39,6 +39,7 @@ public: protected: void resizeEvent(QGraphicsSceneResizeEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *event); protected Q_SLOTS: void widthChanged(); diff --git a/declarativeimports/core/dialog.cpp b/declarativeimports/core/dialog.cpp index 57e9adecd..7327503cf 100644 --- a/declarativeimports/core/dialog.cpp +++ b/declarativeimports/core/dialog.cpp @@ -135,6 +135,11 @@ void DialogProxy::syncMainItem() return; } + if (static_cast(m_dialog->graphicsWidget()) == m_mainItem.data() || + (m_declarativeItemContainer && m_declarativeItemContainer->declarativeItem() == m_mainItem.data())) { + return; + } + //not have a scene? go up in the hyerarchy until we find something with a scene QGraphicsScene *scene = m_mainItem.data()->scene(); if (!scene) { @@ -178,8 +183,8 @@ void DialogProxy::syncMainItem() m_dialog->setGraphicsWidget(widget); if (!qobject_cast(scene)) { - offscreenX -= 1024; - offscreenY -= 1024; + offscreenX -= 10000; + offscreenY -= 10000; widget->setPos(offscreenX, offscreenY); } } @@ -194,7 +199,6 @@ void DialogProxy::setVisible(const bool visible) if (m_dialog->isVisible() != visible) { m_dialog->setVisible(visible); if (visible) { - m_dialog->setWindowFlags(m_flags); m_dialog->setVisible(visible); m_dialog->raise(); } @@ -332,15 +336,29 @@ bool DialogProxy::isActiveWindow() const return m_activeWindow; } +void DialogProxy::activateWindow() +{ + m_dialog->activateWindow(); +} + int DialogProxy::windowFlags() const { - return (int)m_dialog->windowFlags(); + return (int)m_flags; } void DialogProxy::setWindowFlags(const int flags) { - m_flags = (Qt::WindowFlags)flags; - m_dialog->setWindowFlags((Qt::WindowFlags)flags); + /*X misbehaviour: the only way to make a window with the Popup flag working, is to create it with that flag from the beginning*/ + if (((Qt::WindowFlags)flags & Qt::Popup) != (m_flags & Qt::Popup)) { + delete m_dialog; + m_flags = (Qt::WindowFlags)flags; + m_dialog = new Plasma::Dialog(0, Qt::FramelessWindowHint|m_flags); + m_margins = new DialogMargins(m_dialog, this); + m_dialog->installEventFilter(this); + } else { + m_flags = (Qt::WindowFlags)flags; + m_dialog->setWindowFlags(Qt::FramelessWindowHint|m_flags); + } } int DialogProxy::location() const diff --git a/declarativeimports/core/dialog.h b/declarativeimports/core/dialog.h index 5e307bea3..50158a45c 100644 --- a/declarativeimports/core/dialog.h +++ b/declarativeimports/core/dialog.h @@ -110,6 +110,8 @@ public: bool isActiveWindow() const; + Q_INVOKABLE void activateWindow(); + //FIXME: passing an int is ugly int windowFlags() const; void setWindowFlags(const int); diff --git a/declarativeimports/core/tooltip.cpp b/declarativeimports/core/tooltip.cpp index 4eaa5b8fc..9f5836c79 100644 --- a/declarativeimports/core/tooltip.cpp +++ b/declarativeimports/core/tooltip.cpp @@ -92,12 +92,12 @@ void ToolTipProxy::syncTarget() return; } - if (!m_declarativeItemContainer) { - m_declarativeItemContainer = QWeakPointer(new DeclarativeItemContainer()); + if (!m_declarativeItemContainer && scene) { + m_declarativeItemContainer = QWeakPointer(new DeclarativeItemContainer()); m_declarativeItemContainer.data()->setObjectName("DIContainer"); scene->addItem(m_declarativeItemContainer.data()); - } - + } + if (m_declarativeItemContainer) { m_target.data()->setObjectName("Original Item"); m_declarativeItemContainer.data()->setDeclarativeItem(item, false); @@ -105,7 +105,7 @@ void ToolTipProxy::syncTarget() m_declarativeItemContainer.data()->setParentItem(m_target.data()); m_widget = m_declarativeItemContainer.data(); emit targetChanged(); - } + } } QString ToolTipProxy::mainText() const @@ -163,7 +163,12 @@ void ToolTipProxy::updateToolTip() Plasma::ToolTipContent data; data.setMainText(m_mainText); data.setSubText(m_subText); - data.setImage(KIcon(m_image).pixmap(IconSize(KIconLoader::Desktop))); + if (!m_image.isEmpty()) { + KIcon icon(m_image); + if (!icon.isNull()) { + data.setImage(icon.pixmap(IconSize(KIconLoader::Desktop))); + } + } Plasma::ToolTipManager::self()->setContent(m_widget, data); } diff --git a/declarativeimports/draganddrop/CMakeLists.txt b/declarativeimports/draganddrop/CMakeLists.txt index 5450873c7..d9a3813b0 100644 --- a/declarativeimports/draganddrop/CMakeLists.txt +++ b/declarativeimports/draganddrop/CMakeLists.txt @@ -19,9 +19,9 @@ INCLUDE_DIRECTORIES( qt4_automoc(${declarativedragdrop_SRCS}) -kde4_add_library(dragdropplugin SHARED ${declarativedragdrop_SRCS}) -target_link_libraries(dragdropplugin ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) +kde4_add_library(draganddropplugin SHARED ${declarativedragdrop_SRCS}) +target_link_libraries(draganddropplugin ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) -install(TARGETS dragdropplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/draganddrop) +install(TARGETS draganddropplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/draganddrop) install(FILES qmldir DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/draganddrop) diff --git a/declarativeimports/draganddrop/DeclarativeDragArea.cpp b/declarativeimports/draganddrop/DeclarativeDragArea.cpp index 93943e609..7af74414c 100644 --- a/declarativeimports/draganddrop/DeclarativeDragArea.cpp +++ b/declarativeimports/draganddrop/DeclarativeDragArea.cpp @@ -46,6 +46,7 @@ DeclarativeDragArea::DeclarativeDragArea(QDeclarativeItem *parent) m_data(new DeclarativeMimeData()) // m_data is owned by us, and we shouldn't pass it to Qt directly as it will automatically delete it after the drag and drop. { setAcceptedMouseButtons(Qt::LeftButton); + setFiltersChildEvents(true); } DeclarativeDragArea::~DeclarativeDragArea() @@ -103,7 +104,7 @@ QDeclarativeItem* DeclarativeDragArea::target() const } // data -DeclarativeMimeData* DeclarativeDragArea::data() const +DeclarativeMimeData* DeclarativeDragArea::mimeData() const { return m_data; } @@ -184,3 +185,18 @@ void DeclarativeDragArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) Qt::DropAction action = drag->exec(m_supportedActions, m_defaultAction); emit drop(action); } + + +bool DeclarativeDragArea::sceneEventFilter(QGraphicsItem *item, QEvent *event) +{ + if (!isEnabled()) { + return false; + } + + if (event->type() == QEvent::GraphicsSceneMouseMove) { + QGraphicsSceneMouseEvent *me = static_cast(event); + mouseMoveEvent(me); + } + + return QDeclarativeItem::sceneEventFilter(item, event); +} \ No newline at end of file diff --git a/declarativeimports/draganddrop/DeclarativeDragArea.h b/declarativeimports/draganddrop/DeclarativeDragArea.h index f2f638c14..c25b96ab8 100644 --- a/declarativeimports/draganddrop/DeclarativeDragArea.h +++ b/declarativeimports/draganddrop/DeclarativeDragArea.h @@ -35,7 +35,7 @@ class DeclarativeDragArea : public QDeclarativeItem Q_PROPERTY(QDeclarativeComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged RESET resetDelegate) Q_PROPERTY(QDeclarativeItem* source READ source WRITE setSource NOTIFY sourceChanged RESET resetSource) Q_PROPERTY(QDeclarativeItem* target READ source NOTIFY targetChanged) - Q_PROPERTY(DeclarativeMimeData* data READ data CONSTANT) + Q_PROPERTY(DeclarativeMimeData* mimeData READ mimeData CONSTANT) Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) //TODO: Should call setAcceptDrops() Q_PROPERTY(Qt::DropActions supportedActions READ supportedActions WRITE setSupportedActions NOTIFY supportedActionsChanged) Q_PROPERTY(Qt::DropAction defaultAction READ defaultAction WRITE setDefaultAction NOTIFY defaultActionChanged) @@ -65,7 +65,7 @@ public: Qt::DropAction defaultAction() const; void setDefaultAction(Qt::DropAction action); - DeclarativeMimeData* data() const; + DeclarativeMimeData* mimeData() const; signals: void delegateChanged(); @@ -81,6 +81,7 @@ protected: void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mousePressEvent(QGraphicsSceneMouseEvent *) {} void mouseReleaseEvent(QGraphicsSceneMouseEvent *) {} + bool sceneEventFilter(QGraphicsItem *item, QEvent *event); private: QDeclarativeComponent* m_delegate; diff --git a/declarativeimports/draganddrop/DeclarativeDragDropEvent.h b/declarativeimports/draganddrop/DeclarativeDragDropEvent.h index 824650541..e84876d2b 100644 --- a/declarativeimports/draganddrop/DeclarativeDragDropEvent.h +++ b/declarativeimports/draganddrop/DeclarativeDragDropEvent.h @@ -35,7 +35,7 @@ class DeclarativeDragDropEvent : public QObject Q_PROPERTY(int y READ y) Q_PROPERTY(int buttons READ buttons) Q_PROPERTY(int modifiers READ modifiers) - Q_PROPERTY(DeclarativeMimeData* data READ data) + Q_PROPERTY(DeclarativeMimeData* mimeData READ mimeData) Q_PROPERTY(Qt::DropActions possibleActions READ possibleActions) Q_PROPERTY(Qt::DropAction proposedAction READ proposedAction) @@ -47,7 +47,7 @@ public: int y() const { return m_y; } int buttons() const { return m_buttons; } int modifiers() const { return m_modifiers; } - DeclarativeMimeData* data() { return &m_data; } + DeclarativeMimeData* mimeData() { return &m_data; } Qt::DropAction proposedAction() const { return m_event->proposedAction(); } Qt::DropActions possibleActions() const { return m_event->possibleActions(); } diff --git a/declarativeimports/draganddrop/DeclarativeMimeData.cpp b/declarativeimports/draganddrop/DeclarativeMimeData.cpp index 09dbef02d..2b2659786 100644 --- a/declarativeimports/draganddrop/DeclarativeMimeData.cpp +++ b/declarativeimports/draganddrop/DeclarativeMimeData.cpp @@ -68,7 +68,7 @@ DeclarativeMimeData::DeclarativeMimeData(const QMimeData* copy) QUrl DeclarativeMimeData::url() const { if ( this->hasUrls() && !this->urls().isEmpty()) { - return urls().first(); + return QMimeData::urls().first(); } return QUrl(); } @@ -79,10 +79,29 @@ void DeclarativeMimeData::setUrl(const QUrl &url) QList urlList; urlList.append(url); - setUrls(urlList); + QMimeData::setUrls(urlList); emit urlChanged(); } +QVariantList DeclarativeMimeData::urls() const +{ + QVariantList varUrls; + foreach (const QUrl &url, QMimeData::urls()) { + varUrls << url; + } + return varUrls; +} + +void DeclarativeMimeData::setUrls(const QVariantList &urls) +{ + QList urlList; + foreach (const QVariant &varUrl, urls) { + urlList << varUrl.value(); + } + QMimeData::setUrls(urlList); + emit urlsChanged(); +} + // color QColor DeclarativeMimeData::color() const { diff --git a/declarativeimports/draganddrop/DeclarativeMimeData.h b/declarativeimports/draganddrop/DeclarativeMimeData.h index 1c9b1cd5b..e919584a9 100644 --- a/declarativeimports/draganddrop/DeclarativeMimeData.h +++ b/declarativeimports/draganddrop/DeclarativeMimeData.h @@ -35,7 +35,8 @@ class DeclarativeMimeData : public QMimeData Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) Q_PROPERTY(QString html READ html WRITE setHtml NOTIFY htmlChanged) - Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) //TODO: use QDeclarativeListProperty to return the whole list instead of only the first url + Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) + Q_PROPERTY(QVariantList urls READ urls WRITE setUrls NOTIFY urlsChanged) Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) Q_PROPERTY(QDeclarativeItem* source READ source WRITE setSource NOTIFY sourceChanged) //TODO: Image property @@ -47,12 +48,16 @@ public: QUrl url() const; void setUrl(const QUrl &url); + QVariantList urls() const; + void setUrls(const QVariantList &urls); + QColor color() const; void setColor(const QColor &color); QDeclarativeItem* source() const; void setSource(QDeclarativeItem* source); + /* QString text() const; //TODO: Reimplement this to issue the onChanged signals void setText(const QString &text); @@ -64,12 +69,12 @@ signals: void textChanged(); //FIXME not being used void htmlChanged(); //FIXME not being used void urlChanged(); + void urlsChanged(); void colorChanged(); void sourceChanged(); private: - QDeclarativeItem* m_source; - + QDeclarativeItem* m_source; }; #endif // DECLARATIVEMIMEDATA_H diff --git a/declarativeimports/plasmacomponents/CMakeLists.txt b/declarativeimports/plasmacomponents/CMakeLists.txt index f855e3b3e..8af2dfad3 100644 --- a/declarativeimports/plasmacomponents/CMakeLists.txt +++ b/declarativeimports/plasmacomponents/CMakeLists.txt @@ -28,8 +28,46 @@ install(DIRECTORY qml/ DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/compone #The platform specific stuff, overwrites a copy of the desktop one -#it does install some files on top of the old ones, it's pretty hackyu but it's intended since there are no more elegant ways to produce a fallback during a qml import from the most specific files to the general ones if specific were not found +#it does install some files on top of the old ones, has to be done file by file since if some component from the generic set is more recent than the specifc ones, it wouldn't be overwritten install(TARGETS plasmacomponentsplugin DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) -install(DIRECTORY qml/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) + + +install(FILES qml/AppManager.js DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/BusyIndicator.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ButtonColumn.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ButtonGroup.js DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/Button.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ButtonRow.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/CheckBox.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/CommonDialog.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/Dialog.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/DualStateButton.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/Highlight.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/IconLoader.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/Label.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ListItem.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/Page.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/PageStack.js DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/PageStack.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ProgressBar.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/RadioButton.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ScrollBarDelegate.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ScrollDecoratorDelegate.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/SectionScroller.js DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/SelectionDialog.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/Slider.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/Switch.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/TabBarLayout.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/TabBar.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/TabButton.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/TabGroup.js DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/TabGroup.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/TextArea.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/TextField.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ToolBarLayout.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) +install(FILES qml/ToolBar.qml DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) + + +#install platform overrides install(DIRECTORY platformcomponents/touch/ DESTINATION ${PLUGIN_INSTALL_DIR}/platformimports/touch/org/kde/plasma/components) diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/Dialog.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/Dialog.qml new file mode 100644 index 000000000..f81ca6b5f --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/Dialog.qml @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Marco Martin +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.0 +import org.kde.plasma.core 0.1 as PlasmaCore +import "AppManager.js" as Utils +import "." 0.1 + +Item { + id: root + + property alias title: titleBar.children + property alias content: contentItem.children + property alias buttons: buttonItem.children +// property alias visualParent: dialog.visualParent + property int status: DialogStatus.Closed + + + property alias privateTitleHeight: titleBar.height + property alias privateButtonsHeight: buttonItem.height + + signal accepted + signal rejected + signal clickedOutside + + function open() + { + var pos = dialog.popupPosition(null, Qt.alignCenter) + dialog.x = pos.x + dialog.y = pos.y + + dialog.visible = true + dialog.activateWindow() + } + + function accept() + { + if (status == DialogStatus.Open) { + dialog.visible = false + accepted() + } + } + + function reject() { + if (status == DialogStatus.Open) { + dialog.visible = false + rejected() + } + } + + function close() { + dialog.visible = false + } + + visible: false + + PlasmaCore.Dialog { + id: dialog + windowFlags: Qt.Dialog + + //onFaderClicked: root.clickedOutside() + property Item rootItem + + //state: "Hidden" + visible: false + onVisibleChanged: { + if (visible) { + status = DialogStatus.Open + } else { + status = DialogStatus.Closed + } + } + onActiveWindowChanged: if (!activeWindow) dialog.visible = false + + mainItem: Item { + id: mainItem + width: theme.defaultFont.mSize.width * 40 + height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonItem.childrenRect.height + 8 + + // Consume all key events that are not processed by children + Keys.onPressed: event.accepted = true + Keys.onReleased: event.accepted = true + + Item { + id: titleBar + + height: childrenRect.height + anchors { + top: parent.top + left: parent.left + right: parent.right + } + } + + Item { + id: contentItem + + clip: true + onChildrenRectChanged: mainItem.width = Math.max(childrenRect.width, buttonItem.childrenRect.width) + anchors { + top: titleBar.bottom + left: parent.left + right: parent.right + bottom: buttonItem.top + } + } + + Item { + id: buttonItem + + height: childrenRect.height + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + bottomMargin: 8 + } + } + } + + Component.onCompleted: { + rootItem = Utils.rootObject() + } + } +} diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml index b60c7c037..995404668 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/Menu.qml @@ -36,7 +36,7 @@ Item { dialog.y = pos.y dialog.visible = true - dialog.focus = true + dialog.activateWindow() } function close() diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml index 0db1406f7..6969fde33 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/SectionScroller.qml @@ -151,11 +151,6 @@ Item { } sectionLabel.text = Sections.closestSection(y/listView.height) } - Behavior on y { - NumberAnimation { - duration: 150 - } - } } PlasmaCore.FrameSvgItem { imagePath: "widgets/tooltip" @@ -163,7 +158,7 @@ Item { height: sectionLabel.paintedHeight + margins.top + margins.bottom Label { id: sectionLabel - font.pointSize: theme.defaultFont.pointSize*3 + font.pointSize: theme.defaultFont.pointSize * 1.5 x: parent.margins.left y: parent.margins.top } @@ -179,18 +174,11 @@ Item { } } } - /*Repeater { - id: sectionsRepeater - delegate: Label { - anchors.horizontalCenter: parent.horizontalCenter - text: Sections._sections[modelData] - y: Sections._sectionData[modelData].index*(listView.height/listView.model.count) - } - }*/ + MouseArea { id: dragArea anchors.fill: parent - enabled: scrollbar.enabled + //enabled: scrollbar.enabled drag { target: handle axis: Drag.YAxis @@ -200,6 +188,7 @@ Item { onPressed: { mouse.accepted = true handle.y = mouse.y + fadeTimer.running = false } onReleased: fadeTimer.restart() @@ -231,8 +220,6 @@ Item { if (listView.model.itemsRemoved) listView.model.itemsRemoved.connect(dirtyObserver); - - sectionsRepeater.model = Sections._sections.length } } } diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/ToolButton.qml b/declarativeimports/plasmacomponents/platformcomponents/touch/ToolButton.qml new file mode 100644 index 000000000..ef66cfcea --- /dev/null +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/ToolButton.qml @@ -0,0 +1,232 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* Copyright (C) 2011 by 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.core 0.1 as PlasmaCore + +Item { + id: button + + // Commmon API + property bool flat: true + property bool checked: defaultAction ? defaultAction.checked : false + property bool checkable: defaultAction ? defaultAction.checkable : false + property alias pressed: mouse.pressed + property alias text: label.text + property alias iconSource: icon.source + property alias font: label.font + + signal clicked() + + // Plasma extensiuons + property QtObject defaultAction + + onFlatChanged: { + if (!flat) { + delegate.opacity = 1 + } + } + + enabled: defaultAction==undefined||defaultAction.enabled + + implicitWidth: { + if (label.paintedWidth == 0) { + return implicitHeight + } else { + return Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + delegate.margins.left + delegate.margins.right) + ((icon.valid) ? delegate.margins.left : 0) + } + } + implicitHeight: Math.max(theme.defaultFont.mSize.height*1.6, Math.max(icon.height, label.paintedHeight) + delegate.margins.top/2 + delegate.margins.bottom/2) + + // TODO: needs to define if there will be specific graphics for + // disabled buttons + opacity: enabled ? 1.0 : 0.5 + + Keys.onSpacePressed: internal.userPressed = true + Keys.onReturnPressed: internal.userPressed = true + Keys.onReleased: { + internal.userPressed = false + if (event.key == Qt.Key_Space || + event.key == Qt.Key_Return) + internal.clickButton() + } + + QtObject { + id: internal + property bool userPressed: false + + function clickButton() + { + if (!button.enabled) { + return + } + + if (defaultAction && defaultAction.checkable) { + defaultAction.checked = !defaultAction.checked + } else if (button.checkable) { + button.checked = !button.checked + } + + button.clicked() + button.forceActiveFocus() + + if (defaultAction) { + defaultAction.trigger() + } + } + } + + Loader { + id: delegate + anchors.fill:parent + property QtObject margins: item.margins + sourceComponent: { + if (label.paintedWidth == 0 && !flat) { + return roundButtonComponent + } else { + return buttonComponent + } + } + } + + Component { + id: buttonComponent + Item { + anchors.fill: parent + property alias margins: surface.margins + ButtonShadow { + id: shadow + anchors.fill: parent + visible: !flat + state: (internal.userPressed || checked) ? "hidden" : "shadow" + } + + PlasmaCore.FrameSvgItem { + id: surface + + anchors.fill: parent + imagePath: "widgets/button" + prefix: (internal.userPressed || checked) ? "pressed" : "normal" + //internal: if there is no hover status, don't paint on mouse over in touchscreens + opacity: (internal.userPressed || checked || !flat || (shadow.hasOverState && mouse.containsMouse)) ? 1 : 0 + Behavior on opacity { + PropertyAnimation { duration: 250 } + } + } + } + } + + Component { + id: roundButtonComponent + Item { + anchors.fill: parent + property QtObject margins: QtObject { + property int left: 8 + property int top: 8 + property int right: 8 + property int bottom: 8 + } + RoundShadow { + anchors.fill: parent + state: (internal.userPressed || checked) ? "hidden" : "shadow" + } + + PlasmaCore.Svg { + id: buttonSvg + imagePath: "widgets/actionbutton" + } + + PlasmaCore.SvgItem { + id: buttonItem + svg: buttonSvg + elementId: (internal.userPressed || checked) ? "pressed" : "normal" + width: parent.height + height: width + } + } + } + + Item { + anchors { + fill: parent + leftMargin: delegate.margins.left + topMargin: delegate.margins.top + rightMargin: delegate.margins.right + bottomMargin: delegate.margins.bottom + } + scale: internal.userPressed ? 0.9 : 1 + Behavior on scale { + PropertyAnimation { duration: 100 } + } + + IconLoader { + id: icon + + anchors { + verticalCenter: parent.verticalCenter + left: label.text ? parent.left : undefined + horizontalCenter: label.text ? undefined : parent.horizontalCenter + } + width: label.text ? implicitWidth : roundToStandardSize(parent.width) + height: width + } + + Text { + id: label + + //FIXME: why this is needed? + onPaintedWidthChanged: { + icon.anchors.horizontalCenter = label.paintedWidth > 0 ? undefined : icon.parent.horizontalCenter + icon.anchors.left = label.paintedWidth > 0 ? icon.parent.left : undefined + } + + anchors { + top: parent.top + bottom: parent.bottom + left: icon.valid ? icon.right : parent.left + right: parent.right + } + font.capitalization: theme.defaultFont.capitalization + font.family: theme.defaultFont.family + font.italic: theme.defaultFont.italic + font.letterSpacing: theme.defaultFont.letterSpacing + font.pointSize: theme.defaultFont.pointSize + font.strikeout: theme.defaultFont.strikeout + font.underline: theme.defaultFont.underline + font.weight: theme.defaultFont.weight + font.wordSpacing: theme.defaultFont.wordSpacing + color: theme.buttonTextColor + horizontalAlignment: icon.valid ? Text.AlignLeft : Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + MouseArea { + id: mouse + + anchors.fill: parent + hoverEnabled: true + + onPressed: internal.userPressed = true + onReleased: internal.userPressed = false + onClicked: internal.clickButton() + } +} + diff --git a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir index 27cf61792..d523958b8 100644 --- a/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir +++ b/declarativeimports/plasmacomponents/platformcomponents/touch/qmldir @@ -6,37 +6,32 @@ ButtonColumn 0.1 ButtonColumn.qml ButtonGroup 0.1 ButtonGroup.js ButtonRow 0.1 ButtonRow.qml CheckBox 0.1 CheckBox.qml -FlashingLabel 0.1 FlashingLabel.qml -Frame 0.1 Frame.qml +CommonDialog 0.1 CommonDialog.qml +ContextMenu 0.1 Menu.qml +Dialog 0.1 Dialog.qml Highlight 0.1 Highlight.qml -IconWidget 0.1 IconWidget.qml Label 0.1 Label.qml +ListItem 0.1 ListItem.qml +Menu 0.1 Menu.qml +MenuItem 0.1 MenuItem.qml +Page 0.1 Page.qml +PageStack 0.1 PageStack.qml ProgressBar 0.1 ProgressBar.qml PushButton 0.1 PushButton.qml +QueryDialog 0.1 QueryDialog.qml RadioButton 0.1 RadioButton.qml ScrollBar 0.1 ScrollBar.qml ScrollDecorator 0.1 ScrollDecorator.qml +SectionScroller 0.1 SectionScroller.qml +SelectionDialog 0.1 SelectionDialog.qml Slider 0.1 Slider.qml Switch 0.1 Switch.qml -TextArea 0.1 TextArea.qml -TextField 0.1 TextField.qml -ToolBar 0.1 ToolBar.qml -ToolButton 0.1 ToolButton.qml -ListItem 0.1 ListItem.qml - -CommonDialog 0.1 CommonDialog.qml -QueryDialog 0.1 QueryDialog.qml -SelectionDialog 0.1 SelectionDialog.qml -Window 0.1 Window.qml -ToolBarLayout 0.1 ToolBarLayout.qml -Menu 0.1 Menu.qml -ContextMenu 0.1 Menu.qml -MenuItem 0.1 MenuItem.qml - -Page 0.1 Page.qml -PageStack 0.1 PageStack.qml - TabBar 0.1 TabBar.qml TabButton 0.1 TabButton.qml TabGroup 0.1 TabGroup.qml -SectionScroller 0.1 SectionScroller.qml +TextArea 0.1 TextArea.qml +TextField 0.1 TextField.qml +ToolBar 0.1 ToolBar.qml +ToolBarLayout 0.1 ToolBarLayout.qml +ToolButton 0.1 ToolButton.qml +Window 0.1 Window.qml diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml index 23dd0d9bd..9dc1ea8f4 100644 --- a/declarativeimports/plasmacomponents/qml/Button.qml +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -19,6 +19,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + /**Documentanted API Inherits: Item @@ -66,7 +67,9 @@ Signals: onClicked: This handler is called when there is a click. **/ -import QtQuick 1.0 + +import QtQuick 1.1 + import org.kde.plasma.core 0.1 as PlasmaCore Item { @@ -82,14 +85,15 @@ Item { signal clicked() - width: { + implicitWidth: { if (label.paintedWidth == 0) { return height } else { + //return Math.max(theme.defaultFont.mSize.width*12, label.paintedWidth) return Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surfaceNormal.margins.left + surfaceNormal.margins.right) + ((icon.valid) ? surfaceNormal.margins.left : 0) } } - height: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top + surfaceNormal.margins.bottom) + implicitHeight: Math.max(theme.defaultFont.mSize.height*1.6, Math.max(icon.height, label.paintedHeight) + surfaceNormal.margins.top/2 + surfaceNormal.margins.bottom/2) // TODO: needs to define if there will be specific graphics for // disabled buttons @@ -106,12 +110,7 @@ Item { && button.parent.exclusive } - function pressButton() - { - userPressed = true - } - - function releaseButton() + function clickButton() { userPressed = false if (!button.enabled) { @@ -127,12 +126,13 @@ Item { } } - Keys.onSpacePressed: internal.pressButton() - Keys.onReturnPressed: internal.pressButton() + Keys.onSpacePressed: internal.userPressed = true + Keys.onReturnPressed: internal.userPressed = true Keys.onReleased: { + internal.userPressed = false if (event.key == Qt.Key_Space || event.key == Qt.Key_Return) - internal.releaseButton(); + internal.clickButton(); } ButtonShadow { @@ -173,6 +173,10 @@ Item { Item { id: buttonContent state: (internal.userPressed || checked) ? "pressed" : "normal" + scale: state == "pressed" ? 0.9 : 1 + Behavior on scale { + PropertyAnimation { duration: 100 } + } states: [ State { name: "normal" }, @@ -210,14 +214,20 @@ Item { anchors { verticalCenter: parent.verticalCenter - left: label.text ? parent.left : undefined - horizontalCenter: label.text ? undefined : parent.horizontalCenter + left: label.paintedWidth > 0 ? parent.left : undefined + horizontalCenter: label.paintedWidth > 0 ? undefined : parent.horizontalCenter } } Text { id: label + //FIXME: why this is needed? + onPaintedWidthChanged: { + icon.anchors.horizontalCenter = label.paintedWidth > 0 ? undefined : icon.parent.horizontalCenter + icon.anchors.left = label.paintedWidth > 0 ? icon.parent.left : undefined + } + anchors { top: parent.top bottom: parent.bottom @@ -246,8 +256,9 @@ Item { anchors.fill: parent hoverEnabled: true - onPressed: internal.pressButton() - onReleased: internal.releaseButton() - onCanceled: internal.releaseButton() + onPressed: internal.userPressed = true + onReleased: internal.userPressed = false + onCanceled: internal.userPressed = false + onClicked: internal.clickButton() } } diff --git a/declarativeimports/plasmacomponents/qml/CommonDialog.qml b/declarativeimports/plasmacomponents/qml/CommonDialog.qml index 3aeb5724e..b9c150186 100644 --- a/declarativeimports/plasmacomponents/qml/CommonDialog.qml +++ b/declarativeimports/plasmacomponents/qml/CommonDialog.qml @@ -82,14 +82,14 @@ Dialog { QtObject { id: internal - function buttonWidth() { + /*function buttonWidth() { switch (buttonTexts.length) { case 0: return 0 case 1: return Math.round((800 - 3 * 4) / 2) default: return (buttonContainer.width - (buttonTexts.length + 1) * 4) / buttonTexts.length } - } + }*/ function iconSource() { return root.titleIcon @@ -107,7 +107,7 @@ Dialog { LayoutMirroring.enabled: privateCloseIcon ? false : undefined LayoutMirroring.childrenInherit: true - Item { + Column { id: titleLayoutHelper // needed to make the text mirror correctly anchors { @@ -123,11 +123,7 @@ Dialog { Label { id: titleAreaText - LayoutMirroring.enabled: root.LayoutMirroring.enabled - - anchors.fill: parent - elide: Text.ElideRight horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter @@ -145,20 +141,13 @@ Dialog { } } - buttons: Item { - id: buttonContainer + buttons: Row { + id: buttonRow LayoutMirroring.enabled: false LayoutMirroring.childrenInherit: true - - width: parent.width - height: buttonTexts.length ? 48 + 2 * 2 : 0 - - Row { - id: buttonRow - objectName: "buttonRow" - anchors.centerIn: parent - spacing: 4 - } + objectName: "buttonRow" + anchors.centerIn: parent + spacing: 4 } } diff --git a/declarativeimports/plasmacomponents/qml/Dialog.qml b/declarativeimports/plasmacomponents/qml/Dialog.qml index c5696594c..8045914aa 100644 --- a/declarativeimports/plasmacomponents/qml/Dialog.qml +++ b/declarativeimports/plasmacomponents/qml/Dialog.qml @@ -69,7 +69,7 @@ Item { dialog.y = pos.y dialog.visible = true - dialog.focus = true + dialog.activateWindow() } function accept() @@ -95,6 +95,7 @@ Item { PlasmaCore.Dialog { id: dialog + windowFlags: Qt.Dialog //onFaderClicked: root.clickedOutside() @@ -111,8 +112,9 @@ Item { } mainItem: Item { + id: mainItem width: theme.defaultFont.mSize.width * 40 - height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonItem.childrenRect.height + height: titleBar.childrenRect.height + contentItem.childrenRect.height + buttonItem.childrenRect.height + 8 // Consume all key events that are not processed by children Keys.onPressed: event.accepted = true @@ -132,12 +134,15 @@ Item { Item { id: contentItem + onChildrenRectChanged: mainItem.width = Math.max(childrenRect.width, buttonItem.childrenRect.width) + clip: true anchors { top: titleBar.bottom left: parent.left right: parent.right bottom: buttonItem.top + bottomMargin: 8 } } @@ -145,15 +150,15 @@ Item { id: buttonItem height: childrenRect.height - clip: true anchors { left: parent.left right: parent.right bottom: parent.bottom + bottomMargin: 4 } } } - + Component.onCompleted: { rootItem = Utils.rootObject() } diff --git a/declarativeimports/plasmacomponents/qml/DualStateButton.qml b/declarativeimports/plasmacomponents/qml/DualStateButton.qml index 588857f45..caa68e61b 100644 --- a/declarativeimports/plasmacomponents/qml/DualStateButton.qml +++ b/declarativeimports/plasmacomponents/qml/DualStateButton.qml @@ -69,7 +69,7 @@ Item { property alias shadow: shadowLoader.sourceComponent width: surfaceLoader.width + label.paintedWidth - height: theme.defaultFont.mSize.height*1.8 + height: theme.defaultFont.mSize.height*1.6 // TODO: needs to define if there will be specific graphics for // disabled buttons opacity: dualButton.enabled ? 1.0 : 0.5 diff --git a/declarativeimports/plasmacomponents/qml/IconLoader.qml b/declarativeimports/plasmacomponents/qml/IconLoader.qml index 388989ad9..186de9460 100644 --- a/declarativeimports/plasmacomponents/qml/IconLoader.qml +++ b/declarativeimports/plasmacomponents/qml/IconLoader.qml @@ -54,7 +54,11 @@ Item { valid = false } - svgIcon.imagePath = "icons/"+root.source.split("-")[0] + svgIcon.imagePath = "toolbar-icons/"+root.source.split("-")[0] + if (!svgIcon.isValid() || !svgIcon.hasElement(root.source)) { + svgIcon.imagePath = "icons/"+root.source.split("-")[0] + } + if (svgIcon.isValid() && svgIcon.hasElement(root.source)) { imageLoader.sourceComponent = svgComponent } else if (root.source.indexOf(".") == -1 && root.source.indexOf(":") == -1) { @@ -72,6 +76,23 @@ Item { id: svgIcon } + 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 + } + } + Loader { id: imageLoader anchors.fill: parent @@ -83,6 +104,7 @@ Item { svg: svgIcon elementId: root.source anchors.fill: parent + smooth: true } } diff --git a/declarativeimports/plasmacomponents/qml/Label.qml b/declarativeimports/plasmacomponents/qml/Label.qml index 07818e4fb..90789e196 100644 --- a/declarativeimports/plasmacomponents/qml/Label.qml +++ b/declarativeimports/plasmacomponents/qml/Label.qml @@ -35,7 +35,7 @@ import org.kde.plasma.core 0.1 as PlasmaCore Text { id: root - height: theme.defaultFont.mSize.height*1.8 + height: Math.max(paintedHeight, theme.defaultFont.mSize.height*1.6) //FIXME: wait to rely on 1.1 for lineCount > 1 verticalAlignment: paintedHeight > theme.defaultFont.mSize.height*1.5 ? Text.AlignTop : Text.AlignVCenter @@ -49,6 +49,4 @@ Text { font.weight: theme.defaultFont.weight font.wordSpacing: theme.defaultFont.wordSpacing color: theme.textColor - - wrapMode: Text.Wrap } diff --git a/declarativeimports/plasmacomponents/qml/PageStack.qml b/declarativeimports/plasmacomponents/qml/PageStack.qml index caa95a1e9..204d30f01 100644 --- a/declarativeimports/plasmacomponents/qml/PageStack.qml +++ b/declarativeimports/plasmacomponents/qml/PageStack.qml @@ -148,17 +148,23 @@ Item { } onInitialPageChanged: { + if (!internal.completed) { + return + } + if (initialPage) { - if (depth == 0) + if (depth == 0) { push(initialPage, null, true) - else if (depth == 1) + } else if (depth == 1) { replace(initialPage, null, true) - else + } else { console.log("Cannot update PageStack.initialPage") + } } } Component.onCompleted: { + internal.completed = true if (initialPage && depth == 0) push(initialPage, null, true) } @@ -169,6 +175,9 @@ Item { // The number of ongoing transitions. property int ongoingTransitionCount: 0 + //FIXME: there should be a way to access to theh without storing it in an ugly way + property bool completed: false + // Sets the page status. function setPageStatus(page, status) { diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml index 4e7742cbf..ba84605cc 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollBar.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -83,8 +83,8 @@ Item { property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false property real scrollButtonInterval: 50 - implicitWidth: internalLoader.isVertical ? (interactive ? 22 : 12) : 200 - implicitHeight: internalLoader.isVertical ? 200 : (interactive ? 22 : 12) + implicitWidth: internalLoader.isVertical ? (interactive ? 16 : 12) : 200 + implicitHeight: internalLoader.isVertical ? 200 : (interactive ? 16 : 12) // TODO: needs to define if there will be specific graphics for // disabled scroll bars opacity: enabled ? 1.0 : 0.5 diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml index 2e9422bb0..4da4c315f 100644 --- a/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml +++ b/declarativeimports/plasmacomponents/qml/ScrollDecoratorDelegate.qml @@ -48,19 +48,38 @@ PlasmaCore.FrameSvgItem { imagePath:"widgets/scrollbar" prefix: "slider" - function length() { + function length() + { + var nh, ny; + if (internalLoader.isVertical) { - var overshoot = 0 - if (flickableItem.atYBeginning || flickableItem.atYEnd) { - overshoot = Math.abs(flickableItem.visibleArea.yPosition * parent.height) - } - return (flickableItem.visibleArea.heightRatio * parent.height) - overshoot + nh = flickableItem.visibleArea.heightRatio * internalLoader.height } else { - var overshoot = 0 - if (flickableItem.atXBeginning || flickableItem.atXEnd) { - overshoot = Math.abs(flickableItem.visibleArea.xPosition * parent.width) + nh = flickableItem.visibleArea.widthRatio * internalLoader.width + } + + if (internalLoader.isVertical) { + ny = flickableItem.visibleArea.yPosition * internalLoader.height + } else { + ny = flickableItem.visibleArea.xPosition * internalLoader.width + } + + if (ny > 3) { + var t + + if (internalLoader.isVertical) { + t = Math.ceil(internalLoader.height - 3 - ny) + } else { + t = Math.ceil(internalLoader.width - 3 - ny) } - return (flickableItem.visibleArea.widthRatio * parent.width) - overshoot + + if (nh > t) { + return t + } else { + return nh + } + } else { + return nh + ny } } diff --git a/declarativeimports/plasmacomponents/qml/SelectionDialog.qml b/declarativeimports/plasmacomponents/qml/SelectionDialog.qml index 8c493b76f..1f0f8b721 100644 --- a/declarativeimports/plasmacomponents/qml/SelectionDialog.qml +++ b/declarativeimports/plasmacomponents/qml/SelectionDialog.qml @@ -41,6 +41,7 @@ ****************************************************************************/ import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore import "." 0.1 @@ -58,7 +59,8 @@ CommonDialog { id: defaultDelegate Label { - //platformInverted: root.platformInverted + visible: modelData.search(RegExp(filterField.filterText, "i")) != -1 + height: visible? paintedHeight*2 : 0 text: modelData MouseArea { anchors.fill: parent @@ -77,42 +79,60 @@ CommonDialog { content: Item { id: contentItem - - width: theme.defaultFont.mSize.width * 40 + property alias filterText: filterField.filterText + implicitWidth: theme.defaultFont.mSize.width * 40 height: theme.defaultFont.mSize.height * 12 - Item { - // Clipping item with bottom margin added to align content with rounded background graphics - id: clipItem - anchors.fill: parent - anchors.bottomMargin: 4 + TextField { + id: filterField + property string filterText + onTextChanged: searchTimer.restart() + clearButtonShown: true + anchors { + top: parent.top + left: parent.left + right: parent.right + } + Timer { + id: searchTimer + running: false + repeat: false + interval: 500 + onTriggered: filterField.filterText = filterField.text + } + } + ListView { + id: listView + + anchors { + top: filterField.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + currentIndex : -1 + width: contentItem.width + height: contentItem.height + delegate: root.delegate clip: true - ListView { - id: listView - currentIndex : -1 - width: contentItem.width - height: contentItem.height - delegate: root.delegate - clip: true - - Keys.onPressed: { - if (event.key == Qt.Key_Up || event.key == Qt.Key_Down - || event.key == Qt.Key_Left || event.key == Qt.Key_Right - || event.key == Qt.Key_Select || event.key == Qt.Key_Enter - || event.key == Qt.Key_Return) { - listView.currentIndex = 0 - event.accepted = true - } + Keys.onPressed: { + if (event.key == Qt.Key_Up || event.key == Qt.Key_Down + || event.key == Qt.Key_Left || event.key == Qt.Key_Right + || event.key == Qt.Key_Select || event.key == Qt.Key_Enter + || event.key == Qt.Key_Return) { + listView.currentIndex = 0 + event.accepted = true } } } + ScrollBar { id: scrollBar flickableItem: listView visible: listView.contentHeight > contentItem.height //platformInverted: root.platformInverted - anchors { top: clipItem.top; right: clipItem.right } + anchors { top: contentItem.top; right: contentItem.right } } } diff --git a/declarativeimports/plasmacomponents/qml/Slider.qml b/declarativeimports/plasmacomponents/qml/Slider.qml index 1c8b4d53d..3eb26570e 100644 --- a/declarativeimports/plasmacomponents/qml/Slider.qml +++ b/declarativeimports/plasmacomponents/qml/Slider.qml @@ -101,22 +101,16 @@ Item { property string valueIndicatorText: value // Plasma API - property bool animated: false property alias inverted: range.inverted - property bool updateValueWhileDragging: true - property real handleSize: 22 - // Convenience API - property bool _isVertical: orientation == Qt.Vertical - - width: _isVertical ? theme.defaultFont.mSize.height*1.8 : 200 - height: _isVertical ? 200 : theme.defaultFont.mSize.height*1.8 + width: contents.isVertical ? theme.defaultFont.mSize.height*1.6 : 200 + height: contents.isVertical ? 200 : theme.defaultFont.mSize.height*1.6 // TODO: needs to define if there will be specific graphics for // disabled sliders opacity: enabled ? 1.0 : 0.5 Keys.onUpPressed: { - if (!enabled || !_isVertical) + if (!enabled || !contents.isVertical) return; if (inverted) @@ -129,7 +123,7 @@ Item { if (!enabled || !enabled) return; - if (!_isVertical) + if (!contents.isVertical) return; if (inverted) @@ -139,7 +133,7 @@ Item { } Keys.onLeftPressed: { - if (!enabled || _isVertical) + if (!enabled || contents.isVertical) return; if (inverted) @@ -149,7 +143,7 @@ Item { } Keys.onRightPressed: { - if (!enabled || _isVertical) + if (!enabled || contents.isVertical) return; if (inverted) @@ -161,9 +155,17 @@ Item { Item { id: contents - width: _isVertical ? slider.height : slider.width - height: _isVertical ? slider.width : slider.height - rotation: _isVertical ? -90 : 0 + // Plasma API + property bool animated: true + property bool updateValueWhileDragging: true + property real handleSize: theme.defaultFont.mSize.height*1.3 + + // Convenience API + property bool isVertical: orientation == Qt.Vertical + + width: contents.isVertical ? slider.height : slider.width + height: contents.isVertical ? slider.width : slider.height + rotation: contents.isVertical ? -90 : 0 anchors.centerIn: parent @@ -224,8 +226,8 @@ Item { anchors { verticalCenter: groove.verticalCenter } - width: handleSize - height: handleSize + width: contents.handleSize + height: contents.handleSize svg: PlasmaCore.Svg { imagePath: "widgets/slider" } elementId: "horizontal-slider-handle" diff --git a/declarativeimports/plasmacomponents/qml/TabBar.qml b/declarativeimports/plasmacomponents/qml/TabBar.qml index 66ac34ac7..dbcd4965b 100644 --- a/declarativeimports/plasmacomponents/qml/TabBar.qml +++ b/declarativeimports/plasmacomponents/qml/TabBar.qml @@ -108,5 +108,10 @@ Item { rightMargin: backgroundFrame.margins.right + buttonFrame.margins.right bottomMargin: backgroundFrame.margins.bottom + buttonFrame.margins.bottom } + Component.onCompleted: { + if (!root.currentTab) { + root.currentTab = tabBarLayout.children[0] + } + } } } diff --git a/declarativeimports/plasmacomponents/qml/TabButton.qml b/declarativeimports/plasmacomponents/qml/TabButton.qml index ff7ab8671..d49926d8a 100644 --- a/declarativeimports/plasmacomponents/qml/TabButton.qml +++ b/declarativeimports/plasmacomponents/qml/TabButton.qml @@ -112,8 +112,8 @@ Item { } Component.onCompleted: { - if (internal.tabGroup.currentTab == tab) { - parent.parent.currentTab = root + if (internal.tabGroup && internal.tabGroup.currentTab == tab) { + internal.tabGroup.currentTab = tab } } } diff --git a/declarativeimports/plasmacomponents/qml/TextArea.qml b/declarativeimports/plasmacomponents/qml/TextArea.qml index c5de1e2aa..66ff1f583 100644 --- a/declarativeimports/plasmacomponents/qml/TextArea.qml +++ b/declarativeimports/plasmacomponents/qml/TextArea.qml @@ -276,6 +276,11 @@ Item { visible: textEdit.text == "" && !textArea.activeFocus opacity: 0.5 } + onActiveFocusChanged: { + if (!textField.activeFocus) { + textInput.closeSoftwareInputPanel() + } + } } } diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml index d092c4486..f9a15cf15 100644 --- a/declarativeimports/plasmacomponents/qml/TextField.qml +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -166,7 +166,7 @@ Item { // TODO: fix default size implicitWidth: theme.defaultFont.mSize.width*12 - implicitHeight: theme.defaultFont.mSize.height*1.8 + implicitHeight: theme.defaultFont.mSize.height*1.6 // TODO: needs to define if there will be specific graphics for // disabled text fields opacity: enabled ? 1.0 : 0.5 @@ -227,12 +227,17 @@ Item { verticalCenter: parent.verticalCenter // TODO: see what is the correct policy for margins leftMargin: 2 * base.margins.left - rightMargin: 2 * base.margins.right + rightMargin: 2 * base.margins.right + (clearButton.opacity > 0 ? clearButton.width : 0) } selectByMouse: true color: theme.textColor enabled: textField.enabled clip: true + onActiveFocusChanged: { + if (!textField.activeFocus) { + textInput.closeSoftwareInputPanel() + } + } // Proxying keys events is not required by the // common API but is desired in the plasma API. @@ -241,6 +246,7 @@ Item { } PlasmaCore.SvgItem { + id: clearButton svg: PlasmaCore.Svg {imagePath: "widgets/lineedit"} elementId: "clearbutton" width: textInput.height diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml index c3600d6b7..467396c4e 100644 --- a/declarativeimports/plasmacomponents/qml/ToolBar.qml +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -47,7 +47,7 @@ import org.kde.plasma.core 0.1 as PlasmaCore Item{ id: toolBar width: parent.width - height: (tools && enabled) ? theme.defaultFont.mSize.height*2 + frameSvg.margins.top + frameSvg.margins.bottom : 0 + height: (tools && enabled) ? tools.height + frameSvg.margins.top + frameSvg.margins.bottom : 0 visible: height > 0 Behavior on height { PropertyAnimation { @@ -148,8 +148,7 @@ Item{ PlasmaCore.FrameSvgItem { id: frameSvg - imagePath: "widgets/frame" - prefix: "raised" + imagePath: "widgets/toolbar" anchors { fill: parent leftMargin: -margins.left diff --git a/declarativeimports/plasmacomponents/qml/ToolButton.qml b/declarativeimports/plasmacomponents/qml/ToolButton.qml index 7e02255c7..09e6bdc7d 100644 --- a/declarativeimports/plasmacomponents/qml/ToolButton.qml +++ b/declarativeimports/plasmacomponents/qml/ToolButton.qml @@ -63,8 +63,8 @@ Item { // Commmon API property bool flat: true - property bool checked: false - property bool checkable: false + property bool checked: defaultAction ? defaultAction.checked : false + property bool checkable: defaultAction ? defaultAction.checkable : false property alias pressed: mouse.pressed property alias text: label.text property alias iconSource: icon.source @@ -72,6 +72,11 @@ Item { signal clicked() + // Plasma extensiuons + property QtObject defaultAction + + + enabled: defaultAction==undefined||defaultAction.enabled onFlatChanged: { surface.opacity = 1 @@ -85,18 +90,19 @@ Item { return Math.max(theme.defaultFont.mSize.width*12, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) + ((icon.valid) ? surface.margins.left : 0) } } - implicitHeight: Math.max(theme.defaultFont.mSize.height*1.8, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) + implicitHeight: Math.max(theme.defaultFont.mSize.height*1.6, Math.max(icon.height, label.paintedHeight) + surface.margins.top/2 + surface.margins.bottom/2) // TODO: needs to define if there will be specific graphics for // disabled buttons opacity: enabled ? 1.0 : 0.5 - Keys.onSpacePressed: internal.pressButton() - Keys.onReturnPressed: internal.pressButton() + Keys.onSpacePressed: internal.userPressed = true + Keys.onReturnPressed: internal.userPressed = true Keys.onReleased: { + internal.userPressed = false if (event.key == Qt.Key_Space || event.key == Qt.Key_Return) - internal.releaseButton() + internal.clickButton() } onActiveFocusChanged: { @@ -113,24 +119,24 @@ Item { id: internal property bool userPressed: false - function pressButton() + function clickButton() { - userPressed = true - } - - function releaseButton() - { - userPressed = false if (!button.enabled) { return } - if (button.checkable) { + if (defaultAction && defaultAction.checkable) { + defaultAction.checked = !defaultAction.checked + } else if (button.checkable) { button.checked = !button.checked } button.clicked() button.forceActiveFocus() + + if (defaultAction) { + defaultAction.trigger() + } } } @@ -149,7 +155,7 @@ Item { //internal: if there is no hover status, don't paint on mouse over in touchscreens opacity: (internal.userPressed || checked || !flat || (shadow.hasOverState && mouse.containsMouse)) ? 1 : 0 Behavior on opacity { - PropertyAnimation { duration: 250 } + PropertyAnimation { duration: 100 } } } @@ -161,6 +167,10 @@ Item { rightMargin: surface.margins.right bottomMargin: surface.margins.bottom } + scale: internal.userPressed ? 0.9 : 1 + Behavior on scale { + PropertyAnimation { duration: 250 } + } IconLoader { id: icon @@ -175,6 +185,12 @@ Item { Text { id: label + //FIXME: why this is needed? + onPaintedWidthChanged: { + icon.anchors.horizontalCenter = label.paintedWidth > 0 ? undefined : icon.parent.horizontalCenter + icon.anchors.left = label.paintedWidth > 0 ? icon.parent.left : undefined + } + anchors { top: parent.top bottom: parent.bottom @@ -202,9 +218,9 @@ Item { anchors.fill: parent hoverEnabled: true - onPressed: internal.pressButton(); - - onReleased: internal.releaseButton(); + onPressed: internal.userPressed = true + onReleased: internal.userPressed = false + onClicked: internal.clickButton() onEntered: { if (!flat) { diff --git a/declarativeimports/plasmacomponents/qml/qmldir b/declarativeimports/plasmacomponents/qml/qmldir index 33220fa2e..934081bd6 100644 --- a/declarativeimports/plasmacomponents/qml/qmldir +++ b/declarativeimports/plasmacomponents/qml/qmldir @@ -6,31 +6,26 @@ ButtonColumn 0.1 ButtonColumn.qml ButtonGroup 0.1 ButtonGroup.js ButtonRow 0.1 ButtonRow.qml CheckBox 0.1 CheckBox.qml -FlashingLabel 0.1 FlashingLabel.qml -Frame 0.1 Frame.qml +CommonDialog 0.1 CommonDialog.qml +Dialog 0.1 Dialog.qml Highlight 0.1 Highlight.qml -IconWidget 0.1 IconWidget.qml Label 0.1 Label.qml +ListItem 0.1 ListItem.qml +Page 0.1 Page.qml +PageStack 0.1 PageStack.qml ProgressBar 0.1 ProgressBar.qml PushButton 0.1 PushButton.qml RadioButton 0.1 RadioButton.qml ScrollBar 0.1 ScrollBar.qml +SectionScroller 0.1 SectionScroller.qml +SelectionDialog 0.1 SelectionDialog.qml Slider 0.1 Slider.qml Switch 0.1 Switch.qml -TextArea 0.1 TextArea.qml -TextField 0.1 TextField.qml -ToolBar 0.1 ToolBar.qml -ToolButton 0.1 ToolButton.qml -ListItem 0.1 ListItem.qml - -CommonDialog 0.1 CommonDialog.qml -SelectionDialog 0.1 SelectionDialog.qml -ToolBarLayout 0.1 ToolBarLayout.qml - -Page 0.1 Page.qml -PageStack 0.1 PageStack.qml - TabBar 0.1 TabBar.qml TabButton 0.1 TabButton.qml TabGroup 0.1 TabGroup.qml -SectionScroller 0.1 SectionScroller.qml +TextArea 0.1 TextArea.qml +TextField 0.1 TextField.qml +ToolBar 0.1 ToolBar.qml +ToolBarLayout 0.1 ToolBarLayout.qml +ToolButton 0.1 ToolButton.qml diff --git a/kpart/plasma-kpart.desktop b/kpart/plasma-kpart.desktop index 578547fa2..7ceef9936 100644 --- a/kpart/plasma-kpart.desktop +++ b/kpart/plasma-kpart.desktop @@ -13,6 +13,7 @@ Name[en_GB]=plasma-kpart Name[es]=plasma-kpart Name[et]=plasma-kpart Name[eu]=plasma-kpart +Name[fa]=plasma-kpart Name[fi]=plasma-kpart Name[fr]=plasma-kpart Name[he]=plasma-kpart @@ -28,6 +29,7 @@ Name[km]=plasma-kpart Name[kn]=plasma-kpart Name[ko]=plasma-kpart Name[lt]=plasma-kpart +Name[lv]=plasma-kpart Name[nb]=plasma-kpart Name[nds]=Kpart för Plasma Name[nl]=plasma-kpart diff --git a/remotewidgetshelper/kcm_remotewidgets.actions b/remotewidgetshelper/kcm_remotewidgets.actions index e8ba43ee5..370c67728 100644 --- a/remotewidgetshelper/kcm_remotewidgets.actions +++ b/remotewidgetshelper/kcm_remotewidgets.actions @@ -87,6 +87,7 @@ Description[kk]=Қашықтағы Plasma виджеттер ережелері Description[km]=ការពារ​ប្រព័ន្ធ​មិន​ឲ្យ​រក្សាទុក​គោលនយោបាយ​របស់​ធាតុក្រាហ្វិក​ប្លាស្មា​ពី​ចម្ងាយ Description[ko]=Plasma 원격 위젯 정책을 저장하지 못하도록 합니다 Description[lt]=Neleidžia sistemai išsaugoti nutolusių plazmos valdiklių taisyklių +Description[lv]=Liedz sistēmai saglabāt plasma attālināto sīkrīku politikas Description[nb]=Hindrer at systemet lagrer praksiser for plasmaelementer på nettverket Description[nds]=Höllt dat Systeem vun't Sekern vun de Regeln för feern Plasma-Lüttprogrammen af Description[nl]=Voorkomt het opslaan door het systeem van beleidsregels voor widgets op afstand diff --git a/scriptengines/javascript/common/extension_io.cpp b/scriptengines/javascript/common/extension_io.cpp index c25688153..7e43efff8 100644 --- a/scriptengines/javascript/common/extension_io.cpp +++ b/scriptengines/javascript/common/extension_io.cpp @@ -21,11 +21,15 @@ #include +#include #include +#include #include #include #include +#include + QScriptValue ScriptEnv::openUrl(QScriptContext *context, QScriptEngine *engine) { Q_UNUSED(engine) @@ -87,6 +91,67 @@ QScriptValue ScriptEnv::getUrl(QScriptContext *context, QScriptEngine *engine) return engine->newQObject(job); } +QScriptValue ScriptEnv::download(QScriptContext *context, QScriptEngine *engine) +{ + if (context->argumentCount() == 0) { + return engine->undefinedValue(); + } + + QScriptValue v = context->argument(0); + KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast(v); + + if (!url.isValid()) { + return engine->undefinedValue(); + } + + QString requestedFileName; + if (context->argumentCount() > 1) { + requestedFileName = context->argument(1).toString(); + } + + ScriptEnv *env = ScriptEnv::findScriptEnv(engine); + if (!env) { + //kDebug() << "findScriptEnv failed"; + return engine->undefinedValue(); + } + + QStringList protocols; + protocols << "http" << "https" << "ftp" << "ftps"; + if (!protocols.contains(url.protocol())) { + return engine->undefinedValue(); + } + + QScriptContext *c = engine->currentContext(); + QString destination; + while (c) { + QScriptValue v = c->activationObject().property("__plasma_package"); + if (v.isVariant()) { + KDesktopFile config(v.toVariant().value().path() + "/metadata.desktop"); + KConfigGroup cg = config.desktopGroup(); + const QString pluginName = cg.readEntry("X-KDE-PluginInfo-Name", QString()); + destination = KGlobalSettings::downloadPath() + "Plasma/" + pluginName + '/'; + break; + } + + c = c->parentContext(); + } + + if (destination.isEmpty()) { + return engine->undefinedValue(); + } + + requestedFileName.prepend(destination); + QDir dir(requestedFileName); + dir.mkpath(destination); + if (!dir.absolutePath().startsWith(destination)) { + requestedFileName = destination; + } + + //TODO: allow showing desktop progress info? + KIO::CopyJob *job = KIO::copy(url, KUrl(requestedFileName), KIO::HideProgressInfo); + return engine->newQObject(job); +} + QScriptValue ScriptEnv::userDataPath(QScriptContext *context, QScriptEngine *engine) { Q_UNUSED(engine) diff --git a/scriptengines/javascript/common/scriptenv.cpp b/scriptengines/javascript/common/scriptenv.cpp index d90ce301d..bb6543657 100644 --- a/scriptengines/javascript/common/scriptenv.cpp +++ b/scriptengines/javascript/common/scriptenv.cpp @@ -68,7 +68,6 @@ void ScriptEnv::setupGlobalObject() // property is hidden from scripts. global.setProperty("__plasma_scriptenv", m_engine->newQObject(this), QScriptValue::ReadOnly|QScriptValue::Undeletable|QScriptValue::SkipInEnumeration); - // Add utility functions #ifndef DECLARATIVE global.setProperty("print", m_engine->newFunction(ScriptEnv::print)); @@ -182,6 +181,9 @@ bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &o obj.setProperty("userDataPath", m_engine->newFunction(ScriptEnv::userDataPath)); obj.setProperty("runCommand", m_engine->newFunction(ScriptEnv::runCommand)); return true; + } else if ("download" == extension) { + obj.setProperty("download", m_engine->newFunction(ScriptEnv::download)); + return true; } return false; diff --git a/scriptengines/javascript/common/scriptenv.h b/scriptengines/javascript/common/scriptenv.h index 4ec7202d8..cc0c4f5be 100644 --- a/scriptengines/javascript/common/scriptenv.h +++ b/scriptengines/javascript/common/scriptenv.h @@ -27,6 +27,11 @@ #include "authorization.h" +namespace Plasma +{ + class Package; +} // namespace Plasma + class ScriptEnv : public QObject { Q_OBJECT @@ -87,6 +92,7 @@ private: static QScriptValue applicationExists(QScriptContext *context, QScriptEngine *engine); static QScriptValue openUrl(QScriptContext *context, QScriptEngine *engine); static QScriptValue getUrl(QScriptContext *context, QScriptEngine *engine); + static QScriptValue download(QScriptContext *context, QScriptEngine *engine); static QScriptValue userDataPath(QScriptContext *context, QScriptEngine *engine); static QScriptValue listAddons(QScriptContext *context, QScriptEngine *engine); static QScriptValue loadAddon(QScriptContext *context, QScriptEngine *engine); diff --git a/scriptengines/javascript/data/plasma-javascriptaddon.desktop b/scriptengines/javascript/data/plasma-javascriptaddon.desktop index 1743ab726..c1d2bb662 100644 --- a/scriptengines/javascript/data/plasma-javascriptaddon.desktop +++ b/scriptengines/javascript/data/plasma-javascriptaddon.desktop @@ -13,6 +13,7 @@ Name[en_GB]=Plasma JavaScript Addon Name[es]=Complemento de JavaScript para Plasma Name[et]=Plasma JavaScripti lisa Name[eu]=Plasma JavaScript gehigarria +Name[fa]=افزودنی جاوااسکریپت پلاسما Name[fi]=Plasma JavaScript -lisäosa Name[fr]=Module complémentaire Javascript de Plasma Name[he]=תוסף עבור JavaScript של Plasma @@ -28,6 +29,7 @@ Name[km]=ផ្នែក​បន្ថែម​ Plasma JavaScript Name[kn]=ಪ್ಲಾಸ್ಮಾ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಆಡ್‌ಆನ್ Name[ko]=Plasma 자바스크립트 추가 기능 Name[lt]=Plasma JavaScript priedas +Name[lv]=Plasma JavaScript papildinājums Name[nb]=Plasma JavaScript-tillegg Name[nds]=JavaScript-Verwiedern för Plasma Name[nl]=Addon voor Plasma JavaScript diff --git a/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop b/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop index e96fc6552..8e5c5c5e1 100644 --- a/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop +++ b/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop @@ -13,6 +13,7 @@ Name[en_GB]=Javascript Addon Name[es]=Complemento de JavaScript Name[et]=JavaScripti lisa Name[eu]=Javascript gehigarria +Name[fa]=افزودنی جاوااسکریپت Name[fi]=Javascript-lisäosa Name[fr]=Module complémentaire Javascript Name[he]=תוסף JavaScript @@ -28,6 +29,7 @@ Name[km]=ផ្នែក​បន្ថែម Javascript Name[kn]=ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಆಡ್‌ಆನ್ Name[ko]=자바스크립트 추가 기능 Name[lt]=Javascript priedas +Name[lv]=JavaScript papildinājums Name[nb]=JavaScript-tillegg Name[nds]=JavaScript-Verwiedern Name[nl]=Addon voor JavaScript @@ -82,6 +84,7 @@ Comment[kk]=Javascript Plasma плагиніне қосымшасы Comment[km]=កម្មវិធី​បន្ថែម​សម្រាប់​កម្មវិធី​ជំនួយ Javascript Plasma Comment[ko]=자바스크립트 Plasma 플러그인을 위한 추가 기능 Comment[lt]=Javascript Plasma papildinio priedai +Comment[lv]=Papildinājumi Javascript Plasma spraudņiem Comment[nb]=Tillegg for JavaSript Plasma-programtillegg Comment[nds]=Verwiedern för Plasma sien JavaScript-Modulen Comment[nl]=Addons voor Javascript Plasma plugins diff --git a/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop b/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop index 4a565bd84..d78e7e46b 100644 --- a/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop +++ b/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop @@ -24,6 +24,7 @@ Name[kk]=Мәлімдеме виджеті Name[km]=ធាតុ​ក្រាហ្វិក​ដែល​ប្រកាស Name[ko]=Declarative 위젯 Name[lt]=Deklaratyvus valdiklis +Name[lv]=Deklaratīvais sīkrīks Name[nb]=Deklarativt skjermelement Name[nds]=Stüerelement för Verkloren Name[nl]=Widget voor declaratie @@ -77,6 +78,7 @@ Comment[km]=ធាតុ​ក្រាហ្វិក​ប្លា​ស្ Comment[kn]=QML ಹಾಗು ಜಾವಾ ಸ್ಕ್ರಿಪ್ಟ್ ನಲ್ಲಿ ಬರೆಯಲಾದ ಸ್ವಾಭಾವಿಕ ಪ್ಲಾಸ್ಮಾ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) Comment[ko]=QML과 자바스크립트로 작성된 Plasma 위젯 Comment[lt]=Nuosavas Plasma valdiklis parašytas QML ir JavaScript kalba +Comment[lv]=Plasma sīkrīks, rakstīts QML un JavaScript valodās Comment[nb]=Plasmaelement for dette systemet, skrevet i QML og JavaScript Comment[nds]=En orginaal Plasmaelement, schreven in QML un JavaScript Comment[nl]=Hier thuishorend Plasma-widget geschreven in QML en JavaScript diff --git a/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop b/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop index 0da857f2a..8fcaeb2c5 100644 --- a/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop +++ b/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop @@ -18,6 +18,7 @@ Name[eo]=Ĝavaskripta fenestraĵo Name[es]=Elemento gráfico JavaScript Name[et]=JavaScripti vidin Name[eu]=JavaScript trepeta +Name[fa]=ویجت جاوااسکریپت Name[fi]=JavaScript-sovelma Name[fr]=Composant graphique JavaScript Name[fy]=JavaSkript Widget diff --git a/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop b/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop index 088e0a121..54086efa5 100644 --- a/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop +++ b/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop @@ -16,6 +16,7 @@ Name[eo]=Ĝavaskripta Datummodulo Name[es]=Motor de datos JavaScript Name[et]=JavaScripti andmemootor Name[eu]=JavaScript datu-motorea +Name[fa]=موتور داده‌ی جاوااسکریپت Name[fi]=JavaScript-datakone Name[fr]=Moteur de données JavaScript Name[fy]=JavaSkript gegevens motor diff --git a/scriptengines/javascript/declarative/packageaccessmanager.cpp b/scriptengines/javascript/declarative/packageaccessmanager.cpp index b9f9b0b8e..b32fa2546 100644 --- a/scriptengines/javascript/declarative/packageaccessmanager.cpp +++ b/scriptengines/javascript/declarative/packageaccessmanager.cpp @@ -76,7 +76,6 @@ QNetworkReply *PackageAccessManager::createRequest(QNetworkAccessManager::Operat (!m_auth->authorizeRequiredExtension("networkio"))) { return new ErrorReply(op, req); } else { - return KIO::AccessManager::createRequest(op, req, outgoingData); #ifndef PLASMA_NO_KIO return KIO::AccessManager::createRequest(op, req, outgoingData); #else diff --git a/scriptengines/javascript/plasmoid/appletinterface.cpp b/scriptengines/javascript/plasmoid/appletinterface.cpp index cc70e8b27..b09b52224 100644 --- a/scriptengines/javascript/plasmoid/appletinterface.cpp +++ b/scriptengines/javascript/plasmoid/appletinterface.cpp @@ -22,12 +22,14 @@ #include "appletinterface.h" #include +#include #include #include #include #include #include +#include #include #include #include @@ -412,6 +414,23 @@ AppletInterface::ItemStatus AppletInterface::status() const return (AppletInterface::ItemStatus)((int)(applet()->status())); } +/* +QString AppletInterface::downloadPath(const QString &file) +{ + KDesktopFile config(v.toVariant().value().path() + "/metadata.desktop"); + KConfigGroup cg = config.desktopGroup(); + const QString pluginName = cg.readEntry("X-KDE-PluginInfo-Name", QString()); + destination = KGlobalSettings::downloadPath() + "/Plasma/" + pluginName + '/'; +} +*/ + +QStringList AppletInterface::downloadedFiles() const +{ + const QString downloadDir = KGlobalSettings::downloadPath() + "/Plasma/" + applet()->pluginName(); + QDir dir(downloadDir); + return dir.entryList(QDir::Files | QDir::NoSymLinks | QDir::Readable); +} + void AppletInterface::gc() { QTimer::singleShot(0, m_appletScriptEngine, SLOT(collectGarbage())); @@ -421,6 +440,7 @@ void AppletInterface::gc() PopupAppletInterface::PopupAppletInterface(AbstractJsAppletScript *parent) : APPLETSUPERCLASS(parent) { + connect(m_appletScriptEngine, SIGNAL(popupEvent(bool)), this, SIGNAL(popupEvent(bool))); } void PopupAppletInterface::setPopupIcon(const QIcon &icon) diff --git a/scriptengines/javascript/plasmoid/appletinterface.h b/scriptengines/javascript/plasmoid/appletinterface.h index 53d0a2c0a..f782b3549 100644 --- a/scriptengines/javascript/plasmoid/appletinterface.h +++ b/scriptengines/javascript/plasmoid/appletinterface.h @@ -304,6 +304,9 @@ enum IntervalAlignment { void setStatus(const ItemStatus &status); ItemStatus status() const; +// Q_INVOKABLE QString downloadPath(const QString &file); + Q_INVOKABLE QStringList downloadedFiles() const; + Q_SIGNALS: void releaseVisualFocus(); void configNeedsSaving(); @@ -367,6 +370,9 @@ public: void setPopupWidget(QGraphicsWidget *widget); QGraphicsWidget *popupWidget(); +Q_SIGNALS: + void popupEvent(bool); + public Q_SLOTS: void setPopupIconByName(const QString &name); void togglePopup(); diff --git a/scriptengines/javascript/plasmoid/declarativeappletscript.cpp b/scriptengines/javascript/plasmoid/declarativeappletscript.cpp index 005894a2f..72f83c809 100644 --- a/scriptengines/javascript/plasmoid/declarativeappletscript.cpp +++ b/scriptengines/javascript/plasmoid/declarativeappletscript.cpp @@ -390,6 +390,10 @@ void DeclarativeAppletScript::setupObjects() QScriptValue global = m_engine->globalObject(); + QScriptValue v = m_engine->newVariant(QVariant::fromValue(*applet()->package())); + global.setProperty("__plasma_package", v, + QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + m_self = m_engine->newQObject(m_interface); m_self.setScope(global); global.setProperty("plasmoid", m_self); diff --git a/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp b/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp index 112c26520..5804114d6 100644 --- a/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp +++ b/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp @@ -510,6 +510,10 @@ void SimpleJavaScriptApplet::setupObjects() global.setProperty("AnimationGroup", m_engine->newFunction(SimpleJavaScriptApplet::animationGroup)); global.setProperty("ParallelAnimationGroup", m_engine->newFunction(SimpleJavaScriptApplet::parallelAnimationGroup)); + QScriptValue v = m_engine->newVariant(QVariant::fromValue(*applet()->package())); + global.setProperty("__plasma_package", v, + QScriptValue::ReadOnly | QScriptValue::Undeletable | QScriptValue::SkipInEnumeration); + // Bindings for data engine bindI18N(m_engine); diff --git a/scriptengines/javascript/simplebindings/backportglobal.h b/scriptengines/javascript/simplebindings/backportglobal.h index 1a572499c..6f676a9f6 100644 --- a/scriptengines/javascript/simplebindings/backportglobal.h +++ b/scriptengines/javascript/simplebindings/backportglobal.h @@ -21,6 +21,10 @@ #include +#include +Q_DECLARE_METATYPE(QPixmap*) +Q_DECLARE_METATYPE(QPixmap) + #define DECLARE_SELF(Class, __fn__) \ Class* self = qscriptvalue_cast(ctx->thisObject()); \ if (!self) { \ diff --git a/scriptengines/javascript/simplebindings/painter.cpp b/scriptengines/javascript/simplebindings/painter.cpp index 0bc7cfe1b..6c4458331 100644 --- a/scriptengines/javascript/simplebindings/painter.cpp +++ b/scriptengines/javascript/simplebindings/painter.cpp @@ -50,6 +50,14 @@ static QScriptValue ctor(QScriptContext *ctx, QScriptEngine *eng) { if (ctx->argumentCount() > 0) { QPaintDevice *device = qscriptvalue_cast(ctx->argument(0)); + if (!device) { + QPixmap *pixmap = qscriptvalue_cast(ctx->argument(0)); + if (pixmap) { + return newPainter(eng, new QPainter(pixmap)); + } else { + return newPainter(eng, new QPainter()); + } + } return newPainter(eng, new QPainter(device)); } else { return newPainter(eng, new QPainter()); diff --git a/scriptengines/javascript/simplebindings/pixmap.cpp b/scriptengines/javascript/simplebindings/pixmap.cpp index 0719dc7d5..8894776e1 100644 --- a/scriptengines/javascript/simplebindings/pixmap.cpp +++ b/scriptengines/javascript/simplebindings/pixmap.cpp @@ -23,9 +23,6 @@ #include "backportglobal.h" #include "plasmoid/appletinterface.h" -Q_DECLARE_METATYPE(QPixmap*) -Q_DECLARE_METATYPE(QPixmap) - static QScriptValue ctor(QScriptContext *ctx, QScriptEngine *eng) { if (ctx->argumentCount() == 1 && ctx->argument(0).isString()) {