diff --git a/declarativeimports/CMakeLists.txt b/declarativeimports/CMakeLists.txt index c113b603f..5774a12b2 100644 --- a/declarativeimports/CMakeLists.txt +++ b/declarativeimports/CMakeLists.txt @@ -1,4 +1,6 @@ add_subdirectory(core) +add_subdirectory(draganddrop) add_subdirectory(graphicslayouts) add_subdirectory(graphicswidgets) - +add_subdirectory(qtextracomponents) +add_subdirectory(plasmacomponents) \ No newline at end of file diff --git a/declarativeimports/core/CMakeLists.txt b/declarativeimports/core/CMakeLists.txt index 0333971b8..64254ac8d 100644 --- a/declarativeimports/core/CMakeLists.txt +++ b/declarativeimports/core/CMakeLists.txt @@ -1,6 +1,7 @@ project(corebindings) set(corebindings_SRCS + declarativeitemcontainer.cpp corebindingsplugin.cpp dataengineconsumer.cpp theme.cpp @@ -8,6 +9,8 @@ set(corebindings_SRCS datasource.cpp svgitem.cpp framesvgitem.cpp + dialog.cpp + tooltip.cpp ) INCLUDE_DIRECTORIES( diff --git a/declarativeimports/core/corebindingsplugin.cpp b/declarativeimports/core/corebindingsplugin.cpp index a82faa778..460526349 100644 --- a/declarativeimports/core/corebindingsplugin.cpp +++ b/declarativeimports/core/corebindingsplugin.cpp @@ -31,6 +31,8 @@ #include "framesvgitem_p.h" #include "svgitem_p.h" #include "theme_p.h" +#include "dialog.h" +#include "tooltip.h" void CoreBindingsPlugin::registerTypes(const char *uri) { @@ -47,8 +49,13 @@ void CoreBindingsPlugin::registerTypes(const char *uri) qmlRegisterType(uri, 0, 1, "DataModel"); qmlRegisterType(uri, 0, 1, "SortFilterModel"); + qmlRegisterType(uri, 0, 1, "Dialog"); + qmlRegisterType(uri, 0, 1, "ToolTip"); + qmlRegisterInterface("Service"); qRegisterMetaType("Service"); + qmlRegisterInterface("ServiceJob"); + qRegisterMetaType("ServiceJob"); /*qmlRegisterInterface("DataSource"); qRegisterMetaType("DataSource");*/ diff --git a/declarativeimports/core/corebindingsplugin.h b/declarativeimports/core/corebindingsplugin.h index 6b452f827..d0a61517a 100644 --- a/declarativeimports/core/corebindingsplugin.h +++ b/declarativeimports/core/corebindingsplugin.h @@ -26,8 +26,6 @@ #include -Q_DECLARE_METATYPE(Plasma::Service*) - class CoreBindingsPlugin : public QDeclarativeExtensionPlugin { Q_OBJECT diff --git a/declarativeimports/core/dataengineconsumer.cpp b/declarativeimports/core/dataengineconsumer.cpp index ecf58732e..2120e1c41 100644 --- a/declarativeimports/core/dataengineconsumer.cpp +++ b/declarativeimports/core/dataengineconsumer.cpp @@ -42,33 +42,32 @@ ServiceMonitor::~ServiceMonitor() void ServiceMonitor::slotJobFinished(Plasma::ServiceJob *job) { - kDebug() << "engine ready!"; + //kDebug() << "engine ready!"; QString engineName = job->parameters()["EngineName"].toString(); QString location = job->destination(); QPair pair(location, engineName); - kDebug() << "pair = " << pair; + //kDebug() << "pair = " << pair; if (!m_consumer->m_remoteEngines.contains(pair)) { kDebug() << "engine does not exist yet!"; } else { KUrl engineLocation(location); engineLocation.setFileName(job->result().toString()); - kDebug() << "setting location : " - << engineLocation.prettyUrl(); + //kDebug() << "setting location : " << engineLocation.prettyUrl(); // m_consumer->m_remoteEngines[pair]->setLocation(engineLocation); } } void ServiceMonitor::slotServiceReady(Plasma::Service *plasmoidService) { - kDebug() << "service ready!"; + //kDebug() << "service ready!"; if (!m_consumer->m_engineNameForService.contains(plasmoidService)) { kDebug() << "no engine name for service!"; kDebug() << "amount of services in map: " << m_consumer->m_engineNameForService.count(); } else { - kDebug() << "value = " << m_consumer->m_engineNameForService.value(plasmoidService); + //kDebug() << "value = " << m_consumer->m_engineNameForService.value(plasmoidService); } - kDebug() << "requesting dataengine!"; + //kDebug() << "requesting dataengine!"; KConfigGroup op = plasmoidService->operationDescription("DataEngine"); op.writeEntry("EngineName", m_consumer->m_engineNameForService.value(plasmoidService)); plasmoidService->startOperationCall(op); @@ -90,6 +89,13 @@ DataEngineConsumer::~DataEngineConsumer() delete m_monitor; } +void DataEngineConsumer::finishedWithEngine(const QString &name) +{ + if (m_loadedEngines.contains(name)) { + DataEngineManager::self()->unloadEngine(name); + } +} + DataEngine *DataEngineConsumer::dataEngine(const QString &name) { if (m_loadedEngines.contains(name)) { @@ -106,6 +112,8 @@ DataEngine *DataEngineConsumer::dataEngine(const QString &name) DataEngine *DataEngineConsumer::remoteDataEngine(const KUrl &location, const QString &name) { + Q_UNUSED(location); + Q_UNUSED(name); return 0; } diff --git a/declarativeimports/core/dataengineconsumer_p.h b/declarativeimports/core/dataengineconsumer_p.h index 579548033..3b2c574e0 100644 --- a/declarativeimports/core/dataengineconsumer_p.h +++ b/declarativeimports/core/dataengineconsumer_p.h @@ -57,6 +57,7 @@ public: ~DataEngineConsumer(); DataEngine *dataEngine(const QString &name); DataEngine *remoteDataEngine(const KUrl &location, const QString &name); + void finishedWithEngine(const QString &name); private: QSet m_loadedEngines; diff --git a/declarativeimports/core/datamodel.cpp b/declarativeimports/core/datamodel.cpp index 39386c0c8..2cc7d2593 100644 --- a/declarativeimports/core/datamodel.cpp +++ b/declarativeimports/core/datamodel.cpp @@ -20,6 +20,8 @@ #include "datamodel.h" #include "datasource_p.h" +#include + #include namespace Plasma @@ -81,10 +83,11 @@ void SortFilterModel::setModel(QObject *source) void SortFilterModel::setFilterRegExp(const QString &exp) { //FIXME: this delaying of the reset signal seems to make the views behave a bit better, i.e. less holes and avoids some crashes, in theory shouldn't be necessary + beginResetModel(); blockSignals(true); QSortFilterProxyModel::setFilterRegExp(QRegExp(exp, Qt::CaseInsensitive)); blockSignals(false); - reset(); + endResetModel(); } QString SortFilterModel::filterRegExp() const @@ -126,8 +129,13 @@ void SortFilterModel::setSortOrder(const Qt::SortOrder order) DataModel::DataModel(QObject* parent) : QAbstractItemModel(parent), m_dataSource(0), - m_maxRoleId(Qt::UserRole) + m_maxRoleId(Qt::UserRole+1) { + //There is one reserved role name: DataEngineSource + m_roleNames[m_maxRoleId] = "DataEngineSource"; + m_roleIds["DataEngineSource"] = m_maxRoleId; + ++m_maxRoleId; + setObjectName("DataModel"); connect(this, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SIGNAL(countChanged())); @@ -143,32 +151,44 @@ DataModel::~DataModel() void DataModel::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) { - if (!m_keyRoleFilter.isEmpty()) { - //a key that matches the one we want exists and is a list of DataEngine::Data - if (data.contains(m_keyRoleFilter) && data.value(m_keyRoleFilter).canConvert()) { - setItems(sourceName, data.value(m_keyRoleFilter).value()); - //try to match the key we want with a regular expression if set - } else { - QRegExp regExp(m_keyRoleFilter); - if (regExp.isValid()) { - QHash::const_iterator i; - QVariantList list; - for (i = data.constBegin(); i != data.constEnd(); ++i) { - if (regExp.exactMatch(i.key())) { - list.append(i.value()); - } - } - setItems(sourceName, list); - } - } - //an item is represented by a source: keys are roles m_roleLevel == FirstLevel - } else { + if (!m_sourceFilter.isEmpty() && m_sourceFilterRE.isValid() && !m_sourceFilterRE.exactMatch(sourceName)) { + return; + } + + if (m_keyRoleFilter.isEmpty()) { + //an item is represented by a source: keys are roles m_roleLevel == FirstLevel QVariantList list; - foreach (QVariant data, m_dataSource->data()) { - list.append(data.value()); + if (!m_dataSource->data().isEmpty()) { + QVariantHash::const_iterator i = m_dataSource->data().constBegin(); + + while (i != m_dataSource->data().constEnd()) { + QVariant value = i.value(); + if (value.isValid() && value.canConvert()) { + Plasma::DataEngine::Data data = value.value(); + data["DataEngineSource"] = i.key(); + list.append(data); + } + ++i; + } } setItems(QString(), list); + } else { + //a key that matches the one we want exists and is a list of DataEngine::Data + if (data.contains(m_keyRoleFilter) && + data.value(m_keyRoleFilter).canConvert()) { + setItems(sourceName, data.value(m_keyRoleFilter).value()); + } else if (m_keyRoleFilterRE.isValid()) { + //try to match the key we want with a regular expression if set + QVariantList list; + QHash::const_iterator i; + for (i = data.constBegin(); i != data.constEnd(); ++i) { + if (m_keyRoleFilterRE.exactMatch(i.key())) { + list.append(i.value()); + } + } + setItems(sourceName, list); + } } } @@ -183,8 +203,19 @@ void DataModel::setDataSource(QObject *object) return; } - disconnect(m_dataSource, 0, this, 0); + if (m_dataSource) { + disconnect(m_dataSource, 0, this, 0); + } + m_dataSource = source; + + const QHash data = source->data(); + QHash::const_iterator i = data.constBegin(); + while (i != data.constEnd()) { + dataUpdated(i.key(), i.value().value()); + ++i; + } + connect(m_dataSource, SIGNAL(newData(const QString &, const Plasma::DataEngine::Data &)), this, SLOT(dataUpdated(const QString &, const Plasma::DataEngine::Data &))); connect(m_dataSource, SIGNAL(sourceRemoved(const QString &)), this, SLOT(removeSource(const QString &))); @@ -196,13 +227,21 @@ QObject *DataModel::dataSource() const return m_dataSource; } -void DataModel::setKeyRoleFilter(const QString key) +void DataModel::setKeyRoleFilter(const QString& key) { + // the "key role filter" can be used in one of three ways: + // + // 1) empty string -> all data is used, each source is one row in the model + // 2) matches a key in the data exactly -> only that key/value pair is used, and the value is + // treated as a collection where each item in the collection becomes a row in the model + // 3) regular expression -> matches zero or more keys in the data, and each matching key/value + // pair becomes a row in the model if (m_keyRoleFilter == key) { return; } m_keyRoleFilter = key; + m_keyRoleFilterRE = QRegExp(m_keyRoleFilter); } QString DataModel::keyRoleFilter() const @@ -210,28 +249,62 @@ QString DataModel::keyRoleFilter() const return m_keyRoleFilter; } +void DataModel::setSourceFilter(const QString& key) +{ + if (m_sourceFilter == key) { + return; + } + + m_sourceFilter = key; + m_sourceFilterRE = QRegExp(key); + /* + FIXME: if the user changes the source filter, it won't immediately be reflected in the + available data + if (m_sourceFilterRE.isValid()) { + .. iterate through all items and weed out the ones that don't match .. + } + */ +} + +QString DataModel::sourceFilter() const +{ + return m_sourceFilter; +} + void DataModel::setItems(const QString &sourceName, const QVariantList &list) { - emit modelAboutToBeReset(); + beginResetModel(); //convert to vector, so data() will be O(1) m_items[sourceName] = list.toVector(); if (!list.isEmpty()) { if (list.first().canConvert()) { - foreach (const QString& roleName, list.first().value().keys()) { - if (!m_roleIds.contains(roleName)) { - ++m_maxRoleId; - m_roleNames[m_maxRoleId] = roleName.toLatin1(); - m_roleIds[roleName] = m_maxRoleId; + foreach (const QVariant &item, list) { + const QVariantHash &vh = item.value(); + QHashIterator it(vh); + while (it.hasNext()) { + it.next(); + const QString &roleName = it.key(); + if (!m_roleIds.contains(roleName)) { + ++m_maxRoleId; + m_roleNames[m_maxRoleId] = roleName.toLatin1(); + m_roleIds[roleName] = m_maxRoleId; + } } } } else { - foreach (const QString& roleName, list.first().value().keys()) { - if (!m_roleIds.contains(roleName)) { - ++m_maxRoleId; - m_roleNames[m_maxRoleId] = roleName.toLatin1(); - m_roleIds[roleName] = m_maxRoleId; + foreach (const QVariant &item, list) { + const QVariantMap &vh = item.value(); + QMapIterator it(vh); + while (it.hasNext()) { + it.next(); + const QString &roleName = it.key(); + if (!m_roleIds.contains(roleName)) { + ++m_maxRoleId; + m_roleNames[m_maxRoleId] = roleName.toLatin1(); + m_roleIds[roleName] = m_maxRoleId; + } } } } @@ -239,18 +312,36 @@ void DataModel::setItems(const QString &sourceName, const QVariantList &list) setRoleNames(m_roleNames); } + setRoleNames(m_roleNames); + //make the declarative view reload everything, //would be nice an incremental update but is not possible - emit modelReset(); + endResetModel(); } void DataModel::removeSource(const QString &sourceName) { //FIXME: this could be way more efficient by not resetting the whole model //FIXME: find a way to remove only the proper things also in the case where sources are items - emit modelAboutToBeReset(); - m_items.remove(sourceName); - emit modelReset(); + + if (m_keyRoleFilter.isEmpty()) { + //source name in the map, linear scan + for (int i = 0; i < m_items.value(QString()).count(); ++i) { + if (m_items.value(QString())[i].value().value("DataEngineSource") == sourceName) { + beginResetModel(); + m_items[QString()].remove(i); + endResetModel(); + break; + } + } + } else { + //source name as key of the map + if (m_items.contains(sourceName)) { + beginResetModel(); + m_items.remove(sourceName); + endResetModel(); + } + } } QVariant DataModel::data(const QModelIndex &index, int role) const @@ -275,7 +366,12 @@ QVariant DataModel::data(const QModelIndex &index, int role) const } } - if (m_items.value(source).value(actualRow).canConvert()) { + //is it the reserved role: DataEngineSource ? + //also, if each source is an item DataEngineSource is a role between all the others, otherwise we know it from the role variable + //finally, sub items are some times QVariantHash some times QVariantMaps + if (!m_keyRoleFilter.isEmpty() && m_roleNames.value(role) == "DataEngineSource") { + return source; + } else if (m_items.value(source).value(actualRow).canConvert()) { return m_items.value(source).value(actualRow).value().value(m_roleNames.value(role)); } else { return m_items.value(source).value(actualRow).value().value(m_roleNames.value(role)); diff --git a/declarativeimports/core/datamodel.h b/declarativeimports/core/datamodel.h index 0d9a35c37..744ec9e93 100644 --- a/declarativeimports/core/datamodel.h +++ b/declarativeimports/core/datamodel.h @@ -26,6 +26,7 @@ #include +class QTimer; namespace Plasma { @@ -87,6 +88,7 @@ class DataModel : public QAbstractItemModel Q_OBJECT Q_PROPERTY(QObject *dataSource READ dataSource WRITE setDataSource) Q_PROPERTY(QString keyRoleFilter READ keyRoleFilter WRITE setKeyRoleFilter) + Q_PROPERTY(QString sourceFilter READ sourceFilter WRITE setSourceFilter) Q_PROPERTY(int count READ count NOTIFY countChanged) public: @@ -96,9 +98,18 @@ public: void setDataSource(QObject *source); QObject *dataSource() const; - void setKeyRoleFilter(const QString key); + /** + * Include only items with a key that matches this regexp in the model + */ + void setKeyRoleFilter(const QString& key); QString keyRoleFilter() const; + /** + * Include only sources that matches this regexp in the model + */ + void setSourceFilter(const QString& key); + QString sourceFilter() const; + int roleNameToId(const QString &name); //Reimplemented @@ -118,8 +129,6 @@ protected: inline int countItems() const; Q_SIGNALS: - void modelAboutToBeReset(); - void modelReset(); void countChanged(); private Q_SLOTS: @@ -129,6 +138,9 @@ private Q_SLOTS: private: DataSource *m_dataSource; QString m_keyRoleFilter; + QRegExp m_keyRoleFilterRE; + QString m_sourceFilter; + QRegExp m_sourceFilterRE; QMap > m_items; QHash m_roleNames; QHash m_roleIds; diff --git a/declarativeimports/core/datasource.cpp b/declarativeimports/core/datasource.cpp index d59b57a1c..b33a38728 100644 --- a/declarativeimports/core/datasource.cpp +++ b/declarativeimports/core/datasource.cpp @@ -32,35 +32,39 @@ namespace Plasma { DataSource::DataSource(QObject* parent) : QObject(parent), - m_interval(1000), + m_interval(0), m_dataEngine(0) { setObjectName("DataSource"); - - connect(this, SIGNAL(engineChanged()), - this, SLOT(setupData())); - connect(this, SIGNAL(connectedSourcesChanged()), - this, SLOT(setupData())); - connect(this, SIGNAL(intervalChanged()), - this, SLOT(setupData())); } void DataSource::setConnectedSources(const QStringList &sources) { + bool sourcesChanged = false; foreach (const QString &source, sources) { if (!m_connectedSources.contains(source)) { - m_newSources.append(source); - } - } - foreach (const QString &source, m_connectedSources) { - if (!sources.contains(source)) { - m_oldSources.append(source); + sourcesChanged = true; + if (m_dataEngine) { + m_connectedSources.append(source); + m_dataEngine->connectSource(source, this, m_interval); + emit sourceConnected(source); + } } } - if (!m_newSources.isEmpty() || !m_oldSources.isEmpty()) { + foreach (const QString &source, m_connectedSources) { + if (!sources.contains(source)) { + m_data.remove(source); + sourcesChanged = true; + if (m_dataEngine) { + m_dataEngine->disconnectSource(source, this); + emit sourceDisconnected(source); + } + } + } + + if (sourcesChanged) { m_connectedSources = sources; - m_changes |= SourcesChanged; emit connectedSourcesChanged(); } } @@ -70,9 +74,9 @@ void DataSource::setEngine(const QString &e) if (e == m_engine) { return; } - m_engine = e; - m_changes |= DataEngineChanged; + m_engine = e; + setupData(); emit engineChanged(); } @@ -81,60 +85,44 @@ void DataSource::setInterval(const int interval) if (interval == m_interval) { return; } + m_interval = interval; - m_changes |= DataEngineChanged; + setupData(); emit intervalChanged(); } //TODO: event compression for this void DataSource::setupData() { + //FIXME: should all services be deleted just because we're changing the interval, etc? + qDeleteAll(m_services); + m_services.clear(); - if (m_changes & DataEngineChanged) { + Plasma::DataEngine *engine = dataEngine(m_engine); + if (!engine) { + kWarning() << "DataEngine" << m_engine << "not found"; + return; + } + + if (engine != m_dataEngine) { if (m_dataEngine) { - foreach (const QString &source, m_connectedSources) { - m_dataEngine->disconnectSource(source, this); - } + m_dataEngine->disconnect(this); + finishedWithEngine(m_dataEngine->pluginName()); } - //FIXME: delete all? - m_services.clear(); - m_dataEngine = dataEngine(m_engine); - if (!m_dataEngine) { - kWarning() << "DataEngine" << m_engine << "not found"; - return; - } - connect(m_dataEngine, SIGNAL(sourceAdded(const QString&)), this, SIGNAL(allSourcesChanged())); - connect(m_dataEngine, SIGNAL(sourceRemoved(const QString&)), this, SIGNAL(allSourcesChanged())); + m_dataEngine = engine; + connect(m_dataEngine, SIGNAL(sourceAdded(const QString&)), this, SIGNAL(sourcesChanged())); + 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(sourceRemoved(const QString&)), this, SLOT(removeSource(const QString&))); connect(m_dataEngine, SIGNAL(sourceRemoved(const QString&)), this, SIGNAL(sourceRemoved(const QString&))); - - //TODO: remove after event compression done - if (!(m_changes & SourcesChanged)) { - foreach (const QString &source, m_connectedSources) { - m_dataEngine->connectSource(source, this, m_interval); - emit sourceConnected(source); - } - } } - if (m_changes & SourcesChanged) { - if (m_dataEngine) { - foreach (const QString &source, m_oldSources) { - m_dataEngine->disconnectSource(source, this); - emit sourceDisconnected(source); - } - foreach (const QString &source, m_newSources) { - m_dataEngine->connectSource(source, this, m_interval); - emit sourceConnected(source); - } - m_oldSources.clear(); - m_newSources.clear(); - } + foreach (const QString &source, m_connectedSources) { + m_dataEngine->connectSource(source, this, m_interval); + emit sourceConnected(source); } - m_changes = NoChange; } void DataSource::dataUpdated(const QString &sourceName, const Plasma::DataEngine::Data &data) @@ -145,6 +133,8 @@ void DataSource::dataUpdated(const QString &sourceName, const Plasma::DataEngine emit dataChanged(); emit newData(sourceName, data); + } else if (m_dataEngine) { + m_dataEngine->disconnectSource(sourceName, this); } } @@ -154,30 +144,28 @@ void DataSource::removeSource(const QString &source) //TODO: emit those signals as last thing if (m_connectedSources.contains(source)) { + m_connectedSources.removeAll(source); emit sourceDisconnected(source); emit connectedSourcesChanged(); } - if (m_dataEngine) { - m_connectedSources.removeAll(source); - m_newSources.removeAll(source); - m_oldSources.removeAll(source); - //TODO: delete it? - m_services.remove(source); - } -} -QStringList DataSource::keysForSource(const QString &source) const -{ - if (!m_data.contains(source)) { - return QStringList(); + if (m_dataEngine) { + QHash::iterator it = m_services.find(source); + if (it != m_services.end()) { + delete it.value(); + m_services.erase(it); + } } - return m_data.value(source).value().keys(); } Plasma::Service *DataSource::serviceForSource(const QString &source) { if (!m_services.contains(source)) { - m_services[source] = m_dataEngine->serviceForSource(source); + Plasma::Service *service = m_dataEngine->serviceForSource(source); + if (!service) { + return 0; + } + m_services[source] = service; } return m_services.value(source); @@ -185,20 +173,26 @@ Plasma::Service *DataSource::serviceForSource(const QString &source) void DataSource::connectSource(const QString &source) { - m_newSources.append(source); + if (m_connectedSources.contains(source)) { + return; + } + m_connectedSources.append(source); - m_changes |= SourcesChanged; - emit sourceConnected(source); - emit connectedSourcesChanged(); + if (m_dataEngine) { + m_dataEngine->connectSource(source, this, m_interval); + emit sourceConnected(source); + emit connectedSourcesChanged(); + } } void DataSource::disconnectSource(const QString &source) { - m_oldSources.append(source); - m_connectedSources.removeAll(source); - m_changes |= SourcesChanged; - emit sourceDisconnected(source); - emit connectedSourcesChanged(); + if (m_dataEngine && m_connectedSources.contains(source)) { + m_connectedSources.removeAll(source); + m_dataEngine->disconnectSource(source, this); + emit sourceDisconnected(source); + emit connectedSourcesChanged(); + } } } diff --git a/declarativeimports/core/datasource_p.h b/declarativeimports/core/datasource_p.h index 2d2cb137d..371fd6e3a 100644 --- a/declarativeimports/core/datasource_p.h +++ b/declarativeimports/core/datasource_p.h @@ -55,12 +55,13 @@ public: DataSource(QObject* parent=0); Q_PROPERTY(bool valid READ valid) - bool valid() const {return m_dataEngine != 0;} + bool valid() const {return m_dataEngine && m_dataEngine->isValid();} Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged) int interval() const {return m_interval;} void setInterval(const int interval); + Q_PROPERTY(QString dataEngine READ engine WRITE setEngine NOTIFY engineChanged) Q_PROPERTY(QString engine READ engine WRITE setEngine NOTIFY engineChanged) QString engine() const {return m_engine;} void setEngine(const QString &e); @@ -72,10 +73,9 @@ public: Q_PROPERTY(QStringList sources READ sources NOTIFY sourcesChanged) QStringList sources() const {if (m_dataEngine) return m_dataEngine->sources(); else return QStringList();} - Q_PROPERTY(QVariantMap data READ data NOTIFY dataChanged); - QVariantMap data() const {return m_data;} + Q_PROPERTY(QVariantHash data READ data NOTIFY dataChanged); + QVariantHash data() const {return m_data;} - Q_INVOKABLE QStringList keysForSource(const QString &source) const; Q_INVOKABLE Plasma::Service *serviceForSource(const QString &source); Q_INVOKABLE void connectSource(const QString &source); @@ -102,13 +102,13 @@ private: QString m_id; int m_interval; QString m_engine; - QVariantMap m_data; + QVariantHash m_data; Plasma::DataEngine* m_dataEngine; QStringList m_connectedSources; QStringList m_oldSources; QStringList m_newSources; Changes m_changes; - QHash m_services; + QHash m_services; }; Q_DECLARE_OPERATORS_FOR_FLAGS(DataSource::Changes) } diff --git a/declarativeimports/core/declarativeitemcontainer.cpp b/declarativeimports/core/declarativeitemcontainer.cpp new file mode 100644 index 000000000..4d5ed88e1 --- /dev/null +++ b/declarativeimports/core/declarativeitemcontainer.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * 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 . * + ***************************************************************************/ + +#include "declarativeitemcontainer_p.h" + +#include + +DeclarativeItemContainer::DeclarativeItemContainer(QGraphicsItem *parent) + : QGraphicsWidget(parent) +{ +} + +DeclarativeItemContainer::~DeclarativeItemContainer() +{ +} + +void DeclarativeItemContainer::setDeclarativeItem(QDeclarativeItem *item, bool reparent) +{ + if (m_declarativeItem) { + disconnect(m_declarativeItem.data(), 0, this, 0); + } + m_declarativeItem = item; + if (reparent) { + static_cast(item)->setParentItem(this); + } + setMinimumWidth(item->implicitWidth()); + setMinimumHeight(item->implicitHeight()); + resize(item->width(), item->height()); + connect(m_declarativeItem.data(), SIGNAL(widthChanged()), this, SLOT(widthChanged())); + connect(m_declarativeItem.data(), SIGNAL(heightChanged()), this, SLOT(heightChanged())); +} + +QDeclarativeItem *DeclarativeItemContainer::declarativeItem() const +{ + return m_declarativeItem.data(); +} + +void DeclarativeItemContainer::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + if (m_declarativeItem) { + m_declarativeItem.data()->setProperty("width", event->newSize().width()); + m_declarativeItem.data()->setProperty("height", event->newSize().height()); + } +} + +void DeclarativeItemContainer::widthChanged() +{ + if (!m_declarativeItem) { + return; + } + + QSizeF newSize(size()); + newSize.setWidth(m_declarativeItem.data()->width()); + resize(newSize); +} + +void DeclarativeItemContainer::heightChanged() +{ + if (!m_declarativeItem) { + return; + } + + QSizeF newSize(size()); + newSize.setHeight(m_declarativeItem.data()->height()); + resize(newSize); +} + +#include "declarativeitemcontainer_p.moc" diff --git a/declarativeimports/core/declarativeitemcontainer_p.h b/declarativeimports/core/declarativeitemcontainer_p.h new file mode 100644 index 000000000..a92ce19bb --- /dev/null +++ b/declarativeimports/core/declarativeitemcontainer_p.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * 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 DECLARATIVEITEMCONTAINER_P +#define DECLARATIVEITEMCONTAINER_P + +#include +#include +#include +#include + + +class DeclarativeItemContainer : public QGraphicsWidget +{ + Q_OBJECT + +public: + DeclarativeItemContainer(QGraphicsItem *parent = 0); + ~DeclarativeItemContainer(); + + void setDeclarativeItem(QDeclarativeItem *item, bool reparent = true); + QDeclarativeItem *declarativeItem() const; + +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event); + +protected Q_SLOTS: + void widthChanged(); + void heightChanged(); + +private: + QWeakPointer m_declarativeItem; +}; + +#endif diff --git a/declarativeimports/core/dialog.cpp b/declarativeimports/core/dialog.cpp new file mode 100644 index 000000000..3b063f36e --- /dev/null +++ b/declarativeimports/core/dialog.cpp @@ -0,0 +1,316 @@ +/*************************************************************************** + * 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 . * + ***************************************************************************/ + +#include "dialog.h" +#include "declarativeitemcontainer_p.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + + +DialogMargins::DialogMargins(Plasma::Dialog *dialog, QObject *parent) + : QObject(parent), + m_dialog(dialog) +{ + checkMargins(); +} + +void DialogMargins::checkMargins() +{ + int left, top, right, bottom; + m_dialog->getContentsMargins(&left, &top, &right, &bottom); + + if (left != m_left) { + m_left = left; + emit leftChanged(); + } + if (top != m_top) { + m_top = top; + emit topChanged(); + } + if (right != m_right) { + m_right = right; + emit rightChanged(); + } + if (bottom != m_bottom) { + m_bottom = bottom; + emit bottomChanged(); + } +} + +int DialogMargins::left() const +{ + return m_left; +} + +int DialogMargins::top() const +{ + return m_top; +} + +int DialogMargins::right() const +{ + return m_right; +} + +int DialogMargins::bottom() const +{ + return m_bottom; +} + +DialogProxy::DialogProxy(QObject *parent) + : QObject(parent), + m_declarativeItemContainer(0), + m_activeWindow(false), + m_location(Plasma::Floating) +{ + m_dialog = new Plasma::Dialog(); + m_margins = new DialogMargins(m_dialog, this); + m_dialog->installEventFilter(this); + m_flags = m_dialog->windowFlags(); +} + +DialogProxy::~DialogProxy() +{ + delete m_dialog; + delete m_declarativeItemContainer; +} + +QGraphicsObject *DialogProxy::mainItem() const +{ + return m_mainItem.data(); +} + +void DialogProxy::setMainItem(QGraphicsObject *mainItem) +{ + if (m_mainItem.data() != mainItem) { + if (m_mainItem) { + m_mainItem.data()->setParent(mainItem ? mainItem->parent() : 0); + } + + m_mainItem = mainItem; + + if (mainItem) { + mainItem->setParentItem(0); + mainItem->setParent(this); + } + + //if this is called in Compenent.onCompleted we have to wait a loop the item is added to a scene + QTimer::singleShot(0, this, SLOT(syncMainItem())); + emit mainItemChanged(); + } +} + +void DialogProxy::syncMainItem() +{ + if (!m_mainItem) { + 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) { + QObject *parent = m_mainItem.data(); + while ((parent = parent->parent())) { + QGraphicsObject *qo = qobject_cast(parent); + if (qo) { + scene = qo->scene(); + if (scene) { + scene->addItem(m_mainItem.data()); + break; + } + } + } + } + + if (!scene) { + return; + } + + //the parent of the qobject never changed, only the parentitem, so put it back what it was + m_mainItem.data()->setParentItem(qobject_cast(m_mainItem.data()->parent())); + + QGraphicsWidget *widget = qobject_cast(m_mainItem.data()); + if (widget) { + if (m_declarativeItemContainer) { + m_declarativeItemContainer->deleteLater(); + m_declarativeItemContainer = 0; + } + } else { + QDeclarativeItem *di = qobject_cast(m_mainItem.data()); + if (di) { + if (!m_declarativeItemContainer) { + m_declarativeItemContainer = new DeclarativeItemContainer(); + scene->addItem(m_declarativeItemContainer); + } + m_declarativeItemContainer->setDeclarativeItem(di); + widget = m_declarativeItemContainer; + } + } + m_dialog->setGraphicsWidget(widget); +} + +bool DialogProxy::isVisible() const +{ + return m_dialog->isVisible(); +} + +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(); + } + } +} + +QPoint DialogProxy::popupPosition(QGraphicsObject *item, int alignment) const +{ + if (!item) { + return QPoint(); + } + Plasma::Corona *corona = qobject_cast(item->scene()); + if (corona) { + return corona->popupPosition(item, m_dialog->size(), (Qt::AlignmentFlag)alignment); + } else { + return QPoint(); + } +} + + +int DialogProxy::x() const +{ + return m_dialog->pos().x(); +} + +void DialogProxy::setX(int x) +{ + m_dialog->move(x, m_dialog->pos().y()); +} + +int DialogProxy::y() const +{ + return m_dialog->pos().y(); +} + +void DialogProxy::setY(int y) +{ + m_dialog->move(m_dialog->pos().x(), y); +} + +int DialogProxy::width() const +{ + return m_dialog->size().width(); +} + +int DialogProxy::height() const +{ + return m_dialog->size().height(); +} + +bool DialogProxy::isActiveWindow() const +{ + return m_activeWindow; +} + +int DialogProxy::windowFlags() const +{ + return (int)m_dialog->windowFlags(); +} + +void DialogProxy::setWindowFlags(const int flags) +{ + m_flags = (Qt::WindowFlags)flags; + m_dialog->setWindowFlags((Qt::WindowFlags)flags); +} + +int DialogProxy::location() const +{ + return (int)m_location; +} + +void DialogProxy::setLocation(int location) +{ + if (m_location == location) { + return; + } + m_location = (Plasma::Location)location; + emit locationChanged(); +} + + +QObject *DialogProxy::margins() const +{ + return m_margins; +} + +bool DialogProxy::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == m_dialog && event->type() == QEvent::Move) { + QMoveEvent *me = static_cast(event); + if (me->oldPos().x() != me->pos().x()) { + emit xChanged(); + } + if (me->oldPos().y() != me->pos().y()) { + emit yChanged(); + } + if ((me->oldPos().x() != me->pos().x()) || (me->oldPos().y() != me->pos().y())) { + m_margins->checkMargins(); + } + } else if (watched == m_dialog && event->type() == QEvent::Resize) { + QResizeEvent *re = static_cast(event); + if (re->oldSize().width() != re->size().width()) { + emit widthChanged(); + } + if (re->oldSize().height() != re->size().height()) { + emit heightChanged(); + } + } else if (watched == m_dialog && event->type() == QEvent::Show) { + Plasma::WindowEffects::slideWindow(m_dialog, m_location); + emit visibleChanged(); + } else if (watched == m_dialog && event->type() == QEvent::Hide) { + Plasma::WindowEffects::slideWindow(m_dialog, m_location); + emit visibleChanged(); + } else if (watched == m_dialog && event->type() == QEvent::WindowActivate) { + m_activeWindow = true; + emit activeWindowChanged(); + } else if (watched == m_dialog && event->type() == QEvent::WindowDeactivate) { + m_activeWindow = false; + emit activeWindowChanged(); + } + return false; +} + +void DialogProxy::setAttribute(int attribute, bool on) +{ + m_dialog->setAttribute((Qt::WidgetAttribute)attribute, on); +} + +#include "dialog.moc" + diff --git a/declarativeimports/core/dialog.h b/declarativeimports/core/dialog.h new file mode 100644 index 000000000..a871a80d1 --- /dev/null +++ b/declarativeimports/core/dialog.h @@ -0,0 +1,153 @@ +/*************************************************************************** + * 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 DIALOG_PROXY_P +#define DIALOG_PROXY_P + +#include +#include +#include + +#include + +class QGraphicsObject; + +namespace Plasma +{ + class Dialog; +} + +class DeclarativeItemContainer; + +class DialogMargins : public QObject +{ + Q_OBJECT + + Q_PROPERTY(int left READ left NOTIFY leftChanged) + Q_PROPERTY(int top READ top NOTIFY topChanged) + Q_PROPERTY(int right READ right NOTIFY rightChanged) + Q_PROPERTY(int bottom READ bottom NOTIFY bottomChanged) + +public: + DialogMargins(Plasma::Dialog *dialog, QObject *parent = 0); + + int left() const; + int top() const; + int right() const; + int bottom() const; + +Q_SIGNALS: + void leftChanged(); + void rightChanged(); + void topChanged(); + void bottomChanged(); + +protected: + void checkMargins(); + +private: + int m_left; + int m_top; + int m_right; + int m_bottom; + Plasma::Dialog *m_dialog; + friend class DialogProxy; +}; + +class DialogProxy : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QGraphicsObject *mainItem READ mainItem WRITE setMainItem NOTIFY mainItemChanged) + Q_PROPERTY(bool visible READ isVisible WRITE setVisible NOTIFY visibleChanged) + Q_PROPERTY(int x READ x WRITE setX NOTIFY xChanged) + Q_PROPERTY(int y READ y WRITE setY NOTIFY yChanged) + //to set the size try to force doing so from the inner item + Q_PROPERTY(int width READ width NOTIFY widthChanged) + Q_PROPERTY(int height READ height NOTIFY heightChanged) + Q_PROPERTY(int windowFlags READ windowFlags WRITE setWindowFlags) + Q_PROPERTY(QObject *margins READ margins CONSTANT) + Q_PROPERTY(bool activeWindow READ isActiveWindow NOTIFY activeWindowChanged) + Q_PROPERTY(int location READ location WRITE setLocation NOTIFY locationChanged) + +public: + enum WidgetAttribute { + WA_X11NetWmWindowTypeDock = Qt::WA_X11NetWmWindowTypeDock + }; + + DialogProxy(QObject *parent = 0); + ~DialogProxy(); + + QGraphicsObject *mainItem() const; + void setMainItem(QGraphicsObject *mainItem); + + bool isVisible() const; + void setVisible(const bool visible); + + int x() const; + void setX(int x); + + int y() const; + void setY(int y); + + int width() const; + int height() const; + + bool isActiveWindow() const; + + //FIXME: passing an int is ugly + int windowFlags() const; + void setWindowFlags(const int); + + int location() const; + void setLocation(int location); + + QObject *margins() const; + + //FIXME: alignment should be Qt::AlignmentFlag + Q_INVOKABLE QPoint popupPosition(QGraphicsObject *item, int alignment=Qt::AlignLeft) const; + //FIXME:: Qt::WidgetAttribute should be already + Q_INVOKABLE void setAttribute(int attribute, bool on); + +Q_SIGNALS: + void mainItemChanged(); + void visibleChanged(); + void xChanged(); + void yChanged(); + void widthChanged(); + void heightChanged(); + void activeWindowChanged(); + void locationChanged(); + +protected Q_SLOTS: + void syncMainItem(); + +protected: + bool eventFilter(QObject *watched, QEvent *event); + +private: + Plasma::Dialog *m_dialog; + Qt::WindowFlags m_flags; + DeclarativeItemContainer *m_declarativeItemContainer; + QWeakPointer m_mainItem; + DialogMargins *m_margins; + bool m_activeWindow; + Plasma::Location m_location; +}; + +#endif diff --git a/declarativeimports/core/framesvgitem.cpp b/declarativeimports/core/framesvgitem.cpp index 1a9f811b2..4c030f356 100644 --- a/declarativeimports/core/framesvgitem.cpp +++ b/declarativeimports/core/framesvgitem.cpp @@ -71,6 +71,7 @@ FrameSvgItem::~FrameSvgItem() void FrameSvgItem::setImagePath(const QString &path) { m_frameSvg->setImagePath(path); + m_frameSvg->setElementPrefix(m_prefix); update(); } @@ -83,12 +84,13 @@ QString FrameSvgItem::imagePath() const void FrameSvgItem::setPrefix(const QString &prefix) { m_frameSvg->setElementPrefix(prefix); + m_prefix = prefix; update(); } QString FrameSvgItem::prefix() const { - return m_frameSvg->prefix(); + return m_prefix; } FrameSvgItemMargins *FrameSvgItem::margins() const diff --git a/declarativeimports/core/framesvgitem_p.h b/declarativeimports/core/framesvgitem_p.h index abdb42a79..f6cf16284 100644 --- a/declarativeimports/core/framesvgitem_p.h +++ b/declarativeimports/core/framesvgitem_p.h @@ -88,6 +88,7 @@ private Q_SLOTS: private: Plasma::FrameSvg *m_frameSvg; FrameSvgItemMargins *m_margins; + QString m_prefix; }; } diff --git a/declarativeimports/core/svgitem.cpp b/declarativeimports/core/svgitem.cpp index 0cb30ef99..ae246e717 100644 --- a/declarativeimports/core/svgitem.cpp +++ b/declarativeimports/core/svgitem.cpp @@ -69,9 +69,11 @@ void SvgItem::setSvg(Plasma::Svg *svg) disconnect(m_svg.data(), 0, this, 0); } m_svg = svg; - connect(svg, SIGNAL(repaintNeeded()), this, SLOT(update())); - connect(svg, SIGNAL(repaintNeeded()), this, SIGNAL(naturalSizeChanged())); - connect(svg, SIGNAL(sizeChanged()), this, SIGNAL(naturalSizeChanged())); + if (svg) { + connect(svg, SIGNAL(repaintNeeded()), this, SLOT(updateNeeded())); + connect(svg, SIGNAL(repaintNeeded()), this, SIGNAL(naturalSizeChanged())); + connect(svg, SIGNAL(sizeChanged()), this, SIGNAL(naturalSizeChanged())); + } emit naturalSizeChanged(); } @@ -115,6 +117,11 @@ void SvgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); } +void SvgItem::updateNeeded() +{ + update(); +} + } // Plasma namespace #include "svgitem_p.moc" diff --git a/declarativeimports/core/svgitem_p.h b/declarativeimports/core/svgitem_p.h index 25cd4be91..d9ad33e33 100644 --- a/declarativeimports/core/svgitem_p.h +++ b/declarativeimports/core/svgitem_p.h @@ -54,6 +54,9 @@ public: Q_SIGNALS: void naturalSizeChanged(); +protected Q_SLOTS: + void updateNeeded(); + private: QWeakPointer m_svg; QString m_elementID; diff --git a/declarativeimports/core/theme.cpp b/declarativeimports/core/theme.cpp index b793c5ff5..a271d88e2 100644 --- a/declarativeimports/core/theme.cpp +++ b/declarativeimports/core/theme.cpp @@ -21,6 +21,109 @@ #include +class FontProxySingleton +{ +public: + FontProxy self; +}; + +K_GLOBAL_STATIC(FontProxySingleton, privateFontProxySingleton) + +FontProxy::FontProxy(QObject *parent) + : QObject(parent) +{ + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(boldChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(capitalizationChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(familyChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(italicChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(letterSpacingChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(pixelSizeChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(pointSizeChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(strikeOutChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(underlineChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(weightChanged())); + connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), + this, SLOT(wordSpacingChanged())); +} + +FontProxy::~FontProxy() +{ +} + +FontProxy *FontProxy::self() +{ + return &privateFontProxySingleton->self; +} + +bool FontProxy::bold() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).bold(); +} + +FontProxy::Capitalization FontProxy::capitalization() const +{ + return (FontProxy::Capitalization)Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).capitalization(); +} + +QString FontProxy::family() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).family(); +} + +bool FontProxy::italic() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).italic(); +} + +qreal FontProxy::letterSpacing() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).letterSpacing(); +} + +int FontProxy::pixelSize() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).pixelSize(); +} + +qreal FontProxy::pointSize() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).pointSize(); +} + +bool FontProxy::strikeOut() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).strikeOut(); +} + +bool FontProxy::underline() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).underline(); +} + +FontProxy::Weight FontProxy::weight() const +{ + return (FontProxy::Weight)Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).weight(); +} + +qreal FontProxy::wordSpacing() const +{ + return Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont).wordSpacing(); +} + + + +//********** Theme ************* + ThemeProxy::ThemeProxy(QObject *parent) : QObject(parent) { @@ -31,6 +134,41 @@ ThemeProxy::~ThemeProxy() { } +QString ThemeProxy::themeName() const +{ + return Plasma::Theme::defaultTheme()->themeName(); +} + +QObject *ThemeProxy::font() const +{ + return FontProxy::self(); +} + +bool ThemeProxy::windowTranslucencyEnabled() const +{ + return Plasma::Theme::defaultTheme()->windowTranslucencyEnabled(); +} + +KUrl ThemeProxy::homepage() const +{ + return Plasma::Theme::defaultTheme()->homepage(); +} + +bool ThemeProxy::useGlobalSettings() const +{ + return Plasma::Theme::defaultTheme()->useGlobalSettings(); +} + +QString ThemeProxy::wallpaperPath() const +{ + return Plasma::Theme::defaultTheme()->wallpaperPath(); +} + +QString ThemeProxy::wallpaperPathForSize(int width, int height) const +{ + return Plasma::Theme::defaultTheme()->wallpaperPath(QSize(width, height)); +} + QColor ThemeProxy::textColor() const { return Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor); @@ -96,6 +234,11 @@ QColor ThemeProxy::viewFocusColor() const return Plasma::Theme::defaultTheme()->color(Plasma::Theme::ViewFocusColor); } +QString ThemeProxy::styleSheet() const +{ + return Plasma::Theme::defaultTheme()->styleSheet(QString()); +} + #include "theme_p.moc" diff --git a/declarativeimports/core/theme_p.h b/declarativeimports/core/theme_p.h index 86b6def12..a58bedf08 100644 --- a/declarativeimports/core/theme_p.h +++ b/declarativeimports/core/theme_p.h @@ -21,12 +21,89 @@ #include +#include +#include #include +class FontProxy : public QObject +{ + Q_OBJECT + Q_PROPERTY(bool bold READ bold NOTIFY boldChanged) + Q_PROPERTY(Capitalization capitalization READ capitalization NOTIFY capitalizationChanged ) + Q_PROPERTY(QString family READ family NOTIFY familyChanged ) + Q_PROPERTY(bool italic READ italic NOTIFY italicChanged ) + Q_PROPERTY(qreal letterSpacing READ letterSpacing NOTIFY letterSpacingChanged ) + Q_PROPERTY(int pixelSize READ pixelSize NOTIFY pixelSizeChanged ) + Q_PROPERTY(qreal pointSize READ pointSize NOTIFY pointSizeChanged ) + Q_PROPERTY(bool strikeOut READ strikeOut NOTIFY strikeOutChanged ) + Q_PROPERTY(bool underline READ underline NOTIFY underlineChanged ) + Q_PROPERTY(Weight weight READ weight NOTIFY weightChanged ) + Q_PROPERTY(qreal wordSpacing READ wordSpacing NOTIFY wordSpacingChanged ) + + Q_ENUMS(Capitalization) + Q_ENUMS(Weight) + +public: + enum Capitalization { + MixedCase = 0, + AllUppercase = 1, + AllLowercase = 2, + SmallCaps = 3, + Capitalize = 4 + }; + + enum Weight { + Light = 25, + Normal = 50, + DemiBold = 63, + Bold = 75, + Black = 87 + }; + + FontProxy(QObject *parent = 0); + ~FontProxy(); + static FontProxy *self(); + + bool bold() const; + Capitalization capitalization() const; + QString family() const; + bool italic() const; + qreal letterSpacing() const; + int pixelSize() const; + qreal pointSize() const; + bool strikeOut() const; + bool underline() const; + Weight weight() const; + qreal wordSpacing() const; + +Q_SIGNALS: + void boldChanged(); + void capitalizationChanged(); + void familyChanged(); + void italicChanged(); + void letterSpacingChanged(); + void pixelSizeChanged(); + void pointSizeChanged(); + void strikeOutChanged(); + void underlineChanged(); + void weightChanged(); + void wordSpacingChanged(); +}; + class ThemeProxy : public QObject { Q_OBJECT + Q_PROPERTY(QString themeName READ themeName NOTIFY themeChanged) + Q_PROPERTY(bool windowTranslucentEnabled READ windowTranslucencyEnabled NOTIFY themeChanged) + Q_PROPERTY(KUrl homepage READ homepage NOTIFY themeChanged) + Q_PROPERTY(bool useGlobalSettings READ useGlobalSettings NOTIFY themeChanged) + Q_PROPERTY(QString wallpaperPath READ wallpaperPath NOTIFY themeChanged) + + //fonts + Q_PROPERTY(QObject *font READ font CONSTANT) + + // colors Q_PROPERTY(QColor textColor READ textColor NOTIFY themeChanged) Q_PROPERTY(QColor highlightColor READ highlightColor NOTIFY themeChanged) Q_PROPERTY(QColor backgroundColor READ backgroundColor NOTIFY themeChanged) @@ -41,11 +118,20 @@ class ThemeProxy : public QObject Q_PROPERTY(QColor viewBackgroundColor READ viewBackgroundColor NOTIFY themeChanged) Q_PROPERTY(QColor viewHoverColor READ viewHoverColor NOTIFY themeChanged) Q_PROPERTY(QColor viewFocusColor READ viewFocusColor NOTIFY themeChanged) + Q_PROPERTY(QString styleSheet READ styleSheet NOTIFY themeChanged) public: ThemeProxy(QObject *parent = 0); ~ThemeProxy(); + QString themeName() const; + QObject *font() const; + bool windowTranslucencyEnabled() const; + KUrl homepage() const; + bool useGlobalSettings() const; + QString wallpaperPath() const; + Q_INVOKABLE QString wallpaperPathForSize(int width=-1, int height=-1) const; + QColor textColor() const; QColor highlightColor() const; QColor backgroundColor() const; @@ -59,6 +145,7 @@ public: QColor viewBackgroundColor() const; QColor viewHoverColor() const; QColor viewFocusColor() const; + QString styleSheet() const; Q_SIGNALS: void themeChanged(); diff --git a/declarativeimports/core/tooltip.cpp b/declarativeimports/core/tooltip.cpp new file mode 100644 index 000000000..966450ce5 --- /dev/null +++ b/declarativeimports/core/tooltip.cpp @@ -0,0 +1,168 @@ +/*************************************************************************** + * Copyright 2011 Marco Martin * + * Copyright 2011 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 "tooltip.h" +#include "declarativeitemcontainer_p.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +ToolTipProxy::ToolTipProxy(QObject *parent) + : QObject(parent), m_mainText(""), m_subText(""), m_widget(0) +{ + connect(this, SIGNAL(targetChanged()), this, SLOT(updateToolTip())); + connect(this, SIGNAL(mainTextChanged()), this, SLOT(updateToolTip())); + connect(this, SIGNAL(subTextChanged()), this, SLOT(updateToolTip())); + connect(this, SIGNAL(imageChanged()), this, SLOT(updateToolTip())); +} + +ToolTipProxy::~ToolTipProxy() +{ +} + +QGraphicsObject *ToolTipProxy::target() const +{ + return m_target.data(); +} + +void ToolTipProxy::setTarget(QGraphicsObject *target) +{ + if (m_target.data() != target) { + m_target = target; + + m_widget = qobject_cast(m_target.data()); + if (!m_widget) { + // if this is called in Compenent.onCompleted we have to + // wait a loop for the item to be added to a scene + QTimer::singleShot(0, this, SLOT(syncTarget())); + return; + } + emit targetChanged(); + } +} + +void ToolTipProxy::syncTarget() +{ + // find the scene + QGraphicsScene *scene = m_target.data()->scene(); + if (!scene) { + QObject *parent = m_target.data(); + while ((parent = parent->parent())) { + QGraphicsObject *qo = qobject_cast(parent); + if (qo) { + scene = qo->scene(); + scene->addItem(m_target.data()); + break; + } + } + } + + QDeclarativeItem *item = qobject_cast(m_target.data()); + if (!item) { + return; + } + + if (!m_declarativeItemContainer) { + 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); + m_declarativeItemContainer.data()->setAcceptHoverEvents(true); + m_declarativeItemContainer.data()->setParentItem(m_target.data()); + m_widget = m_declarativeItemContainer.data(); + emit targetChanged(); + } +} + +QString ToolTipProxy::mainText() const +{ + return m_mainText; +} + +void ToolTipProxy::setMainText(const QString &text) +{ + if (text == m_mainText) { + return; + } + + m_mainText = text; + emit mainTextChanged(); +} + +QString ToolTipProxy::subText() const +{ + return m_subText; +} + +void ToolTipProxy::setSubText(const QString &text) +{ + if (text == m_subText) { + return; + } + + m_subText = text; + emit subTextChanged(); +} + +// ###TODO: SHOULD BE PIXMAP OR QICON?? +QString ToolTipProxy::image() const +{ + return m_image; +} + +void ToolTipProxy::setImage(const QString &name) +{ + if (name == m_image) { + return; + } + + m_image = name; + emit imageChanged(); +} + +void ToolTipProxy::updateToolTip() +{ + if (!m_widget) { + return; + } + + Plasma::ToolTipContent data; + data.setMainText(m_mainText); + data.setSubText(m_subText); + data.setImage(KIcon(m_image).pixmap(IconSize(KIconLoader::Desktop))); + Plasma::ToolTipManager::self()->setContent(m_widget, data); +} + +#include "tooltip.moc" + diff --git a/declarativeimports/core/tooltip.h b/declarativeimports/core/tooltip.h new file mode 100644 index 000000000..59658582e --- /dev/null +++ b/declarativeimports/core/tooltip.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright 2011 Marco Martin * + * Copyright 2011 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 . * + ***************************************************************************/ + +#ifndef TOOLTIP_PROXY_P +#define TOOLTIP_PROXY_P + +#include +#include + +class QGraphicsObject; +class QGraphicsWidget; +class DeclarativeItemContainer; + +class ToolTipProxy : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QGraphicsObject *target READ target WRITE setTarget NOTIFY targetChanged) + Q_PROPERTY(QString mainText READ mainText WRITE setMainText NOTIFY mainTextChanged) + Q_PROPERTY(QString subText READ subText WRITE setSubText NOTIFY subTextChanged) + Q_PROPERTY(QString image READ image WRITE setImage NOTIFY imageChanged) + +public: + ToolTipProxy(QObject *parent = 0); + ~ToolTipProxy(); + + QGraphicsObject *target() const; + void setTarget(QGraphicsObject *target); + + QString mainText() const; + void setMainText(const QString &text); + + QString subText() const; + void setSubText(const QString &text); + + // SHOULD BE PIXMAP OR QICON + QString image() const; + void setImage(const QString &name); + +Q_SIGNALS: + void targetChanged(); + void mainTextChanged(); + void subTextChanged(); + void imageChanged(); + +protected Q_SLOTS: + void syncTarget(); + void updateToolTip(); + +private: + QString m_mainText; + QString m_subText; + QString m_image; + QGraphicsWidget *m_widget; + QWeakPointer m_declarativeItemContainer; + QWeakPointer m_target; +}; + +#endif diff --git a/declarativeimports/draganddrop/CMakeLists.txt b/declarativeimports/draganddrop/CMakeLists.txt new file mode 100644 index 000000000..5450873c7 --- /dev/null +++ b/declarativeimports/draganddrop/CMakeLists.txt @@ -0,0 +1,27 @@ +project(draganddrop) + +include(KDE4Defaults) + +set(declarativedragdrop_SRCS + draganddropplugin.cpp + DeclarativeDragArea.cpp + DeclarativeDragDropEvent.cpp + DeclarativeDropArea.cpp + DeclarativeMimeData.cpp + ) + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${KDE4_INCLUDES} +) + +qt4_automoc(${declarativedragdrop_SRCS}) + + +kde4_add_library(dragdropplugin SHARED ${declarativedragdrop_SRCS}) +target_link_libraries(dragdropplugin ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) + +install(TARGETS dragdropplugin 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 new file mode 100644 index 000000000..93943e609 --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeDragArea.cpp @@ -0,0 +1,186 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "DeclarativeDragArea.h" +#include "DeclarativeMimeData.h" + +#include +#include +#include +#include +#include +#include + +/*! + A DragArea is used to make an item draggable. +*/ + +DeclarativeDragArea::DeclarativeDragArea(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_delegate(0), + m_source(0), + m_target(0), + m_enabled(true), + m_supportedActions(Qt::MoveAction), + m_defaultAction(Qt::MoveAction), + 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); +} + +DeclarativeDragArea::~DeclarativeDragArea() +{ + if (m_data) { + delete m_data; + } +} + +/*! + The delegate is the item that will be displayed next to the mouse cursor during the drag and drop operation. + It usually consists of a large, semi-transparent icon representing the data being dragged. +*/ +QDeclarativeComponent* DeclarativeDragArea::delegate() const +{ + return m_delegate; +} +void DeclarativeDragArea::setDelegate(QDeclarativeComponent *delegate) +{ + if (m_delegate != delegate) { + m_delegate = delegate; + emit delegateChanged(); + } +} +void DeclarativeDragArea::resetDelegate() +{ + setDelegate(0); +} + +/*! + The QML element that is the source of this drag and drop operation. This can be defined to any item, and will + be available to the DropArea as event.data.source +*/ +QDeclarativeItem* DeclarativeDragArea::source() const +{ + return m_source; +} +void DeclarativeDragArea::setSource(QDeclarativeItem* source) +{ + if (m_source != source) { + m_source = source; + emit sourceChanged(); + } +} +void DeclarativeDragArea::resetSource() +{ + setSource(0); +} + +// target +QDeclarativeItem* DeclarativeDragArea::target() const +{ + //TODO: implement me + return 0; +} + +// data +DeclarativeMimeData* DeclarativeDragArea::data() const +{ + return m_data; +} + +// enabled +bool DeclarativeDragArea::isEnabled() const +{ + return m_enabled; +} +void DeclarativeDragArea::setEnabled(bool enabled) +{ + if (enabled != m_enabled) { + m_enabled = enabled; + emit enabledChanged(); + } +} + +// supported actions +Qt::DropActions DeclarativeDragArea::supportedActions() const +{ + return m_supportedActions; +} +void DeclarativeDragArea::setSupportedActions(Qt::DropActions actions) +{ + if (actions != m_supportedActions) { + m_supportedActions = actions; + emit supportedActionsChanged(); + } +} + +// default action +Qt::DropAction DeclarativeDragArea::defaultAction() const +{ + return m_defaultAction; +} +void DeclarativeDragArea::setDefaultAction(Qt::DropAction action) +{ + if (action != m_defaultAction) { + m_defaultAction = action; + emit defaultActionChanged(); + } +} + +void DeclarativeDragArea::mouseMoveEvent(QGraphicsSceneMouseEvent *event) +{ + if ( !m_enabled + || QLineF(event->screenPos(), event->buttonDownScreenPos(Qt::LeftButton)).length() + < QApplication::startDragDistance()) { + return; + } + + QDrag *drag = new QDrag(event->widget()); + DeclarativeMimeData* dataCopy = new DeclarativeMimeData(m_data); //Qt will take ownership of this copy and delete it. + drag->setMimeData(dataCopy); + + if (m_delegate) { + + // Render the delegate to a Pixmap + + QDeclarativeItem* item = qobject_cast(m_delegate->create()); + + QGraphicsScene scene; + scene.addItem(item); + + QPixmap pixmap(scene.sceneRect().width(), scene.sceneRect().height()); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + scene.render(&painter); + + drag->setPixmap(pixmap); + drag->setHotSpot(QPoint(0, 0)); // TODO: Make a property for that + } + + //setCursor(Qt::OpenHandCursor); //TODO? Make a property for the cursor + + Qt::DropAction action = drag->exec(m_supportedActions, m_defaultAction); + emit drop(action); +} diff --git a/declarativeimports/draganddrop/DeclarativeDragArea.h b/declarativeimports/draganddrop/DeclarativeDragArea.h new file mode 100644 index 000000000..f2f638c14 --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeDragArea.h @@ -0,0 +1,95 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef DECLARATIVEDRAGAREA_H +#define DECLARATIVEDRAGAREA_H + +#include + +class QDeclarativeComponent; +class DeclarativeMimeData; + +class DeclarativeDragArea : public QDeclarativeItem +{ + Q_OBJECT + 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(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) + + +public: + DeclarativeDragArea(QDeclarativeItem *parent=0); + ~DeclarativeDragArea(); + + QDeclarativeComponent *delegate() const; + void setDelegate(QDeclarativeComponent* delegate); + void resetDelegate(); + + QDeclarativeItem* target() const; + QDeclarativeItem* source() const; + void setSource(QDeclarativeItem* source); + void resetSource(); + + bool isEnabled() const; + void setEnabled(bool enabled); + + //supported actions + Qt::DropActions supportedActions() const; + void setSupportedActions(Qt::DropActions actions); + + //default action + Qt::DropAction defaultAction() const; + void setDefaultAction(Qt::DropAction action); + + DeclarativeMimeData* data() const; + +signals: + void delegateChanged(); + void sourceChanged(); + void targetChanged(); + void dataChanged(); + void enabledChanged(); + void drop(int action); + void supportedActionsChanged(); + void defaultActionChanged(); + +protected: + void mouseMoveEvent(QGraphicsSceneMouseEvent *event); + void mousePressEvent(QGraphicsSceneMouseEvent *) {} + void mouseReleaseEvent(QGraphicsSceneMouseEvent *) {} + +private: + QDeclarativeComponent* m_delegate; + QDeclarativeItem* m_source; + QDeclarativeItem* m_target; + bool m_enabled; + Qt::DropActions m_supportedActions; + Qt::DropAction m_defaultAction; + DeclarativeMimeData* const m_data; +}; + +#endif // DECLARATIVEDRAGAREA_H diff --git a/declarativeimports/draganddrop/DeclarativeDragDropEvent.cpp b/declarativeimports/draganddrop/DeclarativeDragDropEvent.cpp new file mode 100644 index 000000000..765386259 --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeDragDropEvent.cpp @@ -0,0 +1,42 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "DeclarativeDragDropEvent.h" + +DeclarativeDragDropEvent::DeclarativeDragDropEvent(QGraphicsSceneDragDropEvent* e, QObject* parent) : + QObject(parent), + m_x(e->pos().x()), + m_y(e->pos().y()), + m_buttons(e->buttons()), + m_modifiers(e->modifiers()), + m_data(e->mimeData()), + m_event(e) +{ + +} + +void DeclarativeDragDropEvent::accept(int action) +{ + m_event->setDropAction( (Qt::DropAction) action ); + m_event->accept(); +} diff --git a/declarativeimports/draganddrop/DeclarativeDragDropEvent.h b/declarativeimports/draganddrop/DeclarativeDragDropEvent.h new file mode 100644 index 000000000..824650541 --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeDragDropEvent.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef DECLARATIVEDRAGDROPEVENT_H +#define DECLARATIVEDRAGDROPEVENT_H + +#include +#include +#include "DeclarativeMimeData.h" + +class DeclarativeDragDropEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int x READ x) + 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(Qt::DropActions possibleActions READ possibleActions) + Q_PROPERTY(Qt::DropAction proposedAction READ proposedAction) + +public: + + DeclarativeDragDropEvent(QGraphicsSceneDragDropEvent* e, QObject* parent = 0); + + int x() const { return m_x; } + int y() const { return m_y; } + int buttons() const { return m_buttons; } + int modifiers() const { return m_modifiers; } + DeclarativeMimeData* data() { return &m_data; } + Qt::DropAction proposedAction() const { return m_event->proposedAction(); } + Qt::DropActions possibleActions() const { return m_event->possibleActions(); } + +public slots: + void accept(int action); + +private: + int m_x; + int m_y; + Qt::MouseButtons m_buttons; + Qt::KeyboardModifiers m_modifiers; + DeclarativeMimeData m_data; + QGraphicsSceneDragDropEvent* m_event; +}; + +#endif // DECLARATIVEDRAGDROPEVENT_H diff --git a/declarativeimports/draganddrop/DeclarativeDropArea.cpp b/declarativeimports/draganddrop/DeclarativeDropArea.cpp new file mode 100644 index 000000000..3b394ab0b --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeDropArea.cpp @@ -0,0 +1,68 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "DeclarativeDropArea.h" +#include "DeclarativeDragDropEvent.h" + +#include +#include + +DeclarativeDropArea::DeclarativeDropArea(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_enabled(true) +{ + setAcceptDrops(m_enabled); +} + +void DeclarativeDropArea::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { + DeclarativeDragDropEvent dde(event, this); + emit dragEnter(&dde); +} + +void DeclarativeDropArea::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) +{ + DeclarativeDragDropEvent dde(event, this); + emit dragLeave(&dde); +} + +void DeclarativeDropArea::dropEvent(QGraphicsSceneDragDropEvent *event) +{ + DeclarativeDragDropEvent dde(event, this); + emit drop(&dde); +} + +bool DeclarativeDropArea::isEnabled() const +{ + return m_enabled; +} + +void DeclarativeDropArea::setEnabled(bool enabled) +{ + if (enabled == m_enabled) { + return; + } + + m_enabled = enabled; + setAcceptDrops(m_enabled); + emit enabledChanged(); +} diff --git a/declarativeimports/draganddrop/DeclarativeDropArea.h b/declarativeimports/draganddrop/DeclarativeDropArea.h new file mode 100644 index 000000000..0394ecf6b --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeDropArea.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef DECLARATIVEDROPAREA_H +#define DECLARATIVEDROPAREA_H + +#include + +class DeclarativeDragDropEvent; + +class DeclarativeDropArea : public QDeclarativeItem +{ + Q_OBJECT + Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged) + +public: + DeclarativeDropArea(QDeclarativeItem *parent=0); + bool isEnabled() const; + void setEnabled(bool enabled); + +signals: + void dragEnter(DeclarativeDragDropEvent* event); + void dragLeave(DeclarativeDragDropEvent* event); + void drop(DeclarativeDragDropEvent* event); + void enabledChanged(); + +protected: + void dragEnterEvent(QGraphicsSceneDragDropEvent *event); + void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); + void dropEvent(QGraphicsSceneDragDropEvent *event); + +private: + bool m_enabled; +}; + +#endif + diff --git a/declarativeimports/draganddrop/DeclarativeMimeData.cpp b/declarativeimports/draganddrop/DeclarativeMimeData.cpp new file mode 100644 index 000000000..09dbef02d --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeMimeData.cpp @@ -0,0 +1,121 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "DeclarativeMimeData.h" + +/*! + \qmlclass MimeData DeclarativeMimeData + + This is a wrapper class around QMimeData, with a few extensions to provide better support for in-qml drag & drops. +*/ + +/*! + \internal + \class DeclarativeMimeData + + Creates a new DeclarativeMimeData by cloning the QMimeData passed as parameter. + This is useful for two reasons : + - In DragArea, we want to clone our "working copy" of the DeclarativeMimeData instance, as Qt will automatically + delete it after the drag and drop operation. + - In the drop events, the QMimeData is const, and we have troubles passing const to QML. So we clone it to + remove the "constness" + + This method will try to cast the QMimeData to DeclarativeMimeData, and will clone our extensions to QMimeData as well +*/ +DeclarativeMimeData::DeclarativeMimeData(const QMimeData* copy) + : QMimeData(), + m_source(0) +{ + // Copy the standard MIME data + foreach(QString format, copy->formats()) { + this->setData(format, copy->data(format)); + } + + // If the object we are copying actually is a DeclarativeMimeData, copy our extended properties as well + const DeclarativeMimeData* declarativeMimeData = qobject_cast(copy); + if (declarativeMimeData) { + this->setSource(declarativeMimeData->source()); + } +} + + +/*! + \qmlproperty url MimeData::url + + Returns the first URL from the urls property of QMimeData + TODO: We should use QDeclarativeListProperty to return the whole list instead of only the first element. +*/ +QUrl DeclarativeMimeData::url() const +{ + if ( this->hasUrls() && !this->urls().isEmpty()) { + return urls().first(); + } + return QUrl(); +} +void DeclarativeMimeData::setUrl(const QUrl &url) +{ + if (this->url() == url) + return; + + QList urlList; + urlList.append(url); + setUrls(urlList); + emit urlChanged(); +} + +// color +QColor DeclarativeMimeData::color() const +{ + if ( this->hasColor()) { + return qvariant_cast(this->colorData()); + } + return QColor(); +} +void DeclarativeMimeData::setColor(const QColor &color) +{ + if (this->color() != color) { + this->setColorData(color); + emit colorChanged(); + } +} + +/*! + \qmlproperty item MimeData::source + + Setting source to any existing qml item will enable the receiver of the drag and drop operation to know in which item + the operation originated. + + In the case of inter-application drag and drop operations, the source will not be available, and will be 0. + Be sure to test it in your QML code, before using it, or it will generate errors in the console. +*/ +QDeclarativeItem* DeclarativeMimeData::source() const +{ + return m_source; +} +void DeclarativeMimeData::setSource(QDeclarativeItem* source) +{ + if (m_source != source) { + m_source = source; + emit sourceChanged(); + } +} diff --git a/declarativeimports/draganddrop/DeclarativeMimeData.h b/declarativeimports/draganddrop/DeclarativeMimeData.h new file mode 100644 index 000000000..1c9b1cd5b --- /dev/null +++ b/declarativeimports/draganddrop/DeclarativeMimeData.h @@ -0,0 +1,75 @@ +/* + Copyright (C) 2010 by BetterInbox + Original author: Gregory Schlomoff + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef DECLARATIVEMIMEDATA_H +#define DECLARATIVEMIMEDATA_H + +#include +#include +#include +#include + +class DeclarativeMimeData : public QMimeData +{ + Q_OBJECT + + 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(QColor color READ color WRITE setColor NOTIFY colorChanged) + Q_PROPERTY(QDeclarativeItem* source READ source WRITE setSource NOTIFY sourceChanged) + //TODO: Image property + +public: + DeclarativeMimeData() : QMimeData() {} + DeclarativeMimeData(const QMimeData* copy); + + QUrl url() const; + void setUrl(const QUrl &url); + + 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); + QString html() const; + void setHtml(const QString &html); + */ + +signals: + void textChanged(); //FIXME not being used + void htmlChanged(); //FIXME not being used + void urlChanged(); + void colorChanged(); + void sourceChanged(); + +private: + QDeclarativeItem* m_source; + +}; + +#endif // DECLARATIVEMIMEDATA_H diff --git a/declarativeimports/draganddrop/draganddropplugin.cpp b/declarativeimports/draganddrop/draganddropplugin.cpp new file mode 100644 index 000000000..228ef79d4 --- /dev/null +++ b/declarativeimports/draganddrop/draganddropplugin.cpp @@ -0,0 +1,43 @@ +/* + Copyright 2011 by Marco Martin + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "draganddropplugin.h" + +#include + +#include "DeclarativeDragArea.h" +#include "DeclarativeDragDropEvent.h" +#include "DeclarativeDropArea.h" +#include "DeclarativeMimeData.h" + +void DragAndDropPlugin::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QLatin1String("org.kde.draganddrop")); + + qmlRegisterType(uri, 1, 0, "DropArea"); + qmlRegisterType(uri, 1, 0, "DragArea"); + qmlRegisterUncreatableType(uri, 1, 0, "MimeData", "MimeData cannot be created from QML."); + qmlRegisterUncreatableType(uri, 1, 0, "DragDropEvent", "DragDropEvent cannot be created from QML."); +} + +Q_EXPORT_PLUGIN2(draganddropplugin, DragAndDropPlugin) + diff --git a/declarativeimports/draganddrop/draganddropplugin.h b/declarativeimports/draganddrop/draganddropplugin.h new file mode 100644 index 000000000..ce7aba576 --- /dev/null +++ b/declarativeimports/draganddrop/draganddropplugin.h @@ -0,0 +1,36 @@ +/* + Copyright 2011 by Marco Martin + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef DRAGANDDROPPLUGIN_H +#define DRAGANDDROPPLUGIN_H + +#include + +class DragAndDropPlugin : public QDeclarativeExtensionPlugin +{ + Q_OBJECT + +public: + void registerTypes(const char *uri); +}; + +#endif diff --git a/declarativeimports/draganddrop/qmldir b/declarativeimports/draganddrop/qmldir new file mode 100644 index 000000000..92ed88537 --- /dev/null +++ b/declarativeimports/draganddrop/qmldir @@ -0,0 +1,2 @@ +plugin draganddropplugin + diff --git a/declarativeimports/plasmacomponents/CMakeLists.txt b/declarativeimports/plasmacomponents/CMakeLists.txt new file mode 100644 index 000000000..bf0c4c280 --- /dev/null +++ b/declarativeimports/plasmacomponents/CMakeLists.txt @@ -0,0 +1,22 @@ +project(plasmacomponents) + +set(plasmacomponents_SRCS + plasmacomponentsplugin.cpp + qrangemodel.cpp + ) + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${KDE4_INCLUDES} +) + +qt4_automoc(${plasmacomponents_SRCS}) + + +add_library(plasmacomponentsplugin SHARED ${plasmacomponents_SRCS}) +target_link_libraries(plasmacomponentsplugin ${QT_QTCORE_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) + +install(TARGETS plasmacomponentsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/components) + +install(DIRECTORY qml/ DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/plasma/components) diff --git a/scriptengines/javascript/plasmoid/engineaccess.cpp b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp similarity index 64% rename from scriptengines/javascript/plasmoid/engineaccess.cpp rename to declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp index 2fa99867a..b1f7bd607 100644 --- a/scriptengines/javascript/plasmoid/engineaccess.cpp +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.cpp @@ -1,6 +1,6 @@ /* - * Copyright 2010 Marco Martin - * + * Copyright 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 @@ -17,24 +17,20 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include "engineaccess.h" -#include "scriptenv.h" +#include "plasmacomponentsplugin.h" -#include "plasmoid/declarativeappletscript.h" +#include -EngineAccess::EngineAccess(DeclarativeAppletScript *parent) - : QObject(parent), - m_appletScriptEngine(parent) +#include "qrangemodel.h" + + +void PlasmaComponentsPlugin::registerTypes(const char *uri) { + Q_ASSERT(uri == QLatin1String("org.kde.plasma.components")); + + qmlRegisterType(uri, 0, 1, "RangeModel"); } -EngineAccess::~EngineAccess() -{ -} -void EngineAccess::setEngine(QScriptValue val) -{ - m_appletScriptEngine->setEngine(val); -} +#include "plasmacomponentsplugin.moc" -#include "engineaccess.moc" diff --git a/scriptengines/javascript/plasmoid/engineaccess.h b/declarativeimports/plasmacomponents/plasmacomponentsplugin.h similarity index 66% rename from scriptengines/javascript/plasmoid/engineaccess.h rename to declarativeimports/plasmacomponents/plasmacomponentsplugin.h index ef95ef6d1..65ca8bdca 100644 --- a/scriptengines/javascript/plasmoid/engineaccess.h +++ b/declarativeimports/plasmacomponents/plasmacomponentsplugin.h @@ -1,6 +1,6 @@ /* - * Copyright 2010 Marco Martin - * + * Copyright 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 @@ -17,29 +17,19 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef ENGINEACCESS_H -#define ENGINEACCESS_H +#ifndef PLASMACOMPONENTSPLUGIN_H +#define PLASMACOMPONENTSPLUGIN_H -#include +#include -#include - -class DeclarativeAppletScript; - -class EngineAccess : public QObject +class PlasmaComponentsPlugin : public QDeclarativeExtensionPlugin { Q_OBJECT - public: - EngineAccess(DeclarativeAppletScript *parent); - ~EngineAccess(); - - Q_INVOKABLE void setEngine(QScriptValue val); - -private: - DeclarativeAppletScript *m_appletScriptEngine; - + void registerTypes(const char *uri); }; +Q_EXPORT_PLUGIN2(plasmacomponentsplugin, PlasmaComponentsPlugin) + #endif diff --git a/declarativeimports/plasmacomponents/qml/BusyIndicator.qml b/declarativeimports/plasmacomponents/qml/BusyIndicator.qml new file mode 100644 index 000000000..5335d4328 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/BusyIndicator.qml @@ -0,0 +1,64 @@ +/* +* Copyright (C) 2010 by Artur Duque de Souza +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +Item { + id: busy + + // Common API + property bool running: false + + // Plasma API + property bool smoothAnimation: true + + implicitWidth: 52 + implicitHeight: 52 + + // Should use animation's pause to keep the + // rotation smooth when running changes but + // it has lot's of side effects on + // initialization. + onRunningChanged: { + rotationAnimation.from = rotation; + rotationAnimation.to = rotation + 360; + } + + RotationAnimation on rotation { + id: rotationAnimation + + from: 0 + to: 360 + duration: 1500 + running: busy.running + loops: Animation.Infinite + } + + PlasmaCore.SvgItem { + id: widget + + anchors.centerIn: parent + width: busy.width + height: busy.height + smooth: !running || smoothAnimation + svg: PlasmaCore.Svg { imagePath: "widgets/busywidget" } + } +} diff --git a/declarativeimports/plasmacomponents/qml/Button.qml b/declarativeimports/plasmacomponents/qml/Button.qml new file mode 100644 index 000000000..7bd29c881 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/Button.qml @@ -0,0 +1,161 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +Item { + id: button + + // Commmon API + property bool checked: false + property bool checkable: false + property alias pressed: mouse.pressed + property alias text: label.text + property alias iconSource: icon.source + property alias font: label.font + + signal clicked() + + PlasmaCore.Theme { + id: theme + } + + function pressButton() { + if (button.enabled) + surface.prefix = "pressed"; + } + + function releaseButton() { + if (!button.enabled) + return; + + if (button.checkable) + button.checked = !button.checked; + + // TODO: "checked" state must have special graphics? + if (button.checked) + surface.prefix = "pressed"; + else + surface.prefix = "normal"; + + button.clicked(); + button.forceActiveFocus(); + } + + width: Math.max(50, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) + height: Math.max(20, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) + // TODO: needs to define if there will be specific graphics for + // disabled buttons + opacity: enabled ? 1.0 : 0.5 + + Keys.onSpacePressed: pressButton(); + Keys.onReturnPressed: pressButton(); + Keys.onReleased: { + if (event.key == Qt.Key_Space || + event.key == Qt.Key_Return) + releaseButton(); + } + + onActiveFocusChanged: { + if (activeFocus) { + shadow.state = "focus" + } else if (checked) { + shadow.state = "hidden" + } else { + shadow.state = "shadow" + } + } + + ButtonShadow { + id: shadow + anchors.fill: parent + } + + PlasmaCore.FrameSvgItem { + id: surface + + anchors.fill: parent + imagePath: "widgets/button" + prefix: "normal" + } + + Item { + anchors { + fill: parent + leftMargin: surface.margins.left + topMargin: surface.margins.top + rightMargin: surface.margins.right + bottomMargin: surface.margins.bottom + } + + Image { + id: icon + + anchors { + fill: label.text ? undefined : parent + top: label.text ? parent.top : undefined + left: label.text ? parent.left : undefined + bottom: label.text ? parent.bottom : undefined + } + fillMode: Image.PreserveAspectFit + } + + Text { + id: label + + anchors { + top: parent.top + bottom: parent.bottom + left: icon.right + right: parent.right + } + color: theme.buttonTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + MouseArea { + id: mouse + + anchors.fill: parent + hoverEnabled: true + + onPressed: { + pressButton(); + } + onReleased: { + releaseButton(); + } + onEntered: { + shadow.state = "hover" + } + onExited: { + if (button.activeFocus) { + shadow.state = "focus" + } else if (checked) { + shadow.state = "hidden" + } else { + shadow.state = "shadow" + } + } + } +} + diff --git a/declarativeimports/plasmacomponents/qml/ButtonColumn.qml b/declarativeimports/plasmacomponents/qml/ButtonColumn.qml new file mode 100644 index 000000000..752481c26 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ButtonColumn.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** 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:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import Qt 4.7 +import "ButtonGroup.js" as Behavior + +/* + Class: ButtonColumn + A ButtonColumn allows you to group Buttons in a column. It provides a selection-behavior as well. + + Note: This component don't support the enabled property. + If you need to disable it you should disable all the buttons inside it. + + + ButtonColumn { + Button { text: "Top" } + Button { text: "Bottom" } + } + +*/ +Column { + id: root + + /* + * Property: exclusive + * [bool=true] Specifies the grouping behavior. If enabled, the checked property on buttons contained + * in the group will be exclusive. + * + * Note that a button in an exclusive group will allways be checkable + */ + property bool exclusive: true + + /* + * Property: checkedButton + * [string] Contains the last checked Button. + */ + property Item checkedButton; + + Component.onCompleted: { + Behavior.create(root, {direction: Qt.Vertical}); + } + + Component.onDestruction: { + Behavior.destroy(); + } + +} diff --git a/declarativeimports/plasmacomponents/qml/ButtonGroup.js b/declarativeimports/plasmacomponents/qml/ButtonGroup.js new file mode 100644 index 000000000..ea8ca7485 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ButtonGroup.js @@ -0,0 +1,178 @@ +/**************************************************************************** +** +** 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:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +var self; +var checkHandlers = []; +var visibleButtons = []; +var nonVisibleButtons = []; +var direction; + +function create(that, options) { + self = that; + direction = options.direction || Qt.Horizontal; + self.childrenChanged.connect(rebuild); +// self.widthChanged.connect(resizeChildren); + build(); +} + +function isButton(item) { + if (item && item.hasOwnProperty("__position")) + return true; + return false; +} + +function hasChecked(item) { + return (item && item.hasOwnProperty("checked")); +} + +function destroy() { + self.childrenChanged.disconnect(rebuild); +// self.widthChanged.disconnect(resizeChildren); + cleanup(); +} + +function build() { + visibleButtons = []; + nonVisibleButtons = []; + + for (var i = 0, item; (item = self.children[i]); i++) { + if (!hasChecked(item)) + continue; + + item.visibleChanged.connect(rebuild); // Not optimal, but hardly a bottleneck in your app + if (!item.visible) { + nonVisibleButtons.push(item); + continue; + } + visibleButtons.push(item); + + if (self.exclusive && item.hasOwnProperty("checkable")) + item.checkable = true; + + if (self.exclusive) { + item.checked = false; + checkHandlers.push(checkExclusive(item)); + item.checkedChanged.connect(checkHandlers[checkHandlers.length - 1]); + } + } + + var nrButtons = visibleButtons.length; + if (nrButtons == 0) + return; + + if (self.checkedButton) + self.checkedButton.checked = true; + else if (self.exclusive) { + self.checkedButton = visibleButtons[0]; + self.checkedButton.checked = true; + } + + if (nrButtons == 1) { + finishButton(visibleButtons[0], "only"); + } else { + finishButton(visibleButtons[0], direction == Qt.Horizontal ? "leftmost" : "top"); + for (var i = 1; i < nrButtons - 1; i++) + finishButton(visibleButtons[i], direction == Qt.Horizontal ? "h_middle": "v_middle"); + finishButton(visibleButtons[nrButtons - 1], direction == Qt.Horizontal ? "rightmost" : "bottom"); + } +} + +function finishButton(button, position) { + if (isButton(button)) { + button.__position = position; + if (direction == Qt.Vertical) { + button.anchors.left = self.left //mm How to make this not cause binding loops? see QTBUG-17162 + button.anchors.right = self.right + } + } +} + +function cleanup() { + visibleButtons.forEach(function(item, i) { + if (checkHandlers[i]) + item.checkedChanged.disconnect(checkHandlers[i]); + item.visibleChanged.disconnect(rebuild); + }); + checkHandlers = []; + + nonVisibleButtons.forEach(function(item, i) { + item.visibleChanged.disconnect(rebuild); + }); +} + +function rebuild() { + if (self == undefined) + return; + + cleanup(); + build(); +} + +function resizeChildren() { + if (direction != Qt.Horizontal) + return; + + var extraPixels = self.width % visibleButtons; + var buttonSize = (self.width - extraPixels) / visibleButtons; + visibleButtons.forEach(function(item, i) { + if (!item || !item.visible) + return; + item.width = buttonSize + (extraPixels > 0 ? 1 : 0); + if (extraPixels > 0) + extraPixels--; + }); +} + +function checkExclusive(item) { + var button = item; + return function() { + for (var i = 0, ref; (ref = visibleButtons[i]); i++) { + if (ref.checked == (button === ref)) + continue; + + // Disconnect the signal to avoid recursive calls + ref.checkedChanged.disconnect(checkHandlers[i]); + ref.checked = !ref.checked; + ref.checkedChanged.connect(checkHandlers[i]); + } + self.checkedButton = button; + } +} diff --git a/declarativeimports/plasmacomponents/qml/ButtonRow.qml b/declarativeimports/plasmacomponents/qml/ButtonRow.qml new file mode 100644 index 000000000..e88b015d4 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ButtonRow.qml @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** 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:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 +import "ButtonGroup.js" as Behavior + +/* + Class: ButtonRow + A ButtonRow allows you to group Buttons in a row. It provides a selection-behavior as well. + + Note: This component don't support the enabled property. + If you need to disable it you should disable all the buttons inside it. + + + ButtonRow { + Button { text: "Left" } + Button { text: "Right" } + } + +*/ +Row { + id: root + + /* + * Property: exclusive + * [bool=true] Specifies the grouping behavior. If enabled, the checked property on buttons contained + * in the group will be exclusive. + * + * Note that a button in an exclusive group will allways be checkable + */ + property bool exclusive: true + + /* + * Property: checkedButton + * [string] Contains the last checked Button. + */ + property Item checkedButton; + + Component.onCompleted: { + Behavior.create(root, {direction: Qt.Horizontal}); + } + + Component.onDestruction: { + Behavior.destroy(); + } +} diff --git a/declarativeimports/plasmacomponents/qml/ButtonShadow.qml b/declarativeimports/plasmacomponents/qml/ButtonShadow.qml new file mode 100644 index 000000000..dcf8d233e --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ButtonShadow.qml @@ -0,0 +1,117 @@ +/* + * 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: main + state: parent.state + + PlasmaCore.FrameSvgItem { + id: hover + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + opacity: 0 + imagePath: "widgets/button" + prefix: "hover" + } + + PlasmaCore.FrameSvgItem { + id: shadow + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/button" + prefix: "shadow" + } + + states: [ + State { + name: "shadow" + PropertyChanges { + target: shadow + opacity: 1 + } + PropertyChanges { + target: hover + opacity: 0 + prefix: "hover" + } + }, + State { + name: "hover" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 1 + prefix: "hover" + } + }, + State { + name: "focus" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 1 + prefix: "focus" + } + }, + State { + name: "hidden" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 0 + prefix: "hover" + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: 250 + easing.type: Easing.OutQuad + } + } + ] +} diff --git a/declarativeimports/plasmacomponents/qml/CheckBox.qml b/declarativeimports/plasmacomponents/qml/CheckBox.qml new file mode 100644 index 000000000..28bf4cc94 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/CheckBox.qml @@ -0,0 +1,57 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +DualStateButton { + id: checkBox + view: PlasmaCore.FrameSvgItem { + imagePath: "widgets/button" + prefix: "normal" + width: fontMetricText.height + margins.left + height: fontMetricText.height + margins.top + //FIXME: an hack to have font metrics: can we have a proper binding? + Text { + id: fontMetricText + text: "M" + visible: false + } + PlasmaCore.SvgItem { + svg: PlasmaCore.Svg { + id: checkmarkSvg + imagePath: "widgets/checkmarks" + } + elementId: "checkbox" + opacity: checked ? 1 : 0 + anchors { + fill: parent + margins: parent.margins.left/2 + } + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + } + + shadow: ButtonShadow {} +} \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/DualStateButton.qml b/declarativeimports/plasmacomponents/qml/DualStateButton.qml new file mode 100644 index 000000000..3b6d529b3 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/DualStateButton.qml @@ -0,0 +1,110 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +Item { + id: dualButton + + // Common API + property bool checked + property alias pressed: mouseArea.pressed + + signal clicked() + + // Plasma API + property alias text: label.text // TODO: Not yet part of the common API + property QtObject theme: PlasmaCore.Theme { } + property alias view: surfaceLoader.sourceComponent + property alias shadow: shadowLoader.sourceComponent + + width: surfaceLoader.width + label.paintedWidth + height: surfaceLoader.height + // TODO: needs to define if there will be specific graphics for + // disabled buttons + opacity: dualButton.enabled ? 1.0 : 0.5 + + function entered() { + if (dualButton.enabled) { + shadowLoader.state = "hover" + } + } + + function released() { + if (dualButton.enabled) { + dualButton.checked = !dualButton.checked; + dualButton.clicked(); + } + } + + Keys.onSpacePressed: entered(); + Keys.onReturnPressed: entered(); + Keys.onReleased: { + if(event.key == Qt.Key_Space || + event.key == Qt.Key_Return) + released(); + } + + Loader { + id: shadowLoader + anchors.fill: surfaceLoader + } + + Loader { + id: surfaceLoader + + anchors { + verticalCenter: parent.verticalCenter + left: text ? parent.left : undefined + horizontalCenter: text ? undefined : parent.horizontalCenter + } + } + + Text { + id: label + + text: dualButton.text + anchors { + top: parent.top + bottom: parent.bottom + left: surfaceLoader.right + right: parent.right + //FIXME: see how this margin will be set + leftMargin: height/4 + } + color: theme.textColor + verticalAlignment: Text.AlignVCenter + } + + MouseArea { + id: mouseArea + + anchors.fill: parent + hoverEnabled: true + + onReleased: dualButton.released(); + onEntered: dualButton.entered(); + onPressed: dualButton.forceActiveFocus(); + onExited: { + shadowLoader.state = "shadow" + } + } +} + diff --git a/declarativeimports/plasmacomponents/qml/Highlight.qml b/declarativeimports/plasmacomponents/qml/Highlight.qml new file mode 100644 index 000000000..9670c2837 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/Highlight.qml @@ -0,0 +1,49 @@ +/* + * Copyright 2011 Daker Fernandes Pinheiro + * + * 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 + +Item { + id: highlight + + property bool hover: false + property bool pressed: false + + PlasmaCore.FrameSvgItem { + id: background + imagePath: "widgets/viewitem" + prefix: { + if (pressed) + return hover ? "selected+hover" : "selected"; + + if (hover) + return "hover"; + + return "normal"; + } + + anchors { + fill: parent + topMargin: -background.margins.top + leftMargin: -background.margins.left + bottomMargin: -background.margins.bottom + rightMargin: -background.margins.right + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/Label.qml b/declarativeimports/plasmacomponents/qml/Label.qml new file mode 100644 index 000000000..dabf13195 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/Label.qml @@ -0,0 +1,42 @@ +/* +* 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Text { + id: root + + font.capitalization: theme.font.capitalization + font.family: theme.font.family + font.italic: theme.font.italic + font.letterSpacing: theme.font.letterSpacing + font.pointSize: theme.font.pointSize + font.strikeout: theme.font.strikeout + font.underline: theme.font.underline + font.weight: theme.font.weight + font.wordSpacing: theme.font.wordSpacing + + wrapMode: Text.Wrap + color: theme.textColor + + PlasmaCore.Theme { + id: theme + } +} diff --git a/declarativeimports/plasmacomponents/qml/ProgressBar.qml b/declarativeimports/plasmacomponents/qml/ProgressBar.qml new file mode 100644 index 000000000..efce6f20f --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ProgressBar.qml @@ -0,0 +1,99 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: progressBar + + // Common API + property alias minimumValue: range.minimumValue + property alias maximumValue: range.maximumValue + property alias value: range.value + property alias indeterminate: indeterminateAnimation.running + + // Plasma API + property int orientation: Qt.Horizontal + + // Convinience API + property bool _isVertical: orientation == Qt.Vertical + + width: 100 + height: 20 + opacity: enabled ? 1.0 : 0.5 + + RangeModel { + id: range + + // default values + minimumValue: 0.0 + maximumValue: 1.0 + value: 0 + + positionAtMinimum: 0 + positionAtMaximum: contents.width + } + + Item { + id: contents + + width: _isVertical ? progressBar.height : progressBar.width + height: _isVertical ? progressBar.width : progressBar.height + rotation: _isVertical ? 90 : 0 + anchors.centerIn: parent + + PlasmaCore.FrameSvgItem { + id: background + + anchors.fill: parent + imagePath: "widgets/bar_meter_horizontal" + prefix: "bar-inactive" + } + + PlasmaCore.FrameSvgItem { + id: bar + + width: indeterminate ? contents.width / 4 : range.position + height: contents.height + imagePath: "widgets/bar_meter_horizontal" + prefix: "bar-active" + visible: indeterminate || value > 0 + + SequentialAnimation { + id: indeterminateAnimation + + loops: Animation.Infinite + + PropertyAnimation { + target: bar; + property: "x" + duration: 800 + to: 0 + } + PropertyAnimation { + target: bar; + property: "x" + duration: 800 + to: background.width - bar.width + } + } + } + } +} \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/RadioButton.qml b/declarativeimports/plasmacomponents/qml/RadioButton.qml new file mode 100644 index 000000000..f417c25c5 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/RadioButton.qml @@ -0,0 +1,62 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + + +//FIXME: this should be round, DualStateButton shouldn't draw the shadow +DualStateButton { + id: radioButton + view: PlasmaCore.SvgItem { + svg: PlasmaCore.Svg { + id: buttonSvg + imagePath: "widgets/actionbutton" + } + elementId: "normal" + width: fontMetricText.height + 6 + height: width + //FIXME: an hack to have font metrics: can we have a proper binding? + Text { + id: fontMetricText + text: "M" + visible: false + } + PlasmaCore.SvgItem { + svg: PlasmaCore.Svg { + id: checkmarkSvg + imagePath: "widgets/checkmarks" + } + elementId: "radiobutton" + opacity: checked ? 1 : 0 + anchors { + fill: parent + margins: parent.margins.left/2 + } + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + } + + shadow: RoundShadow {} +} \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/RoundShadow.qml b/declarativeimports/plasmacomponents/qml/RoundShadow.qml new file mode 100644 index 000000000..fce6f7eb9 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/RoundShadow.qml @@ -0,0 +1,112 @@ +/* + * 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item { + id: main + state: parent.state + + PlasmaCore.SvgItem { + id: hover + svg: PlasmaCore.Svg { + id: hoverSvg + imagePath: "widgets/actionbutton" + } + elementId: "hover" + + anchors.fill: parent + + opacity: 0 + } + + PlasmaCore.SvgItem { + id: shadow + svg: PlasmaCore.Svg { + id: shadowSvg + imagePath: "widgets/actionbutton" + } + elementId: "shadow" + + anchors.fill: parent + } + + states: [ + State { + name: "shadow" + PropertyChanges { + target: shadow + opacity: 1 + } + PropertyChanges { + target: hover + opacity: 0 + elementId: "hover" + } + }, + State { + name: "hover" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 1 + elementId: "hover" + } + }, + State { + name: "focus" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 1 + elementId: "focus" + } + }, + State { + name: "hover" + PropertyChanges { + target: shadow + opacity: 0 + } + PropertyChanges { + target: hover + opacity: 0 + elementId: "hover" + } + } + ] + + transitions: [ + Transition { + PropertyAnimation { + properties: "opacity" + duration: 250 + easing.type: Easing.OutQuad + } + } + ] +} diff --git a/declarativeimports/plasmacomponents/qml/ScrollBar.qml b/declarativeimports/plasmacomponents/qml/ScrollBar.qml new file mode 100644 index 000000000..8adc8b615 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ScrollBar.qml @@ -0,0 +1,349 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +// TODO: add support mouse wheel and key events +Item { + id: scrollbar + + // Common API + property Flickable flickableItem: null + + // Plasma API + property int orientation: Qt.Horizontal + property bool animated: true + property bool inverted: false + property bool updateValueWhileDragging: true + property alias stepSize: range.stepSize + property alias pressed: mouseArea.pressed + property real scrollButtonInterval: 50 + + // Convinience API + property bool _isVertical: orientation == Qt.Vertical + property bool _showButtons: stepSize != 0 + property bool _inverted: _isVertical ? + !scrollbar.inverted : scrollbar.inverted + + implicitWidth: _isVertical ? 22 : 200 + implicitHeight: _isVertical ? 200 : 22 + // TODO: needs to define if there will be specific graphics for + // disabled scroll bars + opacity: enabled ? 1.0 : 0.5 + + visible: flickableItem && handle.width < contents.width + + function incrementValue(increment) { + if (!flickableItem) + return; + + if (_isVertical) { + flickableItem.contentY = Math.min(flickableItem.contentHeight, + flickableItem.contentY + increment); + } else { + flickableItem.contentX = Math.min(flickableItem.contentWidth, + flickableItem.contentX + increment); + } + } + + Keys.onUpPressed: { + if (!enabled || !_isVertical) + return; + + if (_inverted) + incrementValue(-stepSize); + else + incrementValue(stepSize); + } + + Keys.onDownPressed: { + if (!enabled || !_isVertical) + return; + + if (_inverted) + incrementValue(stepSize); + else + incrementValue(-stepSize); + } + + Keys.onLeftPressed: { + if (!enabled || _isVertical) + return; + + if (_inverted) + incrementValue(stepSize); + else + incrementValue(-stepSize); + } + + Keys.onRightPressed: { + if (!enabled || _isVertical) + return; + + if (_inverted) + incrementValue(-stepSize); + else + incrementValue(stepSize); + } + + + Item { + + width: _isVertical ? scrollbar.height : scrollbar.width + height: _isVertical ? scrollbar.width : scrollbar.height + rotation: _isVertical ? -90 : 0 + + anchors.centerIn: parent + PlasmaCore.Svg { + id: scrollbarSvg + imagePath: "widgets/scrollbar" + } + + PlasmaCore.SvgItem { + id: leftButton + + anchors { + left: parent.left + verticalCenter: parent.verticalCenter + } + height: 18 + width: _showButtons ? 18 : 0 + svg: scrollbarSvg + elementId: { + if (leftMousArea.pressed) + return "sunken-arrow-left"; + + if (scrollbar.activeFocus || leftMousArea.containsMouse) + return "mouseover-arrow-left"; + else + return "arrow-left"; + } + + MouseArea { + id: leftMousArea + + anchors.fill: parent + enabled: scrollbar.enabled + Timer { + id: leftTimer + interval: scrollbar.scrollButtonInterval; + running: parent.pressed + repeat: true + onTriggered: { + scrollbar.forceActiveFocus(); + if (_inverted) + incrementValue(stepSize); + else + incrementValue(-stepSize); + } + } + } + } + + PlasmaCore.SvgItem { + id: rightButton + + anchors { + right: parent.right + verticalCenter: parent.verticalCenter + } + height: 18 + width: _showButtons ? 18 : 0 + svg: scrollbarSvg + elementId: { + if (rightMousArea.pressed) + return "sunken-arrow-right"; + + if (scrollbar.activeFocus || rightMousArea.containsMouse) + return "mouseover-arrow-right"; + else + return "arrow-right"; + } + + MouseArea { + id: rightMousArea + + anchors.fill: parent + enabled: scrollbar.enabled + Timer { + id: rightTimer + interval: scrollbar.scrollButtonInterval; + running: parent.pressed; + repeat: true + onTriggered: { + scrollbar.forceActiveFocus(); + if (_inverted) + incrementValue(-stepSize); + else + incrementValue(stepSize); + } + } + } + } + + Item { + id: contents + + anchors { + left: leftButton.right + top: parent.top + bottom: parent.bottom + right: rightButton.left + } + + RangeModel { + id: range + + minimumValue: 0 + maximumValue: { + var diff; + if (_isVertical) + diff = flickableItem.contentHeight - flickableItem.height; + else + diff = flickableItem.contentWidth - flickableItem.width; + + return Math.max(0, diff); + } + stepSize: 0.0 + inverted: _inverted + positionAtMinimum: 0 + handle.width / 2 + positionAtMaximum: contents.width - handle.width / 2 + value: _isVertical ? flickableItem.contentY : flickableItem.contentX + onValueChanged: { + if (flickableItem.flicking) + return; + + if (_isVertical) + flickableItem.contentY = value; + else + flickableItem.contentX = value; + } + position: handle.x + onPositionChanged: { handle.x = position; } + } + + PlasmaCore.FrameSvgItem { + id: groove + + anchors.fill: parent + imagePath: "widgets/scrollbar" + prefix: "background-horizontal" + } + + PlasmaCore.FrameSvgItem { + id: handle + + transform: Translate { x: - handle.width / 2 } + x: fakeHandle.x + anchors.verticalCenter: groove.verticalCenter + width: { + var ratio; + if (_isVertical) + ratio = flickableItem.visibleArea.heightRatio; + else + ratio = flickableItem.visibleArea.widthRatio; + + return ratio * parent.width; + } + height: parent.height - margins.top // TODO: check mergin + imagePath: "widgets/scrollbar" + prefix: { + if (scrollbar.pressed) + return "sunken-slider"; + + if (scrollbar.activeFocus || mouseArea.containsMouse) + return "mouseover-slider"; + else + return "slider"; + } + + Behavior on x { + id: behavior + enabled: !mouseArea.drag.active && scrollbar.animated && + !flickableItem.flicking + + PropertyAnimation { + duration: behavior.enabled ? 150 : 0 + easing.type: Easing.OutSine + } + } + } + + Item { + id: fakeHandle + width: handle.width + height: handle.height + transform: Translate { x: - handle.width / 2 } + } + + MouseArea { + id: mouseArea + + anchors.fill: parent + enabled: scrollbar.enabled + drag { + target: fakeHandle + axis: Drag.XAxis + minimumX: range.positionAtMinimum + maximumX: range.positionAtMaximum + } + + onPressed: { + // Clamp the value + var newX = Math.max(mouse.x, drag.minimumX); + newX = Math.min(newX, drag.maximumX); + + // Debounce the press: a press event inside the handler will not + // change its position, the user needs to drag it. + if (Math.abs(newX - fakeHandle.x) > handle.width / 2) + range.position = newX; + + scrollbar.forceActiveFocus(); + } + onReleased: { + // If we don't update while dragging, this is the only + // moment that the range is updated. + if (!scrollbar.updateValueWhileDragging) + range.position = fakeHandle.x; + } + } + } + + // Range position normally follow fakeHandle, except when + // 'updateValueWhileDragging' is false. In this case it will only follow + // if the user is not pressing the handle. + Binding { + when: updateValueWhileDragging || !mouseArea.pressed + target: range + property: "position" + value: fakeHandle.x + } + + // During the drag, we simply ignore position set from the range, this + // means that setting a value while dragging will not "interrupt" the + // dragging activity. + Binding { + when: !mouseArea.drag.active + target: fakeHandle + property: "x" + value: range.position + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml b/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml new file mode 100644 index 000000000..61025fe87 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ScrollDecorator.qml @@ -0,0 +1,106 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +Item { + id: scrollDecorator + + // Common API + property Flickable flickableItem + + // Plasma API + property int orientation: Qt.Horizontal + property bool inverted: false + + // Convinience API + property bool _isVertical: orientation == Qt.Vertical + property bool _inverted: _isVertical ? + !scrollDecorator.inverted : scrollDecorator.inverted + property alias _value: range.value + + implicitWidth: _isVertical ? 16 : 200 + implicitHeight: _isVertical ? 200 : 16 + + visible: flickableItem && handle.width < contents.width + + Item { + width: _isVertical ? scrollDecorator.height : scrollDecorator.width + height: _isVertical ? scrollDecorator.width : scrollDecorator.height + rotation: _isVertical ? -90 : 0 + + anchors.centerIn: parent + + PlasmaCore.FrameSvgItem { + id: contents + imagePath: "widgets/scrollbar" + prefix: "background-horizontal" + + anchors.fill: parent + opacity: flickableItem && (flickableItem.flicking || flickableItem.moving) ? 1 : 0 + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.OutQuad + } + } + + RangeModel { + id: range + + minimumValue: 0 + maximumValue: { + var diff; + if (_isVertical) + diff = flickableItem.contentHeight - flickableItem.height; + else + diff = flickableItem.contentWidth - flickableItem.width; + + return Math.max(0, diff); + } + stepSize: 0.0 + inverted: _inverted + positionAtMinimum: 0 + handle.width / 2 + positionAtMaximum: contents.width - handle.width / 2 + value: _isVertical ? flickableItem.contentY : flickableItem.contentX + } + + PlasmaCore.FrameSvgItem { + id: handle + + x: range.position + transform: Translate { x: - handle.width / 2 } + anchors.verticalCenter: parent.verticalCenter + width: { + var ratio; + if (_isVertical) + ratio = flickableItem.visibleArea.heightRatio; + else + ratio = flickableItem.visibleArea.widthRatio; + + return ratio * parent.width; + } + height: parent.height - margins.top // TODO: check mergin + imagePath: "widgets/scrollbar" + prefix: "slider" + } + } + } +} \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/Slider.qml b/declarativeimports/plasmacomponents/qml/Slider.qml new file mode 100644 index 000000000..1458dc6ec --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/Slider.qml @@ -0,0 +1,272 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +// TODO: create a value indicator for plasma? +Item { + id: slider + + // Common API + property alias stepSize: range.stepSize + property alias minimumValue: range.minimumValue + property alias maximumValue: range.maximumValue + property alias value: range.value + property int orientation: Qt.Horizontal + property alias pressed: mouseArea.pressed + property bool valueIndicatorVisible: false + property string valueIndicatorText: value + + // Plasma API + property bool animated: false + property alias inverted: range.inverted + property bool updateValueWhileDragging: true + property real handleSize: 22 + + // Convinience API + property bool _isVertical: orientation == Qt.Vertical + + width: _isVertical ? 22 : 200 + height: _isVertical ? 200 : 22 + // TODO: needs to define if there will be specific graphics for + // disabled sliders + opacity: enabled ? 1.0 : 0.5 + + Keys.onUpPressed: { + if (!enabled || !_isVertical) + return; + + if (inverted) + value -= stepSize; + else + value += stepSize; + } + + Keys.onDownPressed: { + if (!enabled || !enabled) + return; + + if (!_isVertical) + return; + + if (inverted) + value += stepSize; + else + value -= stepSize; + } + + Keys.onLeftPressed: { + if (!enabled || _isVertical) + return; + + if (inverted) + value += stepSize; + else + value -= stepSize; + } + + Keys.onRightPressed: { + if (!enabled || _isVertical) + return; + + if (inverted) + value -= stepSize; + else + value += stepSize; + } + + Item { + id: contents + + width: _isVertical ? slider.height : slider.width + height: _isVertical ? slider.width : slider.height + rotation: _isVertical ? -90 : 0 + + anchors.centerIn: parent + + RangeModel { + id: range + + minimumValue: 0.0 + maximumValue: 1.0 + value: 0 + stepSize: 0.0 + inverted: false + positionAtMinimum: 0 + handle.width / 2 + positionAtMaximum: contents.width - handle.width / 2 + } + + PlasmaCore.Svg { + id: grooveSvg + imagePath: "widgets/slider" + } + PlasmaCore.FrameSvgItem { + id: groove + imagePath: "widgets/slider" + prefix: "groove" + //FIXME: frameSvg should have a minimumSize attribute, could be added to kdelibs 4.7(maybe just the qml binding is enough)? + height: grooveSvg.elementSize("groove-topleft").height + grooveSvg.elementSize("groove-bottomleft").height + anchors { + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + } + } + PlasmaCore.FrameSvgItem { + id: highlight + imagePath: "widgets/slider" + prefix: "groove-highlight" + height: groove.height + width: inverted ? groove.width - handle.x : fakeHandle.x + x: inverted ? handle.x : 0 + anchors.verticalCenter: parent.verticalCenter + + visible: range.position > 0 && slider.enabled + } + + PlasmaCore.SvgItem { + id: focus + + transform: Translate { x: - handle.width / 2 } + anchors { + fill: handle + margins: -1 // Hardcoded + } + opacity: slider.activeFocus ? 1 : 0 + svg: PlasmaCore.Svg { imagePath: "widgets/slider" } + elementId: "horizontal-slider-hover" + + Behavior on opacity { + PropertyAnimation { duration: 250 } + } + } + + PlasmaCore.SvgItem { + id: hover + + transform: Translate { x: - handle.width / 2 } + anchors { + fill: handle + margins: -2 // Hardcoded + } + opacity: 0 + svg: PlasmaCore.Svg { imagePath: "widgets/slider" } + elementId: "horizontal-slider-hover" + + Behavior on opacity { + PropertyAnimation { duration: 250 } + } + } + + PlasmaCore.SvgItem { + id: handle + + transform: Translate { x: - handle.width / 2 } + x: fakeHandle.x + anchors { + verticalCenter: groove.verticalCenter + } + width: handleSize + height: handleSize + svg: PlasmaCore.Svg { imagePath: "widgets/slider" } + elementId: "horizontal-slider-handle" + + Behavior on x { + id: behavior + enabled: !mouseArea.drag.active && slider.animated + + PropertyAnimation { + duration: behavior.enabled ? 150 : 0 + easing.type: Easing.OutSine + } + } + } + + Item { + id: fakeHandle + width: handle.width + height: handle.height + transform: Translate { x: - handle.width / 2 } + } + + MouseArea { + id: mouseArea + + anchors.fill: parent + enabled: slider.enabled + drag { + target: fakeHandle + axis: Drag.XAxis + minimumX: range.positionAtMinimum + maximumX: range.positionAtMaximum + } + hoverEnabled: true + + onEntered: { + hover.opacity = 1; + } + onExited: { + if (!pressed) + hover.opacity = 0; + } + onPressed: { + // Clamp the value + var newX = Math.max(mouse.x, drag.minimumX); + newX = Math.min(newX, drag.maximumX); + + // Debounce the press: a press event inside the handler will not + // change its position, the user needs to drag it. + if (Math.abs(newX - fakeHandle.x) > handle.width / 2) + range.position = newX; + + slider.forceActiveFocus(); + } + onReleased: { + // If we don't update while dragging, this is the only + // moment that the range is updated. + if (!slider.updateValueWhileDragging) + range.position = fakeHandle.x; + + if (!containsMouse) + hover.opacity = 0; + } + } + } + + // Range position normally follow fakeHandle, except when + // 'updateValueWhileDragging' is false. In this case it will only follow + // if the user is not pressing the handle. + Binding { + when: updateValueWhileDragging || !mouseArea.pressed + target: range + property: "position" + value: fakeHandle.x + } + + // During the drag, we simply ignore position set from the range, this + // means that setting a value while dragging will not "interrupt" the + // dragging activity. + Binding { + when: !mouseArea.drag.active + target: fakeHandle + property: "x" + value: range.position + } +} \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/Switch.qml b/declarativeimports/plasmacomponents/qml/Switch.qml new file mode 100644 index 000000000..6d997f538 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/Switch.qml @@ -0,0 +1,78 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +DualStateButton { + id: switchItem + + view: PlasmaCore.FrameSvgItem { + imagePath: "widgets/slider" + prefix: "groove" + width: height * 2 + height: fontMetricText.height + margins.top + //FIXME: an hack to have font metrics: can we have a proper binding? + Text { + id: fontMetricText + text: "M" + visible: false + } + + PlasmaCore.FrameSvgItem { + id: highlight + imagePath: "widgets/slider" + prefix: "groove-highlight" + anchors.fill: parent + + opacity: checked ? 1 : 0 + Behavior on opacity { + PropertyAnimation { duration: 100 } + } + } + + PlasmaCore.FrameSvgItem { + imagePath: "widgets/button" + prefix: "shadow" + anchors { + fill: button + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + } + + PlasmaCore.FrameSvgItem { + id: button + imagePath: "widgets/button" + prefix: "normal" + anchors { + top: parent.top + bottom: parent.bottom + } + width: height + x: checked ? width : 0 + Behavior on x { + PropertyAnimation { duration: 100 } + } + } + } +} + diff --git a/declarativeimports/plasmacomponents/qml/TextArea.qml b/declarativeimports/plasmacomponents/qml/TextArea.qml new file mode 100644 index 000000000..839b75a1b --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/TextArea.qml @@ -0,0 +1,232 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +Item { + id: textArea + + // Common API + property alias font: textEdit.font // alias to textEdit.font + property int inputMethodHints + property bool errorHighlight + property alias cursorPosition: textEdit.cursorPosition + property alias horizontalAlignment: textEdit.cursorPosition + property alias verticalAlignment: textEdit.cursorPosition + property alias readOnly: textEdit.readOnly + property alias selectedText: textEdit.selectedText // read-only + property alias selectionEnd: textEdit.selectionEnd // read-only + property alias selectionStart: textEdit.selectionStart // read-only + property alias text: textEdit.text + property alias textFormat: textEdit.textFormat // enumeration + property alias wrapMode: textEdit.wrapMode // enumeration + property string placeholderText + + // functions + function copy() { + textEdit.copy(); + } + + function paste() { + textEdit.paste(); + } + + function cut() { + textEdit.cut(); + } + + function select(start, end) { + textEdit.select(start, end); + } + + function selectAll() { + textEdit.selectAll(); + } + + function selectWord() { + textEdit.selectWord(); + } + + function positionAt(pos) { + textEdit.positionAt(pos); + } + + function positionToRectangle(pos) { + textEdit.positionToRectangle(pos); + } + + // Plasma API + property alias interactive: flickArea.interactive + property alias contentMaxWidth: textEdit.width + property alias contentMaxHeight: textEdit.height + property real scrollWidth: 22 + + // Set active focus to it's internal textInput. + // Overriding QtQuick.Item forceActiveFocus function. + function forceActiveFocus() { + textEdit.forceActiveFocus(); + } + + // Overriding QtQuick.Item activeFocus property. + property alias activeFocus: textEdit.activeFocus + + opacity: enabled ? 1.0 : 0.5 + + PlasmaCore.FrameSvgItem { + id: hover + + anchors { + fill: base + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/lineedit" + prefix: { + if (textEdit.activeFocus) + return "focus"; + else + return "hover"; + } + + opacity: (mouseWatcher.containsMouse||textArea.activeFocus) ? 1 : 0 + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + MouseArea { + id: mouseWatcher + anchors.fill: hover + hoverEnabled: true + } + + PlasmaCore.FrameSvgItem { + id: base + + // TODO: see what is the best policy for margins + anchors { + fill: flickArea + leftMargin: -2 * base.margins.left + rightMargin: -2 * base.margins.right + topMargin: -2 * base.margins.top + bottomMargin: -2 * base.margins.bottom + } + imagePath: "widgets/lineedit" + prefix: "base" + } + + Flickable { + id: flickArea + anchors { + fill: parent + rightMargin: scrollWidth + bottomMargin: scrollWidth + } + interactive: false //textArea.activeFocus + contentWidth: { + if (textEdit.wrapMode == TextEdit.NoWrap) + return textEdit.paintedWidth; + + return Math.min(textEdit.paintedWidth, textEdit.width); + } + contentHeight: Math.min(textEdit.paintedHeight, textEdit.height) + clip: true + + TextEdit { + id: textEdit + + width: flickArea.width + height: flickArea.height + clip: true + wrapMode: TextEdit.Wrap + enabled: textArea.enabled + + onCursorPositionChanged: { + if (cursorRectangle.x < flickArea.contentX) { + flickArea.contentX = cursorRectangle.x; + return; + } + + if (cursorRectangle.x > flickArea.contentX + + flickArea.width - cursorRectangle.width) { + flickArea.contentX = cursorRectangle.x - + cursorRectangle.width; + return; + } + + if (cursorRectangle.y < flickArea.contentY) { + flickArea.contentY = cursorRectangle.y; + return; + } + + if (cursorRectangle.y > flickArea.contentY + + flickArea.height - cursorRectangle.height) { + flickArea.contentY = cursorRectangle.y - + cursorRectangle.height; + return; + } + } + + // Proxying keys events is not required by the + // common API but is desired in the plasma API. + Keys.onPressed: textArea.Keys.pressed(event); + Keys.onReleased: textArea.Keys.released(event); + + Text { + anchors.fill: parent + text: textArea.placeholderText + visible: textEdit.text == "" && !textArea.activeFocus + opacity: 0.5 + } + } + } + + ScrollBar { + id: horizontalScroll + anchors { + bottom: parent.bottom + left: parent.left + right: flickArea.right + } + enabled: parent.enabled + flickableItem: flickArea + height: visible ? scrollWidth : 0 + orientation: Qt.Horizontal + stepSize: textEdit.font.pixelSize + } + + ScrollBar { + id: verticalScroll + anchors { + right: parent.right + top: parent.top + bottom: flickArea.bottom + } + enabled: parent.enabled + flickableItem: flickArea + width: visible ? scrollWidth : 0 + orientation: Qt.Vertical + stepSize: textEdit.font.pixelSize + } +} \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/TextField.qml b/declarativeimports/plasmacomponents/qml/TextField.qml new file mode 100644 index 000000000..71bd57681 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/TextField.qml @@ -0,0 +1,168 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +Item { + id: textField + + // Common API + property bool errorHighlight: false // TODO + property string placeholderText + property alias inputMethodHints: textInput.inputMethodHints + property alias font: textInput.font + + property alias cursorPosition: textInput.cursorPosition + property alias readOnly: textInput.readOnly + property alias echoMode: textInput.echoMode // Supports TextInput.Normal,TextInput.Password, TextInput.NoEcho, TextInput.PasswordEchoOnEdit + property alias acceptableInput: textInput.acceptableInput // read-only + property alias inputMask: textInput.inputMask + property alias validator: textInput.validator + property alias selectedText: textInput.selectedText // read-only + property alias selectionEnd: textInput.selectionEnd // read-only + property alias selectionStart: textInput.selectionStart // read-only + property alias text: textInput.text + property alias maximumLength: textInput.maximumLength + + function copy() { + textInput.copy(); + } + + function paste() { + textInput.paste(); + } + + function cut() { + textInput.cut(); + } + + function select(start, end) { + textInput.select(start, end); + } + + function selectAll() { + textInput.selectAll(); + } + + function selectWord() { + textInput.selectWord(); + } + + function positionAt(pos) { + textInput.positionAt(pos); + } + + function positionToRectangle(pos) { + textInput.positionToRectangle(pos); + } + + // Plasma API + property QtObject theme: PlasmaCore.Theme { } + + // Set active focus to it's internal textInput. + // Overriding QtQuick.Item forceActiveFocus function. + function forceActiveFocus() { + textInput.forceActiveFocus(); + } + + // Overriding QtQuick.Item activeFocus property. + property alias activeFocus: textInput.activeFocus + + // TODO: fix default size + implicitWidth: 100 + implicitHeight: 26 + // TODO: needs to define if there will be specific graphics for + // disabled text fields + opacity: enabled ? 1.0 : 0.5 + + PlasmaCore.FrameSvgItem { + id: base + + // TODO: see what is the correct policy for margins + anchors.fill: parent + imagePath: "widgets/lineedit" + prefix: "base" + } + + PlasmaCore.FrameSvgItem { + id: hover + + anchors { + fill: parent + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + imagePath: "widgets/lineedit" + prefix: { + if (textField.activeFocus) { + return "focus" + } else { + return "hover" + } + } + opacity: (mouseWatcher.containsMouse||textField.activeFocus) ? 1 : 0 + Behavior on opacity { + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + } + } + } + MouseArea { + id: mouseWatcher + anchors.fill: hover + hoverEnabled: true + } + + Text { + anchors.fill: textInput + text: placeholderText + visible: textInput.text == "" && !textField.activeFocus + // XXX: using textColor and low opacity for theming placeholderText + color: theme.textColor + opacity: 0.5 + elide: Text.ElideRight + clip: true + } + + TextInput { + id: textInput + + anchors { + left: parent.left + right: parent.right + // TODO: see what is the correct policy for margins + leftMargin: 2 * base.margins.left + rightMargin: 2 * base.margins.right + } + y: (height - font.pixelSize) * 0.4 // XXX: verticalCenter anchor is not centering the text + height: Math.min(2 * font.pixelSize, parent.height) + color: theme.textColor + enabled: textField.enabled + clip: true + + // Proxying keys events is not required by the + // common API but is desired in the plasma API. + Keys.onPressed: textField.Keys.pressed(event); + Keys.onReleased: textField.Keys.released(event); + } +} \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qml/ToolBar.qml b/declarativeimports/plasmacomponents/qml/ToolBar.qml new file mode 100644 index 000000000..68a7472a4 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ToolBar.qml @@ -0,0 +1,166 @@ +/* +* 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.0 +import org.kde.plasma.core 0.1 as PlasmaCore + +PlasmaCore.FrameSvgItem { + id: toolBar + imagePath: "widgets/frame" + prefix: "raised" + height: 48 + margins.top + margins.bottom + + // The current set of tools; null if none. + property Item tools + + // The transition type. One of the following: + // set an instantaneous change (default) + // push follows page stack push animation + // pop follows page stack pop animation + // replace follows page stack replace animation + property string transition: "set" + + // Sets the tools with a transition. + function setTools(tools, transition) + { + if (toolBar.tools == tools) { + return + } + + toolBar.transition = transition + toolBar.tools = tools + } + onToolsChanged: { + var newContainer + var oldContainer + if (containerA.current) { + newContainer = containerB + oldContainer = containerA + } else { + newContainer = containerA + oldContainer = containerB + } + containerA.current = !containerA.current + + tools.parent = newContainer + tools.visible = true + tools.anchors.left = newContainer.left + tools.anchors.right = newContainer.right + tools.anchors.verticalCenter = newContainer.verticalCenter + + switch (transition) { + case "push": + containerA.animationsEnabled = true + oldContainer.x = -oldContainer.width + + containerA.animationsEnabled = false + newContainer.x = newContainer.width + newContainer.y = 0 + containerA.animationsEnabled = true + newContainer.x = 0 + break + case "pop": + containerA.animationsEnabled = true + oldContainer.x = oldContainer.width + + containerA.animationsEnabled = false + newContainer.x = -newContainer.width + newContainer.y = 0 + containerA.animationsEnabled = true + newContainer.x = 0 + break + case "replace": + containerA.animationsEnabled = true + oldContainer.y = oldContainer.height + + containerA.animationsEnabled = false + newContainer.x = 0 + newContainer.y = -newContainer.height + containerA.animationsEnabled = true + newContainer.y = 0 + break + case "set": + default: + containerA.animationsEnabled = false + containerA.animationsEnabled = false + oldContainer.x = -oldContainer.width + newContainer.x = 0 + break + } + + newContainer.opacity = 1 + oldContainer.opacity = 0 + } + + Item { + anchors { + fill: parent + leftMargin: parent.margins.left + topMargin: parent.margins.top + rightMargin: parent.margins.right + bottomMargin: parent.margins.bottom + } + + Item { + id: containerA + width: parent.width + height: parent.height + property bool animationsEnabled: false + opacity: 0 + //this asymmetry just to not export a property + property bool current: false + Behavior on opacity { + PropertyAnimation { duration: 250 } + } + Behavior on x { + enabled: containerA.animationsEnabled + PropertyAnimation { + duration: 250 + } + } + Behavior on y { + enabled: containerA.animationsEnabled + PropertyAnimation { + duration: 250 + } + } + } + Item { + id: containerB + width: parent.width + height: parent.height + opacity: 0 + Behavior on opacity { + PropertyAnimation { duration: 250 } + } + Behavior on x { + enabled: containerA.animationsEnabled + PropertyAnimation { + duration: 250 + } + } + Behavior on y { + enabled: containerA.animationsEnabled + PropertyAnimation { + duration: 250 + } + } + } + } +} diff --git a/declarativeimports/plasmacomponents/qml/ToolButton.qml b/declarativeimports/plasmacomponents/qml/ToolButton.qml new file mode 100644 index 000000000..d17cbf40b --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/ToolButton.qml @@ -0,0 +1,179 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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 + +Item { + id: button + + // Commmon API + property bool flat: true + property bool checked: false + property bool checkable: false + property alias pressed: mouse.pressed + property alias text: label.text + property alias iconSource: icon.source + property alias font: label.font + + signal clicked() + + PlasmaCore.Theme { + id: theme + } + + onFlatChanged: { + surface.opacity = 1 + } + + function pressButton() { + if (button.enabled) + surface.prefix = "pressed"; + } + + function releaseButton() { + if (!button.enabled) + return; + + if (button.checkable) + button.checked = !button.checked; + + // TODO: "checked" state must have special graphics? + if (button.checked) + surface.prefix = "pressed"; + else + surface.prefix = "normal"; + + button.clicked(); + button.forceActiveFocus(); + } + + width: Math.max(50, icon.width + label.paintedWidth + surface.margins.left + surface.margins.right) + height: Math.max(20, Math.max(icon.height, label.paintedHeight) + surface.margins.top + surface.margins.bottom) + // TODO: needs to define if there will be specific graphics for + // disabled buttons + opacity: enabled ? 1.0 : 0.5 + + Keys.onSpacePressed: pressButton(); + Keys.onReturnPressed: pressButton(); + Keys.onReleased: { + if (event.key == Qt.Key_Space || + event.key == Qt.Key_Return) + releaseButton(); + } + + onActiveFocusChanged: { + if (activeFocus) { + shadow.state = "focus" + } else if (checked) { + shadow.state = "hidden" + } else { + shadow.state = "shadow" + } + } + + ButtonShadow { + id: shadow + anchors.fill: parent + visible: !flat + } + + PlasmaCore.FrameSvgItem { + id: surface + + anchors.fill: parent + imagePath: "widgets/button" + prefix: "normal" + opacity: 0 + Behavior on opacity { + PropertyAnimation { duration: 250 } + } + } + + Item { + anchors { + fill: parent + leftMargin: surface.margins.left + topMargin: surface.margins.top + rightMargin: surface.margins.right + bottomMargin: surface.margins.bottom + } + + Image { + id: icon + + anchors { + fill: label.text ? undefined : parent + top: label.text ? parent.top : undefined + left: label.text ? parent.left : undefined + bottom: label.text ? parent.bottom : undefined + } + fillMode: Image.PreserveAspectFit + } + + Text { + id: label + + anchors { + top: parent.top + bottom: parent.bottom + left: icon.right + right: parent.right + } + color: theme.buttonTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + } + + MouseArea { + id: mouse + + anchors.fill: parent + hoverEnabled: true + + onPressed: { + pressButton(); + } + onReleased: { + releaseButton(); + } + onEntered: { + if (flat) { + surface.opacity = 1 + } else { + shadow.state = "hover" + } + } + onExited: { + if (flat) { + surface.opacity = 0 + } else { + if (button.activeFocus) { + shadow.state = "focus" + } else if (checked) { + shadow.state = "hidden" + } else { + shadow.state = "shadow" + } + } + } + } +} + diff --git a/declarativeimports/plasmacomponents/qml/qmldir b/declarativeimports/plasmacomponents/qml/qmldir new file mode 100644 index 000000000..63cd2e939 --- /dev/null +++ b/declarativeimports/plasmacomponents/qml/qmldir @@ -0,0 +1,24 @@ +plugin plasmacomponentsplugin + +BusyIndicator 0.1 BusyIndicator.qml +Button 0.1 Button.qml +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 +Highlight 0.1 Highlight.qml +IconWidget 0.1 IconWidget.qml +Label 0.1 Label.qml +ProgressBar 0.1 ProgressBar.qml +PushButton 0.1 PushButton.qml +RadioButton 0.1 RadioButton.qml +ScrollBar 0.1 ScrollBar.qml +ScrollDecorator 0.1 ScrollDecorator.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 \ No newline at end of file diff --git a/declarativeimports/plasmacomponents/qrangemodel.cpp b/declarativeimports/plasmacomponents/qrangemodel.cpp new file mode 100644 index 000000000..fab6d1d9a --- /dev/null +++ b/declarativeimports/plasmacomponents/qrangemodel.cpp @@ -0,0 +1,522 @@ +/**************************************************************************** +** +** 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 on Qt Labs. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +/*! + \class QRangeModel + \brief The QRangeModel class, helps users to build components that depend + on some value and/or position to be in a certain range previously defined + + With this class, the user sets a value range and a position range, which + represent the valid values/positions the model can assume. It is worth telling + that the value property always has priority over the position property. A nice use + case, would be a Slider implementation with the help of QRangeModel. If the user sets + a value range to [0,100], a position range to [50,100] and sets the value + to 80, the equivalent position would be 90. After that, if the user decides to + resize the slider, the value would be the same, but the knob position would + be updated due to the new position range. + + \ingroup qt-components +*/ + +#ifndef QT_NO_ACCESSIBILITY +#include +#endif + +#include "qrangemodel.h" +#include "qrangemodel_p.h" + +namespace Plasma +{ + +QRangeModelPrivate::QRangeModelPrivate(QRangeModel *qq) + : q_ptr(qq) +{ +} + +QRangeModelPrivate::~QRangeModelPrivate() +{ +} + +void QRangeModelPrivate::init() +{ + minimum = 0; + maximum = 99; + stepSize = 0; + value = 0; + pos = 0; + posatmin = 0; + posatmax = 0; + inverted = false; +} + +/*! + Calculates the position that is going to be seen outside by the component + that is using QRangeModel. It takes into account the \l stepSize, + \l positionAtMinimum, \l positionAtMaximum properties + and \a position that is passed as parameter. +*/ + +qreal QRangeModelPrivate::publicPosition(qreal position) const +{ + // Calculate the equivalent stepSize for the position property. + const qreal min = effectivePosAtMin(); + const qreal max = effectivePosAtMax(); + const qreal valueRange = maximum - minimum; + const qreal positionValueRatio = valueRange ? (max - min) / valueRange : 0; + const qreal positionStep = stepSize * positionValueRatio; + + if (positionStep == 0) + return (min < max) ? qBound(min, position, max) : qBound(max, position, min); + + const int stepSizeMultiplier = (position - min) / positionStep; + + // Test whether value is below minimum range + if (stepSizeMultiplier < 0) + return min; + + qreal leftEdge = (stepSizeMultiplier * positionStep) + min; + qreal rightEdge = ((stepSizeMultiplier + 1) * positionStep) + min; + + if (min < max) { + leftEdge = qMin(leftEdge, max); + rightEdge = qMin(rightEdge, max); + } else { + leftEdge = qMax(leftEdge, max); + rightEdge = qMax(rightEdge, max); + } + + if (qAbs(leftEdge - position) <= qAbs(rightEdge - position)) + return leftEdge; + return rightEdge; +} + +/*! + Calculates the value that is going to be seen outside by the component + that is using QRangeModel. It takes into account the \l stepSize, + \l minimumValue, \l maximumValue properties + and \a value that is passed as parameter. +*/ + +qreal QRangeModelPrivate::publicValue(qreal value) const +{ + // It is important to do value-within-range check this + // late (as opposed to during setPosition()). The reason is + // QML bindings; a position that is initially invalid because it lays + // outside the range, might become valid later if the range changes. + + if (stepSize == 0) + return qBound(minimum, value, maximum); + + const int stepSizeMultiplier = (value - minimum) / stepSize; + + // Test whether value is below minimum range + if (stepSizeMultiplier < 0) + return minimum; + + const qreal leftEdge = qMin(maximum, (stepSizeMultiplier * stepSize) + minimum); + const qreal rightEdge = qMin(maximum, ((stepSizeMultiplier + 1) * stepSize) + minimum); + const qreal middle = (leftEdge + rightEdge) / 2; + + return (value <= middle) ? leftEdge : rightEdge; +} + +/*! + Checks if the \l value or \l position, that is seen by the user, has changed and emits the changed signal if it + has changed. +*/ + +void QRangeModelPrivate::emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition) +{ + Q_Q(QRangeModel); + + // Effective value and position might have changed even in cases when e.g. d->value is + // unchanged. This will be the case when operating with values outside range: + const qreal newValue = q->value(); + const qreal newPosition = q->position(); + if (!qFuzzyCompare(newValue, oldValue)) + emit q->valueChanged(newValue); + if (!qFuzzyCompare(newPosition, oldPosition)) + emit q->positionChanged(newPosition); +} + +/*! + Constructs a QRangeModel with \a parent +*/ + +QRangeModel::QRangeModel(QObject *parent) + : QObject(parent), d_ptr(new QRangeModelPrivate(this)) +{ + Q_D(QRangeModel); + d->init(); +} + +/*! + \internal + Constructs a QRangeModel with private class pointer \a dd and \a parent +*/ + +QRangeModel::QRangeModel(QRangeModelPrivate &dd, QObject *parent) + : QObject(parent), d_ptr(&dd) +{ + Q_D(QRangeModel); + d->init(); +} + +/*! + Destroys the QRangeModel +*/ + +QRangeModel::~QRangeModel() +{ + delete d_ptr; + d_ptr = 0; +} + +/*! + Sets the range of valid positions, that \l position can assume externally, with + \a min and \a max. + Such range is represented by \l positionAtMinimum and \l positionAtMaximum +*/ + +void QRangeModel::setPositionRange(qreal min, qreal max) +{ + Q_D(QRangeModel); + + bool emitPosAtMinChanged = !qFuzzyCompare(min, d->posatmin); + bool emitPosAtMaxChanged = !qFuzzyCompare(max, d->posatmax); + + if (!(emitPosAtMinChanged || emitPosAtMaxChanged)) + return; + + const qreal oldPosition = position(); + d->posatmin = min; + d->posatmax = max; + + // When a new positionRange is defined, the position property must be updated based on the value property. + // For instance, imagine that you have a valueRange of [0,100] and a position range of [20,100], + // if a user set the value to 50, the position would be 60. If this positionRange is updated to [0,100], then + // the new position, based on the value (50), will be 50. + // If the newPosition is different than the old one, it must be updated, in order to emit + // the positionChanged signal. + d->pos = d->equivalentPosition(d->value); + + if (emitPosAtMinChanged) + emit positionAtMinimumChanged(d->posatmin); + if (emitPosAtMaxChanged) + emit positionAtMaximumChanged(d->posatmax); + + d->emitValueAndPositionIfChanged(value(), oldPosition); +} +/*! + Sets the range of valid values, that \l value can assume externally, with + \a min and \a max. The range has the following constraint: \a min must be less or equal \a max + Such range is represented by \l minimumValue and \l maximumValue +*/ + +void QRangeModel::setRange(qreal min, qreal max) +{ + Q_D(QRangeModel); + + bool emitMinimumChanged = !qFuzzyCompare(min, d->minimum); + bool emitMaximumChanged = !qFuzzyCompare(max, d->maximum); + + if (!(emitMinimumChanged || emitMaximumChanged)) + return; + + const qreal oldValue = value(); + const qreal oldPosition = position(); + + d->minimum = min; + d->maximum = qMax(min, max); + + // Update internal position if it was changed. It can occurs if internal value changes, due to range update + d->pos = d->equivalentPosition(d->value); + + if (emitMinimumChanged) + emit minimumChanged(d->minimum); + if (emitMaximumChanged) + emit maximumChanged(d->maximum); + + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +/*! + \property QRangeModel::minimumValue + \brief the minimum value that \l value can assume + + This property's default value is 0 +*/ + +void QRangeModel::setMinimum(qreal min) +{ + Q_D(const QRangeModel); + setRange(min, d->maximum); +} + +qreal QRangeModel::minimum() const +{ + Q_D(const QRangeModel); + return d->minimum; +} + +/*! + \property QRangeModel::maximumValue + \brief the maximum value that \l value can assume + + This property's default value is 99 +*/ + +void QRangeModel::setMaximum(qreal max) +{ + Q_D(const QRangeModel); + // if the new maximum value is smaller than + // minimum, update minimum too + setRange(qMin(d->minimum, max), max); +} + +qreal QRangeModel::maximum() const +{ + Q_D(const QRangeModel); + return d->maximum; +} + +/*! + \property QRangeModel::stepSize + \brief the value that is added to the \l value and \l position property + + Example: If a user sets a range of [0,100] and stepSize + to 30, the valid values that are going to be seen externally would be: 0, 30, 60, 90, 100. +*/ + +void QRangeModel::setStepSize(qreal stepSize) +{ + Q_D(QRangeModel); + + stepSize = qMax(qreal(0.0), stepSize); + if (qFuzzyCompare(stepSize, d->stepSize)) + return; + + const qreal oldValue = value(); + const qreal oldPosition = position(); + d->stepSize = stepSize; + + emit stepSizeChanged(d->stepSize); + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +qreal QRangeModel::stepSize() const +{ + Q_D(const QRangeModel); + return d->stepSize; +} + +/*! + Returns a valid position, respecting the \l positionAtMinimum, + \l positionAtMaximum and the \l stepSize properties. + Such calculation is based on the parameter \a value (which is valid externally). +*/ + +qreal QRangeModel::positionForValue(qreal value) const +{ + Q_D(const QRangeModel); + + const qreal unconstrainedPosition = d->equivalentPosition(value); + return d->publicPosition(unconstrainedPosition); +} + +/*! + \property QRangeModel::position + \brief the current position of the model + + Represents a valid external position, based on the \l positionAtMinimum, + \l positionAtMaximum and the \l stepSize properties. + The user can set it internally with a position, that is not within the current position range, + since it can become valid if the user changes the position range later. +*/ + +qreal QRangeModel::position() const +{ + Q_D(const QRangeModel); + + // Return the internal position but observe boundaries and + // stepSize restrictions. + return d->publicPosition(d->pos); +} + +void QRangeModel::setPosition(qreal newPosition) +{ + Q_D(QRangeModel); + + if (qFuzzyCompare(newPosition, d->pos)) + return; + + const qreal oldPosition = position(); + const qreal oldValue = value(); + + // Update position and calculate new value + d->pos = newPosition; + d->value = d->equivalentValue(d->pos); + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +/*! + \property QRangeModel::positionAtMinimum + \brief the minimum value that \l position can assume + + This property's default value is 0 +*/ + +void QRangeModel::setPositionAtMinimum(qreal min) +{ + Q_D(QRangeModel); + setPositionRange(min, d->posatmax); +} + +qreal QRangeModel::positionAtMinimum() const +{ + Q_D(const QRangeModel); + return d->posatmin; +} + +/*! + \property QRangeModel::positionAtMaximum + \brief the maximum value that \l position can assume + + This property's default value is 0 +*/ + +void QRangeModel::setPositionAtMaximum(qreal max) +{ + Q_D(QRangeModel); + setPositionRange(d->posatmin, max); +} + +qreal QRangeModel::positionAtMaximum() const +{ + Q_D(const QRangeModel); + return d->posatmax; +} + +/*! + Returns a valid value, respecting the \l minimumValue, + \l maximumValue and the \l stepSize properties. + Such calculation is based on the parameter \a position (which is valid externally). +*/ + +qreal QRangeModel::valueForPosition(qreal position) const +{ + Q_D(const QRangeModel); + + const qreal unconstrainedValue = d->equivalentValue(position); + return d->publicValue(unconstrainedValue); +} + +/*! + \property QRangeModel::value + \brief the current value of the model + + Represents a valid external value, based on the \l minimumValue, + \l maximumValue and the \l stepSize properties. + The user can set it internally with a value, that is not within the current range, + since it can become valid if the user changes the range later. +*/ + +qreal QRangeModel::value() const +{ + Q_D(const QRangeModel); + + // Return internal value but observe boundaries and + // stepSize restrictions + return d->publicValue(d->value); +} + +void QRangeModel::setValue(qreal newValue) +{ + Q_D(QRangeModel); + + if (qFuzzyCompare(newValue, d->value)) + return; + + const qreal oldValue = value(); + const qreal oldPosition = position(); + + // Update relative value and position + d->value = newValue; + d->pos = d->equivalentPosition(d->value); + d->emitValueAndPositionIfChanged(oldValue, oldPosition); +} + +/*! + \property QRangeModel::inverted + \brief the model is inverted or not + + The model can be represented with an inverted behavior, e.g. when \l value assumes + the maximum value (represented by \l maximumValue) the \l position will be at its + minimum (represented by \l positionAtMinimum). +*/ + +void QRangeModel::setInverted(bool inverted) +{ + Q_D(QRangeModel); + if (inverted == d->inverted) + return; + + d->inverted = inverted; + emit invertedChanged(d->inverted); + + // After updating the internal value, the position property can change. + setPosition(d->equivalentPosition(d->value)); +} + +bool QRangeModel::inverted() const +{ + Q_D(const QRangeModel); + return d->inverted; +} + +/*! + Sets the \l value to \l minimumValue. +*/ + +void QRangeModel::toMinimum() +{ + Q_D(const QRangeModel); + setValue(d->minimum); +} + +/*! + Sets the \l value to \l maximumValue. +*/ + +void QRangeModel::toMaximum() +{ + Q_D(const QRangeModel); + setValue(d->maximum); +} + +} // Plasma namespace + +#include "qrangemodel.moc" diff --git a/declarativeimports/plasmacomponents/qrangemodel.h b/declarativeimports/plasmacomponents/qrangemodel.h new file mode 100644 index 000000000..bdc8122e7 --- /dev/null +++ b/declarativeimports/plasmacomponents/qrangemodel.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** 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 on Qt Labs. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QRANGEMODEL_H +#define QRANGEMODEL_H + +#include + +namespace Plasma +{ + +class QRangeModelPrivate; + +class QRangeModel : public QObject +{ + Q_OBJECT + + Q_PROPERTY(qreal value READ value WRITE setValue NOTIFY valueChanged USER true) + Q_PROPERTY(qreal minimumValue READ minimum WRITE setMinimum NOTIFY minimumChanged) + Q_PROPERTY(qreal maximumValue READ maximum WRITE setMaximum NOTIFY maximumChanged) + Q_PROPERTY(qreal stepSize READ stepSize WRITE setStepSize NOTIFY stepSizeChanged) + Q_PROPERTY(qreal position READ position WRITE setPosition NOTIFY positionChanged) + Q_PROPERTY(qreal positionAtMinimum READ positionAtMinimum WRITE setPositionAtMinimum NOTIFY positionAtMinimumChanged) + Q_PROPERTY(qreal positionAtMaximum READ positionAtMaximum WRITE setPositionAtMaximum NOTIFY positionAtMaximumChanged) + Q_PROPERTY(bool inverted READ inverted WRITE setInverted NOTIFY invertedChanged) + +public: + QRangeModel(QObject *parent = 0); + virtual ~QRangeModel(); + + void setRange(qreal min, qreal max); + void setPositionRange(qreal min, qreal max); + + void setStepSize(qreal stepSize); + qreal stepSize() const; + + void setMinimum(qreal min); + qreal minimum() const; + + void setMaximum(qreal max); + qreal maximum() const; + + void setPositionAtMinimum(qreal posAtMin); + qreal positionAtMinimum() const; + + void setPositionAtMaximum(qreal posAtMax); + qreal positionAtMaximum() const; + + void setInverted(bool inverted); + bool inverted() const; + + qreal value() const; + qreal position() const; + + Q_INVOKABLE qreal valueForPosition(qreal position) const; + Q_INVOKABLE qreal positionForValue(qreal value) const; + +public Q_SLOTS: + void toMinimum(); + void toMaximum(); + void setValue(qreal value); + void setPosition(qreal position); + +Q_SIGNALS: + void valueChanged(qreal value); + void positionChanged(qreal position); + + void stepSizeChanged(qreal stepSize); + + void invertedChanged(bool inverted); + + void minimumChanged(qreal min); + void maximumChanged(qreal max); + void positionAtMinimumChanged(qreal min); + void positionAtMaximumChanged(qreal max); + +protected: + QRangeModel(QRangeModelPrivate &dd, QObject *parent); + QRangeModelPrivate* d_ptr; + +private: + Q_DISABLE_COPY(QRangeModel) + Q_DECLARE_PRIVATE(QRangeModel) + +}; + +} // Plasma namespace + +#endif // QRANGEMODEL_H diff --git a/declarativeimports/plasmacomponents/qrangemodel_p.h b/declarativeimports/plasmacomponents/qrangemodel_p.h new file mode 100644 index 000000000..5eb628671 --- /dev/null +++ b/declarativeimports/plasmacomponents/qrangemodel_p.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** 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 on Qt Labs. +** +** 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. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +#ifndef QRANGEMODEL_P_H +#define QRANGEMODEL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt Components API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qrangemodel.h" + +namespace Plasma +{ + +class QRangeModelPrivate +{ + Q_DECLARE_PUBLIC(QRangeModel) +public: + QRangeModelPrivate(QRangeModel *qq); + virtual ~QRangeModelPrivate(); + + void init(); + + qreal posatmin, posatmax; + qreal minimum, maximum, stepSize, pos, value; + + uint inverted : 1; + + QRangeModel *q_ptr; + + inline qreal effectivePosAtMin() const { + return inverted ? posatmax : posatmin; + } + + inline qreal effectivePosAtMax() const { + return inverted ? posatmin : posatmax; + } + + inline qreal equivalentPosition(qreal value) const { + // Return absolute position from absolute value + const qreal valueRange = maximum - minimum; + if (valueRange == 0) + return effectivePosAtMin(); + + const qreal scale = (effectivePosAtMax() - effectivePosAtMin()) / valueRange; + return (value - minimum) * scale + effectivePosAtMin(); + } + + inline qreal equivalentValue(qreal pos) const { + // Return absolute value from absolute position + const qreal posRange = effectivePosAtMax() - effectivePosAtMin(); + if (posRange == 0) + return minimum; + + const qreal scale = (maximum - minimum) / posRange; + return (pos - effectivePosAtMin()) * scale + minimum; + } + + qreal publicPosition(qreal position) const; + qreal publicValue(qreal value) const; + void emitValueAndPositionIfChanged(const qreal oldValue, const qreal oldPosition); +}; + +} // Plasma namespace + +#endif // QRANGEMODEL_P_H diff --git a/declarativeimports/qtextracomponents/CMakeLists.txt b/declarativeimports/qtextracomponents/CMakeLists.txt new file mode 100644 index 000000000..3264ae8e2 --- /dev/null +++ b/declarativeimports/qtextracomponents/CMakeLists.txt @@ -0,0 +1,26 @@ +project(qtextracomponents) + +include(KDE4Defaults) + +set(qtextracomponents_SRCS + qtextracomponentsplugin.cpp + qpixmapitem.cpp + qimageitem.cpp + qiconitem.cpp + ) + +INCLUDE_DIRECTORIES( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${KDE4_INCLUDES} +) + +qt4_automoc(${qtextracomponents_SRCS}) + + +add_library(qtextracomponentsplugin SHARED ${qtextracomponents_SRCS}) +target_link_libraries(qtextracomponentsplugin ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QTDECLARATIVE_LIBRARY}) + +install(TARGETS qtextracomponentsplugin DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/qtextracomponents) + +install(FILES qmldir DESTINATION ${IMPORTS_INSTALL_DIR}/org/kde/qtextracomponents) diff --git a/declarativeimports/qtextracomponents/qiconitem.cpp b/declarativeimports/qtextracomponents/qiconitem.cpp new file mode 100644 index 000000000..d72381e47 --- /dev/null +++ b/declarativeimports/qtextracomponents/qiconitem.cpp @@ -0,0 +1,82 @@ +/* + * 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 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 "qiconitem.h" + +#include + + +QIconItem::QIconItem(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_smooth(false) +{ + setFlag(QGraphicsItem::ItemHasNoContents, false); +} + + +QIconItem::~QIconItem() +{ +} + +void QIconItem::setIcon(const QIcon &icon) +{ + m_icon = icon; + update(); +} + +QIcon QIconItem::icon() const +{ + return m_icon; +} + +void QIconItem::setSmooth(const bool smooth) +{ + if (smooth == m_smooth) { + return; + } + m_smooth = smooth; + update(); +} + +bool QIconItem::smooth() const +{ + return m_smooth; +} + +void QIconItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + if (m_icon.isNull()) { + return; + } + //do without painter save, faster and the support can be compiled out + const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing); + const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->setRenderHint(QPainter::Antialiasing, m_smooth); + painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); + + m_icon.paint(painter, boundingRect().toRect(), Qt::AlignCenter, isEnabled()?QIcon::Normal:QIcon::Disabled); + painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); + painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); +} + + +#include "qiconitem.moc" diff --git a/declarativeimports/qtextracomponents/qiconitem.h b/declarativeimports/qtextracomponents/qiconitem.h new file mode 100644 index 000000000..9972a98fe --- /dev/null +++ b/declarativeimports/qtextracomponents/qiconitem.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * 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 QICONITEM_H +#define QICONITEM_H + +#include +#include + +class QIconItem : public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QIcon icon READ icon WRITE setIcon) + Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) + +public: + QIconItem(QDeclarativeItem *parent=0); + ~QIconItem(); + + void setIcon(const QIcon &icon); + QIcon icon() const; + + void setSmooth(const bool smooth); + bool smooth() const; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +private: + QIcon m_icon; + bool m_smooth; +}; + +#endif diff --git a/declarativeimports/qtextracomponents/qimageitem.cpp b/declarativeimports/qtextracomponents/qimageitem.cpp new file mode 100644 index 000000000..086449d19 --- /dev/null +++ b/declarativeimports/qtextracomponents/qimageitem.cpp @@ -0,0 +1,94 @@ +/* + * 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 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 "qimageitem.h" + +#include + + +QImageItem::QImageItem(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_smooth(false) +{ + setFlag(QGraphicsItem::ItemHasNoContents, false); +} + + +QImageItem::~QImageItem() +{ +} + +void QImageItem::setImage(const QImage &image) +{ + m_image = image; + update(); + emit nativeWidthChanged(); + emit nativeHeightChanged(); +} + +QImage QImageItem::image() const +{ + return m_image; +} + +void QImageItem::setSmooth(const bool smooth) +{ + if (smooth == m_smooth) { + return; + } + m_smooth = smooth; + update(); +} + +bool QImageItem::smooth() const +{ + return m_smooth; +} + +int QImageItem::nativeWidth() const +{ + return m_image.size().width(); +} + +int QImageItem::nativeHeight() const +{ + return m_image.size().height(); +} + +void QImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + if (m_image.isNull()) { + return; + } + //do without painter save, faster and the support can be compiled out + const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing); + const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->setRenderHint(QPainter::Antialiasing, m_smooth); + painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); + + painter->drawImage(boundingRect(), m_image, m_image.rect()); + painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); + painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); +} + + +#include "qimageitem.moc" diff --git a/declarativeimports/qtextracomponents/qimageitem.h b/declarativeimports/qtextracomponents/qimageitem.h new file mode 100644 index 000000000..a4365b5dc --- /dev/null +++ b/declarativeimports/qtextracomponents/qimageitem.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * 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 QIMAGEITEM_H +#define QIMAGEITEM_H + +#include +#include + +class QImageItem : public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QImage image READ image WRITE setImage) + Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) + Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged) + Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged) + +public: + QImageItem(QDeclarativeItem *parent=0); + ~QImageItem(); + + void setImage(const QImage &image); + QImage image() const; + + void setSmooth(const bool smooth); + bool smooth() const; + + int nativeWidth() const; + int nativeHeight() const; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +Q_SIGNALS: + void nativeWidthChanged(); + void nativeHeightChanged(); + +private: + QImage m_image; + bool m_smooth; +}; + +#endif diff --git a/declarativeimports/qtextracomponents/qmldir b/declarativeimports/qtextracomponents/qmldir new file mode 100644 index 000000000..b2452e3fc --- /dev/null +++ b/declarativeimports/qtextracomponents/qmldir @@ -0,0 +1,3 @@ +plugin qtextracomponentsplugin + + diff --git a/declarativeimports/qtextracomponents/qpixmapitem.cpp b/declarativeimports/qtextracomponents/qpixmapitem.cpp new file mode 100644 index 000000000..3c09efec1 --- /dev/null +++ b/declarativeimports/qtextracomponents/qpixmapitem.cpp @@ -0,0 +1,94 @@ +/* + * 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 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 "qpixmapitem.h" + +#include + + +QPixmapItem::QPixmapItem(QDeclarativeItem *parent) + : QDeclarativeItem(parent), + m_smooth(false) +{ + setFlag(QGraphicsItem::ItemHasNoContents, false); +} + + +QPixmapItem::~QPixmapItem() +{ +} + +void QPixmapItem::setPixmap(const QPixmap &pixmap) +{ + m_pixmap = pixmap; + update(); + emit nativeWidthChanged(); + emit nativeHeightChanged(); +} + +QPixmap QPixmapItem::pixmap() const +{ + return m_pixmap; +} + +void QPixmapItem::setSmooth(const bool smooth) +{ + if (smooth == m_smooth) { + return; + } + m_smooth = smooth; + update(); +} + +bool QPixmapItem::smooth() const +{ + return m_smooth; +} + +int QPixmapItem::nativeWidth() const +{ + return m_pixmap.size().width(); +} + +int QPixmapItem::nativeHeight() const +{ + return m_pixmap.size().height(); +} + +void QPixmapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) +{ + Q_UNUSED(option); + Q_UNUSED(widget); + + if (m_pixmap.isNull()) { + return; + } + //do without painter save, faster and the support can be compiled out + const bool wasAntiAlias = painter->testRenderHint(QPainter::Antialiasing); + const bool wasSmoothTransform = painter->testRenderHint(QPainter::SmoothPixmapTransform); + painter->setRenderHint(QPainter::Antialiasing, m_smooth); + painter->setRenderHint(QPainter::SmoothPixmapTransform, m_smooth); + + painter->drawPixmap(boundingRect(), m_pixmap, m_pixmap.rect()); + painter->setRenderHint(QPainter::Antialiasing, wasAntiAlias); + painter->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothTransform); +} + + +#include "qpixmapitem.moc" diff --git a/declarativeimports/qtextracomponents/qpixmapitem.h b/declarativeimports/qtextracomponents/qpixmapitem.h new file mode 100644 index 000000000..af2cc9ef0 --- /dev/null +++ b/declarativeimports/qtextracomponents/qpixmapitem.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * 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 QPIXMAPITEM_H +#define QPIXMAPITEM_H + +#include +#include + +class QPixmapItem : public QDeclarativeItem +{ + Q_OBJECT + + Q_PROPERTY(QPixmap pixmap READ pixmap WRITE setPixmap) + Q_PROPERTY(bool smooth READ smooth WRITE setSmooth) + Q_PROPERTY(int nativeWidth READ nativeWidth NOTIFY nativeWidthChanged) + Q_PROPERTY(int nativeHeight READ nativeHeight NOTIFY nativeHeightChanged) + +public: + QPixmapItem(QDeclarativeItem *parent=0); + ~QPixmapItem(); + + void setPixmap(const QPixmap &pixmap); + QPixmap pixmap() const; + + void setSmooth(const bool smooth); + bool smooth() const; + + int nativeWidth() const; + int nativeHeight() const; + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +Q_SIGNALS: + void nativeWidthChanged(); + void nativeHeightChanged(); + +private: + QPixmap m_pixmap; + bool m_smooth; +}; + +#endif diff --git a/declarativeimports/qtextracomponents/qtextracomponentsplugin.cpp b/declarativeimports/qtextracomponents/qtextracomponentsplugin.cpp new file mode 100644 index 000000000..7d6b61f82 --- /dev/null +++ b/declarativeimports/qtextracomponents/qtextracomponentsplugin.cpp @@ -0,0 +1,41 @@ +/* + * Copyright 2009 by Alan Alpert + * Copyright 2010 by Ménard Alexis + * Copyright 2010 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 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 "qtextracomponentsplugin.h" + +#include + +#include "qpixmapitem.h" +#include "qimageitem.h" +#include "qiconitem.h" + +void QtExtraComponentsPlugin::registerTypes(const char *uri) +{ + Q_ASSERT(uri == QLatin1String("org.kde.qtextracomponents")); + + qmlRegisterType(uri, 0, 1, "QPixmapItem"); + qmlRegisterType(uri, 0, 1, "QImageItem"); + qmlRegisterType(uri, 0, 1, "QIconItem"); +} + + +#include "qtextracomponentsplugin.moc" + diff --git a/declarativeimports/qtextracomponents/qtextracomponentsplugin.h b/declarativeimports/qtextracomponents/qtextracomponentsplugin.h new file mode 100644 index 000000000..8b1353ce7 --- /dev/null +++ b/declarativeimports/qtextracomponents/qtextracomponentsplugin.h @@ -0,0 +1,38 @@ +/* + * Copyright 2009 by Alan Alpert + * Copyright 2010 by Ménard Alexis + * Copyright 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 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. + */ + +#ifndef QTEXTRACOMPONENTSPLUGIN_H +#define QTEXTRACOMPONENTSPLUGIN_H + +#include + + +class QtExtraComponentsPlugin : public QDeclarativeExtensionPlugin +{ + Q_OBJECT + +public: + void registerTypes(const char *uri); +}; + +Q_EXPORT_PLUGIN2(qtextracomponentsplugin, QtExtraComponentsPlugin); + +#endif diff --git a/declarativeimports/test/gallery/Busy.qml b/declarativeimports/test/gallery/Busy.qml new file mode 100644 index 000000000..8e77db1ec --- /dev/null +++ b/declarativeimports/test/gallery/Busy.qml @@ -0,0 +1,78 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.components 0.1 as PlasmaComponents + +Column { + spacing: 20 + + Text { + font.pixelSize: 20 + text: "Busy Indicator" + } + + PlasmaComponents.BusyIndicator { } + + PlasmaComponents.BusyIndicator { running: true } + + Text { + font.pixelSize: 20 + text: "Progress Bar" + } + + Text { text: "Horizontal" } + + PlasmaComponents.ProgressBar { + value: 0.3 + } + + PlasmaComponents.ProgressBar { + indeterminate: true + } + + PlasmaComponents.ProgressBar { + minimumValue: 0 + maximumValue: 100 + value: 30 + } + + Text { text: "Vertical" } + Row { + spacing: 20 + PlasmaComponents.ProgressBar { + value: 0.3 + orientation: Qt.Vertical + width: 20 + height: 100 + } + PlasmaComponents.ProgressBar { + value: 0.4 + orientation: Qt.Vertical + width: 20 + height: 120 + } + PlasmaComponents.ProgressBar { + orientation: Qt.Vertical + width: 20 + height: 100 + indeterminate: true + } + } +} diff --git a/declarativeimports/test/gallery/Buttons.qml b/declarativeimports/test/gallery/Buttons.qml new file mode 100644 index 000000000..b1d9ecf7b --- /dev/null +++ b/declarativeimports/test/gallery/Buttons.qml @@ -0,0 +1,99 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.components 0.1 as PlasmaComponents + +Column { + spacing: 20 + + Text { + font.pixelSize: 20 + text: "Buttons" + } + + PlasmaComponents.Button { + id: bt1 + width: 140 + height: 30 + text: "Button" + + onClicked: { + console.log("Clicked"); + } + + Keys.onTabPressed: bt2.forceActiveFocus(); + } + + PlasmaComponents.Button { + id: bt2 + width: 140 + height: 30 + text: "Checkable Button" + checkable: true + + onCheckedChanged: { + if (checked) + console.log("Button Checked"); + else + console.log("Button Unchecked"); + } + + Keys.onTabPressed: bt3.forceActiveFocus(); + } + + PlasmaComponents.Button { + id: bt3 + width: 140 + height: 30 + text: "Different Font" + font { + pixelSize: 20 + family: "Helvetica" + } + + Keys.onTabPressed: bt4.forceActiveFocus(); + } + + PlasmaComponents.Button { + id: bt4 + width: 140 + height: 30 + text: "Icon Button" + iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png" + + Keys.onTabPressed: bt5.forceActiveFocus(); + } + + PlasmaComponents.Button { + id: bt5 + width: 140 + height: 30 + iconSource: "/home/dakerfp/work/comics-reader/ui/images/random.png" + + Keys.onTabPressed: bt1.forceActiveFocus(); + } + + PlasmaComponents.Button { + width: 140 + height: 30 + text: "Disabled Button" + enabled: false + } +} diff --git a/declarativeimports/test/gallery/CheckableButtons.qml b/declarativeimports/test/gallery/CheckableButtons.qml new file mode 100644 index 000000000..fee6032b4 --- /dev/null +++ b/declarativeimports/test/gallery/CheckableButtons.qml @@ -0,0 +1,107 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.components 0.1 as PlasmaComponents + +Column { + spacing: 20 + + Text { + font.pixelSize: 20 + text: "Check Box" + } + + PlasmaComponents.CheckBox { + width: 140 + height: 30 + text: "Check Box 1" + + onCheckedChanged: { + if (checked) + console.log("CheckBox checked"); + else + console.log("CheckBox unchecked"); + } + onClicked: { + console.log("CheckBox clicked"); + } + } + + PlasmaComponents.CheckBox { + height: 30 + text: "Disabled" + enabled: false + } + + PlasmaComponents.CheckBox { + height: 30 + text: "" + } + + PlasmaComponents.CheckBox { + height: 30 + text: "A loooooooooooooong text" + } + + Text { + font.pixelSize: 20 + text: "Radio Button" + } + + PlasmaComponents.RadioButton { + width: 140 + height: 30 + text: "RadioButton" + + onCheckedChanged: { + if (checked) + console.log("RadioButton Checked"); + else + console.log("RadioButton Unchecked"); + } + } + + PlasmaComponents.Switch { } + + Text { + font.pixelSize: 20 + text: "Button Row" + } + + PlasmaComponents.ButtonRow { + spacing: 20 + PlasmaComponents.RadioButton { text: "A" } + PlasmaComponents.RadioButton { text: "B" } + PlasmaComponents.RadioButton { text: "C" } + } + + Text { + font.pixelSize: 20 + text: "Button Column" + } + + PlasmaComponents.ButtonColumn { + spacing: 20 + PlasmaComponents.RadioButton { text: "Alice" } + PlasmaComponents.RadioButton { text: "Bob" } + PlasmaComponents.RadioButton { text: "Charles" } + } + +} diff --git a/declarativeimports/test/gallery/Gallery.qml b/declarativeimports/test/gallery/Gallery.qml new file mode 100644 index 000000000..bae3ada49 --- /dev/null +++ b/declarativeimports/test/gallery/Gallery.qml @@ -0,0 +1,127 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.components 0.1 as PlasmaComponents + +Rectangle { + width: 1000 + height: 800 + color: "lightgrey" + + PlasmaComponents.ToolBar { + id: toolBar + z: 10 + anchors { + top: parent.top + left: parent.left + right: parent.right + } + tools: toolbarA + } + Row { + id: toolbarA + visible: false + spacing: 5 + PlasmaComponents.ToolButton { + text: "Switch toolbar" + onClicked: toolBar.setTools(toolbarB, "push") + } + PlasmaComponents.ToolButton { + text: "button on first toolbar" + } + } + Row { + id: toolbarB + visible: false + spacing: 5 + PlasmaComponents.ToolButton { + text: "Switch toolbar" + onClicked: toolBar.setTools(toolbarA, "pop") + } + PlasmaComponents.ToolButton { + flat: false + text: "button on second toolbar" + } + PlasmaComponents.TextField {} + } + Flickable { + id: page + + anchors { + top: toolBar.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + contentWidth: 2200 + contentHeight: 1000 + + Row { + x: 30 + anchors { + top: parent.top + bottom: parent.bottom + margins: 20 + } + spacing: 30 + + Buttons{ } + + CheckableButtons { } + + Busy { } + + Sliders { } + + Scrollers { } + + Texts { } + } + } + + PlasmaComponents.ScrollBar { + id: horizontalScrollBar + + stepSize: 30 + + flickableItem: page + animated: true + anchors { + left: parent.left + right: verticalScrollBar.left + bottom: parent.bottom + } + } + + PlasmaComponents.ScrollBar { + id: verticalScrollBar + + stepSize: 30 + + orientation: Qt.Vertical + flickableItem: page + animated: true + anchors { + top: toolBar.bottom + right: parent.right + bottom: horizontalScrollBar.top + } + } +} diff --git a/declarativeimports/test/gallery/Scrollers.qml b/declarativeimports/test/gallery/Scrollers.qml new file mode 100644 index 000000000..dea2d8c81 --- /dev/null +++ b/declarativeimports/test/gallery/Scrollers.qml @@ -0,0 +1,131 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.components 0.1 as PlasmaComponents + +Column { + spacing: 20 + + Text { + font.pixelSize: 20 + text: "Scroll Bar" + } + + ListView { + id: scrollList + + width: 200 + height: 200 + clip: true + model: 20 + delegate: Text { + width: 200 + height: 30 + text: index + font.pixelSize: 18 + } + + Rectangle { + anchors.fill: parent + color: "grey" + opacity: 0.3 + } + + PlasmaComponents.ScrollBar { + id: scrollBar + orientation: Qt.Vertical + flickableItem: scrollList + animated: true + stepSize: 40 + scrollButtonInterval: 50 + anchors { + top: scrollList.top + right: scrollList.right + bottom: scrollList.bottom + } + } + } + + Text { + font.pixelSize: 20 + text: "Scroll Decorator" + } + + Item { + width: 200 + height: 200 + PlasmaComponents.Highlight { anchors.fill: parent } + Flickable { + id: scrollArea + anchors.fill: parent + clip: true + contentWidth: 400 + contentHeight: 400 + + // Flickable Contents + Rectangle { + color: "green" + width: 100 + height: 100 + } + Rectangle { + x: 80 + y: 80 + color: "blue" + width: 200 + height: 200 + } + Rectangle { + x: 200 + y: 200 + color: "red" + width: 150 + height: 150 + } + } + + // Scroll Decorators + PlasmaComponents.ScrollDecorator { + orientation: Qt.Vertical + flickableItem: scrollArea + inverted: true + anchors { + top: scrollArea.top + right: scrollArea.right + bottom: scrollArea.bottom + } + Text { + y: parent.height / 2 + x: 13 + rotation: -90 + text: "inverted" + } + } + PlasmaComponents.ScrollDecorator { + orientation: Qt.Horizontal + flickableItem: scrollArea + anchors { + left: scrollArea.left + right: scrollArea.right + bottom: scrollArea.bottom + } + } + } +} diff --git a/declarativeimports/test/gallery/Sliders.qml b/declarativeimports/test/gallery/Sliders.qml new file mode 100644 index 000000000..a87c53a2b --- /dev/null +++ b/declarativeimports/test/gallery/Sliders.qml @@ -0,0 +1,132 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.0 +import org.kde.plasma.components 0.1 as PlasmaComponents + +Column { + spacing: 20 + + PlasmaComponents.Label { + font.pixelSize: 20 + text: "Slider" + } + + PlasmaComponents.Highlight { + width: 300 + height: 400 + Column { + anchors { + fill: parent + } + spacing: 10 + + PlasmaComponents.Label { text: "Color Selector"; font.pixelSize: 20 } + + PlasmaComponents.Label { text: "Red" } + + PlasmaComponents.Slider { + id: redSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + animated: true + Keys.onTabPressed: greenSlider.forceActiveFocus() + } + + PlasmaComponents.Label { text: "Green" } + + PlasmaComponents.Slider { + id: greenSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + animated: true + Keys.onTabPressed: blueSlider.forceActiveFocus() + } + + PlasmaComponents.Label { text: "Blue" } + + PlasmaComponents.Slider { + id: blueSlider + height: 20 + width: 255 + orientation: Qt.Horizontal + minimumValue: 0 + maximumValue: 255 + stepSize: 10 + animated: true + Keys.onTabPressed: redSlider.forceActiveFocus() + } + + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + width: parent.width / 2 + height: width + color: Qt.rgba(redSlider.value / 255, greenSlider.value / 255, blueSlider.value / 255, 1) + } + } + } + + PlasmaComponents.Label { text: "Disabled Horizontal Slider" } + + PlasmaComponents.Slider { + id: horizontalSlider + width: 140 + height: 20 + animated: true + enabled: false + } + + PlasmaComponents.Label { text: "Inverted Horizontal Slider" } + + PlasmaComponents.Slider { + id: invHorizontalSlider + width: 140 + height: 20 + inverted: true + animated: true + enabled: true + } + + PlasmaComponents.Label { text: "Vertical Slider" } + + Row { + spacing: 30 + PlasmaComponents.Slider { + id: verticalSlider + width: 20 + height: 140 + orientation: Qt.Vertical + minimumValue: 10 + maximumValue: 1000 + stepSize: 50 + inverted: true + animated: true + } + PlasmaComponents.Label { text: verticalSlider.value } + } + +} diff --git a/declarativeimports/test/gallery/Texts.qml b/declarativeimports/test/gallery/Texts.qml new file mode 100644 index 000000000..ae3d0df48 --- /dev/null +++ b/declarativeimports/test/gallery/Texts.qml @@ -0,0 +1,99 @@ +/* +* Copyright (C) 2011 by Daker Fernandes Pinheiro +* +* 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.components 0.1 as PlasmaComponents + +Column { + spacing: 30 + Text { + text: "Text Fields" + font.pixelSize: 20 + } + + PlasmaComponents.Highlight { + width: 200 + height: 100 + Column { + spacing: 10 + Row { + Text { + text: "Username: " + anchors.verticalCenter: tf1.verticalCenter + } + PlasmaComponents.TextField { + id: tf1 + placeholderText: "login" + Keys.onTabPressed: tf2.forceActiveFocus(); + } + } + + Row { + Text { + text: "Password: " + anchors.verticalCenter: tf2.verticalCenter + } + PlasmaComponents.TextField { + id: tf2 + width: 120 + echoMode: TextInput.Password + Keys.onTabPressed: loginButton.forceActiveFocus(); + } + } + + PlasmaComponents.Button { + id: loginButton + text: "Login" + anchors { + right: parent.right + rightMargin: 0 + } + width: 100 + } + } + } + + PlasmaComponents.TextField { + width: 120 + placeholderText: "Disabled Text Field" + Keys.onTabPressed: loginButton.forceActiveFocus(); + enabled: false + } + + Text { + text: "Text Area" + font.pixelSize: 20 + } + + PlasmaComponents.TextArea { + width: 200 + height: 200 + placeholderText: "Lorem ipsum et dolor" + wrapMode: TextEdit.WordWrap + contentMaxWidth: 400 + contentMaxHeight: 400 + } + + PlasmaComponents.TextArea { + width: 200 + height: 100 + enabled: false + text: "Disabled Text Area" + } +} diff --git a/kpart/plasma-kpart.desktop b/kpart/plasma-kpart.desktop index 06526ae0c..578547fa2 100644 --- a/kpart/plasma-kpart.desktop +++ b/kpart/plasma-kpart.desktop @@ -1,5 +1,60 @@ [Desktop Entry] Name=plasma-kpart +Name[ast]=plasma-kpart +Name[bg]=plasma-kpart +Name[bs]=plasma-kpart +Name[ca]=plasma-kpart +Name[ca@valencia]=plasma-kpart +Name[cs]=plasma-kpart +Name[da]=plasma-kpart +Name[de]=plasma-kpart +Name[el]=plasma-kpart +Name[en_GB]=plasma-kpart +Name[es]=plasma-kpart +Name[et]=plasma-kpart +Name[eu]=plasma-kpart +Name[fi]=plasma-kpart +Name[fr]=plasma-kpart +Name[he]=plasma-kpart +Name[hi]=plasma-kpart +Name[hr]=plasma-kpart +Name[hu]=plasma-kpart +Name[ia]=plasma-kpart +Name[is]=plasma-kpart +Name[it]=plasma-kpart +Name[ja]=plasma-kpart +Name[kk]=plasma-kpart +Name[km]=plasma-kpart +Name[kn]=plasma-kpart +Name[ko]=plasma-kpart +Name[lt]=plasma-kpart +Name[nb]=plasma-kpart +Name[nds]=Kpart för Plasma +Name[nl]=plasma-kpart +Name[nn]=plasma-kpart +Name[pa]=plasma-kpart +Name[pl]=plasma-kpart +Name[pt]=plasma-kpart +Name[pt_BR]=plasma-kpart +Name[ro]=plasma-kpart +Name[ru]=plasma-kpart +Name[si]=plasma-kpart +Name[sk]=plasma-kpart +Name[sl]=plasma-kpart +Name[sr]=plasma-kpart +Name[sr@ijekavian]=plasma-kpart +Name[sr@ijekavianlatin]=plasma-kpart +Name[sr@latin]=plasma-kpart +Name[sv]=Plasma-delprogram +Name[tg]=plasma-kpart +Name[th]=plasma-kpart +Name[tr]=plasma-kpart +Name[ug]=plasma-kpart +Name[uk]=plasma-kpart +Name[wa]=plasma-kpårt +Name[x-test]=xxplasma-kpartxx +Name[zh_CN]=plasma-kpart +Name[zh_TW]=plasma-kpart Type=Service ServiceTypes=KParts/Part X-KDE-Library=plasma-kpart diff --git a/kpart/plasmakpart.cpp b/kpart/plasmakpart.cpp index 06f612cef..9259a20b7 100644 --- a/kpart/plasmakpart.cpp +++ b/kpart/plasmakpart.cpp @@ -22,8 +22,15 @@ #include "plasmakpart.h" -#include "plasmakpartcorona.h" -#include "plasmakpartview.h" +#include +#include +#include +#include +#include +#include + +#include +#include #include #include @@ -31,13 +38,8 @@ #include #include -#include -#include - -#include -#include -#include -#include +#include "plasmakpartcorona.h" +#include "plasmakpartview.h" K_PLUGIN_FACTORY(plasmaKPartFactory, registerPlugin();) K_EXPORT_PLUGIN(plasmaKPartFactory("plasma-kpart","plasma-kpart") ) @@ -45,8 +47,7 @@ K_EXPORT_PLUGIN(plasmaKPartFactory("plasma-kpart","plasma-kpart") ) PlasmaKPart::PlasmaKPart(QWidget *parentWidget, QObject *parent, const QVariantList &args) : KParts::ReadOnlyPart(parent), m_corona(0), - m_view(new PlasmaKPartView(0, 1, parentWidget)), - m_service(0) + m_view(new PlasmaKPartView(0, 1)) { setComponentData(plasmaKPartFactory::componentData()); @@ -66,16 +67,24 @@ PlasmaKPart::PlasmaKPart(QWidget *parentWidget, QObject *parent, const QVariantL } } - if (args.length() > 1) { - m_category = args.at(1).value(); - } - - // this line initializes the corona. - corona(); + setAutoDeletePart(false); + QTimer::singleShot(0, this, SLOT(initCorona())); } PlasmaKPart::~PlasmaKPart() { + delete m_view; + m_view = 0; + + if (!m_configFile.isEmpty()) { + m_corona->saveLayout(); + } + + delete m_corona; + m_corona = 0; + + //TODO: This manual sync() should not be necessary? + syncConfig(); } void PlasmaKPart::setThemeDefaults() @@ -90,62 +99,35 @@ void PlasmaKPart::setThemeDefaults() Plasma::Theme::defaultTheme()->setFont(cg.readEntry("desktopFont", QFont("Sans") )); } -void PlasmaKPart::cleanup() -{ - if (m_corona) { - m_corona->saveLayout(); - } - - if (!m_view->containment()) { - return; - } - - // save the mapping of Views to Containments at the moment - // of application exit so we can restore that when we start again. - KConfigGroup viewIds(KGlobal::config(), "ViewIds"); - viewIds.deleteGroup(); - viewIds.writeEntry(QString::number(m_view->containment()->id()), 1); - - delete m_view; - m_view = 0; - - delete m_corona; - m_corona = 0; - - //TODO: This manual sync() should not be necessary? - syncConfig(); -} - void PlasmaKPart::syncConfig() { KGlobal::config()->sync(); } -PlasmaKPartCorona* PlasmaKPart::corona() +void PlasmaKPart::initCorona() { - if (!m_corona) { - m_corona = new PlasmaKPartCorona(this); - connect(m_corona, SIGNAL(containmentAdded(Plasma::Containment*)), this, SLOT(createView(Plasma::Containment*))); - connect(m_corona, SIGNAL(configSynced()), this, SLOT(syncConfig())); - - m_corona->setItemIndexMethod(QGraphicsScene::NoIndex); - m_corona->initializeLayout(); - - m_view->show(); + if (m_corona) { + return; } + m_corona = new PlasmaKPartCorona(this); + connect(m_corona, SIGNAL(containmentAdded(Plasma::Containment*)), this, SLOT(createView(Plasma::Containment*))); + connect(m_corona, SIGNAL(configSynced()), this, SLOT(syncConfig())); + + m_corona->setItemIndexMethod(QGraphicsScene::NoIndex); + m_corona->initializeLayout(m_configFile); + + m_view->show(); +} + +PlasmaKPartCorona* PlasmaKPart::corona() const +{ return m_corona; } void PlasmaKPart::createView(Plasma::Containment *containment) { - KConfigGroup viewIds(KGlobal::config(), "ViewIds"); - int id = viewIds.readEntry(QString::number(containment->id()), 1); - - kDebug() << "new containment" << (QObject*)containment << containment->id()<<"view id"<setContainment(containment); - emit viewCreated(); } void PlasmaKPart::addApplet(const QString& name, const QVariantList& args, const QRectF& geometry ) @@ -153,29 +135,27 @@ void PlasmaKPart::addApplet(const QString& name, const QVariantList& args, const containment()->addApplet(name, args, geometry); } -Plasma::Applet::List PlasmaKPart::listActiveApplets( ) +Plasma::Applet::List PlasmaKPart::listActiveApplets() const { return containment()->applets(); } -Plasma::Containment* PlasmaKPart::containment() +QString PlasmaKPart::configFile() const +{ + return m_configFile; +} + +void PlasmaKPart::setConfigFile(const QString &file) +{ + m_configFile = file; + if (m_corona && QFile::exists(m_configFile)) { + m_corona->initializeLayout(m_configFile); + } +} + +Plasma::Containment* PlasmaKPart::containment() const { return corona()->containments().first(); } -bool PlasmaKPart::setPluginLoader(Plasma::PluginLoader *loader) -{ - if (Plasma::PluginLoader::pluginLoader()) { - return false; - } - - Plasma::PluginLoader::setPluginLoader(loader); - return true; -} - -QString PlasmaKPart::category() -{ - return m_category; -} - #include "plasmakpart.moc" diff --git a/kpart/plasmakpart.h b/kpart/plasmakpart.h index d0f2a07dd..92de38524 100644 --- a/kpart/plasmakpart.h +++ b/kpart/plasmakpart.h @@ -35,7 +35,6 @@ namespace Plasma } #include -#include #include class QVariant; @@ -45,16 +44,33 @@ class PlasmaKPart : public KParts::ReadOnlyPart { Q_OBJECT Q_PROPERTY(Plasma::Applet::List activeApplets READ listActiveApplets) + Q_PROPERTY(QString configFile READ configFile WRITE setConfigFile) public: + /** + * The default constructor. + * The args may contain a pointer to a Plasma::PluginLoader as the first parameter. + * Note that only one Plasma::PluginLoader can be active at a time, and that the + * prefered mechanism for registering the plugin loader is via + * Plasma::PluginLoader::setPluginLoader + */ PlasmaKPart(QWidget *parentWidget, QObject *parent, const QVariantList &args); ~PlasmaKPart(); void notifyStartup(bool completed); - PlasmaKPartCorona *corona(); - Plasma::Containment *containment(); - QString category(); + PlasmaKPartCorona *corona() const; + Plasma::Containment *containment() const; + + /** + * Returns a list of active applets in the containment. + * + * @return A list of the containment's Applets + **/ + Plasma::Applet::List listActiveApplets() const; + + QString configFile() const; + void setConfigFile(const QString &file); public Q_SLOTS: /** @@ -66,40 +82,8 @@ public Q_SLOTS: **/ void addApplet(const QString &pluginName, const QVariantList &args = QVariantList(), const QRectF &dimensions = QRectF()); - /** - * Sets the application-specific plugin loader. This allows - * applications which need to add internal applets (such - * as existing QWidget-based dashboard plugins), services or - * data engines to the Plasma dashboard. The preferred way to - * set this loader is by passing it to the KPart wrapped in a - * QVariant in the @p args parameter of the KPart constructor. - * This method is provided for applications which cannot set - * the loader in this method. - * The method will return false if Plasma already has a - * PluginLoader in memory, and will return true if the PluginLoader - * is successfully set. - * - * @param loader The loader which you want Plasma to query for - * new Applets, Data Engines and Services. - * @return True if the loader was successfully set, false otherwise - * (If Plasma already has a PluginLoader in memory) - * - * @short Set application-specific plugin loader - **/ - bool setPluginLoader(Plasma::PluginLoader *loader); - - /** - * Returns a list of active applets in the containment. - * - * @return A list of the containment's Applets - **/ - Plasma::Applet::List listActiveApplets(); - -Q_SIGNALS: - void viewCreated(); - private Q_SLOTS: - void cleanup(); + void initCorona(); void syncConfig(); void createView(Plasma::Containment* containment); void setThemeDefaults(); @@ -107,10 +91,9 @@ private Q_SLOTS: private: PlasmaKPartCorona* m_corona; PlasmaKPartView* m_view; - QString m_category; - KService::Ptr m_service; QHash* m_appletList; QVBoxLayout* m_configLayout; + QString m_configFile; }; #endif // multiple inclusion guard diff --git a/kpart/plasmakpartcorona.cpp b/kpart/plasmakpartcorona.cpp index 1fea9211c..6bcece1cd 100644 --- a/kpart/plasmakpartcorona.cpp +++ b/kpart/plasmakpartcorona.cpp @@ -33,11 +33,6 @@ PlasmaKPartCorona::PlasmaKPartCorona(QObject *parent) : Plasma::Corona(parent) -{ - init(); -} - -void PlasmaKPartCorona::init() { enableAction("Lock Widgets", false); enableAction("Shortcut Settings", false); @@ -47,7 +42,6 @@ void PlasmaKPartCorona::init() void PlasmaKPartCorona::loadDefaultLayout() { // used to force a save into the config file - KConfigGroup invalidConfig; Plasma::Containment *c = addContainment(QString()); if (!c) { @@ -77,7 +71,7 @@ void PlasmaKPartCorona::evaluateScripts(const QStringList &scripts) void PlasmaKPartCorona::printScriptError(const QString &error) { - kWarning() << "Startup script errror:" << error; + kWarning() << "Startup script error:" << error; } void PlasmaKPartCorona::printScriptMessage(const QString &error) @@ -85,15 +79,4 @@ void PlasmaKPartCorona::printScriptMessage(const QString &error) kDebug() << "Startup script: " << error; } -Plasma::Containment* PlasmaKPartCorona::containment() -{ - // We only have one containment, so just try and return the first one - QList list = containments(); - if (!list.isEmpty()) { - return list.first(); - } - - return 0; -} - #include "plasmakpartcorona.moc" diff --git a/kpart/plasmakpartcorona.h b/kpart/plasmakpartcorona.h index 3df552502..6137b8c8b 100644 --- a/kpart/plasmakpartcorona.h +++ b/kpart/plasmakpartcorona.h @@ -38,13 +38,9 @@ Q_OBJECT public: PlasmaKPartCorona(QObject* parent); - Plasma::Containment *containment(); - +protected: void loadDefaultLayout(); - -private: void evaluateScripts(const QStringList &scripts); - void init(); private Q_SLOTS: void printScriptError(const QString &error); diff --git a/remotewidgetshelper/kcm_remotewidgets.actions b/remotewidgetshelper/kcm_remotewidgets.actions index 70c564c9d..e8ba43ee5 100644 --- a/remotewidgetshelper/kcm_remotewidgets.actions +++ b/remotewidgetshelper/kcm_remotewidgets.actions @@ -1,4 +1,116 @@ [org.kde.kcontrol.kcmremotewidgets.save] Name=Save remote widgets' policies +Name[ar]=احفظ سياسات الودجات البعيدة +Name[ast]=Guardáu de polítiques d'elementos gráficos remotos +Name[bg]=Запазване на правилата на отдалечените джаджи +Name[bs]=Sačuvaj smjernice za udaljene grafičke kontrole +Name[ca]=Desa les polítiques d'estris remots +Name[ca@valencia]=Alça les polítiques d'estris remots +Name[cs]=Uložit zásady vzdálených widgetů +Name[da]=Gem politikker for eksterne widgets +Name[de]=Regelungen für entfernte Miniprogramme speichern +Name[el]=Αποθήκευση των πολιτικών απομακρυσμένων μικροεφαρμογών +Name[en_GB]=Save remote widgets' policies +Name[es]=Guardado de políticas de elementos gráficos remotos +Name[et]=Välisvidinate reeglite salvestamine +Name[eu]=Gorde urruneko trepeten politikak +Name[fi]=Tallenna etäkäyttöliittymäkomponenttien menettelytavat +Name[fr]=Enregistrer la politique des composants graphiques distants +Name[ga]=Sábháil polasaithe um giuirléidí cianda +Name[he]=שמירת מדיניות של ווידג׳טים מרוחקים +Name[hr]=Spremi pravila za udaljene widgete +Name[hu]=Távoli widgetek irányelveinek mentése +Name[ia]=Il salva le politicas del widgets remote +Name[id]=Simpan kebijakan widget jarak jauh +Name[is]=Vista stefnur varðandi fjartengdar græjur +Name[it]=Salva le linee guida degli oggetti remoti +Name[ja]=リモートウィジェットポリシーを保存 +Name[kk]=Қашықтағы виджеттер ережелерін сақтау +Name[km]=រក្សាទុក​គោលនយោបាយ​របស់​ធាតុក្រាហ្វិក​ពី​ចម្ងាយ +Name[ko]=원격 위젯의 정책 저장하기 +Name[lt]=Išsaugoti nutolusių valdiklių taisykles +Name[lv]=Saglabāt attālinātā sīkrīka politiku +Name[ml]=വിദൂര ഉരുപ്പടികള്‍ക്കുള്ള നയങ്ങള്‍ സൂക്ഷിയ്ക്കുക +Name[nb]=Lagre praksis for nettverkselementer +Name[nds]=Regeln för feern Lüttprogrammen sekern +Name[nl]=Beleidsregels voor widgets op afstand opslaan +Name[nn]=Lagra reglar for fjernelement +Name[pa]=ਰਿਮੋਟ ਵਿਦਜੈੱਟ ਦੀ ਪਾਲਸੀ ਸੰਭਾਲੋ +Name[pl]=Zapisz polityki zdalnych elementów interfejsu +Name[pt]=Gravar as políticas dos elementos remotos +Name[pt_BR]=Salvar políticas de widgets remotos +Name[ro]=Salvează politicile controalelor distante +Name[ru]=Сохранение правил удалённо доступных виджетов +Name[si]=දුරස්ථ විජට්ටුවල ප්‍රතිපත්ති සුරකින්න +Name[sk]=Uložiť politiky pre vzdialené widgety +Name[sl]=Shrani pravila za oddaljene gradnike +Name[sr]=Сачувај смернице за удаљене виџете +Name[sr@ijekavian]=Сачувај смјернице за удаљене виџете +Name[sr@ijekavianlatin]=Sačuvaj smjernice za udaljene vidžete +Name[sr@latin]=Sačuvaj smernice za udaljene vidžete +Name[sv]=Spara policy för grafiska fjärrkomponenter +Name[tg]=Танзимоти видҷетҳои дурдастро сабт кунед +Name[th]=บันทึกกฎของวิดเจ็ตระยะไกล +Name[tr]=Uzak programcık politikalarını kaydet +Name[ug]=يىراقتىكى ۋىجېتلارنى ساقلاش تەدبىرى +Name[uk]=Зберегти правила для віддалених віджетів +Name[x-test]=xxSave remote widgets' policiesxx +Name[zh_CN]=保存远程部件的策略 +Name[zh_TW]=儲存遠端元件政策 Description=Prevents the system from saving remote plasma widgets' policies +Description[ar]=يمنع النظام من حفظ سياسات ودجات بلازما البعيدة +Description[ast]=Impide que'l sistema guarde polítiques d'elementos gráficos Plasma remotos +Description[bg]=Забраняване запазването на правилата на отдалечените джаджи +Description[bs]=Sprečava sistem da sačuva smjernice udaljenih plazma grafičkih kontrola +Description[ca]=Evita al sistema de desar polítiques d'estris remots del plasma +Description[ca@valencia]=Evita al sistema d'alçar polítiques d'estris remots del plasma +Description[cs]=Zabrání systému ukládat zásady vzdálených widgetů plasmy +Description[da]=Forhindrer systemet i et gemme politikker for eksterne plasma-widgets +Description[de]=Hindert das System daran, Regelungen für entfernte Miniprogramme zu speichern. +Description[el]=Αποτρέπει το σύστημα από το να σώσει τις πολιτικές απομακρυσμένων μικροεφαρμογών plasma +Description[en_GB]=Prevents the system from saving remote plasma widgets' policies +Description[es]=Impide que el sistema guarde políticas de elementos gráficos Plasma remotos +Description[et]=Takistab süsteemil salvestamast Plasma välisvidinate reegleid +Description[eu]=Sistemak urruneko plasma trepeten politikak gorde ditzan galarazten du +Description[fi]=Estää järjestelmää tallentamasta etäplasmakäyttöliittymäkomponenttien menettelytapoja +Description[fr]=Empêche le système d'enregistrer la politique des composants graphiques distants +Description[ga]=Ná lig don chóras polasaithe um giuirléidí cianda plasma a shábháil +Description[he]=מונע מהמערכת מלשמור מדיניות של ווידג׳טים מרוחקים +Description[hr]=Brani sustavu spremanje pravila za udaljene widgete Plasme +Description[hu]=Megakadályozza a rendszert a távoli widgetek irányelveinek mentésében +Description[ia]=Il preveni le systema ab salvar le politicas del widgets (elementos graphic) remote de plasma +Description[id]=Mencegah sistem dari menyimpan kebijakan widget jarak jauh plasma +Description[is]=Kemur í veg fyrir að kerfið geti vistað stefnur varðandi fjartengdar græjur +Description[it]=Impedisce al sistema di salvare le linee guida degli oggetti remoti di Plasma +Description[ja]=システムがリモート Plasma ウィジェットポリシー保存するのを防ぎます +Description[kk]=Қашықтағы Plasma виджеттер ережелерін жүйеде сақтауын болдырмау +Description[km]=ការពារ​ប្រព័ន្ធ​មិន​ឲ្យ​រក្សាទុក​គោលនយោបាយ​របស់​ធាតុក្រាហ្វិក​ប្លាស្មា​ពី​ចម្ងាយ +Description[ko]=Plasma 원격 위젯 정책을 저장하지 못하도록 합니다 +Description[lt]=Neleidžia sistemai išsaugoti nutolusių plazmos valdiklių taisyklių +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 +Description[nn]=Hindrar systemet i å lagra reglar for fjernelement +Description[pa]=ਰਿਮੋਟ ਪਲਾਜ਼ਮਾ ਵਿਦਜੈੱਟ ਦੀਆਂ ਨੀਤੀਆਂ ਸੰਭਾਲਣ ਤੋਂ ਸਿਸਟਮ ਨੂੰ ਰੋਕਦਾ ਹੈ +Description[pl]=Wyłącza zapisywanie polityk zdalnych elementów interfejsu +Description[pt]=Impede o sistema de gravar as políticas dos elementos remotos do Plasma +Description[pt_BR]=Previne o sistema de salvar as políticas de widgets Plasma remotos +Description[ro]=Impiedică sistemul să salveze politicile controalelor distante +Description[ru]=Сохранение правил доступа к удалённо доступным виджетам +Description[si]=දුරස්ථ ප්ලැස්මා විජට්ටු ප්‍රතිපත්ති සුරැකීමෙන් පද්ධතිය වළක්වයි +Description[sk]=Zabraňuje systému ukladať politiky pre vzdialené widgety +Description[sl]=Sistemu prepreči shranjevanje pravil za oddaljene gradnike +Description[sr]=Спречава систем да сачува смернице удаљених плазма виџета +Description[sr@ijekavian]=Спречава систем да сачува смјернице удаљених плазма виџета +Description[sr@ijekavianlatin]=Sprečava sistem da sačuva smjernice udaljenih plasma vidžeta +Description[sr@latin]=Sprečava sistem da sačuva smernice udaljenih plasma vidžeta +Description[sv]=Förhindrar systemet från att spara policy för Plasma grafiska fjärrkomponenter +Description[tg]=Системаро аз сабткунии танзимоти видҷетҳои plasma-и дурдаст пешгирӣ мекунад +Description[th]=ป้องกันระบบจากการบันทึกกฎของวิดเจ็ตของพลาสมาจากทางไกล +Description[tr]=Sistemin uzak plasma programcık politikalarını kaydetmesini engelle +Description[ug]=سىستېما يىراقتىكى پلازما ۋىجېتلىرىنىڭ تەدبىرىنى ساقلاشنى چەكلەيدۇ +Description[uk]=Заборонити системі зберігати правила для віддалених віджетів Плазми +Description[x-test]=xxPrevents the system from saving remote plasma widgets' policiesxx +Description[zh_CN]=禁止系统保存远程 Plasma 部件的策略 +Description[zh_TW]=避免系統儲存遠端 plasma 元件政策 Policy=auth_admin diff --git a/scriptengines/javascript/CMakeLists.txt b/scriptengines/javascript/CMakeLists.txt index 27606724d..8b62d6816 100644 --- a/scriptengines/javascript/CMakeLists.txt +++ b/scriptengines/javascript/CMakeLists.txt @@ -8,8 +8,10 @@ if(KDE_PLATFORM_FEATURE_BINARY_COMPATIBLE_FEATURE_REDUCTION) endif(KDE_PLATFORM_FEATURE_BINARY_COMPATIBLE_FEATURE_REDUCTION) set(simple_javascript_engine_SRCS + common/extension_launchapp.cpp + common/extension_io.cpp + common/guiscriptenv.cpp common/javascriptaddonpackagestructure.cpp - common/jsscriptenv.cpp plasmoid/abstractjsappletscript.cpp plasmoid/appletauthorization.cpp plasmoid/jsappletinterface.cpp @@ -62,6 +64,8 @@ install(FILES data/plasma-scriptengine-applet-simple-javascript.desktop DESTINAT # RUNNER set(javascript_runner_engine_SRCS + common/extension_launchapp.cpp + common/extension_io.cpp common/javascriptaddonpackagestructure.cpp common/scriptenv.cpp runner/javascriptrunner.cpp @@ -83,6 +87,8 @@ install(FILES data/plasma-scriptengine-runner-javascript.desktop DESTINATION ${S # DATAENGINE set(javascript_dataengine_engine_SRCS + common/extension_launchapp.cpp + common/extension_io.cpp common/javascriptaddonpackagestructure.cpp common/scriptenv.cpp dataengine/javascriptdataengine.cpp @@ -119,6 +125,8 @@ install(FILES data/plasma-javascriptaddon.desktop DESTINATION ${SERVICETYPES_INS #DECLARATIVE APPLET set(declarative_appletscript_SRCS + common/extension_launchapp.cpp + common/extension_io.cpp common/javascriptaddonpackagestructure.cpp common/declarativescriptenv.cpp declarative/packageaccessmanager.cpp @@ -127,17 +135,13 @@ set(declarative_appletscript_SRCS plasmoid/appletauthorization.cpp plasmoid/appletinterface.cpp plasmoid/declarativeappletscript.cpp - plasmoid/engineaccess.cpp plasmoid/themedsvg.cpp simplebindings/bytearrayclass.cpp simplebindings/bytearrayprototype.cpp simplebindings/dataengine.cpp simplebindings/dataenginereceiver.cpp simplebindings/filedialogproxy.cpp - simplebindings/i18n.cpp - simplebindings/icon.cpp simplebindings/qscriptbookkeeping.cpp - simplebindings/url.cpp ) include_directories(${PHONON_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR}/common) diff --git a/scriptengines/javascript/common/extension_io.cpp b/scriptengines/javascript/common/extension_io.cpp new file mode 100644 index 000000000..c25688153 --- /dev/null +++ b/scriptengines/javascript/common/extension_io.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2011 Aaron Seigo + * + * 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 "scriptenv.h" + +#include + +#include +#include +#include +#include + +QScriptValue ScriptEnv::openUrl(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine) + if (context->argumentCount() == 0) { + return false; + } + + QScriptValue v = context->argument(0); + KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast(v); + + if (!url.isValid()) { + return false; + } + + ScriptEnv *env = ScriptEnv::findScriptEnv(engine); + if (!env) { + return false; + } + + if (!(env->m_allowedUrls & AppLaunching) && + !((env->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) { + return false; + } + + new KRun(url, 0); + return true; +} + +// TODO these should throw an exception +QScriptValue ScriptEnv::getUrl(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(); + } + + ScriptEnv *env = ScriptEnv::findScriptEnv(engine); + if (!env) { + //kDebug() << "findScriptEnv failed"; + return engine->undefinedValue(); + } + + if (url.isLocalFile()) { + if (!(env->m_allowedUrls & LocalUrls)) { + return engine->undefinedValue(); + } + } else if (!(env->m_allowedUrls & NetworkUrls) && + !((env->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) { + return engine->undefinedValue(); + } + + KIO::Job *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo); + return engine->newQObject(job); +} + +QScriptValue ScriptEnv::userDataPath(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine) + if (context->argumentCount() == 0) { + return QDir::homePath(); + } + + const QString type = context->argument(0).toString(); + if (type.isEmpty()) { + return QDir::homePath(); + } + + if (context->argumentCount() > 1) { + const QString filename = context->argument(1).toString(); + return KStandardDirs::locateLocal(type.toLatin1(), filename); + } + + if (type.compare("desktop", Qt::CaseInsensitive) == 0) { + return KGlobalSettings::desktopPath(); + } else if (type.compare("autostart", Qt::CaseInsensitive) == 0) { + return KGlobalSettings::autostartPath(); + } else if (type.compare("documents", Qt::CaseInsensitive) == 0) { + return KGlobalSettings::documentPath(); + } else if (type.compare("music", Qt::CaseInsensitive) == 0) { + return KGlobalSettings::musicPath(); + } else if (type.compare("video", Qt::CaseInsensitive) == 0) { + return KGlobalSettings::videosPath(); + } else if (type.compare("downloads", Qt::CaseInsensitive) == 0) { + return KGlobalSettings::downloadPath(); + } else if (type.compare("pictures", Qt::CaseInsensitive) == 0) { + return KGlobalSettings::picturesPath(); + } + + return QString(); +} + +void ScriptEnv::registerGetUrl(QScriptValue &obj) +{ + QScriptValue get = obj.property("getUrl"); + if (!get.isValid()) { + obj.setProperty("getUrl", m_engine->newFunction(ScriptEnv::getUrl)); + } +} + +void ScriptEnv::registerOpenUrl(QScriptValue &obj) +{ + QScriptValue value = obj.property("openUrl"); + if (!value.isValid()) { + obj.setProperty("openUrl", m_engine->newFunction(ScriptEnv::openUrl)); + } +} + + diff --git a/scriptengines/javascript/common/extension_launchapp.cpp b/scriptengines/javascript/common/extension_launchapp.cpp new file mode 100644 index 000000000..93b7c29ca --- /dev/null +++ b/scriptengines/javascript/common/extension_launchapp.cpp @@ -0,0 +1,253 @@ +/* + * Copyright 2011 Aaron Seigo + * + * 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 "scriptenv.h" + +#include +#include +#include +#include +#include +#include + +QScriptValue ScriptEnv::runApplication(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine) + if (context->argumentCount() == 0) { + return false; + } + + KUrl::List urls; + if (context->argumentCount() > 1) { + urls = qscriptvalue_cast(context->argument(1)); + } + + const QString app = context->argument(0).toString(); + + const QString exec = KGlobal::dirs()->findExe(app); + if (!exec.isEmpty()) { + return KRun::run(exec, urls, 0); + } + + KService::Ptr service = KService::serviceByStorageId(app); + if (service) { + return KRun::run(*service, urls, 0); + } + + return false; +} + +QScriptValue ScriptEnv::runCommand(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine); + + if (context->argumentCount() == 0) { + return false; + } + + const QString exec = KGlobal::dirs()->findExe(context->argument(0).toString()); + if (!exec.isEmpty()) { + QString args; + if (context->argumentCount() > 1) { + const QStringList argList = qscriptvalue_cast(context->argument(1)); + if (!argList.isEmpty()) { + args = ' ' + KShell::joinArgs(argList); + } + } + + return KRun::runCommand(exec + args, 0); + } + + return false; +} + +QScriptValue ScriptEnv::applicationExists(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine) + if (context->argumentCount() == 0) { + return false; + } + + const QString application = context->argument(0).toString(); + if (application.isEmpty()) { + return false; + } + + // first, check for it in $PATH + if (!KStandardDirs::findExe(application).isEmpty()) { + return true; + } + + if (KService::serviceByStorageId(application)) { + return true; + } + + if (application.contains("'")) { + // apostrophes just screw up the trader lookups below, so check for it + return false; + } + + // next, consult ksycoca for an app by that name + if (!KServiceTypeTrader::self()->query("Application", QString("Name =~ '%1'").arg(application)).isEmpty()) { + return true; + } + + // next, consult ksycoca for an app by that generic name + if (!KServiceTypeTrader::self()->query("Application", QString("GenericName =~ '%1'").arg(application)).isEmpty()) { + return true; + } + + return false; +} + +QScriptValue ScriptEnv::defaultApplication(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine) + if (context->argumentCount() == 0) { + return false; + } + + const QString application = context->argument(0).toString(); + if (application.isEmpty()) { + return false; + } + + const bool storageId = context->argumentCount() < 2 ? false : context->argument(1).toBool(); + + // FIXME: there are some pretty horrible hacks below, in the sense that they assume a very + // specific implementation system. there is much room for improvement here. see + // kdebase-runtime/kcontrol/componentchooser/ for all the gory details ;) + if (application.compare("mailer", Qt::CaseInsensitive) == 0) { + KEMailSettings settings; + + // in KToolInvocation, the default is kmail; but let's be friendlier :) + QString command = settings.getSetting(KEMailSettings::ClientProgram); + if (command.isEmpty()) { + if (KService::Ptr kontact = KService::serviceByStorageId("kontact")) { + return storageId ? kontact->storageId() : kontact->exec(); + } else if (KService::Ptr kmail = KService::serviceByStorageId("kmail")) { + return storageId ? kmail->storageId() : kmail->exec(); + } + } + + if (!command.isEmpty()) { + if (settings.getSetting(KEMailSettings::ClientTerminal) == "true") { + KConfigGroup confGroup(KGlobal::config(), "General"); + const QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", + QString::fromLatin1("konsole")); + command = preferredTerminal + QString::fromLatin1(" -e ") + command; + } + + return command; + } + } else if (application.compare("browser", Qt::CaseInsensitive) == 0) { + KConfigGroup config(KGlobal::config(), "General"); + QString browserApp = config.readPathEntry("BrowserApplication", QString()); + if (browserApp.isEmpty()) { + const KService::Ptr htmlApp = KMimeTypeTrader::self()->preferredService(QLatin1String("text/html")); + if (htmlApp) { + browserApp = storageId ? htmlApp->storageId() : htmlApp->exec(); + } + } else if (browserApp.startsWith('!')) { + browserApp = browserApp.mid(1); + } + + return browserApp; + } else if (application.compare("terminal", Qt::CaseInsensitive) == 0) { + KConfigGroup confGroup(KGlobal::config(), "General"); + return confGroup.readPathEntry("TerminalApplication", QString::fromLatin1("konsole")); + } else if (application.compare("filemanager", Qt::CaseInsensitive) == 0) { + KService::Ptr service = KMimeTypeTrader::self()->preferredService("inode/directory"); + if (service) { + return storageId ? service->storageId() : service->exec(); + } + } else if (application.compare("windowmanager", Qt::CaseInsensitive) == 0) { + KConfig cfg("ksmserverrc", KConfig::NoGlobals); + KConfigGroup confGroup(&cfg, "General"); + return confGroup.readEntry("windowManager", QString::fromLatin1("konsole")); + } else if (KService::Ptr service = KMimeTypeTrader::self()->preferredService(application)) { + return storageId ? service->storageId() : service->exec(); + } else { + // try the files in share/apps/kcm_componentchooser/ + const QStringList services = KGlobal::dirs()->findAllResources("data","kcm_componentchooser/*.desktop", KStandardDirs::NoDuplicates); + //kDebug() << "ok, trying in" << services.count(); + foreach (const QString &service, services) { + KConfig config(service, KConfig::SimpleConfig); + KConfigGroup cg = config.group(QByteArray()); + const QString type = cg.readEntry("valueName", QString()); + //kDebug() << " checking" << service << type << application; + if (type.compare(application, Qt::CaseInsensitive) == 0) { + KConfig store(cg.readPathEntry("storeInFile", "null")); + KConfigGroup storeCg(&store, cg.readEntry("valueSection", QString())); + const QString exec = storeCg.readPathEntry(cg.readEntry("valueName", "kcm_componenchooser_null"), + cg.readEntry("defaultImplementation", QString())); + if (!exec.isEmpty()) { + return exec; + } + + break; + } + } + } + + return false; +} + +QScriptValue ScriptEnv::applicationPath(QScriptContext *context, QScriptEngine *engine) +{ + Q_UNUSED(engine) + if (context->argumentCount() == 0) { + return false; + } + + const QString application = context->argument(0).toString(); + if (application.isEmpty()) { + return false; + } + + // first, check for it in $PATH + const QString path = KStandardDirs::findExe(application); + if (!path.isEmpty()) { + return path; + } + + if (KService::Ptr service = KService::serviceByStorageId(application)) { + return KStandardDirs::locate("apps", service->entryPath()); + } + + if (application.contains("'")) { + // apostrophes just screw up the trader lookups below, so check for it + return QString(); + } + + // next, consult ksycoca for an app by that name + KService::List offers = KServiceTypeTrader::self()->query("Application", QString("Name =~ '%1'").arg(application)); + if (offers.isEmpty()) { + // next, consult ksycoca for an app by that generic name + offers = KServiceTypeTrader::self()->query("Application", QString("GenericName =~ '%1'").arg(application)); + } + + if (!offers.isEmpty()) { + KService::Ptr offer = offers.first(); + return KStandardDirs::locate("apps", offer->entryPath()); + } + + return QString(); +} + diff --git a/scriptengines/javascript/common/jsscriptenv.cpp b/scriptengines/javascript/common/guiscriptenv.cpp similarity index 100% rename from scriptengines/javascript/common/jsscriptenv.cpp rename to scriptengines/javascript/common/guiscriptenv.cpp diff --git a/scriptengines/javascript/common/scriptenv.cpp b/scriptengines/javascript/common/scriptenv.cpp index 515ca2697..d90ce301d 100644 --- a/scriptengines/javascript/common/scriptenv.cpp +++ b/scriptengines/javascript/common/scriptenv.cpp @@ -153,114 +153,6 @@ bool ScriptEnv::checkForErrors(bool fatal) return false; } -QScriptValue ScriptEnv::runApplication(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(engine) - if (context->argumentCount() == 0) { - return false; - } - - KUrl::List urls; - if (context->argumentCount() > 1) { - urls = qscriptvalue_cast(context->argument(1)); - } - - const QString app = context->argument(0).toString(); - - const QString exec = KGlobal::dirs()->findExe(app); - if (!exec.isEmpty()) { - return KRun::run(exec, urls, 0); - } - - KService::Ptr service = KService::serviceByStorageId(app); - if (service) { - return KRun::run(*service, urls, 0); - } - - return false; -} - -QScriptValue ScriptEnv::runCommand(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(engine); - - if (context->argumentCount() == 0) { - return false; - } - - const QString exec = KGlobal::dirs()->findExe(context->argument(0).toString()); - if (!exec.isEmpty()) { - QString args; - if (context->argumentCount() > 1) { - const QStringList argList = qscriptvalue_cast(context->argument(1)); - if (!argList.isEmpty()) { - args = ' ' + KShell::joinArgs(argList); - } - } - - return KRun::runCommand(exec + args, 0); - } - - return false; -} - -QScriptValue ScriptEnv::openUrl(QScriptContext *context, QScriptEngine *engine) -{ - Q_UNUSED(engine) - if (context->argumentCount() == 0) { - return false; - } - - QScriptValue v = context->argument(0); - KUrl url = v.isString() ? KUrl(v.toString()) : qscriptvalue_cast(v); - if (url.isValid()) { - new KRun(url, 0); - } - - return false; -} - -// TODO these should throw an exception -QScriptValue ScriptEnv::getUrl(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(); - } - - ScriptEnv *env = ScriptEnv::findScriptEnv(engine); - if (!env) { - //kDebug() << "findScriptEnv failed"; - return engine->undefinedValue(); - } - - if (url.isLocalFile()) { - if (!(env->m_allowedUrls & LocalUrls)) { - return engine->undefinedValue(); - } - } else if (!(env->m_allowedUrls & NetworkUrls) && - !((env->m_allowedUrls & HttpUrls) && (url.protocol() == "http" || url.protocol() == "https"))) { - return engine->undefinedValue(); - } - - KIO::Job *job = KIO::get(url, KIO::NoReload, KIO::HideProgressInfo); - return engine->newQObject(job); -} - -void ScriptEnv::registerGetUrl(QScriptValue &obj) -{ - QScriptValue get = obj.property("getUrl"); - if (!get.isValid()) { - obj.setProperty("getUrl", m_engine->newFunction(ScriptEnv::getUrl)); - } -} - bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &obj) { kDebug() << extension; @@ -270,13 +162,15 @@ bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &o return true; #endif } else if ("launchapp" == extension) { + m_allowedUrls |= AppLaunching; obj.setProperty("runApplication", m_engine->newFunction(ScriptEnv::runApplication)); obj.setProperty("runCommand", m_engine->newFunction(ScriptEnv::runCommand)); - obj.setProperty("openUrl", m_engine->newFunction(ScriptEnv::openUrl)); + registerOpenUrl(obj); return true; } else if ("http" == extension) { m_allowedUrls |= HttpUrls; registerGetUrl(obj); + registerOpenUrl(obj); return true; } else if ("networkio" == extension) { m_allowedUrls |= HttpUrls | NetworkUrls; @@ -285,6 +179,8 @@ bool ScriptEnv::importBuiltinExtension(const QString &extension, QScriptValue &o } else if ("localio" == extension) { m_allowedUrls |= LocalUrls; registerGetUrl(obj); + obj.setProperty("userDataPath", m_engine->newFunction(ScriptEnv::userDataPath)); + obj.setProperty("runCommand", m_engine->newFunction(ScriptEnv::runCommand)); return true; } diff --git a/scriptengines/javascript/common/scriptenv.h b/scriptengines/javascript/common/scriptenv.h index ac7c8ec1c..4ec7202d8 100644 --- a/scriptengines/javascript/common/scriptenv.h +++ b/scriptengines/javascript/common/scriptenv.h @@ -34,7 +34,8 @@ public: enum AllowedUrl { NoUrls = 0, HttpUrls = 1, NetworkUrls = 2, - LocalUrls = 4 }; + LocalUrls = 4, + AppLaunching = 8}; Q_DECLARE_FLAGS(AllowedUrls, AllowedUrl) ScriptEnv(QObject *parent, QScriptEngine *engine); @@ -74,14 +75,19 @@ Q_SIGNALS: private: void registerGetUrl(QScriptValue &obj); + void registerOpenUrl(QScriptValue &obj); bool importBuiltinExtension(const QString &extension, QScriptValue &obj); static QScriptValue debug(QScriptContext *context, QScriptEngine *engine); static QScriptValue print(QScriptContext *context, QScriptEngine *engine); static QScriptValue runApplication(QScriptContext *context, QScriptEngine *engine); static QScriptValue runCommand(QScriptContext *context, QScriptEngine *engine); + static QScriptValue defaultApplication(QScriptContext *context, QScriptEngine *engine); + static QScriptValue applicationPath(QScriptContext *context, QScriptEngine *engine); + static QScriptValue applicationExists(QScriptContext *context, QScriptEngine *engine); static QScriptValue openUrl(QScriptContext *context, QScriptEngine *engine); static QScriptValue getUrl(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); static QScriptValue registerAddon(QScriptContext *context, QScriptEngine *engine); diff --git a/scriptengines/javascript/data/plasma-javascriptaddon.desktop b/scriptengines/javascript/data/plasma-javascriptaddon.desktop index e1ea6f7a0..1743ab726 100644 --- a/scriptengines/javascript/data/plasma-javascriptaddon.desktop +++ b/scriptengines/javascript/data/plasma-javascriptaddon.desktop @@ -1,5 +1,60 @@ [Desktop Entry] Name=Plasma JavaScript Addon +Name[ast]=Complementu de JavaScript pa Plasma +Name[bg]=Добавка за JavaScript на Plasma +Name[bs]=Plazma javaskriptni dodatak +Name[ca]=Complement del JavaScript pel Plasma +Name[ca@valencia]=Complement del JavaScript pel Plasma +Name[cs]=Doplněk Plasmy JavaScript +Name[da]=Plasma JavaScript-tilføjelse +Name[de]=JavaScript-Erweiterung für Plasma +Name[el]=Πρόσθετο Plasma JavaScript +Name[en_GB]=Plasma JavaScript Addon +Name[es]=Complemento de JavaScript para Plasma +Name[et]=Plasma JavaScripti lisa +Name[eu]=Plasma JavaScript gehigarria +Name[fi]=Plasma JavaScript -lisäosa +Name[fr]=Module complémentaire Javascript de Plasma +Name[he]=תוסף עבור JavaScript של Plasma +Name[hi]=प्लाज़मा जावा-स्क्रिप्ट एडोन +Name[hr]=Dodatak JavaScripta Plasmi +Name[hu]=Plazma JavaScript-bővítmény +Name[ia]=Plasma JavaScript Addon +Name[is]=Plasma JavaScript viðbót +Name[it]=Aggiunta per Java e JavaScript +Name[ja]=Plasma JavaScript アドオン +Name[kk]=Plasma JavaScript қосымшасы +Name[km]=ផ្នែក​បន្ថែម​ Plasma JavaScript +Name[kn]=ಪ್ಲಾಸ್ಮಾ ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಆಡ್‌ಆನ್ +Name[ko]=Plasma 자바스크립트 추가 기능 +Name[lt]=Plasma JavaScript priedas +Name[nb]=Plasma JavaScript-tillegg +Name[nds]=JavaScript-Verwiedern för Plasma +Name[nl]=Addon voor Plasma JavaScript +Name[nn]=Plasma–JavaScript-tillegg +Name[pa]=ਪਲਾਜ਼ਮਾ ਜਾਵਾ ਸਕ੍ਰਿਪਟ ਐਡਆਨ +Name[pl]=Dodatek dla JavaScript +Name[pt]=Extensão de JavaScript do Plasma +Name[pt_BR]=Complementos de JavaScript do Plasma +Name[ro]=Supliment JavaScript Plasma +Name[ru]=Расширение Plasma, использующее JavaScript +Name[si]=ප්ලාස්මා හා ජාවාස්ක්‍රිප්ට ඇඩොන +Name[sk]=Doplnok JavaScript pre plasmu +Name[sl]=Dodatek za JavaScript za Plasmo +Name[sr]=Плазма јаваскриптни додатак +Name[sr@ijekavian]=Плазма јаваскриптни додатак +Name[sr@ijekavianlatin]=Plasma JavaScript dodatak +Name[sr@latin]=Plasma JavaScript dodatak +Name[sv]=Plasma Javaskript-tillägg +Name[tg]=Барномаи иловагии Plasma JavaScript +Name[th]=ส่วนเสริมจาวาและจาวาสคริปต์สำหรับพลาสมาส่วนเสริมจาวาและจาวาสคริปต์สำหรับ +Name[tr]=Plasma JavaScript Eklentisi +Name[ug]=Plasma JavaScript قوشۇلما +Name[uk]=Додаток JavaScript до Плазми +Name[wa]=Pacaedje di rawete Plasma JavaScript +Name[x-test]=xxPlasma JavaScript Addonxx +Name[zh_CN]=Plasma JavaScript 附加插件 +Name[zh_TW]=Plasma JavaScript Addon Type=ServiceType X-KDE-ServiceType=Plasma/JavascriptAddon Icon=plasma diff --git a/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop b/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop index 05489fe53..e96fc6552 100644 --- a/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop +++ b/scriptengines/javascript/data/plasma-packagestructure-javascript-addon.desktop @@ -1,6 +1,114 @@ [Desktop Entry] Name=Javascript Addon +Name[ast]=Complementu de JavaScript +Name[bg]=Добавка за Javascript +Name[bs]=Javaskriptni dodatak +Name[ca]=Complement del Javascript +Name[ca@valencia]=Complement del Javascript +Name[cs]=Doplněk JavaScript +Name[da]=JavaScript-tilføjelse +Name[de]=JavaScript-Erweiterung +Name[el]=Πρόσθετο Javascript +Name[en_GB]=Javascript Addon +Name[es]=Complemento de JavaScript +Name[et]=JavaScripti lisa +Name[eu]=Javascript gehigarria +Name[fi]=Javascript-lisäosa +Name[fr]=Module complémentaire Javascript +Name[he]=תוסף JavaScript +Name[hi]=जावास्क्रिप्ट एडोन +Name[hr]=Dodadak za Javascript +Name[hu]=Javascript-bővítmény +Name[ia]=JavaScript Addon +Name[is]=JavaScript viðbót +Name[it]=Aggiunta per JavaScript +Name[ja]=JavaScript アドオン +Name[kk]=Javascript қосымшасы +Name[km]=ផ្នែក​បន្ថែម Javascript +Name[kn]=ಜಾವಾಸ್ಕ್ರಿಪ್ಟ್ ಆಡ್‌ಆನ್ +Name[ko]=자바스크립트 추가 기능 +Name[lt]=Javascript priedas +Name[nb]=JavaScript-tillegg +Name[nds]=JavaScript-Verwiedern +Name[nl]=Addon voor JavaScript +Name[nn]=JavaScript-tillegg +Name[pa]=ਜਾਵਾ ਸਕ੍ਰਿਪਟ ਐਡ-ਆਨ +Name[pl]=Dodatek dla JavaScript +Name[pt]=Extensão de JavaScript +Name[pt_BR]=Complementos de JavaScript +Name[ro]=Supliment Javascript +Name[ru]=Дополнение, использующее JavaScript +Name[si]=ජාවාස්ක්‍රිප්ට ඇඩෝන +Name[sk]=Doplnok JavaScript +Name[sl]=Dodatek za JavaScript +Name[sr]=Јаваскриптни додатак +Name[sr@ijekavian]=Јаваскриптни додатак +Name[sr@ijekavianlatin]=JavaScript dodatak +Name[sr@latin]=JavaScript dodatak +Name[sv]=Javaskript-tillägg +Name[tg]=Барномаи иловагии Javascript +Name[th]=ส่วนเสริมจาวาสคริปต์ +Name[tr]=Javascript Eklentisi +Name[ug]=Javascript قوشۇلما +Name[uk]=Додаток JavaScript +Name[wa]=Pacaedje di rawete Javascript +Name[x-test]=xxJavascript Addonxx +Name[zh_CN]=Javascript 插件 +Name[zh_TW]=Javascript Addon Comment=Addons for Javascript Plasma plugins +Comment[ast]=Amestaos pa complementos de JavaScript pa Plasma +Comment[bg]=Добавки за приставките за Javascript на Plasma +Comment[bs]=Dodaci za javaskriptne plazma priključke +Comment[ca]=Complements pels connectors Javascript del Plasma +Comment[ca@valencia]=Complements pels connectors Javascript del Plasma +Comment[cs]=Doplňky pro javascriptové zásuvné moduly plasmy +Comment[da]=Tilføjelse til Plasma-plugins i JavaScript +Comment[de]=Erweiterungen für JavaScript-Module in Plasma +Comment[el]=Πρόσθετο για Plasma JavaScript +Comment[en_GB]=Addons for Javascript Plasma plugins +Comment[es]=Añadidos para complementos de JavaScript para Plasma +Comment[et]=JavaScripti Plasma pluginate lisad +Comment[eu]=Javascript Plasma pluginentzako gehigarriak +Comment[fi]=Lisäosia JavaScript Plasma -liitännäisille +Comment[fr]=Module complémentaire pour les modules externes en Javascript de Plasma +Comment[he]=תוספים לתוספי JavaScript של Plasma +Comment[hr]=Dodaci za priključke za Javascript Plasma +Comment[hu]=Bővítmények JavaScript Plazma-modulokhoz +Comment[ia]=Addons (elementos adjuncte) pro plugins de Plasma de javascript +Comment[is]=Viðbætur fyrir Plasma JavaScript íforrit +Comment[it]=Aggiunte per le estensioni JavaScript di Plasma +Comment[ja]=JavaScript Plasma プラグイン用のアドオン +Comment[kk]=Javascript Plasma плагиніне қосымшасы +Comment[km]=កម្មវិធី​បន្ថែម​សម្រាប់​កម្មវិធី​ជំនួយ Javascript Plasma +Comment[ko]=자바스크립트 Plasma 플러그인을 위한 추가 기능 +Comment[lt]=Javascript Plasma papildinio priedai +Comment[nb]=Tillegg for JavaSript Plasma-programtillegg +Comment[nds]=Verwiedern för Plasma sien JavaScript-Modulen +Comment[nl]=Addons voor Javascript Plasma plugins +Comment[nn]=Tillegg for JavaScript–Plasma-programtillegg +Comment[pa]=ਜਾਵਾਸਕ੍ਰਿਪਟ ਪਲਾਜ਼ਮਾ ਪਲੱਗਇਨ ਲਈ ਐਡਐਨ +Comment[pl]=Dodatki dla wtyczek Plazmy w JavaScript +Comment[pt]=Extras para os 'plugins' do Plasma em JavaScript +Comment[pt_BR]=Complementos para os plug-ins do Plasma em JavaScript +Comment[ro]=Suplimente pentru module JavaScript Plasma +Comment[ru]=Модули поддержки дополнений Plasma, использующих JavaScript +Comment[si]=ජාවාස්ක්‍රිප්ට ප්ලාස්මා ප්ලගින සඳහා ඇඩෝන +Comment[sk]=Doplnky pre Javascriptové moduly plasmy +Comment[sl]=Dodatki za vstavke JavaScript za Plasmo +Comment[sr]=Додаци за јаваскриптне плазма прикључке +Comment[sr@ijekavian]=Додаци за јаваскриптне плазма прикључке +Comment[sr@ijekavianlatin]=Dodaci za JavaScript plasma priključke +Comment[sr@latin]=Dodaci za JavaScript plasma priključke +Comment[sv]=Tillägg för Javascript Plasma-insticksprogram +Comment[tg]=Барномаҳои иловагӣ барои плагинҳои Javascript Plasma +Comment[th]=ส่วนขยายสำหรับส่วนเสริมพลาสมาที่เป็นจาวาสคริปต์ +Comment[tr]=Javascript Plasma eklentileri için ek araçlar +Comment[ug]=Javascript Plasma قىستۇرمىسى ئۈچۈن قوشۇلما +Comment[uk]=Додатки для використання Javascript у Плазмі +Comment[wa]=Pacaedjes di rawete po les tchôkes-divins Plasma Javascript +Comment[x-test]=xxAddons for Javascript Plasma pluginsxx +Comment[zh_CN]=Javascript Plasma 插件的附件组件 +Comment[zh_TW]=Javascript Plasma 外掛程式的 Addon Type=Service X-KDE-ServiceTypes=Plasma/PackageStructure diff --git a/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop b/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop index 276b40c84..4a565bd84 100644 --- a/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop +++ b/scriptengines/javascript/data/plasma-scriptengine-applet-declarative.desktop @@ -1,6 +1,108 @@ [Desktop Entry] Name=Declarative widget +Name[ast]=Elementu gráficu declarativu +Name[bg]=Декларативна джаджа +Name[bs]=Deklarativna grafička kontrola +Name[ca]=Estri declaratiu +Name[ca@valencia]=Estri declaratiu +Name[cs]=Deklarativní widget +Name[da]=Erklærende widget +Name[de]=Deklaratives Bedienelement +Name[el]=Δηλωτικό συστατικό +Name[en_GB]=Declarative widget +Name[es]=Elemento gráfico declarativo +Name[et]=Deklaratiivne vidin +Name[eu]=Trepeta ezagutarazlea +Name[fr]=Composant graphique « Declarative » +Name[he]=ווידג׳ט מוצהר +Name[hr]=Deklarativni widget +Name[hu]=Deklaratív widget +Name[ia]=Widget declarative +Name[is]=Skilgreiningagræja +Name[it]=Oggetto dichiarativo +Name[kk]=Мәлімдеме виджеті +Name[km]=ធាតុ​ក្រាហ្វិក​ដែល​ប្រកាស +Name[ko]=Declarative 위젯 +Name[lt]=Deklaratyvus valdiklis +Name[nb]=Deklarativt skjermelement +Name[nds]=Stüerelement för Verkloren +Name[nl]=Widget voor declaratie +Name[nn]=Deklarativt skjermelement +Name[pl]=Deklaratywny element interfejsu +Name[pt]=Item declarativo +Name[pt_BR]=Widget declarativo +Name[ro]=Control declarativ +Name[ru]=Декларативный виджет +Name[si]=ප්‍රකාශන විජෙට්ටටුව +Name[sk]=Deklaratívny widget +Name[sl]=Deklarativni gradnik +Name[sr]=Декларативни виџет +Name[sr@ijekavian]=Декларативни виџет +Name[sr@ijekavianlatin]=Deklarativni vidžet +Name[sr@latin]=Deklarativni vidžet +Name[sv]=Deklarativ grafisk komponent +Name[tg]=Видҷети эълонкунӣ +Name[tr]=Bildirim parçacığı +Name[ug]=ئېنىقلىما ۋىجېت +Name[uk]=Декларативний віджет +Name[wa]=Ahesse di gåyotaedje +Name[x-test]=xxDeclarative widgetxx +Name[zh_CN]=描述部件 +Name[zh_TW]=宣告元件 Comment=Native Plasma widget written in QML and JavaScript +Comment[ast]=Elementu gráficu nativu de Plasma escritu en QML y JavaScript +Comment[bg]=Оригинална джаджа за Plasma, написана наQML и JavaScript +Comment[bs]=Samosvojni plazma grafičkih kontrola napisana u QML‑u i javaskriptu +Comment[ca]=Estri nadiu del Plasma escrit en QML i JavaScript +Comment[ca@valencia]=Estri nadiu del Plasma escrit en QML i JavaScript +Comment[cs]=Nativní Plasma widget napsaný v QML a JavaScriptu +Comment[da]=Hjemmehørende Plasma-widget skrevet i QML og JavaScript +Comment[de]=Echtes Plasma-Programm, geschrieben in QML und JavaScript +Comment[el]=Εγγενές συστατικό Plasma γραμμένο σε QML και JavaScript +Comment[en_GB]=Native Plasma widget written in QML and JavaScript +Comment[es]=Elemento gráfico nativo de Plasma escrito en QML y JavaScript +Comment[et]=QML-is ja JavaScriptis kirjutatud Plasma vidin +Comment[eu]=Plasma jatorrizko trepeta QML eta JavaScript-en idatzia +Comment[fi]=Natiivi, QML-pohjainen Plasma-sovelma +Comment[fr]=Composant graphique natif de Plasma écrit en QML et JavaScript +Comment[he]=ווידג׳טים של Plasma הנכתבים ב־QML וב־JavaScript +Comment[hr]=Izvorni Plasma widget napisan u QML-u i JavaScriptu +Comment[hu]=QML-ben és JavaScriptben írt natív Plazma-widget +Comment[ia]=Widget native de Plasma scribite in QLM e JavaScript +Comment[is]=Upprunabundin Plasma græja skrifuð í QML og JavaScript +Comment[it]=Oggetto nativo di Plasma scritto in QML e JavaScript +Comment[ja]=QML と JavaScript で書かれた Plasma のネイティブウィジェット +Comment[kk]=QML мен JavaScript-те жазылған Plasma тума виджеті +Comment[km]=ធាតុ​ក្រាហ្វិក​ប្លា​ស្មា​ដើម ដែល​សរសេរ​ក្នុង JavaScript​ +Comment[kn]=QML ಹಾಗು ಜಾವಾ ಸ್ಕ್ರಿಪ್ಟ್ ನಲ್ಲಿ ಬರೆಯಲಾದ ಸ್ವಾಭಾವಿಕ ಪ್ಲಾಸ್ಮಾ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=QML과 자바스크립트로 작성된 Plasma 위젯 +Comment[lt]=Nuosavas Plasma valdiklis parašytas QML ir JavaScript kalba +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 +Comment[nn]=Plasma-element skriven i QML og JavaScript +Comment[pa]=QML ਤੇ ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਵਿੱਚ ਲਿਖੇ ਨੇਟਿਵ ਪਲਾਜ਼ਮਾ ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu Plazmy napisany w QML lub JavaScript +Comment[pt]=Elemento nativo do Plasma feito em QML e JavaScript +Comment[pt_BR]=Widget do Plasma nativo escrito em QML e JavaScript +Comment[ro]=Miniaplicație Plasma nativă scrisă în QML și JavaScript +Comment[ru]=Виджет Plasma, написанный на языках QML и JavaScript +Comment[si]=ජාවා ස්ක්‍රිප්ට හා QML මගින් ලියූ ප්ලාස්මා විජෙට්ටු +Comment[sk]=Natívny plasma widget napísaný v QML a JavaScripte +Comment[sl]=Pravi gradnik za Plasmo, ki je napisan v QML-u in JavaScriptu +Comment[sr]=Самосвојни плазма виџет написан у КуМЛ‑у и јаваскрипту +Comment[sr@ijekavian]=Самосвојни плазма виџет написан у КуМЛ‑у и јаваскрипту +Comment[sr@ijekavianlatin]=Samosvojni plasma vidžet napisan u QML‑u i JavaScriptu +Comment[sr@latin]=Samosvojni plasma vidžet napisan u QML‑u i JavaScriptu +Comment[sv]=Inbyggd grafisk Plasma-komponent skriven i QML och Javascript +Comment[tg]=Ин модули Plasma дар QML ва JavaScript навишта шуд +Comment[th]=วิดเจ็ตพลาสมาแบบดั้งเดิมที่เขียนด้วย QML และจาวาสคริปต์ +Comment[tr]=JavaScript ve QML ile yazılmış gerçek Plasma gereci +Comment[ug]=QML ۋە JavaScript بىلەن يېزىلغان ئەسلى Plasma ۋىجېتى +Comment[uk]=Віджет Плазми, написаний на QML та JavaScript +Comment[x-test]=xxNative Plasma widget written in QML and JavaScriptxx +Comment[zh_CN]=使用 QML 和 JavaScript 编写的原生 Plasma 部件 +Comment[zh_TW]=用 QML 與 JavaScript 寫的原始 Plasma 元件 Type=Service Icon=text-x-script diff --git a/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop b/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop index c610eedfa..07dc02a8f 100644 --- a/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop +++ b/scriptengines/javascript/data/plasma-scriptengine-applet-simple-javascript.desktop @@ -1,10 +1,154 @@ [Desktop Entry] Name=JavaScript Widget +Name[ar]=ودجة جافا سكربت +Name[ast]=Elementu gráficu JavaScript +Name[be@latin]=Widžet „JavaScript” +Name[bg]=Джаджа JavaScript +Name[bn_IN]=JavaScript Widget +Name[bs]=Javascript grafička kontrola +Name[ca]=Estri del JavaScript +Name[ca@valencia]=Estri del JavaScript +Name[cs]=JavaScript Widget +Name[csb]=Interfejs JavaScript +Name[da]=JavaScript-widget +Name[de]=JavaScript-Programm +Name[el]=Συστατικό JavaScript +Name[en_GB]=JavaScript Widget +Name[eo]=Ĝavaskripta fenestraĵo +Name[es]=Elemento gráfico JavaScript +Name[et]=JavaScripti vidin +Name[eu]=JavaScript trepeta +Name[fi]=JavaScript-sovelma +Name[fr]=Composant graphique JavaScript +Name[fy]=JavaSkript Widget +Name[ga]=Giuirléid JavaScript +Name[gl]=Widget de JavaScript +Name[gu]=જાવાસ્ક્રિપ્ટ વિજેટ +Name[he]=ווידג׳ט JavaScript +Name[hi]=जावास्क्रिप्ट विज़ेट +Name[hne]=जावास्क्रिप्ट विजेट +Name[hr]=JavaScript widgeti +Name[hu]=JavaScript-objektum +Name[ia]=JavaScript Widget +Name[id]=Widget JavaScript +Name[is]=JavaScript græja +Name[it]=Oggetto JavaScript +Name[ja]=JavaScript ウィジェット +Name[kk]=JavaScript интерфейс бөлшегі +Name[km]=ធាតុ​ក្រាហ្វិក JavaScript +Name[kn]=ಜಾವಾ ವಿಧಿಗುಚ್ಛ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Name[ko]=자바스크립트 위젯 +Name[ku]=Amîra JavaScriptê +Name[lt]=JavaScript valdiklis +Name[lv]=JavaScript sīkrīks +Name[ml]=ജാവാസ്ക്രിപ്റ്റ് വിഡ്ജറ്റ് +Name[mr]=जावास्क्रिप्ट विजेट +Name[nb]=JavaScript-skjermelement +Name[nds]=JavaScript-Finster +Name[nl]=JavaScript-widget +Name[nn]=JavaScript-element +Name[or]=JavaScript ୱିଜେଟ +Name[pa]=ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਵਿਦਜੈੱਟ +Name[pl]=Element interfejsu w JavaScript +Name[pt]=Elemento de JavaScript +Name[pt_BR]=Widget de JavaScript +Name[ro]=Miniaplicație JavaScript +Name[ru]=Виджет на языке JavaScript +Name[si]=Python මෙවලම් +Name[sk]=JavaScript widget +Name[sl]=Gradnik v JavaScriptu +Name[sr]=јаваскриптни виџет +Name[sr@ijekavian]=јаваскриптни виџет +Name[sr@ijekavianlatin]=JavaScript vidžet +Name[sr@latin]=JavaScript vidžet +Name[sv]=Grafisk Javascript-komponent +Name[ta]=JavaScript Widget +Name[te]=జావాస్క్రిప్‍ట్ విడ్‍జ్‌ట్ +Name[tg]=Видҷети JavaScript +Name[th]=วิดเจ็ตภาษาจาวาสคริปต์ +Name[tr]=JavaScript Programcığı +Name[ug]=JavaScript ۋىجېتى +Name[uk]=Віджет JavaScript +Name[wa]=Ahesse JavaScript +Name[x-test]=xxJavaScript Widgetxx +Name[zh_CN]=JavaScript 部件 +Name[zh_TW]=JavaScript 元件 Comment=Native Plasma widget written in JavaScript +Comment[ar]=ودجة بلازما أصلية كتبت بجافا سكربت +Comment[ast]=Elementu gráficu nativu de Plasma escritu en JavaScript +Comment[be@latin]=Widžet systemy „Plasma”, napisany ŭ movie „JavaScript” +Comment[bg]=Оригинална джаджа за Plasma, написана с JavaScript +Comment[bs]=Samosvojni plazma grafička kontrola napisana u javaskriptu +Comment[ca]=Estri nadiu del Plasma escrit en JavaScript +Comment[ca@valencia]=Estri nadiu del Plasma escrit en JavaScript +Comment[cs]=Nativní Plasma widget napsaný v JavaScriptu +Comment[csb]=Prôwdzëwi widżet Plasmë napisóny w JavaScript +Comment[da]=Native Plasma-widget skrevet i JavaScript +Comment[de]=Echtes Plasma-Programm, geschrieben in JavaScript +Comment[el]=Εγγενές συστατικό Plasma γραμμένο σε JavaScript +Comment[en_GB]=Native Plasma widget written in JavaScript +Comment[eo]=Indiĝena Plasma-fenestraĵo programita per Ĝavoskripto +Comment[es]=Elemento gráfico nativo de Plasma escrito en JavaScript +Comment[et]=JavaScriptis kirjutatud Plasma vidin +Comment[eu]=Plasma jatorrizko trepeta JavaScript-en idatzia +Comment[fi]=Natiivi, JavaScript-pohjainen Plasma-sovelma +Comment[fr]=Composant graphique natif de Plasma écrit en JavaScript +Comment[fy]=Plasma widget skreaun yn JavaSkript +Comment[ga]=Giuirléid dhúchasach Plasma, scríofa i JavaScript +Comment[gl]=Widget nativo de Plasma escrito en JavaScript +Comment[gu]=જાવાસ્ક્રિપ્ટમાં લખાયેલ મૂળભૂત પ્લાઝમા વિજેટ +Comment[he]=ווידג׳ט של Plasma הנכתב ב־JavaScript +Comment[hi]=जावास्क्रिप्ट में लिखा गया नेटिव प्लाज्मा विजेट +Comment[hne]=जावास्क्रिप्ट मं लिखे नेटिव प्लाज्मा विजेट +Comment[hr]=Izvorna Plasma widget napisana u JavaScriptu +Comment[hu]=Plasma-elem Javascriptben elkészítve +Comment[ia]=Widget native de Plasma scribite in JavaScript +Comment[id]=Widget Plasma asli yang ditulis dalam JavaScript +Comment[is]=Upprunabundin Plasma græja skrifuð í JavaScript +Comment[it]=Oggetto nativo di Plasma scritto in JavaScript +Comment[ja]=JavaScript で書かれた Plasma のネイティブウィジェット +Comment[kk]=JavaScript-те жазылған Plasma тума виджеті +Comment[km]=ធាតុ​ក្រាហ្វិក​ប្លាស្មា​ដើម ដែល​សរសេរ​ក្នុង JavaScript +Comment[kn]=ಜಾವಾ ಸ್ಕ್ರಿಪ್ಟ್ ನಲ್ಲಿ ಬರೆಯಲಾದ ಸ್ವಾಭಾವಿಕ ಪ್ಲಾಸ್ಮಾ ನಿಯಂತ್ರಣಾ ಸಂಪರ್ಕತಟ (ವಿಡ್ಗೆಟ್) +Comment[ko]=자바스크립트로 작성된 Plasma 위젯 +Comment[lt]=Nuosavas Plasma valdiklis parašytas JavaScript kalba +Comment[lv]=Plasma sīkrīks, rakstīts JavaScript +Comment[ml]=ജാവാസ്ക്രിപ്റ്റില്‍ തയ്യാറാക്കിയിരിക്കുന്ന നേറ്റീവ് പ്ലാസ്മാ വിഡ്ജറ്റ് +Comment[mr]=जावास्क्रिप्ट अंतर्गत लिहीले गेलेले मुळ प्लाज्मा विजेट +Comment[nb]=Plasmaelement for dette systemet, skrevet i JavaScript +Comment[nds]=En orginaal Plasmaelement, schreven in JavaScript +Comment[nl]=Plasma-widget geschreven in JavaScript +Comment[nn]=Plasma-element skriven i JavaScript +Comment[or]=JavaScriptରେ ଲିଖିତ ସ୍ଥାନୀୟ ପ୍ଲାଜମା ୱିଜେଟ +Comment[pa]=ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਵਿੱਚ ਲਿਖੇ ਨੇਟਿਵ ਪਲਾਜ਼ਮਾ ਵਿਦਜੈੱਟ +Comment[pl]=Element interfejsu Plazmy napisany w JavaScript +Comment[pt]=Elemento nativo do Plasma feito em JavaScript +Comment[pt_BR]=Widget do Plasma nativo escrito em JavaScript +Comment[ro]=Miniaplicație Plasma scrisă în JavaScript +Comment[ru]=Виджет Plasma, написанный на языке JavaScript +Comment[si]=ජාවා ස්ක්‍රිප්ට මගින් ලියූ ප්ලාස්මා විජෙට්ටු +Comment[sk]=Natívny plasma widget napísaný v JavaScripte +Comment[sl]=Pravi gradnik za Plasmo, ki je napisan v JavaScriptu +Comment[sr]=Самосвојни плазма виџет написан у јаваскрипту +Comment[sr@ijekavian]=Самосвојни плазма виџет написан у јаваскрипту +Comment[sr@ijekavianlatin]=Samosvojni plasma vidžet napisan u JavaScriptu +Comment[sr@latin]=Samosvojni plasma vidžet napisan u JavaScriptu +Comment[sv]=Inbyggd grafisk Plasma-komponent skriven i Javascript +Comment[ta]=Native Plasma widget written in JavaScript +Comment[te]=జావాస్క్రిప్‍ట్‌లో వ్రాసిన నేటివ్ ప్లాజ్మా విడ్‍జ్‌ట్ +Comment[tg]=Ин модули Plasma дар JavaScript навишта шуд +Comment[th]=วิดเจ็ตพลาสมาที่ถูกเขียนด้วยจาวาสคริปต์ +Comment[tr]=JavaScript ile yazılmış gerçek Plasma gereci +Comment[ug]=JavaScript بىلەن يېزىلغان ئەسلى Plasma ۋىجېتى +Comment[uk]=Віджет Плазми, написаний на JavaScript +Comment[wa]=Ahesse askepieye po Plasma eyet scrîte e JavaScript +Comment[x-test]=xxNative Plasma widget written in JavaScriptxx +Comment[zh_CN]=使用 JavaScript 编写的原生 Plasma 部件 +Comment[zh_TW]=用 JavaScript 寫的原始 Plasma 元件 X-KDE-ServiceTypes=Plasma/ScriptEngine Type=Service Icon=text-x-script X-KDE-Library=plasma_appletscript_simple_javascript X-Plasma-API=javascript X-Plasma-ComponentTypes=Applet -X-KDE-PluginInfo-Version=2 +X-KDE-PluginInfo-Version=4 diff --git a/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop b/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop index 42e3d5825..088e0a121 100644 --- a/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop +++ b/scriptengines/javascript/data/plasma-scriptengine-dataengine-javascript.desktop @@ -1,5 +1,69 @@ [Desktop Entry] Name=JavaScript DataEngine +Name[ar]=مشغل جافا سكربت +Name[ast]=Motor de datos JavaScript +Name[bg]=Ядро за данни на JavaScript +Name[bs]=Javascript pogon podataka +Name[ca]=Motor de dades de JavaScript +Name[ca@valencia]=Motor de dades de JavaScript +Name[cs]=Datový nástroj JavaScript +Name[csb]=Mòtór JavaScript +Name[da]=JavaScript-datamotor +Name[de]=JavaScript-Datenmodul +Name[el]=Μηχανή δεδομένων JavaScript +Name[en_GB]=JavaScript DataEngine +Name[eo]=Ĝavaskripta Datummodulo +Name[es]=Motor de datos JavaScript +Name[et]=JavaScripti andmemootor +Name[eu]=JavaScript datu-motorea +Name[fi]=JavaScript-datakone +Name[fr]=Moteur de données JavaScript +Name[fy]=JavaSkript gegevens motor +Name[ga]=Inneall Sonraí JavaScript +Name[gl]=Motor de datos de JavaScript +Name[gu]=જાવાસ્ક્રિપ્ટ માહિતીએન્જિન +Name[he]=מנוע נתונים של JavaScript +Name[hr]=JavaScript podatkovni mehanizam +Name[hu]=JavaScript-adatmodul +Name[ia]=JavaScript Motor de Datos (Data Engine) +Name[id]=Mesin Data JavaScript +Name[is]=JavaScript gagnavél +Name[it]=Motore di dati JavaScript +Name[ja]=JavaScript データエンジン +Name[kk]=JavaScript деректер тетігі +Name[km]=ម៉ាស៊ីន​ទិន្នន័យ JavaScript +Name[kn]=JavaScript DataEngine +Name[ko]=자바스크립트 데이터 엔진 +Name[lt]=JavaScript duomenų variklis +Name[lv]=JavaScript datu dzinējs +Name[ml]=ജാവാസ്ക്രിപ്റ്റ് ഡാറ്റാഎഞ്ചിന്‍ +Name[nb]=JavaScript datamotor +Name[nds]=JavaScript-Datenkarn +Name[nl]=JavaScript-data-engine +Name[nn]=JavaScript-datamotor +Name[pa]=ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਡਾਟਾਇੰਜਣ +Name[pl]=Silnik danych JavaScript +Name[pt]=Motor de Dados do JavaScript +Name[pt_BR]=Mecanismo de dados JavaScript +Name[ro]=MotorDate JavaScript +Name[ru]=Поставщик данных (JavaScript) +Name[si]=JavaScript දත්ත එන්ජිම +Name[sk]=Dátový nástroj JavaScript +Name[sl]=Podatkovni pogon za JavaScript +Name[sr]=јаваскриптни датомотор +Name[sr@ijekavian]=јаваскриптни датомотор +Name[sr@ijekavianlatin]=JavaScript datomotor +Name[sr@latin]=JavaScript datomotor +Name[sv]=Javascript-datagränssnitt +Name[tg]=Маълумоти муҳаррики JavaScript +Name[th]=กลไกข้อมูลของจาวาสคริปต์ +Name[tr]=JavaScript Veri Motoru +Name[ug]=JavaScript سانلىق مەلۇمات ماتورى +Name[uk]=Рушій даних JavaScript +Name[wa]=Moteur di dnêyes JavaScript +Name[x-test]=xxJavaScript DataEnginexx +Name[zh_CN]=JavaScript 数据引擎 +Name[zh_TW]=JavaScript 資料引擎 X-KDE-ServiceTypes=Plasma/ScriptEngine Type=Service Icon=text-x-script diff --git a/scriptengines/javascript/data/plasma-scriptengine-runner-javascript.desktop b/scriptengines/javascript/data/plasma-scriptengine-runner-javascript.desktop index 2c896b488..c0082b695 100644 --- a/scriptengines/javascript/data/plasma-scriptengine-runner-javascript.desktop +++ b/scriptengines/javascript/data/plasma-scriptengine-runner-javascript.desktop @@ -1,6 +1,156 @@ [Desktop Entry] Name=JavaScript Runner +Name[ar]=مشغل جافا سكربت +Name[ast]=Motor de javascript +Name[be@latin]=Uklučeńnie „JavaScript” +Name[bg]=Изпълнение на JavaScript +Name[bn_IN]=JavaScript Runner +Name[bs]=Javascript izvođač +Name[ca]=Executor de JavaScript +Name[ca@valencia]=Executor de JavaScript +Name[cs]=Spouštěč JavaScriptu +Name[csb]=Mòtór JavaScript +Name[da]=JavaScript-runner +Name[de]=JavaScript-Ausführung +Name[el]=Εκτελεστής JavaScript +Name[en_GB]=JavaScript Runner +Name[eo]=Ĝavaskripta ruligilo +Name[es]=Motor de javascript +Name[et]=JavaScripti käivitaja +Name[eu]=JavaScript abiarazlea +Name[fa]=اجراکننده جاوااسکریپت +Name[fi]=JavaScript-suoritusohjelma +Name[fr]=Lanceur JavaScript +Name[fy]=JavaSkript rinner +Name[ga]=Feidhmitheoir JavaScript +Name[gl]=Executor de JavaScript +Name[gu]=જાવાસ્ક્રિપ્ટ ચલાવનાર +Name[he]=מריץ JavaScript +Name[hi]=जावास्क्रिप्ट चलाने वाला +Name[hne]=जावास्क्रिप्ट चलइया +Name[hr]=JavaScript Pokretač +Name[hu]=JavaScript-indító +Name[ia]=JavaScript Executor +Name[id]=Pelari JavaScript +Name[is]=JavaScript keyrari +Name[it]=Esecutore JavaScript +Name[ja]=JavaScript Runner +Name[kk]=JavaScript жеккіші +Name[km]=កម្មវិធី​រត់ JavaScript +Name[kn]=ಜಾವಾ ವಿಧಿಗುಚ್ಛ (ಸ್ಕ್ರಿಪ್ಟ್) ಚಾಲಕ +Name[ko]=자바스크립트 실행기 +Name[ku]=Xebatkara JavaScriptê +Name[lt]=JavaScript paleidiklis +Name[lv]=JavaScript darbinātājs +Name[mk]=Извршувач на JavaScript +Name[ml]=ജാവാസ്ക്രിപ്റ്റ് റണ്ണര്‍ +Name[mr]=जावास्क्रिप्ट चालक +Name[nb]=JavaScript-kjører +Name[nds]=JavaScript-Dreger +Name[nl]=JavaScript-runner +Name[nn]=JavaScript-køyrar +Name[or]=JavaScript ଚାଳକ +Name[pa]=ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਰਨਰ +Name[pl]=Silnik JavaScript +Name[pt]=Execução de JavaScript +Name[pt_BR]=Mecanismo JavaScript +Name[ro]=Executor JavaScript +Name[ru]=JavaScript Runner +Name[si]=JavaScript ධාවකය +Name[sk]=Spúšťač JavaScriptu +Name[sl]=Zaganjalnik javascripta +Name[sr]=јаваскриптни извођач +Name[sr@ijekavian]=јаваскриптни извођач +Name[sr@ijekavianlatin]=JavaScript izvođač +Name[sr@latin]=JavaScript izvođač +Name[sv]=Kör Javascript +Name[ta]=JavaScript Runner +Name[te]=జావాస్క్రిప్‍ట్ నడుపునది +Name[tg]=Иҷрогари JavaScript +Name[th]=ตัวประมวลผลจาวาสคริปต์ +Name[tr]=JavaScript Çalıştırıcı +Name[ug]=JavaScript ئىجراچىسى +Name[uk]=Механізм запуску JavaScript +Name[wa]=Enondeu JavaScript +Name[x-test]=xxJavaScript Runnerxx +Name[zh_CN]=JavaScript 运行器 +Name[zh_TW]=JavaScript 執行器 Comment=JavaScript Runner +Comment[ar]=مشغل جافا سكربت +Comment[ast]=Motor de javascript +Comment[be@latin]=Uklučeńnie „JavaScript”. +Comment[bg]=Изпълнение на JavaScript +Comment[bn_IN]=JavaScript Runner +Comment[bs]=Javascript izvođač +Comment[ca]=Executor de JavaScript +Comment[ca@valencia]=Executor de JavaScript +Comment[cs]=Spouštěč JavaScriptu +Comment[csb]=Zrëszôcz JavaScript +Comment[da]=JavaScript-runner +Comment[de]=JavaScript-Ausführung +Comment[el]=Εκτελεστής JavaScript +Comment[en_GB]=JavaScript Runner +Comment[eo]=Ĝavaskripta ruligilo +Comment[es]=Motor de javascript +Comment[et]=JavaScripti käivitaja +Comment[eu]=JavaScript abiarazlea +Comment[fa]=اجراکننده جاوااسکریپت +Comment[fi]=JavaScript-suoritusohjelma +Comment[fr]=Lanceur JavaScript +Comment[fy]=JavaSkript rinner +Comment[ga]=Feidhmitheoir JavaScript +Comment[gl]=Executor de JavaScript +Comment[gu]=જાવાસ્ક્રિપ્ટ ચલાવનાર +Comment[he]=מריץ JavaScript +Comment[hi]=जावास्क्रिप्ट चलाने वाला +Comment[hne]=जावास्क्रिप्ट चलइया +Comment[hr]=JavaScript pokretač +Comment[hu]=JavaScript-indító +Comment[ia]=JavaScript Executor +Comment[id]=Pelari JavaScript +Comment[is]=JavaScript keyrari +Comment[it]=Esecutore JavaScript +Comment[ja]=JavaScript Runner +Comment[kk]=JavaScript жеккіші +Comment[km]=កម្មវិធី​រត់ JavaScript +Comment[kn]=ಜಾವಾ ವಿಧಿಗುಚ್ಛ (ಸ್ಕ್ರಿಪ್ಟ್) ಚಾಲಕ +Comment[ko]=자바스크립트 실행기 +Comment[ku]=Xebatkara JavaScriptê +Comment[lt]=JavaScript paleidiklis +Comment[lv]=JavaScript darbinātājs +Comment[mk]=Извршувач на JavaScript +Comment[ml]=ജാവാസ്ക്രിപ്റ്റ് റണ്ണര്‍ +Comment[mr]=जावास्क्रिप्ट चालक +Comment[nb]=JavaScript-kjører +Comment[nds]=JavaScript-Dreger +Comment[nl]=JavaScript-runner +Comment[nn]=JavaScript-køyrar +Comment[or]=JavaScript ଚାଳକ +Comment[pa]=ਜਾਵਾ-ਸਕ੍ਰਿਪਟ ਰਨਰ +Comment[pl]=Silnik JavaScript +Comment[pt]=Execução de JavaScript +Comment[pt_BR]=Mecanismo JavaScript +Comment[ro]=Executor JavaScript +Comment[ru]=Модуль запуска, написанный на языке JavaScript +Comment[si]=JavaScript Runner +Comment[sk]=Spúšťač JavaScriptu +Comment[sl]=Zaganjalnik javascripta +Comment[sr]=Јаваскриптни извођач +Comment[sr@ijekavian]=Јаваскриптни извођач +Comment[sr@ijekavianlatin]=JavaScript izvođač +Comment[sr@latin]=JavaScript izvođač +Comment[sv]=Kör Javascript +Comment[ta]=JavaScript Runner +Comment[te]=జావాస్క్రిప్‍ట్ నడుపునది +Comment[tg]=Иҷрогари JavaScript +Comment[th]=ตัวประมวลผลจาวาสคริปต์ +Comment[tr]=JavaScript Çalıştırıcı +Comment[ug]=JavaScript ئىجراچىسى +Comment[uk]=Механізм запуску JavaScript +Comment[wa]=Enondeu JavaScript +Comment[x-test]=xxJavaScript Runnerxx +Comment[zh_CN]=JavaScript 运行器 +Comment[zh_TW]=JavaScript 執行器 X-KDE-ServiceTypes=Plasma/ScriptEngine Type=Service Icon=text-x-script diff --git a/scriptengines/javascript/dataengine/javascriptdataengine.cpp b/scriptengines/javascript/dataengine/javascriptdataengine.cpp index 8a6f0498d..2a1e12767 100644 --- a/scriptengines/javascript/dataengine/javascriptdataengine.cpp +++ b/scriptengines/javascript/dataengine/javascriptdataengine.cpp @@ -2,7 +2,7 @@ * Copyright 2009 Aaron Seigo * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as + * 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. * diff --git a/scriptengines/javascript/dataengine/javascriptdataengine.h b/scriptengines/javascript/dataengine/javascriptdataengine.h index b5bb67cff..bc8802ed1 100644 --- a/scriptengines/javascript/dataengine/javascriptdataengine.h +++ b/scriptengines/javascript/dataengine/javascriptdataengine.h @@ -2,7 +2,7 @@ * Copyright 2009 Aaron Seigo * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as + * 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. * diff --git a/scriptengines/javascript/declarative/packageaccessmanager.cpp b/scriptengines/javascript/declarative/packageaccessmanager.cpp index 9e12194a6..b9f9b0b8e 100644 --- a/scriptengines/javascript/declarative/packageaccessmanager.cpp +++ b/scriptengines/javascript/declarative/packageaccessmanager.cpp @@ -39,6 +39,8 @@ public: qint64 readData(char *data, qint64 maxSize) { + Q_UNUSED(data); + Q_UNUSED(maxSize); return 0; } diff --git a/scriptengines/javascript/plasmoid/abstractjsappletscript.h b/scriptengines/javascript/plasmoid/abstractjsappletscript.h index fde888ae8..2eb4dde1f 100644 --- a/scriptengines/javascript/plasmoid/abstractjsappletscript.h +++ b/scriptengines/javascript/plasmoid/abstractjsappletscript.h @@ -32,6 +32,7 @@ public: AbstractJsAppletScript(QObject *parent, const QVariantList &args = QVariantList()); ~AbstractJsAppletScript(); + virtual QScriptEngine *engine() const = 0; virtual bool include(const QString &path) = 0; virtual QString filePath(const QString &type, const QString &file) const = 0; virtual QScriptValue variantToScriptValue(QVariant var) = 0; diff --git a/scriptengines/javascript/plasmoid/appletinterface.cpp b/scriptengines/javascript/plasmoid/appletinterface.cpp index 0d57675c0..df7996244 100644 --- a/scriptengines/javascript/plasmoid/appletinterface.cpp +++ b/scriptengines/javascript/plasmoid/appletinterface.cpp @@ -34,6 +34,7 @@ #include #include +#include #include #include @@ -47,6 +48,7 @@ AppletInterface::AppletInterface(AbstractJsAppletScript *parent) connect(this, SIGNAL(releaseVisualFocus()), applet(), SIGNAL(releaseVisualFocus())); connect(this, SIGNAL(configNeedsSaving()), applet(), SIGNAL(configNeedsSaving())); connect(applet(), SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)), this, SIGNAL(immutableChanged())); + connect(applet(), SIGNAL(newStatus(Plasma::ItemStatus)), this, SIGNAL(statusChanged())); } AppletInterface::~AppletInterface() @@ -221,6 +223,9 @@ QList AppletInterface::contextualActions() const { QList actions; Plasma::Applet *a = applet(); + if (a->hasFailedToLaunch()) { + return actions; + } foreach (const QString &name, m_actions) { QAction *action = a->action(name); @@ -255,7 +260,7 @@ void AppletInterface::setAction(const QString &name, const QString &text, const a->addAction(name, action); Q_ASSERT(!m_actions.contains(name)); - m_actions.insert(name); + m_actions.append(name); if (!m_actionSignals) { m_actionSignals = new QSignalMapper(this); @@ -291,7 +296,12 @@ void AppletInterface::removeAction(const QString &name) delete action; } - m_actions.remove(name); + m_actions.removeAll(name); +} + +QAction *AppletInterface::action(QString name) const +{ + return applet()->action(name); } void AppletInterface::resize(qreal w, qreal h) @@ -367,6 +377,25 @@ Plasma::Extender *AppletInterface::extender() const return m_appletScriptEngine->extender(); } +void AppletInterface::setAssociatedApplication(const QString &string) +{ + applet()->setAssociatedApplication(string); +} + +QString AppletInterface::associatedApplication() const +{ + return applet()->associatedApplication(); +} + +void AppletInterface::setStatus(const AppletInterface::ItemStatus &status) +{ + applet()->setStatus((Plasma::ItemStatus)status); +} + +AppletInterface::ItemStatus AppletInterface::status() const +{ + return (AppletInterface::ItemStatus)((int)(applet()->status())); +} void AppletInterface::gc() { @@ -375,7 +404,7 @@ void AppletInterface::gc() PopupAppletInterface::PopupAppletInterface(AbstractJsAppletScript *parent) - : POPUPAPPLETSUPERCLASS(parent) + : APPLETSUPERCLASS(parent) { } @@ -429,6 +458,136 @@ QGraphicsWidget *PopupAppletInterface::popupWidget() return popupApplet()->graphicsWidget(); } +ContainmentInterface::ContainmentInterface(AbstractJsAppletScript *parent) + : APPLETSUPERCLASS(parent), + m_movableApplets(true) +{ + connect(containment(), SIGNAL(appletRemoved(Plasma::Applet *)), this, SLOT(appletRemovedForward(Plasma::Applet *))); + + connect(containment(), SIGNAL(appletAdded(Plasma::Applet *, const QPointF &)), this, SLOT(appletAddedForward(Plasma::Applet *, const QPointF &))); + + connect(containment(), SIGNAL(screenChanged(int, int, Plasma::Containment)), this, SLOT(screenChanged())); + + connect(containment()->context(), SIGNAL(activityChanged(Plasma::Context *)), this, SIGNAL(activityNameChanged())); + connect(containment()->context(), SIGNAL(changed(Plasma::Context *)), this, SIGNAL(activityIdChanged())); + + if (containment()->corona()) { + connect(containment()->corona(), SIGNAL(availableScreenRegionChanged()), + this, SIGNAL(availableScreenRegionChanged())); + } +} + +QScriptValue ContainmentInterface::applets() +{ + QScriptValue list = m_appletScriptEngine->engine()->newArray(containment()->applets().size()); + int i = 0; + foreach (Plasma::Applet *applet, containment()->applets()) { + list.setProperty(i, m_appletScriptEngine->engine()->newQObject(applet)); + ++i; + } + return list; +} + +void ContainmentInterface::setDrawWallpaper(bool drawWallpaper) +{ + m_appletScriptEngine->setDrawWallpaper(drawWallpaper); +} + +bool ContainmentInterface::drawWallpaper() +{ + return m_appletScriptEngine->drawWallpaper(); +} + +ContainmentInterface::Type ContainmentInterface::containmentType() const +{ + return (ContainmentInterface::Type)m_appletScriptEngine->containmentType(); +} + +void ContainmentInterface::setContainmentType(ContainmentInterface::Type type) +{ + m_appletScriptEngine->setContainmentType((Plasma::Containment::Type)type); +} + +int ContainmentInterface::screen() const +{ + return containment()->screen(); +} + +QScriptValue ContainmentInterface::screenGeometry(int id) const +{ + QRectF rect; + if (containment()->corona()) { + rect = QRectF(containment()->corona()->screenGeometry(id)); + } + + QScriptValue val = m_appletScriptEngine->engine()->newObject(); + val.setProperty("x", rect.x()); + val.setProperty("y", rect.y()); + val.setProperty("width", rect.width()); + val.setProperty("height", rect.height()); + return val; +} + +QScriptValue ContainmentInterface::availableScreenRegion(int id) const +{ + QRegion reg; + if (containment()->corona()) { + reg = containment()->corona()->availableScreenRegion(id); + } + + QScriptValue regVal = m_appletScriptEngine->engine()->newArray(reg.rects().size()); + int i = 0; + foreach (QRect rect, reg.rects()) { + QScriptValue val = m_appletScriptEngine->engine()->newObject(); + val.setProperty("x", rect.x()); + val.setProperty("y", rect.y()); + val.setProperty("width", rect.width()); + val.setProperty("height", rect.height()); + regVal.setProperty(i++, val); + } + return regVal; +} + +void ContainmentInterface::appletAddedForward(Plasma::Applet *applet, const QPointF &pos) +{ + applet->setFlag(QGraphicsItem::ItemIsMovable, m_movableApplets); + emit appletAdded(applet, pos); +} + +void ContainmentInterface::appletRemovedForward(Plasma::Applet *applet) +{ + applet->setFlag(QGraphicsItem::ItemIsMovable, true); + emit appletRemoved(applet); +} + +void ContainmentInterface::setMovableApplets(bool movable) +{ + if (m_movableApplets == movable) { + return; + } + + m_movableApplets = movable; + + foreach (Plasma::Applet *applet, containment()->applets()) { + applet->setFlag(QGraphicsItem::ItemIsMovable, movable); + } +} + +bool ContainmentInterface::hasMovableApplets() const +{ + return m_movableApplets; +} + +QString ContainmentInterface::activityName() const +{ + return containment()->context()->currentActivity(); +} + +QString ContainmentInterface::activityId() const +{ + return containment()->context()->currentActivityId(); +} + #ifndef USE_JS_SCRIPTENGINE #include "appletinterface.moc" #endif diff --git a/scriptengines/javascript/plasmoid/appletinterface.h b/scriptengines/javascript/plasmoid/appletinterface.h index cd987e6e9..51278b04a 100644 --- a/scriptengines/javascript/plasmoid/appletinterface.h +++ b/scriptengines/javascript/plasmoid/appletinterface.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -63,6 +64,7 @@ class AppletInterface : public QObject Q_ENUMS(AnimationDirection) Q_ENUMS(IntervalAlignment) Q_ENUMS(ThemeColors) + Q_ENUMS(ItemStatus) Q_PROPERTY(AspectRatioMode aspectRatioMode READ aspectRatioMode WRITE setAspectRatioMode) Q_PROPERTY(FormFactor formFactor READ formFactor NOTIFY formFactorChanged) Q_PROPERTY(Location location READ location NOTIFY locationChanged) @@ -74,8 +76,10 @@ class AppletInterface : public QObject Q_PROPERTY(bool immutable READ immutable NOTIFY immutableChanged) Q_PROPERTY(bool userConfiguring READ userConfiguring) // @since 4.5 Q_PROPERTY(int apiVersion READ apiVersion CONSTANT) + Q_PROPERTY(ItemStatus status READ status WRITE setStatus NOTIFY statusChanged) Q_PROPERTY(QRectF rect READ rect) Q_PROPERTY(QSizeF size READ size) + Q_PROPERTY(QString associatedApplication WRITE setAssociatedApplication READ associatedApplication) public: AppletInterface(AbstractJsAppletScript *parent); @@ -126,6 +130,14 @@ enum AspectRatioMode { FixedSize = 4 /** The applet cannot be resized */ }; +enum ItemStatus { + UnknownStatus = 0, /**< The status is unknown **/ + PassiveStatus = 1, /**< The Item is passive **/ + ActiveStatus = 2, /**< The Item is active **/ + NeedsAttentionStatus = 3, /**< The Item needs attention **/ + AcceptingInputStatus = 4 /**< The Item is accepting input **/ +}; + //From Qt namespace enum QtModifiers { QtNoModifier = Qt::NoModifier, @@ -218,6 +230,7 @@ enum IntervalAlignment { AlignToMinute, AlignToHour }; + //------------------------------------------------------------------- Q_INVOKABLE void gc(); @@ -248,6 +261,8 @@ enum IntervalAlignment { Q_INVOKABLE void removeAction(const QString &name); + Q_INVOKABLE QAction *action(QString name) const; + Q_INVOKABLE void resize(qreal w, qreal h); Q_INVOKABLE void setMinimumSize(qreal w, qreal h); @@ -282,6 +297,12 @@ enum IntervalAlignment { static AppletInterface *extract(QScriptEngine *engine); inline Plasma::Applet *applet() const { return m_appletScriptEngine->applet(); } + void setAssociatedApplication(const QString &string); + QString associatedApplication() const; + + void setStatus(const ItemStatus &status); + ItemStatus status() const; + Q_SIGNALS: void releaseVisualFocus(); void configNeedsSaving(); @@ -290,12 +311,13 @@ Q_SIGNALS: void locationChanged(); void contextChanged(); void immutableChanged(); + void statusChanged(); protected: AbstractJsAppletScript *m_appletScriptEngine; private: - QSet m_actions; + QStringList m_actions; QSignalMapper *m_actionSignals; QString m_currentConfig; QMap m_configs; @@ -319,11 +341,11 @@ public: }; #ifdef USE_JS_SCRIPTENGINE -#define POPUPAPPLETSUPERCLASS JsAppletInterface +#define APPLETSUPERCLASS JsAppletInterface #else -#define POPUPAPPLETSUPERCLASS AppletInterface +#define APPLETSUPERCLASS AppletInterface #endif -class PopupAppletInterface : public POPUPAPPLETSUPERCLASS +class PopupAppletInterface : public APPLETSUPERCLASS { Q_OBJECT Q_PROPERTY(QIcon popupIcon READ popupIcon WRITE setPopupIcon) @@ -351,4 +373,63 @@ public Q_SLOTS: void showPopup(); }; + +class ContainmentInterface : public APPLETSUPERCLASS +{ + Q_OBJECT + Q_PROPERTY(QScriptValue applets READ applets) + Q_PROPERTY(bool drawWallpaper READ drawWallpaper WRITE setDrawWallpaper) + Q_PROPERTY(Type containmentType READ containmentType WRITE setContainmentType) + Q_PROPERTY(int screen READ screen NOTIFY screenChanged) + Q_PROPERTY(bool movableApplets READ hasMovableApplets WRITE setMovableApplets) + Q_PROPERTY(QString activityName READ activityName NOTIFY activityNameChanged) + Q_PROPERTY(QString activityId READ activityId NOTIFY activityIdChanged) + Q_ENUMS(Type) + +public: + enum Type { + NoContainmentType = -1, /**< @internal */ + DesktopContainment = 0, /**< A desktop containment */ + PanelContainment, /**< A desktop panel */ + CustomContainment = 127, /**< A containment that is neither a desktop nor a panel + but something application specific */ + CustomPanelContainment = 128 /**< A customized desktop panel */ + }; + ContainmentInterface(AbstractJsAppletScript *parent); + + inline Plasma::Containment *containment() const { return static_cast(m_appletScriptEngine->applet()); } + + QScriptValue applets(); + + void setDrawWallpaper(bool drawWallpaper); + bool drawWallpaper(); + Type containmentType() const; + void setContainmentType(Type type); + int screen() const; + + void setMovableApplets(bool movable); + bool hasMovableApplets() const; + + QString activityName() const; + QString activityId() const; + + Q_INVOKABLE QScriptValue screenGeometry(int id) const; + Q_INVOKABLE QScriptValue availableScreenRegion(int id) const; + +Q_SIGNALS: + void appletAdded(QGraphicsWidget *applet, const QPointF &pos); + void appletRemoved(QGraphicsWidget *applet); + void screenChanged(); + void activityNameChanged(); + void activityIdChanged(); + void availableScreenRegionChanged(); + +protected Q_SLOTS: + void appletAddedForward(Plasma::Applet *applet, const QPointF &pos); + void appletRemovedForward(Plasma::Applet *applet); + +private: + bool m_movableApplets; +}; + #endif diff --git a/scriptengines/javascript/plasmoid/declarativeappletscript.cpp b/scriptengines/javascript/plasmoid/declarativeappletscript.cpp index ca6c9141d..249f5e3c0 100644 --- a/scriptengines/javascript/plasmoid/declarativeappletscript.cpp +++ b/scriptengines/javascript/plasmoid/declarativeappletscript.cpp @@ -46,15 +46,17 @@ #include "plasmoid/declarativeappletscript.h" -#include "engineaccess.h" #include "plasmoid/appletinterface.h" #include "plasmoid/themedsvg.h" #include "common/scriptenv.h" #include "declarative/packageaccessmanagerfactory.h" #include "simplebindings/bytearrayclass.h" +//not pretty but only way to avoid a double Q_DECLARE_METATYPE(QVariant) in dataengine.h +#define DECLARATIVE_BINDING +#include "simplebindings/dataengine.h" #include "simplebindings/dataenginereceiver.h" -#include "simplebindings/i18n.h" + K_EXPORT_PLASMA_APPLETSCRIPTENGINE(declarativeappletscript, DeclarativeAppletScript) @@ -62,10 +64,9 @@ K_EXPORT_PLASMA_APPLETSCRIPTENGINE(declarativeappletscript, DeclarativeAppletScr QScriptValue constructIconClass(QScriptEngine *engine); QScriptValue constructKUrlClass(QScriptEngine *engine); void registerSimpleAppletMetaTypes(QScriptEngine *engine); -void registerNonGuiMetaTypes(QScriptEngine *engine); - DeclarativeAppletScript::DeclarativeAppletScript(QObject *parent, const QVariantList &args) : AbstractJsAppletScript(parent, args), + m_interface(0), m_engine(0), m_env(0), m_auth(this) @@ -81,13 +82,18 @@ bool DeclarativeAppletScript::init() { m_declarativeWidget = new Plasma::DeclarativeWidget(applet()); m_declarativeWidget->setInitializationDelayed(true); + KGlobal::locale()->insertCatalog(description().pluginName()); //make possible to import extensions from the package //FIXME: probably to be removed, would make possible to use native code from within the package :/ //m_declarativeWidget->engine()->addImportPath(package()->path()+"/contents/imports"); - //use our own custom network access manager that will acces Plasma packages and to manage security (i.e. deny access to remote stuff when the proper extension isn't enabled - m_declarativeWidget->engine()->setNetworkAccessManagerFactory(new PackageAccessManagerFactory(package(), &m_auth)); + //use our own custom network access manager that will access Plasma packages and to manage security (i.e. deny access to remote stuff when the proper extension isn't enabled + QDeclarativeEngine *engine = m_declarativeWidget->engine(); + QDeclarativeNetworkAccessManagerFactory *factory = engine->networkAccessManagerFactory(); + engine->setNetworkAccessManagerFactory(0); + delete factory; + engine->setNetworkAccessManagerFactory(new PackageAccessManagerFactory(package(), &m_auth)); m_declarativeWidget->setQmlPath(mainScript()); @@ -102,6 +108,7 @@ bool DeclarativeAppletScript::init() Plasma::Applet *a = applet(); Plasma::PopupApplet *pa = qobject_cast(a); + Plasma::Containment *cont = qobject_cast(a); if (pa) { pa->setPopupIcon(a->icon()); @@ -112,26 +119,30 @@ bool DeclarativeAppletScript::init() lay->addItem(m_declarativeWidget); } - m_interface = pa ? new PopupAppletInterface(this) : new AppletInterface(this); - - m_engineAccess = new EngineAccess(this); - m_declarativeWidget->engine()->rootContext()->setContextProperty("__engineAccess", m_engineAccess); + if (pa) { + m_interface = new PopupAppletInterface(this); + } else if (cont) { + m_interface = new ContainmentInterface(this); + //fail? so it's a normal Applet + } else { + m_interface = new AppletInterface(this); + } connect(applet(), SIGNAL(extenderItemRestored(Plasma::ExtenderItem*)), this, SLOT(extenderItemRestored(Plasma::ExtenderItem*))); connect(applet(), SIGNAL(activate()), this, SLOT(activate())); - //Glorious hack:steal the engine - QDeclarativeExpression *expr = new QDeclarativeExpression(m_declarativeWidget->engine()->rootContext(), m_declarativeWidget->rootObject(), "__engineAccess.setEngine(this)"); - expr->evaluate(); - delete expr; + setupObjects(); return true; } void DeclarativeAppletScript::collectGarbage() { + if (!m_engine) { + return; + } m_engine->collectGarbage(); } @@ -192,6 +203,9 @@ QScriptValue DeclarativeAppletScript::newPlasmaSvg(QScriptContext *context, QScr QScriptValue DeclarativeAppletScript::variantToScriptValue(QVariant var) { + if (!m_engine) { + return QScriptValue(); + } return m_engine->newVariant(var); } @@ -265,6 +279,18 @@ QGraphicsWidget *DeclarativeAppletScript::extractParent(QScriptContext *context, return parent; } +void DeclarativeAppletScript::callPlasmoidFunction(const QString &functionName, const QScriptValueList &args, ScriptEnv *env) +{ + if (!m_env) { + m_env = ScriptEnv::findScriptEnv(m_engine); + } + + if (env) { + QScriptValue func = m_self.property(functionName); + m_env->callFunction(func, args, m_self); + } +} + void DeclarativeAppletScript::constraintsEvent(Plasma::Constraints constraints) { if (constraints & Plasma::FormFactorConstraint) { @@ -294,6 +320,9 @@ void DeclarativeAppletScript::popupEvent(bool popped) void DeclarativeAppletScript::dataUpdated(const QString &name, const Plasma::DataEngine::Data &data) { + if (!m_engine) { + return; + } QScriptValueList args; args << m_engine->toScriptValue(name) << m_engine->toScriptValue(data); @@ -305,6 +334,9 @@ void DeclarativeAppletScript::extenderItemRestored(Plasma::ExtenderItem* item) if (!m_env) { return; } + if (!m_engine) { + return; + } QScriptValueList args; args << m_engine->newQObject(item, QScriptEngine::AutoOwnership, QScriptEngine::PreferExistingWrapperObject); @@ -328,7 +360,9 @@ void DeclarativeAppletScript::executeAction(const QString &name) } const QString func("action_" + name); - m_env->callEventListeners(func); + if (!m_env->callEventListeners(func)) { + callPlasmoidFunction(func, QScriptValueList(), m_env); + } } bool DeclarativeAppletScript::include(const QString &path) @@ -343,10 +377,18 @@ ScriptEnv *DeclarativeAppletScript::scriptEnv() void DeclarativeAppletScript::setupObjects() { - QScriptValue global = m_engine->globalObject(); + m_engine = m_declarativeWidget->scriptEngine(); + if (!m_engine) { + return; + } - m_declarativeWidget->engine()->rootContext()->setContextProperty("__engineAccess", 0); - m_engineAccess->deleteLater(); + connect(m_engine, SIGNAL(signalHandlerException(const QScriptValue &)), + this, SLOT(signalHandlerException(const QScriptValue &))); + + delete m_env; + m_env = new ScriptEnv(this, m_engine); + + QScriptValue global = m_engine->globalObject(); m_self = m_engine->newQObject(m_interface); m_self.setScope(global); @@ -365,24 +407,28 @@ void DeclarativeAppletScript::setupObjects() QScriptValue fun = m_engine->newFunction(DeclarativeAppletScript::loadui); global.setProperty("loadui", fun); - bindI18N(m_engine); + ScriptEnv::registerEnums(global, AppletInterface::staticMetaObject); + global.setProperty("dataEngine", m_engine->newFunction(DeclarativeAppletScript::dataEngine)); global.setProperty("service", m_engine->newFunction(DeclarativeAppletScript::service)); global.setProperty("loadService", m_engine->newFunction(DeclarativeAppletScript::loadService)); //Add stuff from Qt + //TODO: move to libkdeclarative? ByteArrayClass *baClass = new ByteArrayClass(m_engine); global.setProperty("ByteArray", baClass->constructor()); - global.setProperty("QIcon", constructIconClass(m_engine)); - - // Add stuff from KDE libs - qScriptRegisterSequenceMetaType(m_engine); - global.setProperty("Url", constructKUrlClass(m_engine)); // Add stuff from Plasma global.setProperty("Svg", m_engine->newFunction(DeclarativeAppletScript::newPlasmaSvg)); global.setProperty("FrameSvg", m_engine->newFunction(DeclarativeAppletScript::newPlasmaFrameSvg)); global.setProperty("ExtenderItem", m_engine->newFunction(DeclarativeAppletScript::newPlasmaExtenderItem)); + + if (!m_env->importExtensions(description(), m_self, m_auth)) { + return; + } + + registerSimpleAppletMetaTypes(m_engine); + QTimer::singleShot(0, this, SLOT(configChanged())); } QScriptValue DeclarativeAppletScript::dataEngine(QScriptContext *context, QScriptEngine *engine) @@ -400,6 +446,7 @@ QScriptValue DeclarativeAppletScript::dataEngine(QScriptContext *context, QScrip Plasma::DataEngine *dataEngine = interface->dataEngine(dataEngineName); QScriptValue v = engine->newQObject(dataEngine, QScriptEngine::QtOwnership, QScriptEngine::PreferExistingWrapperObject); v.setProperty("connectSource", engine->newFunction(DataEngineReceiver::connectSource)); + v.setProperty("connectAllSources", engine->newFunction(DataEngineReceiver::connectAllSources)); v.setProperty("disconnectSource", engine->newFunction(DataEngineReceiver::disconnectSource)); return v; } @@ -443,65 +490,18 @@ QScriptValue DeclarativeAppletScript::loadService(QScriptContext *context, QScri return engine->newQObject(service, QScriptEngine::AutoOwnership); } -void DeclarativeAppletScript::setEngine(QScriptValue &val) +QList DeclarativeAppletScript::contextualActions() { - if (val.engine() == m_engine) { - return; + if (!m_interface) { + return QList(); } - m_engine = val.engine(); - connect(m_engine, SIGNAL(signalHandlerException(const QScriptValue &)), - this, SLOT(signalHandlerException(const QScriptValue &))); - QScriptValue originalGlobalObject = m_engine->globalObject(); + return m_interface->contextualActions(); +} - QScriptValue newGlobalObject = m_engine->newObject(); - - QString eval = QLatin1String("eval"); - QString version = QLatin1String("version"); - - { - QScriptValueIterator iter(originalGlobalObject); - QVector names; - QVector values; - QVector flags; - while (iter.hasNext()) { - iter.next(); - - QString name = iter.name(); - - if (name == version) { - continue; - } - - if (name != eval) { - names.append(name); - values.append(iter.value()); - flags.append(iter.flags() | QScriptValue::Undeletable); - } - newGlobalObject.setProperty(iter.scriptName(), iter.value()); - - // m_illegalNames.insert(name); - } - - } - - m_engine->setGlobalObject(newGlobalObject); - - delete m_env; - m_env = new ScriptEnv(this, m_engine); - //m_env->addMainObjectProperties(newGlobalObject); - - setupObjects(); - - if (!m_env->importExtensions(description(), m_self, m_auth)) { - return; - } - - qScriptRegisterSequenceMetaType(m_engine); - registerNonGuiMetaTypes(m_engine); - registerSimpleAppletMetaTypes(m_engine); - - QTimer::singleShot(0, this, SLOT(configChanged())); +QScriptEngine *DeclarativeAppletScript::engine() const +{ + return m_engine; } void DeclarativeAppletScript::signalHandlerException(const QScriptValue &exception) diff --git a/scriptengines/javascript/plasmoid/declarativeappletscript.h b/scriptengines/javascript/plasmoid/declarativeappletscript.h index 7de9ee8c4..d1c9d5f65 100644 --- a/scriptengines/javascript/plasmoid/declarativeappletscript.h +++ b/scriptengines/javascript/plasmoid/declarativeappletscript.h @@ -47,11 +47,9 @@ public: DeclarativeAppletScript(QObject *parent, const QVariantList &args); ~DeclarativeAppletScript(); - void setEngine(QScriptValue &val); - QString filePath(const QString &type, const QString &file) const; - void executeAction(const QString &name); + QList contextualActions(); void constraintsEvent(Plasma::Constraints constraints); @@ -59,6 +57,8 @@ public: ScriptEnv *scriptEnv(); + QScriptEngine *engine() const; + QScriptValue variantToScriptValue(QVariant var); static QScriptValue loadui(QScriptContext *context, QScriptEngine *engine); @@ -70,6 +70,7 @@ public: static QScriptValue loadService(QScriptContext *context, QScriptEngine *engine); public Q_SLOTS: + void executeAction(const QString &name); void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data); void signalHandlerException(const QScriptValue &exception); void popupEvent(bool popped); @@ -92,6 +93,7 @@ Q_SIGNALS: void contextChanged(); private: + void callPlasmoidFunction(const QString &functionName, const QScriptValueList &args, ScriptEnv *env); Plasma::DeclarativeWidget *m_declarativeWidget; AppletInterface *m_interface; EngineAccess *m_engineAccess; diff --git a/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp b/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp index 6a7653a92..f879ae94b 100644 --- a/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp +++ b/scriptengines/javascript/plasmoid/simplejavascriptapplet.cpp @@ -100,7 +100,8 @@ KSharedPtr SimpleJavaScriptApplet::s_widgetLoader; QHash SimpleJavaScriptApplet::s_animationDefs; SimpleJavaScriptApplet::SimpleJavaScriptApplet(QObject *parent, const QVariantList &args) - : AbstractJsAppletScript(parent) + : AbstractJsAppletScript(parent), + m_interface(0) { Q_UNUSED(args); // kDebug() << "Script applet launched, args" << applet()->startupArguments(); @@ -231,6 +232,10 @@ void SimpleJavaScriptApplet::paintInterface(QPainter *p, const QStyleOptionGraph QList SimpleJavaScriptApplet::contextualActions() { + if (!m_interface) { + return QList(); + } + return m_interface->contextualActions(); } @@ -309,6 +314,7 @@ bool SimpleJavaScriptApplet::init() this, SLOT(extenderItemRestored(Plasma::ExtenderItem*))); connect(applet(), SIGNAL(activate()), this, SLOT(activate())); + KGlobal::locale()->insertCatalog(description().pluginName()); setupObjects(); AppletAuthorization auth(this); @@ -591,6 +597,7 @@ QScriptValue SimpleJavaScriptApplet::dataEngine(QScriptContext *context, QScript DataEngine *dataEngine = interface->dataEngine(dataEngineName); QScriptValue v = engine->newQObject(dataEngine, QScriptEngine::QtOwnership, QScriptEngine::PreferExistingWrapperObject); v.setProperty("connectSource", engine->newFunction(DataEngineReceiver::connectSource)); + v.setProperty("connectAllSources", engine->newFunction(DataEngineReceiver::connectAllSources)); v.setProperty("disconnectSource", engine->newFunction(DataEngineReceiver::disconnectSource)); return v; } @@ -808,6 +815,11 @@ void SimpleJavaScriptApplet::installWidgets(QScriptEngine *engine) } } +QScriptEngine *SimpleJavaScriptApplet::engine() const +{ + return m_engine; +} + QGraphicsWidget *SimpleJavaScriptApplet::extractParent(QScriptContext *context, QScriptEngine *engine, int argIndex, bool *parentedToApplet) { diff --git a/scriptengines/javascript/plasmoid/simplejavascriptapplet.h b/scriptengines/javascript/plasmoid/simplejavascriptapplet.h index 5e89e16fd..29929dcf7 100644 --- a/scriptengines/javascript/plasmoid/simplejavascriptapplet.h +++ b/scriptengines/javascript/plasmoid/simplejavascriptapplet.h @@ -58,6 +58,8 @@ public: bool eventFilter(QObject *watched, QEvent *event); + QScriptEngine *engine() const; + public Q_SLOTS: void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data); void configChanged(); diff --git a/scriptengines/javascript/simplebindings/backportglobal.h b/scriptengines/javascript/simplebindings/backportglobal.h index 51d66f7ec..1a572499c 100644 --- a/scriptengines/javascript/simplebindings/backportglobal.h +++ b/scriptengines/javascript/simplebindings/backportglobal.h @@ -1,39 +1,20 @@ /**************************************************************************** ** -** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved. +** This file is part of the Qt Script Generator. ** -** This file is part of the plugins of the Qt Toolkit. +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). ** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ +** Contact: Nokia Corporation info@qt.nokia.com ** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** Trolltech ASA (c) 2007 -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** GNU Lesser General Public License Usage +** 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. ** +** Copyright (C) 2011 Nokia. All rights reserved ****************************************************************************/ #ifndef QTSCRIPTEXTENSIONS_GLOBAL_H #define QTSCRIPTEXTENSIONS_GLOBAL_H diff --git a/scriptengines/javascript/simplebindings/dataengine.cpp b/scriptengines/javascript/simplebindings/dataengine.cpp index 98837b2ea..299e00c2f 100644 --- a/scriptengines/javascript/simplebindings/dataengine.cpp +++ b/scriptengines/javascript/simplebindings/dataengine.cpp @@ -54,13 +54,19 @@ void serviceJobFromQScriptValue(const QScriptValue &scriptValue, ServiceJobPtr & serviceJob = static_cast(obj); } +typedef QMap< QString, QString > StringStringMap; +Q_DECLARE_METATYPE(StringStringMap) + void registerDataEngineMetaTypes(QScriptEngine *engine) { qRegisterMetaType("Plasma::DataEngine::Data"); qRegisterMetaType("DataEngine::Data"); - qScriptRegisterMapMetaType(engine); + qScriptRegisterVariantMapMetaType(engine); + qScriptRegisterMapMetaType(engine); qScriptRegisterMetaType(engine, qScriptValueFromService, serviceFromQScriptValue); qScriptRegisterMetaType(engine, qScriptValueFromDataEngine, dataEngineFromQScriptValue); qScriptRegisterMetaType(engine, qScriptValueFromServiceJob, serviceJobFromQScriptValue); + qRegisterMetaType("Service*"); + qRegisterMetaType("ServiceJob*"); } diff --git a/scriptengines/javascript/simplebindings/dataengine.h b/scriptengines/javascript/simplebindings/dataengine.h index 198570666..02fda0124 100644 --- a/scriptengines/javascript/simplebindings/dataengine.h +++ b/scriptengines/javascript/simplebindings/dataengine.h @@ -30,14 +30,29 @@ using namespace Plasma; -Q_DECLARE_METATYPE(Service*) -Q_DECLARE_METATYPE(ServiceJob*) +#ifndef DECLARATIVE_BINDING Q_DECLARE_METATYPE(QVariant) +#endif Q_DECLARE_METATYPE(DataEngine::Dict) Q_DECLARE_METATYPE(DataEngine::Data) template QScriptValue qScriptValueFromMap(QScriptEngine *eng, const M &map) +{ + //kDebug() << "qScriptValueFromMap called"; + QScriptValue obj = eng->newObject(); + typename M::const_iterator begin = map.constBegin(); + typename M::const_iterator end = map.constEnd(); + typename M::const_iterator it; + for (it = begin; it != end; ++it) { + obj.setProperty(it.key(), qScriptValueFromValue(eng, it.value())); + } + + return obj; +} + +template +QScriptValue qScriptValueFromVariantMap(QScriptEngine *eng, const M &map) { //kDebug() << "qScriptValueFromMap called"; QScriptValue obj = eng->newObject(); @@ -68,6 +83,18 @@ void qScriptValueToMap(const QScriptValue &value, M &map) } } +template +int qScriptRegisterVariantMapMetaType( + QScriptEngine *engine, + const QScriptValue &prototype = QScriptValue() +#ifndef qdoc + , T * /* dummy */ = 0 +#endif +) +{ + return qScriptRegisterMetaType(engine, qScriptValueFromVariantMap, qScriptValueToMap, prototype); +} + template int qScriptRegisterMapMetaType( QScriptEngine *engine, diff --git a/scriptengines/javascript/simplebindings/dataenginereceiver.cpp b/scriptengines/javascript/simplebindings/dataenginereceiver.cpp index 034cc5eaf..9d01f9e7a 100644 --- a/scriptengines/javascript/simplebindings/dataenginereceiver.cpp +++ b/scriptengines/javascript/simplebindings/dataenginereceiver.cpp @@ -86,24 +86,10 @@ DataEngineReceiver *DataEngineReceiver::getReceiver(Plasma::DataEngine *dataEngi return 0; } -QScriptValue DataEngineReceiver::connectSource(QScriptContext *context, QScriptEngine *engine) +QObject *DataEngineReceiver::extractTargetQObject(QScriptEngine *engine, const QString &source, const QScriptValue &v, Plasma::DataEngine *dataEngine) { - if (context->argumentCount() < 2) { - return engine->undefinedValue(); - } - - DataEngine *dataEngine = qobject_cast(context->thisObject().toQObject()); - if (!dataEngine) { - return engine->undefinedValue(); - } - - const QString source = context->argument(0).toString(); - if (source.isEmpty()) { - return engine->undefinedValue(); - } - QObject *obj = 0; - QScriptValue v = context->argument(1); + // if it's a function we get, then use that directly // next see if it is a qobject with a good slot; if it is then use that directly // otherwise, try to use the object with a dataUpdated method call @@ -127,6 +113,56 @@ QScriptValue DataEngineReceiver::connectSource(QScriptContext *context, QScriptE } } + return obj; +} + +QScriptValue DataEngineReceiver::connectAllSources(QScriptContext *context, QScriptEngine *engine) +{ + if (context->argumentCount() < 1) { + return engine->undefinedValue(); + } + + DataEngine *dataEngine = qobject_cast(context->thisObject().toQObject()); + if (!dataEngine) { + return engine->undefinedValue(); + } + + int pollingInterval = 0; + Plasma::IntervalAlignment intervalAlignment = Plasma::NoAlignment; + if (context->argumentCount() > 1) { + pollingInterval = context->argument(2).toInt32(); + + if (context->argumentCount() > 2) { + intervalAlignment = static_cast(context->argument(4).toInt32()); + } + } + + QObject *obj = extractTargetQObject(engine, QString(), context->argument(0), dataEngine); + if (!obj) { + return engine->undefinedValue(); + } + + dataEngine->connectAllSources(obj, pollingInterval, intervalAlignment); + return true; +} + +QScriptValue DataEngineReceiver::connectSource(QScriptContext *context, QScriptEngine *engine) +{ + if (context->argumentCount() < 2) { + return engine->undefinedValue(); + } + + DataEngine *dataEngine = qobject_cast(context->thisObject().toQObject()); + if (!dataEngine) { + return engine->undefinedValue(); + } + + const QString source = context->argument(0).toString(); + if (source.isEmpty()) { + return engine->undefinedValue(); + } + + QObject *obj = extractTargetQObject(engine, source, context->argument(1), dataEngine); if (!obj) { return engine->undefinedValue(); } diff --git a/scriptengines/javascript/simplebindings/dataenginereceiver.h b/scriptengines/javascript/simplebindings/dataenginereceiver.h index b1559d8e6..f1f2a426c 100644 --- a/scriptengines/javascript/simplebindings/dataenginereceiver.h +++ b/scriptengines/javascript/simplebindings/dataenginereceiver.h @@ -36,6 +36,7 @@ public: bool isValid() const; static QScriptValue connectSource(QScriptContext *context, QScriptEngine *engine); + static QScriptValue connectAllSources(QScriptContext *context, QScriptEngine *engine); static QScriptValue disconnectSource(QScriptContext *context, QScriptEngine *engine); static QSet s_receivers; @@ -46,6 +47,7 @@ public Q_SLOTS: private: static DataEngineReceiver *getReceiver(Plasma::DataEngine *dataEngine, const QString &source, const QScriptValue &v); + static QObject *extractTargetQObject(QScriptEngine *engine, const QString &source, const QScriptValue &v, Plasma::DataEngine *dataEngine); const Plasma::DataEngine *m_engine; const QString m_source; diff --git a/scriptengines/javascript/simplebindings/i18n.cpp b/scriptengines/javascript/simplebindings/i18n.cpp index 97502da98..2210a1930 100644 --- a/scriptengines/javascript/simplebindings/i18n.cpp +++ b/scriptengines/javascript/simplebindings/i18n.cpp @@ -2,7 +2,7 @@ * Copyright 2009 Aaron Seigo * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as + * 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. * diff --git a/scriptengines/javascript/simplebindings/i18n.h b/scriptengines/javascript/simplebindings/i18n.h index 48f9cbba5..5644a0dff 100644 --- a/scriptengines/javascript/simplebindings/i18n.h +++ b/scriptengines/javascript/simplebindings/i18n.h @@ -2,7 +2,7 @@ * Copyright 2009 Aaron Seigo * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as + * 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. * diff --git a/scriptengines/javascript/simplebindings/icon.cpp b/scriptengines/javascript/simplebindings/icon.cpp index 0b5a5f7f9..62055a571 100644 --- a/scriptengines/javascript/simplebindings/icon.cpp +++ b/scriptengines/javascript/simplebindings/icon.cpp @@ -92,7 +92,6 @@ QScriptValue constructIconClass(QScriptEngine *eng) { QScriptValue proto = qScriptValueFromValue(eng, QIcon()); QScriptValue::PropertyFlags getter = QScriptValue::PropertyGetter; - QScriptValue::PropertyFlags setter = QScriptValue::PropertySetter; proto.setProperty("addPixmap", eng->newFunction(addPixmap)); proto.setProperty("addFile", eng->newFunction(addFile)); proto.setProperty("null", eng->newFunction(isNull), getter); diff --git a/scriptengines/javascript/simplebindings/pixmap.cpp b/scriptengines/javascript/simplebindings/pixmap.cpp index b1f47a3a7..0719dc7d5 100644 --- a/scriptengines/javascript/simplebindings/pixmap.cpp +++ b/scriptengines/javascript/simplebindings/pixmap.cpp @@ -68,7 +68,6 @@ QScriptValue constructQPixmapClass(QScriptEngine *eng) { QScriptValue proto = qScriptValueFromValue(eng, QPixmap()); QScriptValue::PropertyFlags getter = QScriptValue::PropertyGetter; - QScriptValue::PropertyFlags setter = QScriptValue::PropertySetter; proto.setProperty("null", eng->newFunction(null), getter); proto.setProperty("rect", eng->newFunction(rect), getter); proto.setProperty("scaled", eng->newFunction(scaled)); diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 575dea7b8..555096d88 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(plasmapkg) +add_subdirectory(plasma-remote-helper) diff --git a/tools/plasma-remote-helper/CMakeLists.txt b/tools/plasma-remote-helper/CMakeLists.txt new file mode 100644 index 000000000..c2eddb20a --- /dev/null +++ b/tools/plasma-remote-helper/CMakeLists.txt @@ -0,0 +1,10 @@ +set(plasma_remote_helper_SRCS + main.cpp +) + +kde4_add_executable(plasma-remote-helper ${plasma_remote_helper_SRCS}) + +target_link_libraries(plasma-remote-helper ${KDE4_KDEUI_LIBS}) + +install(TARGETS plasma-remote-helper ${INSTALL_TARGETS_DEFAULT_ARGS}) + diff --git a/tools/plasma-remote-helper/Messages.sh b/tools/plasma-remote-helper/Messages.sh new file mode 100755 index 000000000..7b98af468 --- /dev/null +++ b/tools/plasma-remote-helper/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT *.cpp -o $podir/plasma-remote-helper.pot diff --git a/tools/plasma-remote-helper/main.cpp b/tools/plasma-remote-helper/main.cpp new file mode 100644 index 000000000..cda83ab0c --- /dev/null +++ b/tools/plasma-remote-helper/main.cpp @@ -0,0 +1,81 @@ +/* Copyright 2011 Kevin Ottens + + 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, + 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 + +#include +#include + +#include +#include +#include + +static const char description[] = I18N_NOOP("Trigger the installation of a remote Plasma Widget"); +static const char version[] = "0.1"; + +int addRemotePlasmoidToShell(const QString &shellName, const QString &url) +{ + QString serviceName = "org.kde." + shellName; + QDBusInterface iface(serviceName, "/App"); + + if (!iface.isValid()) { + std::cerr << "Error: Couldn't contact " + << shellName.toLocal8Bit().constData() << std::endl; + return 1; + } else { + QDBusReply reply = iface.call("addRemotePlasmoid", url); + if (!reply.isValid()) { + std::cerr << "Error: Couldn't call addRemotePlasmoid on " + << shellName.toLocal8Bit().constData() << std::endl; + return 1; + } + } + + return 0; +} + +int main(int argc, char **argv) +{ + KAboutData aboutData("plasma-remote-helper", 0, ki18n("Plasma Remote Widget Helper"), + version, ki18n(description), KAboutData::License_GPL, + ki18n("(C) 2011 Kevin Ottens")); + aboutData.addAuthor( ki18n("Kevin Ottens"), + ki18n("Original author"), + "ervin@kde.org" ); + + KComponentData componentData(aboutData); + + KCmdLineArgs::init( argc, argv, &aboutData ); + + KCmdLineOptions options; + options.add("+", ki18n("URL to the Plasma Remote Widget.")); + KCmdLineArgs::addCmdLineOptions( options ); + + KApplication app; + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + if (args->count()<1) { + KCmdLineArgs::usageError(i18n("Syntax Error: Not enough arguments")); + } else if (args->count()>1) { + KCmdLineArgs::usageError(i18n("Syntax Error: Too many arguments")); + } + + QString url = args->arg(0); + return addRemotePlasmoidToShell("plasma-desktop", url); +} + diff --git a/tools/plasmapkg/main.cpp b/tools/plasmapkg/main.cpp index a113a1b74..b4241eceb 100644 --- a/tools/plasmapkg/main.cpp +++ b/tools/plasmapkg/main.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include @@ -74,41 +75,93 @@ void listPackages(const QStringList& types) } } +void renderTypeTable(const QMap &plugins) +{ + const QString nameHeader = i18n("Addon Name"); + const QString pluginHeader = i18n("Service Type"); + const QString pathHeader = i18n("Path"); + int nameWidth = nameHeader.length(); + int pluginWidth = pluginHeader.length(); + int pathWidth = pathHeader.length(); + + QMapIterator pluginIt(plugins); + while (pluginIt.hasNext()) { + pluginIt.next(); + if (pluginIt.key().length() > nameWidth) { + nameWidth = pluginIt.key().length(); + } + + if (pluginIt.value()[0].length() > pluginWidth) { + pluginWidth = pluginIt.value()[0].length(); + } + + if (pluginIt.value()[1].length() > pathWidth) { + pathWidth = pluginIt.value()[1].length(); + } + } + + std::cout << nameHeader.toLocal8Bit().constData() << std::setw(nameWidth - nameHeader.length() + 2) << ' ' + << pluginHeader.toLocal8Bit().constData() << std::setw(pluginWidth - pluginHeader.length() + 2) << ' ' + << pathHeader.toLocal8Bit().constData() << std::endl; + std::cout << std::setfill('-') << std::setw(nameWidth) << '-' << " " + << std::setw(pluginWidth) << '-' << " " + << std::setw(pathWidth) << '-' << std::endl; + std::cout << std::setfill(' '); + + pluginIt.toFront(); + while (pluginIt.hasNext()) { + pluginIt.next(); + std::cout << pluginIt.key().toLocal8Bit().constData() << std::setw(nameWidth - pluginIt.key().length() + 2) << ' ' + << pluginIt.value()[0].toLocal8Bit().constData() << std::setw(pluginWidth - pluginIt.value()[0].length() + 2) << ' ' + << pluginIt.value()[1].toLocal8Bit().constData() << std::endl; + } +} + void listTypes() { output(i18n("Package types that are installable with this tool:")); output(i18n("Built in:")); - output(i18n(" dataengine: Plasma DataEngine plugin")); - output(i18n(" layout-template: Plasma containment and widget layout script")); - output(i18n(" plasmoid: Plasma widget")); - output(i18n(" runner: Search plugin (KRunner, etc)")); - output(i18n(" theme: Plasma SVG theme")); - output(i18n(" wallpaper: Image pack for use with wallpaper backgrounds")); - output(i18n(" wallpaperplugin: Wallpaper plugin")); + + QMap builtIns; + builtIns.insert(i18n("DataEngine"), QStringList() << "Plasma/DataEngine" << "plasma/dataengines/"); + builtIns.insert(i18n("Layout Template"), QStringList() << "Plasma/LayoutTemplate" << "plasma/layout-templates/"); + builtIns.insert(i18n("Plasmoid"), QStringList() << "Plasma/Applet" << "plasma/plasmoids/"); + builtIns.insert(i18n("Runner"), QStringList() << "Plasma/Runner" << "plasma/runners/"); + builtIns.insert(i18n("Theme"), QStringList() << "" << "desktoptheme/"); + builtIns.insert(i18n("Wallpaper Images"), QStringList() << "" << "wallpapers/"); + builtIns.insert(i18n("Wallpaper Plugin"), QStringList() << "Plasma/Wallpaper" << "plasma/wallpapers/"); + renderTypeTable(builtIns); KService::List offers = KServiceTypeTrader::self()->query("Plasma/PackageStructure"); if (!offers.isEmpty()) { std::cout << std::endl; output(i18n("Provided by plugins:")); + + QMap plugins; foreach (const KService::Ptr service, offers) { KPluginInfo info(service); - output(i18nc("Plugin name and the kind of Plasma related content it provides, both from the plugin's desktop file", - " %1: %2", info.pluginName(), info.name())); + Plasma::PackageStructure::Ptr structure = Plasma::PackageStructure::load(info.pluginName()); + QString name = info.name(); + QString plugin = info.pluginName(); + QString path = structure->defaultPackageRoot(); + plugins.insert(name, QStringList() << plugin << path); } + + renderTypeTable(plugins); } QStringList desktopFiles = KGlobal::dirs()->findAllResources("data", "plasma/packageformats/*rc", KStandardDirs::NoDuplicates); if (!desktopFiles.isEmpty()) { output(i18n("Provided by .desktop files:")); Plasma::PackageStructure structure; + QMap plugins; foreach (const QString &file, desktopFiles) { // extract the type KConfig config(file, KConfig::SimpleConfig); structure.read(&config); // get the name based on the rc file name, just as Plasma::PackageStructure does const QString name = file.left(file.length() - 2); - output(i18nc("Plugin name and the kind of Plasma related content it provides, both from the plugin's desktop file", - " %1: %2", name, structure.type())); + plugins.insert(name, QStringList() << structure.type() << structure.defaultPackageRoot()); } } }