diff --git a/.directory b/.directory new file mode 100644 index 0000000..4af099d --- /dev/null +++ b/.directory @@ -0,0 +1,6 @@ +[Dolphin] +Timestamp=2015,1,16,11,10,3 +Version=3 + +[Settings] +HiddenFilesShown=true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..23c6b7b --- /dev/null +++ b/.gitignore @@ -0,0 +1,21 @@ +# Ignore hidden files +.directory + +# build directory +build/ + +# backup files +*.qml~ +*.xml~ +*.js~ +*.sh~ +*.desktop~ +*.kate-swp +.~* + +# mo files +*.mo + +# KDevelop Project files +*.kdev4 +.kdev4/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..aeab9e8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,18 @@ +project(PlayBar) + +find_package(KDE4 REQUIRED) + +include(KDE4Defaults) + +add_subdirectory( plasmoid ) +add_subdirectory( engine ) + +execute_process(COMMAND ./messages.sh -compile-po + OUTPUT_VARIABLE out_messages + WORKING_DIRECTORY ${CMAKE_HOME_DIRECTORY}) + +message(${out_messages}) + +#This is not yet implemented +#add_subdirectory( kcm_shortcuts ) + diff --git a/LICENSE b/LICENSE index 6b156fe..ebcb39e 100644 --- a/LICENSE +++ b/LICENSE @@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: - {project} Copyright (C) {year} {fullname} + PlayBar2 Copyright (C) 2015 Johan Smith AR This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. diff --git a/engine/#playbarengine.cpp# b/engine/#playbarengine.cpp# new file mode 100644 index 0000000..f630f9d --- /dev/null +++ b/engine/#playbarengine.cpp# @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2014 smith AR + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "playbarengine.h" +#include "service.h" + +#include +#include + +using Plasma::DataContainer; +using Plasma::DataEngineManager; + +PlayBarEngine::PlayBarEngine(QObject* parent, const QVariantList& args) + : DataEngine(parent, args) +{ + Q_UNUSED(args) + setMinimumPollingInterval(-1); +} + + +PlayBarEngine::~PlayBarEngine() +{ + +} + +Service* PlayBarEngine::serviceForSource(const QString& source) +{ + if (source != "Provider") + return createDefaultService(this); + + updateSourceEvent(source); + return new PlayBarService(mpris2_data, this); +} + +void PlayBarEngine::init() +{ + DataEngineManager* engine = DataEngineManager::self(); + mpris2 = engine->loadEngine("mpris2"); + + return updateSourceEvent(source); +} + +bool PlayBarEngine::updateSourceEvent(const QString& source) +{ + const Data* data = &mediaActions->actions(); + + setData(source, *data); + setData(source, "Mpris2Source", p_mpris2Source); + setData(source, "PlaybackStatus", playbackStat()); + setData(source, "Metadata", mpris2_data.value("Metadata").toMap()); + + delete data; data = 0; + return true; +} + +void PlayBarEngine::startOpOverMpris2(const QString& name) +{ + serv = mpris2->serviceForSource(p_mpris2Source); + op = serv->operationDescription(name); + job = serv->startOperationCall(op); + connect(job, SIGNAL(finished(KJob*)), serv, SLOT(deleteLater())); +} + +QString PlayBarEngine::p_mpris2Source; + +K_EXPORT_PLASMA_DATAENGINE(playbarengine, PlayBarEngine) + +#include "playbarengine.moc" +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/.~CMakeLists.txt b/engine/.~CMakeLists.txt new file mode 100644 index 0000000..4767c92 --- /dev/null +++ b/engine/.~CMakeLists.txt @@ -0,0 +1,36 @@ +project(PlayBarEngine) + +find_package(KDE4 REQUIRED) +#find_package(Taglib 1.8) + +include(KDE4Defaults) +include(MacroLibrary) + +add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${KDE4_INCLUDES} + ${QT_INCLUDES} +# ${TAGLIB_INCLUDES} + ) + +# We add our source code here +set(playbar_engine_SRCS shortcuts.cpp service.cpp playbarengine.cpp) + +# Now make sure all files get to the right place +kde4_add_plugin(plasma_engine_playbar ${playbar_engine_SRCS}) + +target_link_libraries(plasma_engine_playbar + ${KDE4_KDECORE_LIBS} + ${KDE4_PLASMA_LIBS} + ${TAGLIBS}) + +install(TARGETS plasma_engine_playbar + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-engine-playbar.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES playbarservice.operations + DESTINATION ${DATA_INSTALL_DIR}/plasma/services) diff --git a/engine/.~filetype.cpp b/engine/.~filetype.cpp new file mode 100644 index 0000000..f5c6096 --- /dev/null +++ b/engine/.~filetype.cpp @@ -0,0 +1,91 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#include "filetype.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef TAGLIB_WITH_MP4 +#include +#endif + +namespace MediaFiles +{ +static const QLatin1String flacType("audio/flac"); +static const QLatin1String mp3Type("audio/mpeg"); +#ifdef TAGLIB_WITH_MP4 +static const QLatin1String mp4Type("audio/mp4"); +#endif +static const QLatin1String mpcType("audio/x-musepack"); +static const QLatin1String oggType("audio/ogg"); +static const QLatin1String oggFlacType("audio/x-flac+ogg"); +static const QLatin1String oggVorbisType("audio/x-vorbis+ogg"); +static const QLatin1String vorbisType("audio/vorbis"); +} + +File* FileType::createFile(const QString& fileName) +{ + QUrl url(fileName); + if(!url.isLocalFile()) return 0; + + KMimeType::Ptr mime = KMimeType::findByUrl(url.toLocalFile()); + if (!mime->isValid()) return 0; + + File* file(0); + QByteArray encodedFileName(QFile::encodeName(url.toLocalFile())); + + if (mime->is(MediaFiles::flacType)) + file = new FLAC::File(encodedFileName.constData()); + else if (mime->is(MediaFiles::mp3Type)) + file = new MPEG::File(encodedFileName.constData()); + else if (mime->is(MediaFiles::mpcType)) + file = new MPC::File(encodedFileName.constData()); + else if (mime->is(MediaFiles::oggFlacType) || + mime->is(MediaFiles::vorbisType)) + file = new Ogg::FLAC::File(encodedFileName.constData(), AudioProperties::Accurate); + else if (mime->is(MediaFiles::oggVorbisType)) + file = new Ogg::Vorbis::File(encodedFileName.constData(), true, AudioProperties::Accurate); +#ifdef TAGLIB_WITH_MP4 + else if (mime->is(MediaFiles::mp4Type)) + file = new MP4::File(encodedFileName.constData()); +#endif + + if( !file ) + qDebug() << QString( "FileTypeResolver: file %1 (mimetype %2) not" "recognized as compatible" ).arg(fileName, +mime->name()).toLocal8Bit().data(); + + if(file && !file->isValid()){ + delete file; + file = 0; + } + return file; + +} +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/.~service.cpp b/engine/.~service.cpp new file mode 100644 index 0000000..a9c49c2 --- /dev/null +++ b/engine/.~service.cpp @@ -0,0 +1,70 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "service.h" +#include "playbarengine.h" + +PlayBarService::PlayBarService(const DataEngine::Data& data, QObject* parent) + : Service(parent), data(data) +{ + setName("playbarservice"); +} + +ServiceJob* PlayBarService::createJob(const QString& operation, + QMap< QString, QVariant >& parameters) +{ + setDestination(name() + ": " + operation); + parameters.insert("Metadata", data.value("Metadata")); + + return new Job(destination(), operation, parameters, this); +} + +Job::Job(const QString& destination, + const QString& operation, + const QMap< QString, QVariant >& parameters, + QObject* parent): + ServiceJob(destination, operation, parameters, parent) +{ +} + +void Job::start() +{ + const QString operation(operationName()); + + bool result = false; + + if (operation == QLatin1String("SetSource")) { + PlayBarEngine::p_mpris2Source = parameters().value("name").toString(); + result = true; + } + // TODO: Implementar el tagger para el rating + else if (operation == QLatin1String("SetRating")) { + const QVariantMap metadata(parameters().value("Metadata").toMap()); + + if (metadata.isEmpty()) qDebug() << "metadata isEmpty"; + // result = setRating(metadata.value("xesam:url").toString(), parameters().value("rating", "0").toString()); + } + + setResult(result); +} + + +#include "service.moc" +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/.~service.h b/engine/.~service.h new file mode 100644 index 0000000..cb1b101 --- /dev/null +++ b/engine/.~service.h @@ -0,0 +1,67 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef SERVICE_H +#define SERVICE_H + +#include +#include +#include + +#include +#include + +using Plasma::Service; +using Plasma::ServiceJob; +using Plasma::DataEngine; + + +class PlayBarService : public Service +{ + Q_OBJECT + +public: + explicit PlayBarService(const DataEngine::Data& data, QObject* parent); + + const DataEngine::Data &data; + +protected: + virtual ServiceJob* createJob(const QString& operation, + QMap< QString, QVariant >& parameters); +}; + +class Job : public ServiceJob +{ +public: + + Job(const QString& destination, + const QString& operation, + const QMap< QString, QVariant >& parameters, + QObject* parent = 0); + + virtual void start(); + +private: + + bool setRating(const QString& url, const QString& rating); +}; + +#endif // SERVICE_H +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/.~shortcuts.cpp b/engine/.~shortcuts.cpp new file mode 100644 index 0000000..50b167f --- /dev/null +++ b/engine/.~shortcuts.cpp @@ -0,0 +1,160 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#include "shortcuts.h" +#include + +Shortcuts::Shortcuts(PlayBarEngine* engine): + QObject(), mediaActions(this) +{ + playbarEngine = engine; + + KAction* previous = + createAction("Previous", Qt::Key_MediaPrevious); + KAction* pause = + createAction("Pause", Qt::Key_MediaPause); + KAction* play = + createAction("Play", Qt::Key_MediaPlay); + KAction* stop = + createAction("Stop", Qt::Key_MediaStop); + KAction* play_pause = + createAction("PlayPause", Qt::Key_MediaTogglePlayPause); + KAction* next = + createAction("Next", Qt::Key_MediaNext); + KAction* open = + createAction("Open"); + KAction* quit = + createAction("Quit"); + + mediaActions.setConfigGlobal(true); + mediaActions.setConfigGroup("PlayBar"); + + connect(play_pause, SIGNAL(triggered(bool)), this, SLOT(playpause())); + connect(play, SIGNAL(triggered(bool)), this, SLOT(play())); + connect(pause, SIGNAL(triggered(bool)), this, SLOT(pause())); + connect(stop, SIGNAL(triggered(bool)), this, SLOT(stop())); + connect(next, SIGNAL(triggered(bool)), this, SLOT(next())); + connect(previous, SIGNAL(triggered(bool)), this, SLOT(previous())); + connect(open, SIGNAL(triggered(bool)), this, SLOT(open())); + connect(quit, SIGNAL(triggered(bool)), this, SLOT(quit())); +} + +KAction* Shortcuts::createAction(const char* name) +{ + QString text; + if (strcmp(name, "PlayPause") == 0) + text = ki18n("Play").toString() + '/' + ki18n("Pause").toString(); + else text = ki18n(name).toString(); + + KAction* action = new KAction("PlayBar: " + text, 0); + action->setObjectName(name); + action->setParent(&mediaActions); + action->setGlobalShortcut(KShortcut()); + mediaActions.addAction(text, action); + + return action; +} + +KAction* Shortcuts::createAction(const char* name, Qt::Key key) +{ + KAction* action = createAction(name); + action->setGlobalShortcut(KShortcut(key)); + return action; +} + +const Plasma::DataEngine::Data& Shortcuts::actions() const +{ + QList actions(mediaActions.actions()); + QList::const_iterator it = actions.constBegin(); + + Plasma::DataEngine::Data* data = new Plasma::DataEngine::Data(); + + while (it != actions.constEnd()) { + const QString globalShortcut((static_cast(*it))->globalShortcut().toString()); + const QString text = (*it)->text(); + data->insert(text , globalShortcut); + ++it; + } + return *data; +} + + +//SLOTS +void Shortcuts::playpause() +{ + const bool playing = playbarEngine->playbackStat() == QLatin1String("Playing"); + + if (PlayBarEngine::p_mpris2Source == "spotify") { + playbarEngine->startOpOverMpris2("PlayPause"); + return; + } + if (playing) playbarEngine->startOpOverMpris2("PlayPause"); + else playbarEngine->startOpOverMpris2("Play"); + +} + +void Shortcuts::play() +{ + const bool playing = playbarEngine->playbackStat() == QLatin1String("Playing"); + + if (PlayBarEngine::p_mpris2Source == "spotify" && !playing) + playbarEngine->startOpOverMpris2("PlayPause"); + else if (!playing) playbarEngine->startOpOverMpris2("Play"); +} + +void Shortcuts::pause() +{ + const bool playing = playbarEngine->playbackStat() == QLatin1String("Playing"); + + if (PlayBarEngine::p_mpris2Source == "spotify" && playing) + playbarEngine->startOpOverMpris2("Play"); + else if (playing) + playbarEngine->startOpOverMpris2("Pause"); +} + +void Shortcuts::stop() +{ + const bool stopped = playbarEngine->playbackStat() == QLatin1String("Stopped"); + + // if (!stopped) + playbarEngine->startOpOverMpris2("Stop"); +} + +void Shortcuts::next() +{ + playbarEngine->startOpOverMpris2("Next"); +} + +void Shortcuts::previous() +{ + playbarEngine->startOpOverMpris2("Previous"); +} + +void Shortcuts::open() +{ + playbarEngine->startOpOverMpris2("Raise"); +} + +void Shortcuts::quit() +{ + playbarEngine->startOpOverMpris2("Quit"); +} + +#include "shortcuts.moc" +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt new file mode 100644 index 0000000..2fd5ba3 --- /dev/null +++ b/engine/CMakeLists.txt @@ -0,0 +1,37 @@ +project(PlayBarEngine) + +find_package(KDE4 REQUIRED) +#find_package(Taglib 1.8) + +include(KDE4Defaults) +include(MacroLibrary) + +add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS}) +include_directories( + ${CMAKE_SOURCE_DIR} + ${CMAKE_BINARY_DIR} + ${KDE4_INCLUDES} + ${QT_INCLUDES} +# ${TAGLIB_INCLUDES} + ) + +# We add our source code here +set(playbar_engine_SRCS shortcuts.cpp service.cpp playbarengine.cpp) + +# Now make sure all files get to the right place +kde4_add_plugin(plasma_engine_playbar ${playbar_engine_SRCS}) + +target_link_libraries(plasma_engine_playbar + ${KDE4_KDECORE_LIBS} + ${KDE4_PLASMA_LIBS} + #${TAGLIBS} + ) + +install(TARGETS plasma_engine_playbar + DESTINATION ${PLUGIN_INSTALL_DIR}) + +install(FILES plasma-engine-playbar.desktop + DESTINATION ${SERVICES_INSTALL_DIR}) + +install(FILES playbarservice.operations + DESTINATION ${DATA_INSTALL_DIR}/plasma/services) diff --git a/engine/filetype.cpp b/engine/filetype.cpp new file mode 100644 index 0000000..1e4dac6 --- /dev/null +++ b/engine/filetype.cpp @@ -0,0 +1,92 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#include "filetype.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#ifdef TAGLIB_WITH_MP4 +#include +#endif + + +namespace MediaFiles +{ +static const QLatin1String flacType("audio/flac"); +static const QLatin1String mp3Type("audio/mpeg"); +#ifdef TAGLIB_WITH_MP4 +static const QLatin1String mp4Type("audio/mp4"); +#endif +static const QLatin1String mpcType("audio/x-musepack"); +static const QLatin1String oggType("audio/ogg"); +static const QLatin1String oggFlacType("audio/x-flac+ogg"); +static const QLatin1String oggVorbisType("audio/x-vorbis+ogg"); +static const QLatin1String vorbisType("audio/vorbis"); +} + +File* FileType::createFile(const QString& fileName) +{ + QUrl url(fileName); + if(!url.isLocalFile()) return 0; + + KMimeType::Ptr mime = KMimeType::findByUrl(url.toLocalFile()); + if (!mime->isValid()) return 0; + + File* file(0); + QByteArray encodedFileName(QFile::encodeName(url.toLocalFile())); + + if (mime->is(MediaFiles::flacType)) + file = new FLAC::File(encodedFileName.constData()); + else if (mime->is(MediaFiles::mp3Type)) + file = new MPEG::File(encodedFileName.constData()); + else if (mime->is(MediaFiles::mpcType)) + file = new MPC::File(encodedFileName.constData()); + else if (mime->is(MediaFiles::oggFlacType) || + mime->is(MediaFiles::vorbisType)) + file = new Ogg::FLAC::File(encodedFileName.constData(), AudioProperties::Accurate); + else if (mime->is(MediaFiles::oggVorbisType)) + file = new Ogg::Vorbis::File(encodedFileName.constData(), true, AudioProperties::Accurate); +#ifdef TAGLIB_WITH_MP4 + else if (mime->is(MediaFiles::mp4Type)) + file = new MP4::File(encodedFileName.constData()); +#endif + + if( !file ) + qDebug() << QString( "FileTypeResolver: file %1 (mimetype %2) not" "recognized as compatible" ).arg(fileName, +mime->name()).toLocal8Bit().data(); + + if(file && !file->isValid()){ + delete file; + file = 0; + } + return file; + +} +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/filetype.h b/engine/filetype.h new file mode 100644 index 0000000..b574938 --- /dev/null +++ b/engine/filetype.h @@ -0,0 +1,37 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#ifndef FILETYPE_H +#define FILETYPE_H + +#include +#include +#include + +using namespace TagLib; + +namespace MediaFiles{} + +class FileType +{ +public: + static TagLib::File *createFile(const QString& fileName); +}; + +#endif // FILETYPE_H diff --git a/engine/plasma-engine-playbar.desktop b/engine/plasma-engine-playbar.desktop new file mode 100644 index 0000000..d88efbf --- /dev/null +++ b/engine/plasma-engine-playbar.desktop @@ -0,0 +1,21 @@ +[Desktop Entry] +Name=PlayBar provider +Icon=media-playback-start +Comment=Adds support for keyboard shortcuts and provide others services +Type=Service + +X-KDE-Library=plasma_engine_playbar +X-KDE-ServiceTypes=Plasma/DataEngine +X-Plasma-EngineName=playbarengine + +X-KDE-PluginInfo-Author=Smith AR +X-KDE-PluginInfo-Category=Multimedia +X-KDE-PluginInfo-Depends= +X-KDE-PluginInfo-Email=audoban@openmailbox.org +X-KDE-PluginInfo-EnabledByDefault=true +X-KDE-PluginInfo-License=LGPL +X-KDE-PluginInfo-Name=playbarengine +X-KDE-PluginInfo-Version=0.7 +X-KDE-PluginInfo-Website=https://github.com/audoban/PlayBar + +#X-KDE-ParentApp=PlayBar diff --git a/engine/playbarengine.cpp b/engine/playbarengine.cpp new file mode 100644 index 0000000..3305b94 --- /dev/null +++ b/engine/playbarengine.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2014 smith AR + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "playbarengine.h" +#include "service.h" + +#include +#include + +using Plasma::DataContainer; +using Plasma::DataEngineManager; + +PlayBarEngine::PlayBarEngine(QObject* parent, const QVariantList& args) + : DataEngine(parent, args) +{ + Q_UNUSED(args) + setMinimumPollingInterval(-1); +} + + +PlayBarEngine::~PlayBarEngine() +{ + +} + +Service* PlayBarEngine::serviceForSource(const QString& source) +{ + if (source != "Provider") + return createDefaultService(this); + + updateSourceEvent(source); + return new PlayBarService(mpris2_data, this); +} + +void PlayBarEngine::init() +{ + DataEngineManager* engine = DataEngineManager::self(); + mpris2 = engine->loadEngine("mpris2"); +} + +bool PlayBarEngine::sourceRequestEvent(const QString& source) +{ + if (source != "Provider") return false; + mediaActions = new Shortcuts(this); + return updateSourceEvent(source); +} + +bool PlayBarEngine::updateSourceEvent(const QString& source) +{ + const Data* data = &mediaActions->actions(); + + setData(source, *data); + setData(source, "Mpris2Source", p_mpris2Source); + setData(source, "PlaybackStatus", playbackStat()); + setData(source, "Metadata", mpris2_data.value("Metadata").toMap()); + + delete data; data = 0; + return true; +} + +void PlayBarEngine::startOpOverMpris2(const QString& name) +{ + serv = mpris2->serviceForSource(p_mpris2Source); + op = serv->operationDescription(name); + job = serv->startOperationCall(op); + connect(job, SIGNAL(finished(KJob*)), serv, SLOT(deleteLater())); +} + +QString PlayBarEngine::p_mpris2Source; + +K_EXPORT_PLASMA_DATAENGINE(playbarengine, PlayBarEngine) + +#include "playbarengine.moc" +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/playbarengine.h b/engine/playbarengine.h new file mode 100644 index 0000000..7f05d4e --- /dev/null +++ b/engine/playbarengine.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2014 smith AR + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef PLAYBARENGINE_H +#define PLAYBARENGINE_H + +#include +#include +#include +#include + +#include "shortcuts.h" + +#include + +using Plasma::Service; + +class Shortcuts; + +class PlayBarEngine : public Plasma::DataEngine +{ + Q_OBJECT + +public: + PlayBarEngine(QObject* parent, const QVariantList& args); + virtual ~PlayBarEngine(); + + virtual Service* serviceForSource(const QString& source); + + static QString p_mpris2Source; + Plasma::DataEngine::Data mpris2_data; + + // Playing status + QString playbackStat() { + mpris2_data = mpris2->query(p_mpris2Source); + return mpris2_data.value("PlaybackStatus", "").toString(); + }; + + // Do a operation over plasma mpris2 engine + void startOpOverMpris2(const QString& name); + +protected: + virtual void init(); + virtual bool sourceRequestEvent(const QString& source); + virtual bool updateSourceEvent(const QString& source); + +private: + KAction* createAction(const char* name, Qt::Key key); + KAction* createAction(const char* name); + + Plasma::DataEngine* mpris2; + Plasma::Service* serv; + Plasma::ServiceJob* job; + + Shortcuts* mediaActions; + KConfigGroup op; +}; + +#endif // PLAYBARENGINE_H +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/playbarservice.operations b/engine/playbarservice.operations new file mode 100644 index 0000000..3ed5627 --- /dev/null +++ b/engine/playbarservice.operations @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/engine/service.cpp b/engine/service.cpp new file mode 100644 index 0000000..a9c49c2 --- /dev/null +++ b/engine/service.cpp @@ -0,0 +1,70 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include "service.h" +#include "playbarengine.h" + +PlayBarService::PlayBarService(const DataEngine::Data& data, QObject* parent) + : Service(parent), data(data) +{ + setName("playbarservice"); +} + +ServiceJob* PlayBarService::createJob(const QString& operation, + QMap< QString, QVariant >& parameters) +{ + setDestination(name() + ": " + operation); + parameters.insert("Metadata", data.value("Metadata")); + + return new Job(destination(), operation, parameters, this); +} + +Job::Job(const QString& destination, + const QString& operation, + const QMap< QString, QVariant >& parameters, + QObject* parent): + ServiceJob(destination, operation, parameters, parent) +{ +} + +void Job::start() +{ + const QString operation(operationName()); + + bool result = false; + + if (operation == QLatin1String("SetSource")) { + PlayBarEngine::p_mpris2Source = parameters().value("name").toString(); + result = true; + } + // TODO: Implementar el tagger para el rating + else if (operation == QLatin1String("SetRating")) { + const QVariantMap metadata(parameters().value("Metadata").toMap()); + + if (metadata.isEmpty()) qDebug() << "metadata isEmpty"; + // result = setRating(metadata.value("xesam:url").toString(), parameters().value("rating", "0").toString()); + } + + setResult(result); +} + + +#include "service.moc" +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/service.h b/engine/service.h new file mode 100644 index 0000000..54e4bbb --- /dev/null +++ b/engine/service.h @@ -0,0 +1,66 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifndef SERVICE_H +#define SERVICE_H + +#include +#include +#include + +#include +#include + +using Plasma::Service; +using Plasma::ServiceJob; +using Plasma::DataEngine; + + +class PlayBarService : public Service +{ + Q_OBJECT + +public: + explicit PlayBarService(const DataEngine::Data& data, QObject* parent); + + const DataEngine::Data &data; + +protected: + virtual ServiceJob* createJob(const QString& operation, + QMap< QString, QVariant >& parameters); +}; + +class Job : public ServiceJob +{ +public: + + Job(const QString& destination, + const QString& operation, + const QMap< QString, QVariant >& parameters, + QObject* parent = 0); + + virtual void start(); + +private: + +}; + +#endif // SERVICE_H +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/shortcuts.cpp b/engine/shortcuts.cpp new file mode 100644 index 0000000..d6c1a64 --- /dev/null +++ b/engine/shortcuts.cpp @@ -0,0 +1,160 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#include "shortcuts.h" +#include + +Shortcuts::Shortcuts(PlayBarEngine* engine): + QObject(), mediaActions(this) +{ + playbarEngine = engine; + + KAction* previous = + createAction("Previous", Qt::Key_MediaPrevious); + KAction* pause = + createAction("Pause", Qt::Key_MediaPause); + KAction* play = + createAction("Play", Qt::Key_MediaPlay); + KAction* stop = + createAction("Stop", Qt::Key_MediaStop); + KAction* play_pause = + createAction("PlayPause", Qt::Key_MediaTogglePlayPause); + KAction* next = + createAction("Next", Qt::Key_MediaNext); + KAction* open = + createAction("Open"); + KAction* quit = + createAction("Quit"); + + mediaActions.setConfigGlobal(true); + mediaActions.setConfigGroup("PlayBar"); + + connect(play_pause, SIGNAL(triggered(bool)), this, SLOT(playpause())); + connect(play, SIGNAL(triggered(bool)), this, SLOT(play())); + connect(pause, SIGNAL(triggered(bool)), this, SLOT(pause())); + connect(stop, SIGNAL(triggered(bool)), this, SLOT(stop())); + connect(next, SIGNAL(triggered(bool)), this, SLOT(next())); + connect(previous, SIGNAL(triggered(bool)), this, SLOT(previous())); + connect(open, SIGNAL(triggered(bool)), this, SLOT(open())); + connect(quit, SIGNAL(triggered(bool)), this, SLOT(quit())); +} + +KAction* Shortcuts::createAction(const char* name) +{ + QString text; + if (strcmp(name, "PlayPause") == 0) + text = ki18n("Play").toString() + '/' + ki18n("Pause").toString(); + else text = ki18n(name).toString(); + + KAction* action = new KAction("PlayBar: " + text, 0); + action->setObjectName(name); + action->setParent(&mediaActions); + action->setGlobalShortcut(KShortcut()); + mediaActions.addAction(text, action); + + return action; +} + +KAction* Shortcuts::createAction(const char* name, Qt::Key key) +{ + KAction* action = createAction(name); + action->setGlobalShortcut(KShortcut(key)); + return action; +} + +const Plasma::DataEngine::Data& Shortcuts::actions() const +{ + QList actions(mediaActions.actions()); + QList::const_iterator it = actions.constBegin(); + + Plasma::DataEngine::Data* data = new Plasma::DataEngine::Data(); + + while (it != actions.constEnd()) { + const QString globalShortcut((static_cast(*it))->globalShortcut().toString()); + const QString text = (*it)->text(); + data->insert(text , globalShortcut); + ++it; + } + return *data; +} + + +//SLOTS +void Shortcuts::playpause() +{ + const bool playing = playbarEngine->playbackStat() == QLatin1String("Playing"); + + if (PlayBarEngine::p_mpris2Source == "spotify") { + playbarEngine->startOpOverMpris2("PlayPause"); + return; + } + if (playing) playbarEngine->startOpOverMpris2("PlayPause"); + else playbarEngine->startOpOverMpris2("Play"); + +} + +void Shortcuts::play() +{ + const bool playing = playbarEngine->playbackStat() == QLatin1String("Playing"); + + if (PlayBarEngine::p_mpris2Source == "spotify" && !playing) + playbarEngine->startOpOverMpris2("PlayPause"); + else if (!playing) playbarEngine->startOpOverMpris2("Play"); +} + +void Shortcuts::pause() +{ + const bool playing = playbarEngine->playbackStat() == QLatin1String("Playing"); + + if (PlayBarEngine::p_mpris2Source == "spotify" && playing) + playbarEngine->startOpOverMpris2("Play"); + else if (playing) + playbarEngine->startOpOverMpris2("Pause"); +} + +void Shortcuts::stop() +{ + const bool stopped = playbarEngine->playbackStat() == QLatin1String("Stopped"); + + if (!stopped) + playbarEngine->startOpOverMpris2("Stop"); +} + +void Shortcuts::next() +{ + playbarEngine->startOpOverMpris2("Next"); +} + +void Shortcuts::previous() +{ + playbarEngine->startOpOverMpris2("Previous"); +} + +void Shortcuts::open() +{ + playbarEngine->startOpOverMpris2("Raise"); +} + +void Shortcuts::quit() +{ + playbarEngine->startOpOverMpris2("Quit"); +} + +#include "shortcuts.moc" +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/engine/shortcuts.h b/engine/shortcuts.h new file mode 100644 index 0000000..997873b --- /dev/null +++ b/engine/shortcuts.h @@ -0,0 +1,60 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#ifndef SHORTCUTS_H +#define SHORTCUTS_H + +#include +#include + +#include + +class PlayBarEngine; + +class Shortcuts : public QObject +{ + Q_OBJECT + +public: + explicit Shortcuts(PlayBarEngine* engine); + + const Plasma::DataEngine::Data& actions() const; + +private slots: + void playpause(); + void play(); + void pause(); + void stop(); + void next(); + void previous(); + void open(); + void quit(); + +private: + KAction* createAction(const char* name, Qt::Key key); + KAction* createAction(const char* name); + + KActionCollection mediaActions; + + PlayBarEngine* playbarEngine; + +}; + +#endif // SHORTCUTS_H +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/kcm_shortcuts/CMakeLists.txt b/kcm_shortcuts/CMakeLists.txt new file mode 100644 index 0000000..8bbffe9 --- /dev/null +++ b/kcm_shortcuts/CMakeLists.txt @@ -0,0 +1,10 @@ +project(kcm_playbarshortcuts) + +find_package(KDE4 REQUIRED) + +include(KDE4Defaults) +include(MacroLibrary) + +include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} ) + +add_subdirectory( src ) diff --git a/kcm_shortcuts/src/CMakeLists.txt b/kcm_shortcuts/src/CMakeLists.txt new file mode 100644 index 0000000..bf2ffdc --- /dev/null +++ b/kcm_shortcuts/src/CMakeLists.txt @@ -0,0 +1,21 @@ +# In this CMakeLists.txt we define which files +# are used to compile the application +set(kcm_playbarshortcuts_SRCS + kcm_playbarshortcuts.cpp + mprisservice.cpp + ) + +# Set the name of the application +kde4_add_executable(kcm_playbarshortcuts ${kcm_playbarshortcuts_SRCS}) + +# Added plugin +kde4_add_plugin(kcm_playbarshortcuts ${playbarshortcuts_SRCS} ${KDE4_MODULE_DIR}) + +# Select which libraries we need to link to +target_link_libraries(kcm_playbarshortcuts ${KDE4_KDEUI_LIBS} ${KDE4_PLASMA_LIBS}) + +# Tell cmake to install the application binary library +install(TARGETS kcm_playbarshortcuts DESTINATION ${PLUGIN_INSTALL_DIR} ) + +# Install the .desktop file +install( PROGRAMS kcm_playbarshortcuts.desktop DESTINATION ${KDE4_SERVICES_INSTALL_DIR} ) diff --git a/kcm_shortcuts/src/Messages.sh b/kcm_shortcuts/src/Messages.sh new file mode 100644 index 0000000..4ffeb39 --- /dev/null +++ b/kcm_shortcuts/src/Messages.sh @@ -0,0 +1,3 @@ +#! /usr/bin/env bash +$EXTRACTRC `find . -name \*.rc` >> rc.cpp +$XGETTEXT *.cpp -o $podir/kcm_playbarshortcuts.pot diff --git a/kcm_shortcuts/src/kcm_playbarshortcuts.cpp b/kcm_shortcuts/src/kcm_playbarshortcuts.cpp new file mode 100644 index 0000000..016605c --- /dev/null +++ b/kcm_shortcuts/src/kcm_playbarshortcuts.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) %{CURRENT_YEAR} by %{AUTHOR} <%{EMAIL}> * + * * + * 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 "kcm_playbarshortcuts.h" + +//KDE +#include +#include +#include + +#include + +#include + +#include +#include + +//Qt +#include + +using Plasma::DataEngine; +using Plasma::DataEngineManager; + +K_PLUGIN_FACTORY(PlayBarShortcutsFactory, registerPlugin();) + +K_EXPORT_PLUGIN(PlayBarShortcutsFactory( + "kcm_playbarshortcuts" /* kcm name */, + "kcm_playbarshortcuts" /* catalog name */) + ) + +KCM_PlayBarShortcuts::KCM_PlayBarShortcuts(QWidget*& parent, const QVariantList& args) + : KCModule(PlayBarShortcutsFactory::componentData(), parent, args) +{ + // About info + KAboutData about("simple", 0, + ki18n("KCM_PlayBarShortcuts"), "0.6", + ki18n("Configure PlayBar global shortcuts"), + KAboutData::License_GPL, + ki18n("(C) 2014 Smith AR"), + KLocalizedString(), 0, + "audoban@openmailbox.org"); + + about.addAuthor(ki18n("Smith AR"), KLocalizedString(), "mail@example.com"); + + // KShortcutsEditor widget + shortcutsWidget = new KShortcutsEditor(0, KShortcutsEditor::GlobalAction); + shortcutsWidget->setMinimumSize(200, 200); + + //Layout + QVBoxLayout* vBox = new QVBoxLayout(); + vBox->addWidget(shortcutsWidget); + this->setLayoutDirection(Qt::LayoutDirectionAuto); + this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + this->setLayout(vBox); + + //create action collection + createMediaActions(); + +} + +KCM_PlayBarShortcuts::~KCM_PlayBarShortcuts() +{ + shortcutsWidget->clearCollections(); + actions->clear(); + +} + +void KCM_PlayBarShortcuts::createMediaActions() +{ + + compdata = new KComponentData("PlayBar"); + actions = new KActionCollection(shortcutsWidget, *compdata); + shortcutsWidget->addCollection(actions, "PlayBar"); + + DataEngine *engine = + DataEngineManager::self()->engine("playbarkeys"); + + if(engine->isValid()){ + DataEngine::Data source = engine->query("Shortcuts"); + + if (source.empty()) return; + + foreach(QString key, source.keys()) { + KAction act(); + actions->addAction(key); + } + } +} + +KAction* KCM_PlayBarShortcuts::createAction(const char* icon, const char* name, Qt::Key key, QObject* parent) +{ + KAction* action = new KAction(KIcon(icon), ki18n(name).toString(), parent); + action->setObjectName(name); + action->setGlobalShortcut(KShortcut(key)); + + return action; +} + +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/kcm_shortcuts/src/kcm_playbarshortcuts.desktop b/kcm_shortcuts/src/kcm_playbarshortcuts.desktop new file mode 100644 index 0000000..b77fd4b --- /dev/null +++ b/kcm_shortcuts/src/kcm_playbarshortcuts.desktop @@ -0,0 +1,101 @@ +[Desktop Entry] +Name=PlayBar global shortcuts +Name[ast]=PlayBar global shortcuts +Name[bg]=PlayBar global shortcuts +Name[bs]=PlayBar global shortcuts +Name[ca]=PlayBar global shortcuts +Name[ca@valencia]=PlayBar global shortcuts +Name[cs]=PlayBar global shortcuts +Name[da]=PlayBar global shortcuts +Name[de]=PlayBar global shortcuts +Name[el]=PlayBar global shortcuts +Name[en_GB]=PlayBar global shortcuts +Name[eo]=PlayBar global shortcuts +Name[es]=Accesos rápidos globales de PlayBar +Name[et]=PlayBar global shortcuts +Name[fi]=PlayBar global shortcuts +Name[fr]=PlayBar global shortcuts +Name[ga]=PlayBar global shortcuts +Name[gl]=PlayBar global shortcuts +Name[hu]=PlayBar global shortcuts +Name[it]=PlayBar global shortcuts +Name[ja]=PlayBar global shortcuts +Name[kk]=PlayBar global shortcuts +Name[km]=PlayBar global shortcuts +Name[ko]=PlayBar global shortcuts +Name[lt]=PlayBar global shortcuts +Name[lv]=PlayBar global shortcuts +Name[nb]=PlayBar global shortcuts +Name[nds]=PlayBar global shortcuts +Name[nl]=PlayBar global shortcuts +Name[nn]=PlayBar global shortcuts +Name[pa]=PlayBar global shortcuts +Name[pl]=PlayBar global shortcuts +Name[pt]=PlayBar global shortcuts +Name[pt_BR]=PlayBar global shortcuts +Name[ro]=PlayBar global shortcuts +Name[ru]=PlayBar global shortcuts +Name[sk]=PlayBar global shortcuts +Name[sl]=PlayBar global shortcuts +Name[sq]=PlayBar global shortcuts +Name[sr]=PlayBar global shortcuts +Name[sr@ijekavian]=PlayBar global shortcuts +Name[sr@ijekavianlatin]=PlayBar global shortcuts +Name[sr@latin]=PlayBar global shortcuts +Name[sv]=PlayBar global shortcuts +Name[tr]=PlayBar global shortcuts +Name[ug]=PlayBar global shortcuts +Name[uk]=PlayBar global shortcuts +Name[x-test]=xxPlayBar global shortcutsxx +Name[zh_CN]=PlayBar global shortcuts +Name[zh_TW]=PlayBar global shortcuts +Comment=A Simple KDE Application +Comment[bs]= +Comment[ca]= +Comment[ca@valencia]= +Comment[cs]= +Comment[da]= +Comment[de]= +Comment[el]= +Comment[es]=Accesos rápidos de teclado para PlayBar +Comment[et]= +Comment[fi]= +Comment[fr]= +Comment[ga]= +Comment[gl]= +Comment[hu]= +Comment[it]= +Comment[kk]= +Comment[ko]= +Comment[lt]= +Comment[nb]= +Comment[nl]= +Comment[pa]= +Comment[pl]= +Comment[pt]= +Comment[pt_BR]= +Comment[ru]= +Comment[sk]= +Comment[sl]= +Comment[sr]= +Comment[sr@ijekavian]= +Comment[sr@ijekavianlatin]= +Comment[sr@latin]= +Comment[sv]= +Comment[tr]= +Comment[uk]= +Comment[x-test]= +Comment[zh_CN]= +Comment[zh_TW]= + +Exec=kcmshell4 kcm_playbarshortcuts +Icon=preferences-desktop-keyboard-shortcuts +Type=Service +Categories=Qt;KDE;X-KDE-settings-accessibility +#X-KDE-System-Settings-Category=shortcuts-and-gestures +#X-KDE-ParentApp=kcontrol +#X-KDE-System-Settings-Parent-Category=shortcuts-and-gestures +X-KDE-ServiceTypes=KCModule +X-KDE-Keywords=playbar;play;shortcuts;global +X-KDE-Library=kcm_playbarshortcuts +X-DocPath=kcm_playbarshortcuts/index.html diff --git a/kcm_shortcuts/src/kcm_playbarshortcuts.h b/kcm_shortcuts/src/kcm_playbarshortcuts.h new file mode 100644 index 0000000..bc5ee30 --- /dev/null +++ b/kcm_shortcuts/src/kcm_playbarshortcuts.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) %{CURRENT_YEAR} by %{AUTHOR} <%{EMAIL}> * + * * + * 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 KCM_PLAYBARSHORTCUTS_H +#define KCM_PLAYBARSHORTCUTS_H + +#include +#include +#include + + + + +/** + * This class serves as the main window for KCM_PlayBarShortcuts. It handles the + * menus, toolbars and status bars. + * + * @short Main window class + * @author Smith AR + * @version 0.6 + */ +class KCM_PlayBarShortcuts : public KCModule +{ + Q_OBJECT +public: + + KCM_PlayBarShortcuts(QWidget*& parent, const QVariantList& args); + + /** + * Default Destructor + */ + virtual ~KCM_PlayBarShortcuts(); + +private: + + void createMediaActions(); + + KAction* createAction(const char* icon, + const char* name, + Qt::Key key, + QObject* parent); + + //KShortcutsEditor Widget + KShortcutsEditor* shortcutsWidget; + KActionCollection* actions; + KComponentData *compdata; + +}; + +#endif // _KCM_PLAYBARSHORTCUTS_H_ +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; + diff --git a/kcm_shortcuts/src/mprisservice.cpp b/kcm_shortcuts/src/mprisservice.cpp new file mode 100644 index 0000000..da17979 --- /dev/null +++ b/kcm_shortcuts/src/mprisservice.cpp @@ -0,0 +1,89 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#include "mprisservice.h" + +#include "iostream" + +//KDE +#include + +MprisService::MprisService(QObject* parent) + : QObject(parent) +{ + DataEngineManager* engine = DataEngineManager::self(); + mpris2 = engine->loadEngine("mpris2"); + serviceName = "@multiplex"; + serv = mpris2->serviceForSource(serviceName); + +} + +MprisService::~MprisService() +{ + delete serv; +} + +/* Public media slots + * + */ +void MprisService::play_pause() +{ + +} +void MprisService::play() +{ + +} +void MprisService::pause() +{ + +} +void MprisService::stop() +{ + +} +void MprisService::next() +{ + +} +void MprisService::previous() +{ + +} +void MprisService::downVolume() +{ + +} +void MprisService::upVolume() +{ + +} +void MprisService::startOperation(const QString& name) +{ + op = serv->operationDescription(name); + job = serv->startOperationCall(op); + connect(job, SIGNAL(finished(KJob*)), this, SLOT(jobCompleted(KJob*))); +} + +void MprisService::jobCompleted(KJob* job) +{ + +} + +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/kcm_shortcuts/src/mprisservice.h b/kcm_shortcuts/src/mprisservice.h new file mode 100644 index 0000000..3aaf315 --- /dev/null +++ b/kcm_shortcuts/src/mprisservice.h @@ -0,0 +1,61 @@ +/* + * + * Copyright (C) 2014 smith AR + * + * 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 3 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, see . + * + */ + +#ifndef MPRISSERVICE_H +#define MPRISSERVICE_H + +#include +#include +#include +#include + +using namespace Plasma; + +class MprisService : public QObject +{ + Q_OBJECT +public: + MprisService(QObject* parent); + ~MprisService(); + +public slots: + void startOperation(const QString& name); + + void play_pause(); + void play(); + void pause(); + void stop(); + void previous(); + void next(); + void upVolume(); + void downVolume(); + +private: + Plasma::DataEngine* mpris2; + Plasma::Service* serv; + Plasma::ServiceJob* job; + KConfigGroup op; + QString serviceName; + +private slots: + void jobCompleted(KJob*); +}; + +#endif // MPRISSERVICE_H +// kate: indent-mode cstyle; indent-width 4; replace-tabs on; diff --git a/messages.sh b/messages.sh new file mode 100755 index 0000000..9ac7f92 --- /dev/null +++ b/messages.sh @@ -0,0 +1,55 @@ +#!/bin/bash +shopt -s extglob + +help="\n +-add-language \n +-u, -update-pot\n +-c, -compile-po" + +if [ -z "$1" ] ; then + echo -e $help ; exit +fi + +xgettext="xgettext -ki18n -C" +extractrc="extractrc" + +locale_dir='./plasmoid/locale' +output_po="$locale_dir/template/LC_MESSAGES/messages.po" +output_pot=$output_po't' +pot_dir=$locale_dir'/template/LC_MESSAGES' +playbar_mo='plasma_applet_playbar.mo' +playbar_po='playbar.po' +input_files=(./plasmoid/contents/{ui,code}/*.*) +locales=($locale_dir/*/LC_MESSAGES) +rc='./plasmoid/contents/ui/rc.js' + +if [ $1 == '-add-language' ] && [ -n $2 ] ; then + mkdir -p $locale_dir/$2/LC_MESSAGES + cp $output_pot $locale_dir/$2/LC_MESSAGES/$playbar_po + exit +fi + +if [ $1 == '-u' ] || [ $1 == '-update-pot' ] ; then + echo "input files: " ${input_files[@]} + $extractrc './plasmoid/contents/ui/config.ui' > $rc + $xgettext -o "$output_po" ${input_files[@]} $rc + mv $output_po $output_pot + + for d in ${locales[@]} ; do + if [ $d == $pot_dir ] + then continue + fi + msgmerge -o $d/$playbar_po $d/$playbar_po $output_pot + done + exit +fi + +if [ $1 == '-c' ] || [ $1 == '-compile-po' ] ; then + for d in $locale_dir/* ; do + if [ $d == $locale_dir'/template' ] + then continue + fi + echo "Building $d/LC_MESSAGES/playbar.mo ..." + msgfmt "$d/LC_MESSAGES/$playbar_po" -o "$d/LC_MESSAGES/$playbar_mo" + done +fi diff --git a/plasma-desktop.kwinrule b/plasma-desktop.kwinrule new file mode 100644 index 0000000..a5c0912 --- /dev/null +++ b/plasma-desktop.kwinrule @@ -0,0 +1,14 @@ +[Preferencias para la aplicación plasma-desktop] +Description=Preferencias para la aplicación plasma-desktop +clientmachine=opensuse +clientmachinematch=0 +skippager=true +skippagerrule=2 +skipswitcher=true +skipswitcherrule=2 +skiptaskbar=true +skiptaskbarrule=2 +types=4294967295 +wmclass=plasma-desktop +wmclasscomplete=false +wmclassmatch=1 diff --git a/plasmoid/.metadata.desktop~ b/plasmoid/.metadata.desktop~ new file mode 100644 index 0000000..c04ef37 --- /dev/null +++ b/plasmoid/.metadata.desktop~ @@ -0,0 +1,27 @@ +[Desktop Entry] +Name=PlayBar +Comment=Client MPRIS2, allows you to control your favorite media player +Comment[es]=Cliente para MPRIS2, le permite controlar su reproductor de audio favorito +Comment[ru]=Клиент MPRIS2 , позволяет управлять вашим любимым медиа-плеером + +Encoding=UTF-8 +Icon=applications-multimedia +Keywords=play;bar;mpris2;media;player;playbar;2; +Type=Service + +X-Plasma-API=declarativeappletscript +X-Plasma-MainScript=ui/main.qml +X-Plasma-DefaultSize=109,19 +#X-Plasma-ConfigPlugins=kcm_playbarshortcuts + +X-KDE-PluginInfo-Author=Smith AR +X-KDE-PluginInfo-Category=Multimedia +X-KDE-PluginInfo-Email=audoban@openmailbox.org +X-KDE-PluginInfo-License=GPLv3 +X-KDE-PluginInfo-Name=playbar +X-KDE-PluginInfo-Version=0.7 +X-KDE-PluginInfo-Website=https://github.com/audoban/PlayBar + +X-KDE-ServiceTypes=Plasma/Applet + + diff --git a/plasmoid/.~CMakeLists.txt b/plasmoid/.~CMakeLists.txt new file mode 100644 index 0000000..1efda60 --- /dev/null +++ b/plasmoid/.~CMakeLists.txt @@ -0,0 +1,14 @@ +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/playbar ) + +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/playbar/ ) + +install(FILES metadata.desktop + DESTINATION ${KDE4_SERVICES_INSTALL_DIR} + RENAME plasma-applet-playbar.desktop ) + +install(DIRECTORY locale/es + DESTINATION ${KDE4_LOCALE_INSTALL_DIR} + FILES_MATCHING PATTERN "*.mo" + ) diff --git a/plasmoid/CMakeLists.txt b/plasmoid/CMakeLists.txt new file mode 100644 index 0000000..5ff3201 --- /dev/null +++ b/plasmoid/CMakeLists.txt @@ -0,0 +1,18 @@ +install(DIRECTORY contents + DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/playbar ) + +install(FILES metadata.desktop + DESTINATION ${DATA_INSTALL_DIR}/plasma/plasmoids/playbar/ ) + +install(FILES metadata.desktop + DESTINATION ${KDE4_SERVICES_INSTALL_DIR} + RENAME plasma-applet-playbar.desktop ) +set(locale_dirs + locale/es + locale/ru +) + +install(DIRECTORY ${locale_dirs} + DESTINATION ${KDE4_LOCALE_INSTALL_DIR} + FILES_MATCHING PATTERN "*.mo" + ) diff --git a/plasmoid/contents/code/.control.js~ b/plasmoid/contents/code/.control.js~ new file mode 100644 index 0000000..12a097c --- /dev/null +++ b/plasmoid/contents/code/.control.js~ @@ -0,0 +1,119 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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. + */ + +.pragma library + +var source +var serv +var identity +var icon + +var currentVolume = 0 +var openedPopup = false + + +function setSource(sourceName, identity){ + if(sourceName == source) return + + source = sourceName + serv = service("mpris2", sourceName) + if(sourceName != "" ) setActions(sourceName, identity) + else removeActions() +} + +function seek(position, currentPosition){ + if(source == 'clementine') { + seekRelative(position, currentPosition) + return + } + + job = serv.operationDescription('SetPosition') + job['microseconds'] = (position * 1000).toFixed(0) + serv.startOperationCall(job) +} + +function seekRelative(position, currentPosition){ + job = serv.operationDescription('Seek') + job['microseconds'] = ((-currentPosition + position) * 1000).toFixed(0) + serv.startOperationCall(job) +} + +function startOperation(name){ + job = serv.operationDescription(name) + serv.startOperationCall(job) +} + +function setVolume(value){ + job = serv.operationDescription('SetVolume') + job['level'] = value + serv.startOperationCall(job) +} + +function setActions(sourceName, identity){ + + if(sourceName.match('vlc')){ + icon = 'vlc' + }else{ + icon = sourceName + } + + switch(sourceName){ + case 'spotify': + icon = 'spotify-client' + break + } + + plasmoid.setAction('raise', i18n("Open %1", identity), icon) + plasmoid.setAction('quit', i18n("Quit"), 'exit') + plasmoid.setActionSeparator('sep0') + plasmoid.setAction('nextSource', i18n("Next source"), 'go-next') + plasmoid.setActionSeparator('sep1') + +} + +function removeActions(){ + plasmoid.removeAction('raise') + plasmoid.removeAction('quit') + plasmoid.removeAction('sep0') + plasmoid.removeAction('nextSource') + plasmoid.removeAction('sep1') +} + +function autoSelectOpaqueIcons(themeName){ + print("themeName: " + themeName) + switch(themeName){ + case "default": + case "Dynamo Plasma": + case "Tibanna": + case "Midna": + case "midna" + case "org.tilain.plasma": + plasmoid.writeConfig("opaqueIcons", "true") + } +} + +// callbacks +function controlBarWheelEvent(wheel){} + +function sourceNotify(){} + +function controlBarWheelNotify(){} + + diff --git a/plasmoid/contents/code/.~control.js b/plasmoid/contents/code/.~control.js new file mode 100644 index 0000000..c3da0e5 --- /dev/null +++ b/plasmoid/contents/code/.~control.js @@ -0,0 +1,110 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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. + */ + +.pragma library + +var source +var serv +var identity +var icon + +var currentVolume = 0 +var openedPopup = false + + +function setSource(sourceName, identity){ + if(sourceName == source) return + + source = sourceName + serv = service("mpris2", sourceName) + if(sourceName != "" ) setActions(sourceName, identity) + else removeActions() +} + +function seek(position, currentPosition){ + if(source == 'clementine') { + seekRelative(position, currentPosition) + return + } + + job = serv.operationDescription('SetPosition') + job['microseconds'] = (position * 1000).toFixed(0) + serv.startOperationCall(job) +} + +function seekRelative(position, currentPosition){ + job = serv.operationDescription('Seek') + job['microseconds'] = ((-currentPosition + position) * 1000).toFixed(0) + serv.startOperationCall(job) +} + +function startOperation(name){ + job = serv.operationDescription(name) + serv.startOperationCall(job) +} + +function setVolume(value){ + job = serv.operationDescription('SetVolume') + job['level'] = value + serv.startOperationCall(job) +} + +function setActions(sourceName, identity){ + + if(sourceName.match('vlc')){ + icon = 'vlc' + }else{ + icon = sourceName + } + + switch(sourceName){ + case 'spotify': + icon = 'spotify-client' + break + } + + plasmoid.setAction('raise', i18n("Open %1", identity), icon) + plasmoid.setAction('quit', i18n("Quit"), 'exit') + plasmoid.setActionSeparator('sep0') + plasmoid.setAction('nextSource', i18n("Next source"), 'go-next') + plasmoid.setActionSeparator('sep1') + +} + +function removeActions(){ + plasmoid.removeAction('raise') + plasmoid.removeAction('quit') + plasmoid.removeAction('sep0') + plasmoid.removeAction('nextSource') + plasmoid.removeAction('sep1') +} + +function autoSelectOpaqueIcons(){ + plasmoid. +} + +// callbacks +function controlBarWheelEvent(wheel){} + +function sourceNotify(){} + +function controlBarWheelNotify(){} + + diff --git a/plasmoid/contents/code/control.js b/plasmoid/contents/code/control.js new file mode 100644 index 0000000..057d2cd --- /dev/null +++ b/plasmoid/contents/code/control.js @@ -0,0 +1,119 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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. + */ + +.pragma library + +var source +var serv +var identity +var icon + +var currentVolume = 0 +var openedPopup = false + + +function setSource(sourceName, identity){ + if(sourceName == source) return + + source = sourceName + serv = service("mpris2", sourceName) + if(sourceName != "" ) setActions(sourceName, identity) + else removeActions() +} + +function seek(position, currentPosition){ + if(source == 'clementine') { + seekRelative(position, currentPosition) + return + } + + job = serv.operationDescription('SetPosition') + job['microseconds'] = (position * 1000).toFixed(0) + serv.startOperationCall(job) +} + +function seekRelative(position, currentPosition){ + job = serv.operationDescription('Seek') + job['microseconds'] = ((-currentPosition + position) * 1000).toFixed(0) + serv.startOperationCall(job) +} + +function startOperation(name){ + job = serv.operationDescription(name) + serv.startOperationCall(job) +} + +function setVolume(value){ + job = serv.operationDescription('SetVolume') + job['level'] = value + serv.startOperationCall(job) +} + +function setActions(sourceName, identity){ + + if(sourceName.match('vlc')){ + icon = 'vlc' + }else{ + icon = sourceName + } + + switch(sourceName){ + case 'spotify': + icon = 'spotify-client' + break + } + + plasmoid.setAction('raise', i18n("Open %1", identity), icon) + plasmoid.setAction('quit', i18n("Quit"), 'exit') + plasmoid.setActionSeparator('sep0') + plasmoid.setAction('nextSource', i18n("Next source"), 'go-next') + plasmoid.setActionSeparator('sep1') + +} + +function removeActions(){ + plasmoid.removeAction('raise') + plasmoid.removeAction('quit') + plasmoid.removeAction('sep0') + plasmoid.removeAction('nextSource') + plasmoid.removeAction('sep1') +} + +function autoSelectOpaqueIcons(themeName){ + print("themeName: " + themeName) + switch(themeName){ + case "default": + case "Dynamo Plasma": + case "Tibanna": + case "Midna": + case "midna": + case "org.tilain.plasma": + plasmoid.writeConfig("opaqueIcons", "true") + } +} + +// callbacks +function controlBarWheelEvent(wheel){} + +function sourceNotify(){} + +function controlBarWheelNotify(){} + + diff --git a/plasmoid/contents/config/.main.xml~ b/plasmoid/contents/config/.main.xml~ new file mode 100644 index 0000000..7ce0355 --- /dev/null +++ b/plasmoid/contents/config/.main.xml~ @@ -0,0 +1,89 @@ + + + + + + + false + + + + playbar/media-clear + + + + playbar/media-opaque + + + + playbar/media-clear-bar + + + + playbar/media-opaque-bar + + + + playbar/arrows-clear + + + + playbar/arrows-opaque + + + + playbar/rating-clear + + + + playbar/rating-opaque + + + + playbar/audio-clear + + + + playbar/audio-opaque + + + + true + + + + false + + + + 0 + + + + true + + + + true + + + + true + + + + 0 + + + + false + + + + 22 + + + diff --git a/plasmoid/contents/config/main.xml b/plasmoid/contents/config/main.xml new file mode 100644 index 0000000..a6e942e --- /dev/null +++ b/plasmoid/contents/config/main.xml @@ -0,0 +1,93 @@ + + + + + + + true + + + + false + + + + playbar/media-clear + + + + playbar/media-opaque + + + + playbar/media-clear-bar + + + + playbar/media-opaque-bar + + + + playbar/arrows-clear + + + + playbar/arrows-opaque + + + + playbar/rating-clear + + + + playbar/rating-opaque + + + + playbar/audio-clear + + + + playbar/audio-opaque + + + + true + + + + false + + + + 0 + + + + true + + + + true + + + + true + + + + 0 + + + + false + + + + 22 + + + diff --git a/plasmoid/contents/theme/playbar/arrows-clear.svgz b/plasmoid/contents/theme/playbar/arrows-clear.svgz new file mode 100644 index 0000000..8042b47 Binary files /dev/null and b/plasmoid/contents/theme/playbar/arrows-clear.svgz differ diff --git a/plasmoid/contents/theme/playbar/arrows-opaque.svgz b/plasmoid/contents/theme/playbar/arrows-opaque.svgz new file mode 100644 index 0000000..c7b98a9 Binary files /dev/null and b/plasmoid/contents/theme/playbar/arrows-opaque.svgz differ diff --git a/plasmoid/contents/theme/playbar/audio-clear.svgz b/plasmoid/contents/theme/playbar/audio-clear.svgz new file mode 100644 index 0000000..ab99314 Binary files /dev/null and b/plasmoid/contents/theme/playbar/audio-clear.svgz differ diff --git a/plasmoid/contents/theme/playbar/audio-opaque.svgz b/plasmoid/contents/theme/playbar/audio-opaque.svgz new file mode 100644 index 0000000..23b2c1c Binary files /dev/null and b/plasmoid/contents/theme/playbar/audio-opaque.svgz differ diff --git a/plasmoid/contents/theme/playbar/media-clear-bar.svgz b/plasmoid/contents/theme/playbar/media-clear-bar.svgz new file mode 100644 index 0000000..7adb36d Binary files /dev/null and b/plasmoid/contents/theme/playbar/media-clear-bar.svgz differ diff --git a/plasmoid/contents/theme/playbar/media-clear.svgz b/plasmoid/contents/theme/playbar/media-clear.svgz new file mode 100644 index 0000000..6b7b650 Binary files /dev/null and b/plasmoid/contents/theme/playbar/media-clear.svgz differ diff --git a/plasmoid/contents/theme/playbar/media-opaque-bar.svgz b/plasmoid/contents/theme/playbar/media-opaque-bar.svgz new file mode 100644 index 0000000..45e4b68 Binary files /dev/null and b/plasmoid/contents/theme/playbar/media-opaque-bar.svgz differ diff --git a/plasmoid/contents/theme/playbar/media-opaque.svgz b/plasmoid/contents/theme/playbar/media-opaque.svgz new file mode 100644 index 0000000..d802dea Binary files /dev/null and b/plasmoid/contents/theme/playbar/media-opaque.svgz differ diff --git a/plasmoid/contents/theme/playbar/nocover.svgz b/plasmoid/contents/theme/playbar/nocover.svgz new file mode 100644 index 0000000..582ae6a Binary files /dev/null and b/plasmoid/contents/theme/playbar/nocover.svgz differ diff --git a/plasmoid/contents/theme/playbar/rating-clear.svgz b/plasmoid/contents/theme/playbar/rating-clear.svgz new file mode 100644 index 0000000..6158e4b Binary files /dev/null and b/plasmoid/contents/theme/playbar/rating-clear.svgz differ diff --git a/plasmoid/contents/theme/playbar/rating-opaque.svgz b/plasmoid/contents/theme/playbar/rating-opaque.svgz new file mode 100644 index 0000000..c8ccf02 Binary files /dev/null and b/plasmoid/contents/theme/playbar/rating-opaque.svgz differ diff --git a/plasmoid/contents/ui/.Layout.qml~ b/plasmoid/contents/ui/.Layout.qml~ new file mode 100644 index 0000000..b89527f --- /dev/null +++ b/plasmoid/contents/ui/.Layout.qml~ @@ -0,0 +1,59 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 "plasmapackage:/code/control.js" as Control + +Item{ + id: layout + + property bool isSpotify: mpris.source == 'spotify' + + property bool noSource: + mpris.connectedSources == "" + + property variant idLayout: undefined + + LayoutsResources{id: layouts} + + height: childrenRect.height + width: childrenRect.width + + signal layoutChanged() + + Component.onCompleted: { + plasmoid.addEventListener('configChanged', function(){ + idLayout = layouts.resources[plasmoid.readConfig('PlayBarLayout')] + } + ) + } + + Loader{ + id: loader + + sourceComponent: if(noSource) undefined + else if(isSpotify) layouts.spotifyLayout + else idLayout + + onLoaded:{ + layoutChanged() + } + } +} diff --git a/plasmoid/contents/ui/.Mpris2.qml~ b/plasmoid/contents/ui/.Mpris2.qml~ new file mode 100644 index 0000000..65c18f2 --- /dev/null +++ b/plasmoid/contents/ui/.Mpris2.qml~ @@ -0,0 +1,178 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import "plasmapackage:/code/control.js" as Control + +DataSource{ + id: dataSource + + engine: 'mpris2' + + interval: minimumLoad + + connectedSources: sources.length > 1 && sources[0] != '@multiplex' ? [sources[0]] : [""] + + + property int maximumLoad: 500 + + property int minimumLoad: 1500 + + property bool isMaximumLoad: interval == maximumLoad + + property bool initialConnection: true + + + property string previousSource + + property string source: connectedSources[0] != undefined ? connectedSources[0] : '' + + property bool sourceActive: false + + + property string identity: hasSource('Identity') ? data[source]['Identity'] : i18n("No source") + + property string playbackStatus: hasSource('PlaybackStatus') ? data[source]['PlaybackStatus'] : "unknown" + + property string artUrl: hasMetadata('artUrl') ? data[source]['Metadata']['mpris:artUrl'] : "" + + property string artist: hasMetadata('artist') ? data[source]['Metadata']['xesam:artist'].toString() : "" + + property string album: hasMetadata('album') ? data[source]['Metadata']['xesam:album'] : "" + + property string title: hasMetadata('title') ? data[source]['Metadata']['xesam:title'] : "" + + property int length: hasMetadata('length') ? data[source]['Metadata']['mpris:length'] / 1000: 0 + + property int position: 0 + + property real userRating: 0 + + property real volume: hasSource('Volume') ? data[source]['Volume'] : 0 + + + signal sourceChanged(string source) + + signal ratingChanged() + + signal volumeChanged(real value) + + onSourceChanged: { + if(data[source] != undefined ) identity = data[source]['Identity'] + else identity = i18n("No source") + } + + //Component.onCompleted: initialConnection = true + + function hasMetadata(key){ + if (interval == minimumLoad) return false + + if (key == 'artUrl' || key == 'length') key = 'mpris:'+key + else key = 'xesam:'+key + + return data[source] != undefined + && data[source]['Metadata'] != undefined + && data[source]['Metadata'][key] != undefined + } + + function hasSource(key){ + return data[source] != undefined + && data[source][key] != undefined + } + + function connect(source){ + connectedSources = [source] + Control.setSource(source) + } + + function nextSource(){ + for(i = 0; i < sources.length; i++){ + if(connectedSources[0] == sources[i] || connectedSources == "") + { + if(++i < sources.length && sources[i] != '@multiplex'){ + connect(sources[i]) + }else if(++i < sources.length){ + connect(sources[i]) + }else if(sources[0] != '@multiplex') connect(sources[0]) + return + } + } + } + + onNewData: { + if(!isMaximumLoad) return + + position = data['Position'] /1000 + + if(hasMetadata('userRating') && data['Metadata']['xesam:userRating'] != userRating ){ + userRating = data['Metadata']['xesam:userRating'] != undefined ? + data['Metadata']['xesam:userRating'] : 0 + ratingChanged() + }else if(playbackStatus == 'Stopped' && userRating != 0){ + userRating = 0 + ratingChanged() + } + + if(hasSource('Volume')) volumeChanged(data['Volume']) + + } + + onSourceAdded: { + if(initialConnection && source != '@multiplex') { + previousSource = connectedSources == "" ? "" : connectedSources[0] + connectedSources = [source] + initialConnection = false + } + } + + onSourceRemoved: { + if(sources.length == 1){ + sourceActive = false + initialConnection = true + } + if(source == previousSource) + nextSource() + } + + onSourceConnected: { + if(source != previousSource) { + print("connected: "+source) + previousSource = source + sourceChanged(source) + } + if(source != ''){ + sourceActive = true + initialConnection = false + } + idty = data[source] != undefined ? data[source]['Identity'] : i18n("No source") + Control.setSource(source, idty) + } + + onSourceDisconnected: { + print("disconnected: "+source) + if(sources.length == 1){ + sourceChanged(source) + Control.setSource("", identity) + } + } + + //onIntervalChanged: print("interval: "+interval) +} diff --git a/plasmoid/contents/ui/.RatingItem.qml~ b/plasmoid/contents/ui/.RatingItem.qml~ new file mode 100644 index 0000000..3507483 --- /dev/null +++ b/plasmoid/contents/ui/.RatingItem.qml~ @@ -0,0 +1,104 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import "plasmapackage:/code/control.js" as Control + +Item{ + id: ratingItem + + property real rating: mpris.userRating + + property int sizeIcon: 18 + + implicitHeight: content.implicitHeight + + implicitWidth: content.implicitWidth + + property variant svgId: + { + 'low' : "rating-low", + 'medium' : "rating-medium", + 'high' : "rating-high" + } + + Component.onCompleted: { + for(i = 0; i < 5; i++){ + plasmoid.addEventListener('configChanged', function(){ + ratingItems.itemAt(i).Svg = ratingItems.itemAt(i).update() + }) + mpris.ratingChanged.connect(ratingItems.itemAt(i).fetchRating) + } + } + + Component{ + id: svgDelegate + PlasmaCore.SvgItem{ + svg: update() + implicitWidth: sizeIcon + implicitHeight: sizeIcon + + function update(){ + if(plasmoid.readConfig("opaqueIcons") == true) + return Svg(plasmoid.readConfig("rating-opaque")) + else return Svg(plasmoid.readConfig("rating-clear")) + } + + function fetchRating() { + var iRating = (index + 1)/5 + if ( rating >= iRating ) + elementId = svgId['high'] + else if ( rating.toFixed(1) == (iRating - 0.1).toFixed(1) ) + elementId = svgId['medium'] + else + elementId = svgId['low'] + elementIdChanged() + } + + Component.onCompleted: { + fetchRating() + plasmoid.addEventListener('configChanged', function(){ + fetchRating() + svg = update() + print(elementId) + }) + } + + Component.onDestruction: { + mpris.ratingChanged.disconnect(setRating) + } + } + } + + Row{ + id: content + spacing: 3 + opacity: rating < 0.1 ? 0.7 : 1 + + Behavior on opacity{ NumberAnimation{duration: 250} } + + Repeater{ + id: ratingItems + model: 5 + delegate: svgDelegate + } + } +} diff --git a/plasmoid/contents/ui/.Slider.qml~ b/plasmoid/contents/ui/.Slider.qml~ new file mode 100644 index 0000000..cf90bf2 --- /dev/null +++ b/plasmoid/contents/ui/.Slider.qml~ @@ -0,0 +1,301 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import org.kde.qtextracomponents 0.1 as QtExtra +import "plasmapackage:/code/control.js" as Control + +Item{ + id: slider + + property alias maximumValue: range.maximumValue + + property alias value: range.value + + property bool pressAndChange: false + + property alias pressed: seekArea.pressed + + property alias enabledWheel: wheelMouse.enabled + + property double valueForPosition: range.value + + property bool dragActive: seekArea.drag.active + + property int intervalDragCall: 1000 + + property int orientation: QtHorizontal + + + signal valueChanged(real value) + + signal sliderDragged() + + signal controlBarWheelEvent(variant wheel) + + +//##################################################### + + property bool horizontal: orientation == QtHorizontal + + //NOTE: Vertical State + states: State{ + when: orientation == QtVertical + + //range + PropertyChanges{ + target: range + positionAtMaximum: content.height + positionAtMinimum: 0 + } + //bar + PropertyChanges{ + target: bar + height: range.position + + anchors{ + topMargin: 0 + bottomMargin: -1 + } + } + AnchorChanges{ + target: bar + anchors{ + top: undefined + right: parent.right + } + } + //seek + PropertyChanges{ + target: seek + height: 2 + width: bar.width + x: 0 + y: !seekArea.drag.active ? bar.height : 0 + } + AnchorChanges{ + target: seek + anchors{ + verticalCenter: undefined + horizontalCenter: bar.horizontalCenter + left: undefined + right: undefined + bottom: !seekArea.pressed ? bar.top : undefined + } + } + //seekArea + PropertyChanges{ + target: seekArea + drag{ + axis: Drag.YAxis + maximumX: 0 + minimumY: 0 + maximumY: barBg.height + } + } + //wheelMouse + PropertyChanges{ + target: wheelMouse + anchors{ + leftMargin: -8 + rightMargin: -4 + } + } + AnchorChanges{ + target: wheelMouse + anchors{ + top: content.top + } + } + } + +//##################################################### + + RangeModel{ + id: range + + minimumValue: 0 + maximumValue: 0 + value: 0 + positionAtMinimum: 0 + positionAtMaximum: content.width + + } + + Rectangle{ + id: content + + color: theme.textColor + radius: 2 + smooth: true + anchors.fill: parent + + Rectangle{ + id: barBg + + smooth: true + radius: 2 + anchors.fill: parent + color: theme.backgroundColor + opacity: 0.5 + + } + + Rectangle{ + id: bar + + anchors{ + left: parent.left + top: parent.top + bottom: parent.bottom + //topMargin: -1 + //bottomMargin: -1 + } + radius: 2 + smooth: true + color: theme.highlightColor + width: range.position + + Behavior on width{ enabled: horizontal ; NumberAnimation{duration: 150} } + Behavior on height{ enabled: !horizontal ; NumberAnimation{duration: 150} } + } + + Rectangle{ + id: seek + width: 2 + height: parent.height + color: theme.highlightColor + + border{ + color: color + width: 4 + } + + opacity: 0 + radius: 0.1 + smooth: true + + anchors{ + verticalCenter: bar.verticalCenter + leftMargin: -2 + left: !seekArea.pressed ? bar.right : undefined + } + + Behavior on opacity{ NumberAnimation{duration: 150} } + + } + + //ATTENTION: This will be removed in QtQuick 2.0 + QtExtra.MouseEventListener{ + id: wheelMouse + + enabled: false + visible: enabled + + height: 30 + anchors{ + left: parent.left + right: parent.right + bottom: parent.bottom + rightMargin: -30 + bottomMargin: -4 + } + onWheelMoved: { + if(wheel.delta > 0) + range.setValue(range.value + 0.05) + else + range.setValue(range.value - 0.05) + valueChanged(range.value) + } + Component.onCompleted: controlBarWheelEvent.connect(wheelMoved) + } + + MouseArea{ + id: seekArea + + anchors.fill: parent + + hoverEnabled: true + + drag{ + //target: seek + axis: Drag.XAxis + minimumX: 0 + maximumX: barBg.width + } + onEntered: seek.opacity = 1 + + onExited: if(!pressed) seek.opacity = 0 + + onPressed: { + if(horizontal) seek.x = mouseX + else seek.y = mouseY + } + + onReleased: { + if(!containsMouse) seek.opacity = 0 + if(horizontal) + valueChanged(range.valueForPosition(mouseX)) + else + valueChanged(range.valueForPosition( drag.maximumY - mouseY)) + } + + function xPosition(mouseX){ + if(mouseX > drag.maximumX) seek.x = drag.maximumX + else if(mouseX < 0) seek.x = 0 + else seek.x = mouseX + + var currentValue = range.valueForPosition(seek.x) + if(currentValue / intervalDragCall != valueForPosition / intervalDragCall) + { + valueForPosition = currentValue + sliderDragged() + } + + if (pressAndChange) valueChanged(range.valueForPosition(seek.x)) + } + + function yPosition(mouseY){ + if(mouseY > drag.maximumY) seek.y = drag.maximumY + else if(mouseY < 0) seek.y = 0 + else seek.y = mouseY + + //invert y axis + mouseY = drag.maximumY - mouseY + + var currentValue = range.valueForPosition(content.height - seek.y) + if(currentValue / intervalDragCall != valueForPosition / intervalDragCall) + { + valueForPosition = currentValue + sliderDragged() + } + + if (pressAndChange) valueChanged(range.valueForPosition(content.height - seek.y)) + } + + onPositionChanged: { + if(!pressed) return + if(orientation == QtHorizontal) xPosition(mouseX) + else yPosition(mouseY) + } + } + } +} diff --git a/plasmoid/contents/ui/.TitlePopup.qml~ b/plasmoid/contents/ui/.TitlePopup.qml~ new file mode 100644 index 0000000..f504b88 --- /dev/null +++ b/plasmoid/contents/ui/.TitlePopup.qml~ @@ -0,0 +1,51 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import org.kde.plasma.graphicswidgets 0.1 + +Column{ + id: title + + height: childrenRect.height + 10 + + PlasmaComponents.Label{ + id: text + + text: mpris.identity + width: parent.width + lineHeight: 1.2 + styleColor: theme.highlightColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Separator{ + orientation: Qt.Horizontal + width: parent.width + } + + MouseArea{ + anchors.fill: parent + parent: text + onClicked: action_nextSource() + } +} diff --git a/plasmoid/contents/ui/.main.qml~ b/plasmoid/contents/ui/.main.qml~ new file mode 100644 index 0000000..c5490f9 --- /dev/null +++ b/plasmoid/contents/ui/.main.qml~ @@ -0,0 +1,288 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.plasma.components 0.1 as PlasmaComponents +import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets +import org.kde.qtextracomponents 0.1 as QtExtra +import org.kde.draganddrop 1.0 +import "plasmapackage:/code/control.js" as Control + +Item { + id: main + + property int minimumWidth: childrenRect.width + + property int minimumHeight: childrenRect.height + + property int maximumWidth: 256 + + property int maximumHeight: 256 + + property bool vertical: false + + property bool popupOpen: popup.status == PlasmaComponents.DialogStatus.Open + + property bool showNotifications: plasmoid.readConfig('showNotifications') + + opacity: !mouseArea.enabled ? 1 : 0.6 + + Behavior on opacity{ + NumberAnimation{ duration: 250 } + } + + Mpris2{ id: mpris } + + //########################### + //Context menu + function action_raise(){ + Control.startOperation('Raise') + } + + function action_quit(){ + Control.startOperation('Quit') + popup.close() + } + + function action_nextSource(){ + mpris.nextSource() + if(showNotifications) Control.sourceNotify() + } + + //TODO: open file + //########################### + + function setMaximumLoad(){ + mpris.interval = mpris.maximumLoad + } + + function setMinimumLoad(){ + mpris.interval = mpris.minimumLoad + } + + states:[ + State{ + name: "maximumLoad" + when: popupOpen + + StateChangeScript{ + script: setMaximumLoad() + } + }, + State{ + name: "minimumLoad" + when: !popupOpen + + StateChangeScript{ + script: setMinimumLoad() + } + } + ] + + Component.onCompleted:{ + plasmoid.aspectRatioMode = IgnoreAspectRatio + + function formFactorChanged() + { + switch(plasmoid.formFactor) + { + case Planar: + vertical = false + plasmoid.backgroundHints = StandardBackground + plasmoid.resize(minimumWidth, minimumHeight) + return + case Horizontal: + plasmoid.backgroundHints = NoBackground + vertical = false + return + case Vertical: + plasmoid.backgroundHints = NoBackground + vertical = true + return + } + } + print(theme.themeName) + + plasmoid.formFactorChanged.connect(formFactorChanged) + plasmoid.resize(controlBar.width, controlBar.height) + formFactorChanged() + + plasmoid.addEventListener('configChanged', function(){ + showNotifications = plasmoid.readConfig('showNotifications') + sep.visible = plasmoid.readConfig('separatorVisible') + playbackBar.buttonSize = plasmoid.readConfig('buttonSize') + shortcuts.connectSource("Shortcuts") + } + ) + + if(plasmoid.readConfig('first-run') == true){ + plasmoid.writeConfig('first-run', 'false') + Control.autoSelectOpaqueIcons(theme.themeName) + } + } + + //ATTENTION: This will be removed in QtQuick 2.0 because will be unnecessary + // Volume Area + QtExtra.MouseEventListener{ + id: volumeWheelArea + anchors.fill: controlBar + + onWheelMoved: { + if(!mpris.sourceActive) return + if(mpris.source != 'spotify'){ + Control.controlBarWheelEvent(wheel) + Control.controlBarWheelNotify() + } + } + } + + //Enabled when no source active + MouseArea{ + id: mouseArea + acceptedButtons: Qt.LeftButton + anchors.fill: controlBar + z: 99 + enabled: !mpris.sourceActive + } + + Flow{ + id: controlBar + + spacing: 4 + + flow: vertical ? Flow.TopToBottom : Flow.LeftToRight + + anchors{ + centerIn: parent + } + + Item{ + children: [iconPopup, sep] + width: vertical ? playbackBar.width : height + height: vertical ? width : playbackBar.height + } + + PopupButton{ + id: iconPopup + + elementId: main.popupOpen ? opened : closed + onClicked: { main.popupOpen ? popup.close(): popup.open(); } + + anchors.centerIn: parent + + size: playbackBar.flatButtons ? playbackBar.buttonSize - 6 : playbackBar.buttonSize - 10 + } + + PlasmaWidgets.Separator{ + id: sep + + orientation: vertical ? Qt.Horizontal : Qt.Vertical + + anchors{ + top: vertical ? undefined : iconPopup.top + bottom: vertical ? parent.bottom : iconPopup.bottom + left: vertical ? iconPopup.left : undefined + right: vertical ? iconPopup.right : parent.right + leftMargin: vertical ? 0 : controlBar.spacing/2 + topMargin: vertical ? controlBar.spacing/2 : 0 + } + } + + PlaybackBar{ + id: playbackBar + + buttonSize: plasmoid.readConfig('buttonSize') + } + + Dialog{ + id: popup + + content: [ contentItem ] + title: [ titleItem ] + visualParent: iconPopup + + Component.onCompleted: contentItem.layoutChanged.connect(updateSize) + + TitlePopup{ + id: titleItem + width: contentItem.width + } + + Layout{ + id: contentItem + } + } + } + + Component{ + id: notification + + Notification{ + parent: main + maximumWidth: (vertical ? controlBar.height : controlBar.width) + minimumWidth: (vertical ? playbackBar.height : playbackBar.width) + + verticalOffset: (iconPopup.height)/2 + controlBar.spacing + (playbackBar.flatButtons ? 2 : 4) + horizontalOffset: (iconPopup.width)/2 + controlBar.spacing + (playbackBar.flatButtons ? 2 : 4) + + anchors{ + centerIn: parent + } + + Component.onCompleted: mpris.sourceChanged.connect(sourceNotify) + } + } + + //Load the notifications + Loader{ + id: loader + sourceComponent: + if(showNotifications) notification + else undefined + } + + PlasmaCore.DataSource{ + id: shortcuts + + engine: 'playbarengine' + + connectedSources: ['Provider'] + + onNewData: if(data['SourceMpris2'] != undefined) print(data['SourceMpris2']) + + function sourceChanged(source){ + var serv = serviceForSource('Provider'); + var op = serv.operationDescription('SetSource'); + op['name'] = source; + serv.startOperationCall(op); + } + Component.onCompleted: mpris.sourceChanged.connect(sourceChanged) + } + + +} + + + + + + diff --git a/plasmoid/contents/ui/.~main.qml b/plasmoid/contents/ui/.~main.qml new file mode 100644 index 0000000..4173e69 --- /dev/null +++ b/plasmoid/contents/ui/.~main.qml @@ -0,0 +1,282 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.plasma.components 0.1 as PlasmaComponents +import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets +import org.kde.qtextracomponents 0.1 as QtExtra +import org.kde.draganddrop 1.0 +import "plasmapackage:/code/control.js" as Control + +Item { + id: main + + property int minimumWidth: childrenRect.width + + property int minimumHeight: childrenRect.height + + property int maximumWidth: 256 + + property int maximumHeight: 256 + + property bool vertical: false + + property bool popupOpen: popup.status == PlasmaComponents.DialogStatus.Open + + property bool showNotifications: plasmoid.readConfig('showNotifications') + + opacity: !mouseArea.enabled ? 1 : 0.6 + + Behavior on opacity{ + NumberAnimation{ duration: 250 } + } + + Mpris2{ id: mpris } + + //########################### + //Context menu + function action_raise(){ + Control.startOperation('Raise') + } + + function action_quit(){ + Control.startOperation('Quit') + popup.close() + } + + function action_nextSource(){ + mpris.nextSource() + if(showNotifications) Control.sourceNotify() + } + + //TODO: open file + //########################### + + function setMaximumLoad(){ + mpris.interval = mpris.maximumLoad + } + + function setMinimumLoad(){ + mpris.interval = mpris.minimumLoad + } + + states:[ + State{ + name: "maximumLoad" + when: popupOpen + + StateChangeScript{ + script: setMaximumLoad() + } + }, + State{ + name: "minimumLoad" + when: !popupOpen + + StateChangeScript{ + script: setMinimumLoad() + } + } + ] + + Component.onCompleted:{ + plasmoid.aspectRatioMode = IgnoreAspectRatio + + function formFactorChanged() + { + switch(plasmoid.formFactor) + { + case Planar: + vertical = false + plasmoid.backgroundHints = StandardBackground + plasmoid.resize(minimumWidth, minimumHeight) + return + case Horizontal: + plasmoid.backgroundHints = NoBackground + vertical = false + return + case Vertical: + plasmoid.backgroundHints = NoBackground + vertical = true + return + } + } + + plasmoid.formFactorChanged.connect(formFactorChanged) + plasmoid.resize(controlBar.width, controlBar.height) + formFactorChanged() + + plasmoid.addEventListener('configChanged', function(){ + showNotifications = plasmoid.readConfig('showNotifications') + sep.visible = plasmoid.readConfig('separatorVisible') + playbackBar.buttonSize = plasmoid.readConfig('buttonSize') + shortcuts.connectSource("Shortcuts") + } + ) + + } + + //ATTENTION: This will be removed in QtQuick 2.0 because will be unnecessary + // Volume Area + QtExtra.MouseEventListener{ + id: volumeWheelArea + anchors.fill: controlBar + + onWheelMoved: { + if(!mpris.sourceActive) return + if(mpris.source != 'spotify'){ + Control.controlBarWheelEvent(wheel) + Control.controlBarWheelNotify() + } + } + } + + //Enabled when no source active + MouseArea{ + id: mouseArea + acceptedButtons: Qt.LeftButton + anchors.fill: controlBar + z: 99 + enabled: !mpris.sourceActive + } + + Flow{ + id: controlBar + + spacing: 4 + + flow: vertical ? Flow.TopToBottom : Flow.LeftToRight + + anchors{ + centerIn: parent + } + + Item{ + children: [iconPopup, sep] + width: vertical ? playbackBar.width : height + height: vertical ? width : playbackBar.height + } + + PopupButton{ + id: iconPopup + + elementId: main.popupOpen ? opened : closed + onClicked: { main.popupOpen ? popup.close(): popup.open(); } + + anchors.centerIn: parent + + size: playbackBar.flatButtons ? playbackBar.buttonSize - 6 : playbackBar.buttonSize - 10 + } + + PlasmaWidgets.Separator{ + id: sep + + orientation: vertical ? Qt.Horizontal : Qt.Vertical + + anchors{ + top: vertical ? undefined : iconPopup.top + bottom: vertical ? parent.bottom : iconPopup.bottom + left: vertical ? iconPopup.left : undefined + right: vertical ? iconPopup.right : parent.right + leftMargin: vertical ? 0 : controlBar.spacing/2 + topMargin: vertical ? controlBar.spacing/2 : 0 + } + } + + PlaybackBar{ + id: playbackBar + + buttonSize: plasmoid.readConfig('buttonSize') + } + + Dialog{ + id: popup + + content: [ contentItem ] + title: [ titleItem ] + visualParent: iconPopup + + Component.onCompleted: contentItem.layoutChanged.connect(updateSize) + + TitlePopup{ + id: titleItem + width: contentItem.width + } + + Layout{ + id: contentItem + } + } + } + + Component{ + id: notification + + Notification{ + parent: main + maximumWidth: (vertical ? controlBar.height : controlBar.width) + minimumWidth: (vertical ? playbackBar.height : playbackBar.width) + + verticalOffset: (iconPopup.height)/2 + controlBar.spacing + (playbackBar.flatButtons ? 2 : 4) + horizontalOffset: (iconPopup.width)/2 + controlBar.spacing + (playbackBar.flatButtons ? 2 : 4) + + anchors{ + centerIn: parent + } + + Component.onCompleted: mpris.sourceChanged.connect(sourceNotify) + } + } + + //Load the notifications + Loader{ + id: loader + sourceComponent: + if(showNotifications) notification + else undefined + } + + PlasmaCore.DataSource{ + id: shortcuts + + engine: 'playbarengine' + + connectedSources: ['Provider'] + + onNewData: if(data['SourceMpris2'] != undefined) print(data['SourceMpris2']) + + function sourceChanged(source){ + var serv = serviceForSource('Provider'); + var op = serv.operationDescription('SetSource'); + op['name'] = source; + serv.startOperationCall(op); + } + Component.onCompleted: mpris.sourceChanged.connect(sourceChanged) + } + +} + + + + + + diff --git a/plasmoid/contents/ui/CoverArt.qml b/plasmoid/contents/ui/CoverArt.qml new file mode 100644 index 0000000..1705a81 --- /dev/null +++ b/plasmoid/contents/ui/CoverArt.qml @@ -0,0 +1,145 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import org.kde.plasma.core 0.1 as PlasmaCore + +Item{ + id: coverArt + + property int size: 80 + + implicitWidth: size + 8 + + implicitHeight: size + 8 + + states: [ + State{ + name: 'nocover' + when: cover.source == "" || cover.status == Image.NULL || cover.status == Image.Error + PropertyChanges{ + target: nocover + visible: true + } + PropertyChanges{ + target: bg + opacity: 0.8 + } + PropertyChanges{ target: bgMask; opacity: 0.5 } + }, + State{ + name: 'busy' + when: cover.status == Image.Loading + PropertyChanges{ + target: nocover + visible: true + smooth: true + rotation: 180 + } + PropertyChanges{ + target: bg + opacity: 0.8 + } + }, + State{ + name: 'cover' + when: cover.status == Image.Ready + PropertyChanges{ + target: nocover + visible: false + } + PropertyChanges{ + target: bg + color: theme.textColor + } + } + ] + + transitions: Transition { + NumberAnimation{ property: 'opacity'; duration: 500 } + RotationAnimation { duration: 1000; direction: RotationAnimation.Counterclockwise; } + } + + Rectangle{ + id: bg + + color: theme.textColor + width: size + height: size + radius: 2 + clip: true + + anchors.centerIn: parent + + border{ + color: bg.color + width: 4 + } + Rectangle{ + id: bgMask + anchors.fill: parent + color: theme.backgroundColor + + opacity: 0.1 + border{ + color: color + width: 4 + } + } + } + + PlasmaCore.SvgItem{ + id: nocover + + svg: PlasmaCore.Svg{ + imagePath: plasmoid.file("theme", "playbar/nocover.svgz") + usingRenderingCache: true + Component.onCompleted: { + theme.themeChanged.connect(repaintNeeded); repaintNeeded() + } + } + anchors.fill: bg + } + + Image{ + id: cover + + source: Qt.resolvedUrl(mpris.artUrl) + fillMode: Image.PreserveAspectFit + sourceSize: Qt.size(size, size) + anchors.fill: bg + + visible: status == Image.Ready ? true : false + cache: true + + onStatusChanged: { + if(status == Image.Error) + print("Err: " +mpris.artUrl) + } + } + + MouseArea{ + anchors.fill: parent + hoverEnabled: true + onClicked: action_raise() + } + +} diff --git a/plasmoid/contents/ui/Dialog.qml b/plasmoid/contents/ui/Dialog.qml new file mode 100644 index 0000000..757e629 --- /dev/null +++ b/plasmoid/contents/ui/Dialog.qml @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Marco Martin +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Components project. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.plasma.components 0.1 +import "plasmapackage:/code/control.js" as Control +import "private/AppManager.js" as Utils +import "private" as Private + +/** + * Top-level window for short-term tasks and brief interaction with the user + * + * A dialog floats on the top layer of the application view, usually + * overlapping the area reserved for the application content. Normally, a + * dialog provides information and gives warnings to the user, or asks the user + * to answer a question or select an option. + */ +Item { + id: root + + visible: false + /** + * type:list A list of items in the dialog's title area. You can use + * a Text component but also any number of components that are based on + * Item. For example, you can use Text and Image components. + */ + property alias title: titleBar.children + + /** + * type:list A list of items in the dialog's content area. You can + * use any component that is based on Item. For example, you can use + * ListView, so that the user can select from a list of names. + */ + property alias content: contentItem.children + + /** + * The item that the dialog refers to. The dialog will usually be + * positioned relative to VisualParent + */ + property Item visualParent + + /** + * Indicates the dialog's phase in its life cycle. The values are as follows: + * + * - DialogStatus.Opening - the dialog is opening + * - DialogStatus.Open - the dialog is open and visible to the user + * - DialogStatus.Closing - the dialog is closing + * - DialogStatus.Closed - the dialog is closed and not visible to the user + * + * The dialog's initial status is DialogStatus.Closed. + */ + property int status: DialogStatus.Closed + + + property alias privateTitleHeight: titleBar.height + + /** + * This signal is emitted when the user taps in the area that is inside the + * dialog's visual parent area but outside the dialog's area. Normally the + * visual parent is the root object. In that case this signal is emitted if + * the user taps anywhere outside the dialog's area. + * + * @see visualParent + */ + signal clickedOutside + + onClickedOutside: close() + + signal updateSize + /** + * Shows the dialog to the user. + */ + function open() { + updateSize() + + var pos = internalLoader.dialog.popupPosition(root.visualParent, Qt.AlignCenter) + internalLoader.dialog.x = pos.x + internalLoader.dialog.y = pos.y + internalLoader.dialog.visible = true + internalLoader.dialog.activateWindow() + + //HACK: Resize the popup correctly + if(plasmoid.location == TopEdge || plasmoid.location == RightEdge) + dialogMainItem.height = dialogLayout.height + else if(plasmoid.location == LeftEdge) + dialogMainItem.width = dialogLayout.width + + Control.openedPopup = true + } + + + /** + * Closes the dialog without any user interaction. + */ + function close() { + internalLoader.dialog.visible = false + Control.openedPopup = false + } + + Loader { + id: internalLoader + //the root item of the scene. Determines if there is enough room for an inline dialog + property Item rootItem + + //this is when the dialog is a separate window + property Item dialog: sourceComponent == dialogComponent ? item : null + + Component.onCompleted: { + rootItem = Utils.rootObject() + } + + sourceComponent: dialogComponent + } + + Component { + id: dialogComponent + PlasmaCore.Dialog { + id: dialogItem + windowFlags: Qt.Popup | Qt.Dialog | Qt.WindowStaysOnTopHint + + //state: "Hidden" + visible: false + + + property bool __hack_initialLayoutPosition: false + + onActiveWindowChanged: { + if(!activeWindow) root.clickedOutside() + } + + onVisibleChanged: { + if(__hack_initialLayoutPosition){ __hack_initialLayoutPosition = false; return } + if (visible) { + root.status = DialogStatus.Open + } else { + root.status = DialogStatus.Closed + } + } + + function updateSize(){ + dialogMainItem.width = dialogLayout.width + dialogMainItem.height = dialogLayout.height + } + + function config(){ + + if (plasmoid.readConfig('windowFlagDialog') == true) + windowFlags = Qt.Dialog | Qt.WindowStaysOnTopHint + else + windowFlags = Qt.Popup | Qt.WindowStaysOnTopHint + + if(plasmoid.readConfig('popupStyle') == 0){ + setAttribute( Qt.WA_X11NetWmWindowTypeToolTip, false ) + }else{ + setAttribute( Qt.WA_X11NetWmWindowTypeToolTip, true ) + } + + //HACK: fix initial layout position + __hack_initialLayoutPosition = true + if(visible) { + visible = false + root.status = DialogStatus.Closed + } else { + visible = true + visible = false + } + } + + mainItem: dialogMainItem + + Component.onCompleted: { + setAttribute(Qt.WA_X11NetWmWindowTypeMenu, true) + setAttribute(Qt.WA_X11NetWmWindowTypePopupMenu, true) + root.updateSize.connect(updateSize) + plasmoid.addEventListener('configChanged', config) + plasmoid.formFactorChanged.connect(updateSize) + updateSize() + } + } + } + + Item { + id: dialogMainItem + children: dialogLayout + } + + Column { + id: dialogLayout + width: contentItem.width + height: titleBar.height + contentItem.height + 5 + + // Consume all key events that are not processed by children + Keys.onPressed: event.accepted = true + Keys.onReleased: event.accepted = true + + + Row { + id: titleBar + + height: children.length > 0 && children[0].visible ? childrenRect.height : 0 + } + + Row { + id: contentItem + } + } +} diff --git a/plasmoid/contents/ui/Frame.qml b/plasmoid/contents/ui/Frame.qml new file mode 100644 index 0000000..0676d89 --- /dev/null +++ b/plasmoid/contents/ui/Frame.qml @@ -0,0 +1,66 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 + +Rectangle{ + id: frame + + property string bg: theme.highlightColor + color: bg + radius: 1 + smooth: true + + property alias containsMouse: mouseArea.containsMouse + + Component.onCompleted:{ + mouseArea.entered.connect(entered) + mouseArea.exited.connect(exited) + } + + signal entered() + + signal exited() + + function fadeIn(){ fadeInAnimation.start() } + + function fadeOut(){ fadeOutAnimation.start() } + + SequentialAnimation on opacity{ + id: fadeInAnimation + running: false + NumberAnimation { to: 0.8 ; duration: 150 } + } + + SequentialAnimation on opacity{ + id: fadeOutAnimation + running: true + NumberAnimation { to: 0.01 ; duration: 300 } + } + + MouseArea{ + id: mouseArea + + hoverEnabled: true + acceptedButtons: Qt.NoButton + anchors.fill: parent + } + +} diff --git a/plasmoid/contents/ui/IconWidget.qml b/plasmoid/contents/ui/IconWidget.qml new file mode 100644 index 0000000..88f8b8c --- /dev/null +++ b/plasmoid/contents/ui/IconWidget.qml @@ -0,0 +1,65 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 2.3 +import org.kde.plasma.core 2.0 + + +SvgItem { + id: iconWidget + + property alias iconSource: elementId + + property int size: theme.smallIconSize + 3 + + svg: Svg{ imagePath: "icons/media.svgz" } + + implicitWidth: size + + implicitHeight: size + + smooth: true + + signal clicked() + + Component.onCompleted: mouseArea.clicked.connect(clicked) + + SequentialAnimation on scale{ + id: animA + running: false + alwaysRunToEnd: true + NumberAnimation { to: 0.9; duration: 150 } + } + SequentialAnimation on scale{ + id: animB + running: scale == 0.9 && !mouseArea.pressed + alwaysRunToEnd: true + NumberAnimation { to: 1; duration: 150 } + } + + MouseArea{ + id: mouseArea + + acceptedButtons: Qt.LeftButton + anchors.fill: parent + + onPressed: animA.start() + } +} diff --git a/plasmoid/contents/ui/Layout.qml b/plasmoid/contents/ui/Layout.qml new file mode 100644 index 0000000..e37223f --- /dev/null +++ b/plasmoid/contents/ui/Layout.qml @@ -0,0 +1,59 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 "plasmapackage:/code/control.js" as Control + +Item{ + id: layout + + property bool isSpotify: mpris.source == 'spotify' + + property bool noSource: + mpris.connectedSources == "" + + property variant idLayout: null + + LayoutsResources{id: layouts} + + height: childrenRect.height + width: childrenRect.width + + signal layoutChanged() + + Component.onCompleted: { + plasmoid.addEventListener('configChanged', function(){ + idLayout = layouts.resources[plasmoid.readConfig('PlayBarLayout')] + } + ) + } + + Loader{ + id: loader + + sourceComponent: if(noSource) null + else if(isSpotify) layouts.spotifyLayout + else idLayout + + onLoaded:{ + layoutChanged() + } + } +} diff --git a/plasmoid/contents/ui/LayoutsResources.qml b/plasmoid/contents/ui/LayoutsResources.qml new file mode 100644 index 0000000..e8ad257 --- /dev/null +++ b/plasmoid/contents/ui/LayoutsResources.qml @@ -0,0 +1,335 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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.graphicswidgets 0.1 as PlasmaWidgets +import org.kde.plasma.components 0.1 + +Item{ +id: layouts + +resources: [defaultLayout, minimalLayout, coolLayout] + +property variant spotifyLayout: minimalLayout + + +//########### +// Cool +//########### +Component{ + id: coolLayout + + Item{ + + width: childrenRect.width + 8 + height: childrenRect.height + + Flow{ + id: headCover + spacing: 8 + + CoverArt{ + id: cover + size: 120 + + Frame{ + id: frame + width: cover.width - 4 + height: playback.height + + onEntered: fadeIn() + + anchors{ + horizontalCenter: parent.horizontalCenter + bottom: cover.bottom + bottomMargin: 8 + } + } + PlaybackWidget{ + id: playback + + buttonSize: 24 + opacity: frame.opacity + 0.2 + + anchors{ + verticalCenter: frame.verticalCenter + horizontalCenter: parent.horizontalCenter + } + + MouseArea{ + id: playArea + + hoverEnabled: true + acceptedButtons: Qt.NoButton + anchors.fill: parent + onEntered: frame.entered() + onExited: if(!frame.containsMouse) frame.fadeOut() + } + } + } + + Item{ + id: bar + children: [info, time, seek, rating] + height: cover.height + width: childrenRect.width + } + + TrackInfo{ + id: info + contentHeight: 25 + albumArtistPointsize: 11 + titleFontWeight: Font.DemiBold + width: 250 + } + Row{ + id: time + + anchors{ + right: seek.right + bottom: seek.top + bottomMargin: 1 + } + + TimeLabel{ + id: positionTime + + hover: true + topTime: mpris.length + autoTimeTrigger: mpris.isMaximumLoad + negative: plasmoid.readConfig('timeNegative') + } + Label{ + text: ' / ' + } + TimeLabel{ + id: lengthTime + currentTime: mpris.length + autoTimeTrigger: mpris.isMaximumLoad + } + } + RatingItem{ + id: rating + sizeIcon: 16 + + anchors{ + left: seek.left + bottom: seek.top + bottomMargin: 8 + } + } + SliderSeek{ + id: seek + width: info.width + labelVisible: false + + anchors{ + bottom: parent.bottom + horizontalCenter: info.horizontalCenter + } + + onCurrentSeekPosition: { + positionTime.currentTime = position + positionTime.timeChanged() + } + + } + Volume{ + id: volume + visible: false + width: 0 + } + } + } +} + +//########### +// Minimalist +//########### +Component{ + id: minimalLayout + + Item{ + height: cover.height + 4 + width: 350 + + CoverArt{ + id: cover + + anchors{ + rightMargin: 8 + leftMargin: 4 + verticalCenter: parent.verticalCenter + } + } + PlasmaWidgets.Separator{ + id: separator + + orientation: Qt.Vertical + + anchors{ + left: cover.right + top: cover.top + bottom: cover.bottom + topMargin: 4 + bottomMargin: 4 + leftMargin: 8 + rightMargin: 8 + } + } + TrackInfo{ + id: info + + anchors{ + leftMargin: 8 + rightMargin: volume.visible ? 10 : 4 + left: separator.right + right: volume.visible ? volume.left : parent.right + top: parent.top + bottom: playback.top + } + } + PlaybackWidget{ + id: playback + spacing: 8 + + anchors{ + bottom: parent.bottom + topMargin: 4 + horizontalCenter: parent.horizontalCenter + horizontalCenterOffset: cover.width / 2 - (isSpotify ? 0 : 8) + } + } + Volume{ + id: volume + + iconVisible: false + labelVisible: false + orientation: QtVertical + + visible: !isSpotify + + width: 16 + height: cover.height - 6 + + anchors{ + verticalCenter: cover.verticalCenter + right: parent.right + } + } + } +} + + +//########### +// Default +//########### +Component{ + id: defaultLayout + + Item{ + height: cover.height + 4 + width: 500 + + CoverArt{ + id: cover + + anchors{ + rightMargin: 8 + leftMargin: 4 + verticalCenter: parent.verticalCenter + } + } + PlaybackWidget{ + id: playback + + anchors{ + leftMargin: 8 + rightMargin: 8 + topMargin: 2 + top: parent.top + left: cover.right + } + } + RatingItem{ + id: rating + + anchors{ + topMargin: 10 + horizontalCenter: playback.horizontalCenter + top: playback.bottom + bottom: seek.top + } + } + PlasmaWidgets.Separator{ + id: separator + + orientation: Qt.Vertical + + anchors{ + margins: 6 + bottomMargin: 14 + top: playback.top + bottom: seek.top + left: playback.right + } + } + TrackInfo{ + id: info + + widthLabelArtist: width - volume.width - 12 + widthLabelAlbum: width - volume.width - 12 + + anchors{ + leftMargin: 8 + rightMargin: 4 + left: separator.right + right: parent.right + top: parent.top + } + } + Volume{ + id: volume + + width: 120 + anchors{ + rightMargin: 4 + leftMargin: 8 + bottomMargin: 4 + bottom: seek.top + right: info.right + } + } + SliderSeek{ + id: seek + + width: parent.width - cover.width - 16 + anchors{ + leftMargin: 10 + left: cover.right + bottom: cover.bottom + bottomMargin: -4 + } + } + } +} + + +} diff --git a/plasmoid/contents/ui/Mpris2.qml b/plasmoid/contents/ui/Mpris2.qml new file mode 100644 index 0000000..fcaf109 --- /dev/null +++ b/plasmoid/contents/ui/Mpris2.qml @@ -0,0 +1,177 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 2.3 +import org.kde.plasma.core 2.0 +import "plasmapackage:/code/control.js" as Control + +DataSource{ + id: dataSource + + engine: 'mpris2' + + interval: minimumLoad + + connectedSources: sources.length > 1 && sources[0] != '@multiplex' ? [sources[0]] : [""] + + + property int maximumLoad: 500 + + property int minimumLoad: 1500 + + property bool isMaximumLoad: interval == maximumLoad + + property bool initialConnection: true + + + property string previousSource + + property string source: connectedSources[0] != undefined ? connectedSources[0] : '' + + property bool sourceActive: false + + + property string identity: hasSource('Identity') ? data[source]['Identity'] : i18n("No source") + + property string playbackStatus: hasSource('PlaybackStatus') ? data[source]['PlaybackStatus'] : "unknown" + + property string artUrl: hasMetadata('artUrl') ? data[source]['Metadata']['mpris:artUrl'] : "" + + property string artist: hasMetadata('artist') ? data[source]['Metadata']['xesam:artist'].toString() : "" + + property string album: hasMetadata('album') ? data[source]['Metadata']['xesam:album'] : "" + + property string title: hasMetadata('title') ? data[source]['Metadata']['xesam:title'] : "" + + property int length: hasMetadata('length') ? data[source]['Metadata']['mpris:length'] / 1000: 0 + + property int position: 0 + + property real userRating: 0 + + property real volume: hasSource('Volume') ? data[source]['Volume'] : 0 + + + signal sourceChanged(string source) + + signal ratingChanged() + + signal volumeChanged(real value) + + onSourceChanged: { + if(data[source] != undefined ) identity = data[source]['Identity'] + else identity = i18n("No source") + } + + function hasMetadata(key){ + if (interval == minimumLoad) return false + + if (key == 'artUrl' || key == 'length') key = 'mpris:'+key + else key = 'xesam:'+key + + return data[source] != undefined + && data[source]['Metadata'] != undefined + && data[source]['Metadata'][key] != undefined + } + + function hasSource(key){ + return data[source] != undefined + && data[source][key] != undefined + } + + function connect(source){ + connectedSources = [source] + Control.setSource(source) + } + + function nextSource(){ + for(i = 0; i < sources.length; i++){ + if(connectedSources[0] == sources[i] || connectedSources == "") + { + if(++i < sources.length && sources[i] != '@multiplex'){ + connect(sources[i]) + }else if(++i < sources.length){ + connect(sources[i]) + }else if(sources[0] != '@multiplex') connect(sources[0]) + + return + } + } + } + + onNewData: { + if(!isMaximumLoad) return + + position = data['Position'] /1000 + + if(hasMetadata('userRating') && data['Metadata']['xesam:userRating'] != userRating ){ + userRating = data['Metadata']['xesam:userRating'] != undefined ? + data['Metadata']['xesam:userRating'] : 0 + ratingChanged() + }else if(playbackStatus == 'Stopped' && userRating != 0){ + userRating = 0 + ratingChanged() + } + + if(hasSource('Volume')) volumeChanged(data['Volume']) + + } + + onSourceAdded: { + if(initialConnection && source != '@multiplex') { + previousSource = connectedSources == "" ? "" : connectedSources[0] + connectedSources = [source] + initialConnection = false + } + } + + onSourceRemoved: { + if(sources.length == 1){ + sourceActive = false + initialConnection = true + } + if(source == previousSource) + nextSource() + } + + onSourceConnected: { + if(source != previousSource) { + print("connected: "+source) + previousSource = source + sourceChanged(source) + } + if(source != ''){ + sourceActive = true + initialConnection = false + } + idty = data[source] != undefined ? data[source]['Identity'] : i18n("No source") + Control.setSource(source, idty) + } + + onSourceDisconnected: { + print("disconnected: "+source) + if(sources.length == 1){ + sourceChanged(source) + Control.setSource("", identity) + } + } + + //onIntervalChanged: print("interval: "+interval) +} diff --git a/plasmoid/contents/ui/Notification.qml b/plasmoid/contents/ui/Notification.qml new file mode 100644 index 0000000..7a10a19 --- /dev/null +++ b/plasmoid/contents/ui/Notification.qml @@ -0,0 +1,131 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import "plasmapackage:/code/control.js" as Control + +Item{ + id: notification + + property int maximumWidth: 0 + + property int minimumWidth: 0 + + property int duration: 600 + + property int value: 0 + + property int horizontalOffset: 0 + + property int verticalOffset: 0 + + enabled: true + + opacity: 0 + + rotation: vertical ? 90 : 0 + + anchors{ + horizontalCenterOffset: !vertical && frame.width < minimumWidth ? horizontalOffset : (!vertical ? 3 : 0) + verticalCenterOffset: vertical && frame.width < minimumWidth ? verticalOffset : (vertical ? 3 : 0) + } + + function sourceNotify(){ + if( mpris.identity.match('vlc|VLC') ) + title.text = "VLC" + else + title.text = mpris.identity + fadeIn.start() + } + + function controlBarWheelNotify(){ + title.text = parseInt(Control.currentVolume*100)+'%' + fadeIn.restart() + } + + SequentialAnimation on opacity{ + id: fadeIn + + NumberAnimation { to: 1 ; duration: 150 } + PauseAnimation{ duration: 700 } + NumberAnimation { to: 0 ; duration: 300 } + } + + Behavior on value { + NumberAnimation{ duration: 100 } + } + + Component.onCompleted: { + Control.sourceNotify = sourceNotify + Control.controlBarWheelNotify = controlBarWheelNotify + plasmoid.addEventListener('configChanged', function() { + title.font.pointSize = plasmoid.readConfig('buttonSize')/2 + }) + sourceNotify() + } + + Rectangle{ + id: frame + + color: theme.highlightColor + radius: 2 + border{ + width: 2 + color: color + } + implicitWidth: title.width + implicitHeight: title.implicitHeight + opacity: 0.7 + + anchors{ + centerIn: parent + horizontalCenterOffset: -1 + } + } + + Text{ + id: title + + anchors{ + centerIn: parent + } + + width: implicitWidth > maximumWidth ? maximumWidth - 4 : implicitWidth + + clip: true + smooth: true + + style: Text.Raised + styleColor: theme.backgroundColor + color: theme.textColor + maximumLineCount: 1 + + font{ + weight: Font.DemiBold + pointSize: plasmoid.readConfig('buttonSize')/2 + } + + Behavior on text{ + PropertyAnimation{ duration: 50 } + } + } + +} diff --git a/plasmoid/contents/ui/PlaybackBar.qml b/plasmoid/contents/ui/PlaybackBar.qml new file mode 100644 index 0000000..e070861 --- /dev/null +++ b/plasmoid/contents/ui/PlaybackBar.qml @@ -0,0 +1,159 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 2.3 +import org.kde.plasma.components 2.0 + +PlaybackItem{ + id: playbackbar + + property bool vertical: false +// DEPRECATED + property bool flatButtons: plasmoid.readConfig('flatButtons') + + width: childrenRect.width + + height: childrenRect.height + + Component.onCompleted: { + + function formFactorChanged() + { + switch(plasmoid.formFactor) + { + case Planar: + case MediaCenter: + case Horizontal: + vertical = false + return + case Vertical: + vertical = true + return + } + } + formFactorChanged() + plasmoid.formFactorChanged.connect(formFactorChanged) + + function connectMediaActions(){ + model.itemAt(0).clicked.connect(previous) + model.itemAt(1).clicked.connect(playPause) + model.itemAt(2).clicked.connect(stop) + model.itemAt(3).clicked.connect(next) + } + + connectMediaActions() + + //DEPRECATED + plasmoid.addEventListener('configChanged', function(){ + if(plasmoid.readConfig('flatButtons') != flatButtons){ + flatButtons = !flatButtons + connectMediaActions() + } + if(playing) buttons.playingState() + else buttons.pausedState() + } + ) + } + + ListModel{ + id: playmodel + ListElement{ + icon: "media-skip-backward" + } + ListElement{ + icon: "media-playback-start" + } + ListElement{ + icon: "media-playback-stop" + } + ListElement{ + icon: "media-skip-forward" + } + + } + + Component{ + id: toolButtonDelegate + + ToolButton{ + iconSource: icon + visible: index == 2 ? showStop : true + minimunWidth: buttonSize + 2 + minimumHeight: buttonSize + 2 + } + } + + Component{ + id: iconWidgetDelegate + + IconWidget{ + iconSource: icon + visible: index == 2 ? showStop : true + size: buttonSize + + } + + } + + Flow { + id: buttons + + spacing: flatButtons ? 5 : -1 + flow: vertical ? Flow.TopToBottom : Flow.LeftToRight + + function playingState(){ + model.itemAt(1).iconSource = "media-playback-pause" + } + + function pausedState(){ + model.itemAt(1).iconSource = "media-playback-start" + } + + states:[ + State{ + name: "Playing" + when: playing + StateChangeScript{ + script: buttons.playingState() + } + }, + State{ + name: "Paused" + when: !playing + StateChangeScript{ + script: buttons.pausedState() + } + } + ] + + move: Transition { + NumberAnimation { + property: "y" + easing.type: Easing.Linear + } + } + + Repeater{ + id: model + model: playmodel + delegate: flatButtons ? iconWidgetDelegate : toolButtonDelegate + } + } +} diff --git a/plasmoid/contents/ui/PlaybackItem.qml b/plasmoid/contents/ui/PlaybackItem.qml new file mode 100644 index 0000000..b69f71f --- /dev/null +++ b/plasmoid/contents/ui/PlaybackItem.qml @@ -0,0 +1,78 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 2.3 +import "plasmapackage:/code/control.js" as Control + +Item{ + id: playbackitem + + property bool playing: mpris.playbackStatus == 'Playing' + + //DEPRECATED + property bool showStop: mpris.source == 'spotify' ? false : plasmoid.readConfig('showStop') + + property bool vertical: false + + property real spacing: -2 + + property int buttonSize: 22 + + signal playPause() + + signal previous() + + signal next() + + signal stop() + + function showStopChanged(source){ + if( source == undefined ) source = mpris.source + if( source != 'spotify' ) + //DEPRECATED + showStop = plasmoid.readConfig('showStop') + else showStop = false + } + + onPlayPause: { + if(mpris.source == 'spotify' ) { + Control.startOperation('PlayPause') + return + } + if(!playing) Control.startOperation('Play') + else Control.startOperation('PlayPause') + } + + onPrevious: Control.startOperation('Previous') + + onNext: Control.startOperation('Next') + + onStop: if(mpris.playbackStatus != "Stopped") Control.startOperation('Stop') + + Component.onCompleted: { + mpris.sourceChanged.connect(showStopChanged) + //DEPRECATED + plasmoid.addEventListener('configChanged', showStopChanged) + } + + Component.onDestruction: { + mpris.sourceChanged.disconnect(showStopChanged) + } +} diff --git a/plasmoid/contents/ui/PlaybackWidget.qml b/plasmoid/contents/ui/PlaybackWidget.qml new file mode 100644 index 0000000..a965273 --- /dev/null +++ b/plasmoid/contents/ui/PlaybackWidget.qml @@ -0,0 +1,107 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 + +PlaybackItem{ + id: playbackWidget + + property int buttonSize: 26 + + property alias spacing: content.spacing + + width: content.width + ( model.itemAt(2).visible ? 0 : 20 ) + + height: childrenRect.height + + Component.onCompleted: { + model.itemAt(0).clicked.connect(previous) + model.itemAt(1).clicked.connect(playPause) + model.itemAt(2).clicked.connect(stop) + model.itemAt(3).clicked.connect(next) + } + + Component.onDestruction: { + model.itemAt(0).clicked.disconnect(previous) + model.itemAt(1).clicked.disconnect(playPause) + model.itemAt(2).clicked.disconnect(stop) + model.itemAt(3).clicked.disconnect(next) + } + + ListModel{ + id: playmodel + ListElement{ + idIcon: "media-skip-backward" + } + ListElement{ + idIcon: "media-playback-start" + } + ListElement{ + idIcon: "media-playback-stop" + } + ListElement{ + idIcon: "media-skip-forward" + } + } + + Component{ + id: buttonDelegate + + IconWidget{ + + svg: update() + iconSource: idIcon + size: buttonSize + + anchors.verticalCenter: parent.verticalCenter + + visible: index == 2 ? showStop : true + + // DEPRECATED + Component.onCompleted: { + plasmoid.addEventListener('configChanged', function(){svg = update()} ) + } + } + } + + Row{ + id: content + spacing: 5 + anchors.horizontalCenter: parent.horizontalCenter + + states:[ + State{ + name: "Playing" + when: playing + PropertyChanges{ + target: model.itemAt(1) + elementId: "media-playback-pause" + } + } + ] + + Repeater{ + id: model + model: playmodel + delegate: buttonDelegate + } + } +} diff --git a/plasmoid/contents/ui/PopupButton.qml b/plasmoid/contents/ui/PopupButton.qml new file mode 100644 index 0000000..c5f0262 --- /dev/null +++ b/plasmoid/contents/ui/PopupButton.qml @@ -0,0 +1,72 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 + + +IconWidget{ + id: iconPopup + + svg: update() + + elementId: closed + + property variant icons: [ "up-arrow", "down-arrow", "right-arrow", "left-arrow" ] + + property string opened: icons[0] + + property string closed: icons[1] + + function update(){ + if(plasmoid.readConfig("opaqueIcons") == true) + return Svg(plasmoid.readConfig("arrows-opaque")) + else return Svg(plasmoid.readConfig("arrows-clear")) + } + + Component.onCompleted:{ + function locationChanged(){ + + switch(plasmoid.location){ + case Floating: + case Desktop: + case TopEdge: + opened = icons[0] + closed = icons[1] + break + case BottomEdge: + opened = icons[1] + closed = icons[0] + break + case LeftEdge: + opened = icons[3] + closed = icons[2] + break + case RightEdge: + opened = icons[2] + closed = icons[3] + } + } + + plasmoid.addEventListener('configChanged', function(){svg = update()} ) + plasmoid.locationChanged.connect(locationChanged) + locationChanged() + } +} diff --git a/plasmoid/contents/ui/RatingItem.qml b/plasmoid/contents/ui/RatingItem.qml new file mode 100644 index 0000000..fd1bce8 --- /dev/null +++ b/plasmoid/contents/ui/RatingItem.qml @@ -0,0 +1,104 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import "plasmapackage:/code/control.js" as Control + +Item{ + id: ratingItem + + property real rating: mpris.userRating + + property int sizeIcon: 18 + + implicitHeight: content.implicitHeight + + implicitWidth: content.implicitWidth + + property variant svgId: + { + 'low' : "rating-low", + 'medium' : "rating-medium", + 'high' : "rating-high" + } + + Component.onCompleted: { + for(i = 0; i < 5; i++){ + plasmoid.addEventListener('configChanged', function(){ + ratingItems.itemAt(i).Svg = ratingItems.itemAt(i).update() + }) + mpris.ratingChanged.connect(ratingItems.itemAt(i).fetchRating) + } + } + + Component{ + id: svgDelegate + PlasmaCore.SvgItem{ + svg: update() + implicitWidth: sizeIcon + implicitHeight: sizeIcon + + function update(){ + if(plasmoid.readConfig("opaqueIcons") == true) + return Svg(plasmoid.readConfig("rating-opaque")) + else return Svg(plasmoid.readConfig("rating-clear")) + } + + function fetchRating() { + var iRating = (index + 1)/5 + if ( rating >= iRating ) + elementId = svgId['high'] + else if ( rating.toFixed(1) == (iRating - 0.1).toFixed(1) ) + elementId = svgId['medium'] + else + elementId = svgId['low'] + elementIdChanged() + } + + Component.onCompleted: { + fetchRating() + plasmoid.addEventListener('configChanged', function(){ + fetchRating() + svg = update() + print(elementId) + }) + } + + Component.onDestruction: { + mpris.ratingChanged.disconnect(fetchRating) + } + } + } + + Row{ + id: content + spacing: 3 + opacity: rating < 0.1 ? 0.7 : 1 + + Behavior on opacity{ NumberAnimation{duration: 250} } + + Repeater{ + id: ratingItems + model: 5 + delegate: svgDelegate + } + } +} diff --git a/plasmoid/contents/ui/Slider.qml b/plasmoid/contents/ui/Slider.qml new file mode 100644 index 0000000..5e552e8 --- /dev/null +++ b/plasmoid/contents/ui/Slider.qml @@ -0,0 +1,301 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import org.kde.qtextracomponents 0.1 as QtExtra +import "plasmapackage:/code/control.js" as Control + +Item{ + id: slider + + property alias maximumValue: range.maximumValue + + property alias value: range.value + + property bool pressAndChange: false + + property alias pressed: seekArea.pressed + + property alias enabledWheel: wheelMouse.enabled + + property double valueForPosition: range.value + + property bool dragActive: seekArea.drag.active + + property int intervalDragCall: 1000 + + property int orientation: QtHorizontal + + + signal valueChanged(real value) + + signal sliderDragged() + + signal controlBarWheelEvent(variant wheel) + + +//##################################################### + + property bool horizontal: orientation == QtHorizontal + + //NOTE: Vertical State + states: State{ + when: orientation == QtVertical + + //range + PropertyChanges{ + target: range + positionAtMaximum: content.height + positionAtMinimum: 0 + } + //bar + PropertyChanges{ + target: bar + height: range.position + + anchors{ + topMargin: 0 + bottomMargin: -1 + } + } + AnchorChanges{ + target: bar + anchors{ + top: undefined + right: parent.right + } + } + //seek + PropertyChanges{ + target: seek + height: 2 + width: bar.width + x: 0 + y: !seekArea.drag.active ? bar.height : 0 + } + AnchorChanges{ + target: seek + anchors{ + verticalCenter: undefined + horizontalCenter: bar.horizontalCenter + left: undefined + right: undefined + bottom: !seekArea.pressed ? bar.top : undefined + } + } + //seekArea + PropertyChanges{ + target: seekArea + drag{ + axis: Drag.YAxis + maximumX: 0 + minimumY: 0 + maximumY: barBg.height + } + } + //wheelMouse + PropertyChanges{ + target: wheelMouse + anchors{ + leftMargin: -8 + rightMargin: -4 + } + } + AnchorChanges{ + target: wheelMouse + anchors{ + top: content.top + } + } + } + +//##################################################### + + RangeModel{ + id: range + + minimumValue: 0 + maximumValue: 0 + value: 0 + positionAtMinimum: 0 + positionAtMaximum: content.width + + } + + Rectangle{ + id: content + + color: theme.textColor + radius: 2 + smooth: true + anchors.fill: parent + + Rectangle{ + id: barBg + + smooth: true + radius: 2 + anchors.fill: parent + color: theme.backgroundColor + opacity: 0.7 + + } + + Rectangle{ + id: bar + + anchors{ + left: parent.left + top: parent.top + bottom: parent.bottom + //topMargin: -1 + //bottomMargin: -1 + } + radius: 2 + smooth: true + color: theme.highlightColor + width: range.position + + Behavior on width{ enabled: horizontal ; NumberAnimation{duration: 150} } + Behavior on height{ enabled: !horizontal ; NumberAnimation{duration: 150} } + } + + Rectangle{ + id: seek + width: 2 + height: parent.height + color: theme.highlightColor + + border{ + color: color + width: 4 + } + + opacity: 0 + radius: 0.1 + smooth: true + + anchors{ + verticalCenter: bar.verticalCenter + leftMargin: -2 + left: !seekArea.pressed ? bar.right : undefined + } + + Behavior on opacity{ NumberAnimation{duration: 150} } + + } + + //ATTENTION: This will be removed in QtQuick 2.0 + QtExtra.MouseEventListener{ + id: wheelMouse + + enabled: false + visible: enabled + + height: 30 + anchors{ + left: parent.left + right: parent.right + bottom: parent.bottom + rightMargin: -30 + bottomMargin: -4 + } + onWheelMoved: { + if(wheel.delta > 0) + range.setValue(range.value + 0.05) + else + range.setValue(range.value - 0.05) + valueChanged(range.value) + } + Component.onCompleted: controlBarWheelEvent.connect(wheelMoved) + } + + MouseArea{ + id: seekArea + + anchors.fill: parent + + hoverEnabled: true + + drag{ + //target: seek + axis: Drag.XAxis + minimumX: 0 + maximumX: barBg.width + } + onEntered: seek.opacity = 1 + + onExited: if(!pressed) seek.opacity = 0 + + onPressed: { + if(horizontal) seek.x = mouseX + else seek.y = mouseY + } + + onReleased: { + if(!containsMouse) seek.opacity = 0 + if(horizontal) + valueChanged(range.valueForPosition(mouseX)) + else + valueChanged(range.valueForPosition( drag.maximumY - mouseY)) + } + + function xPosition(mouseX){ + if(mouseX > drag.maximumX) seek.x = drag.maximumX + else if(mouseX < 0) seek.x = 0 + else seek.x = mouseX + + var currentValue = range.valueForPosition(seek.x) + if(currentValue / intervalDragCall != valueForPosition / intervalDragCall) + { + valueForPosition = currentValue + sliderDragged() + } + + if (pressAndChange) valueChanged(range.valueForPosition(seek.x)) + } + + function yPosition(mouseY){ + if(mouseY > drag.maximumY) seek.y = drag.maximumY + else if(mouseY < 0) seek.y = 0 + else seek.y = mouseY + + //invert y axis + mouseY = drag.maximumY - mouseY + + var currentValue = range.valueForPosition(content.height - seek.y) + if(currentValue / intervalDragCall != valueForPosition / intervalDragCall) + { + valueForPosition = currentValue + sliderDragged() + } + + if (pressAndChange) valueChanged(range.valueForPosition(content.height - seek.y)) + } + + onPositionChanged: { + if(!pressed) return + if(orientation == QtHorizontal) xPosition(mouseX) + else yPosition(mouseY) + } + } + } +} diff --git a/plasmoid/contents/ui/SliderSeek.qml b/plasmoid/contents/ui/SliderSeek.qml new file mode 100644 index 0000000..b242425 --- /dev/null +++ b/plasmoid/contents/ui/SliderSeek.qml @@ -0,0 +1,87 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import "plasmapackage:/code/control.js" as Control + + +Row{ + id: sliderSeek + + spacing: 8 + + property bool labelVisible: true + + signal currentSeekPosition(int position) + + width: childrenRect.width + + height: childrenRect.height + + TimeLabel{ + id: lengthTime + + hover: false + currentTime: mpris.length + autoTimeTrigger: mpris.isMaximumLoad + + anchors{ + verticalCenter: slider.verticalCenter + verticalCenterOffset: -1 + } + visible: labelVisible + } + + Slider{ + id: slider + + maximumValue: mpris.length + value: mpris.position + width: parent.width - ( labelVisible ? (lengthTime.width * 2 + spacing * 3) : 0 ) + height: 10 + + onValueChanged: Control.seek(value, mpris.position) + onSliderDragged: positionTime.timeChanged() + + } + + TimeLabel{ + id: positionTime + + hover: true + topTime: mpris.length + currentTime: slider.pressed ? slider.valueForPosition : mpris.position + autoTimeTrigger: mpris.isMaximumLoad + + anchors{ + verticalCenter: slider.verticalCenter + verticalCenterOffset: -1 + } + + onTimeChanged: { + if(Control.openedPopup) + parent.currentSeekPosition(currentTime) + } + + visible: labelVisible + negative: plasmoid.readConfig('timeNegative') + } +} diff --git a/plasmoid/contents/ui/TimeLabel.qml b/plasmoid/contents/ui/TimeLabel.qml new file mode 100644 index 0000000..c25a101 --- /dev/null +++ b/plasmoid/contents/ui/TimeLabel.qml @@ -0,0 +1,98 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import "plasmapackage:/code/control.js" as Control + +Item{ + + id: time + + //seconds + property int topTime: 0 + //seconds + property int currentTime: 0 + + property bool negative: false + + property alias hover: mouseArea.enabled + + property int min: 0 + + property int sec: 0 + + property alias autoTimeTrigger: timer.running + + implicitWidth: label.implicitWidth + + implicitHeight: label.implicitHeight + 4 + + signal timeChanged() + + onTimeChanged: { + var min + var sec = currentTime/1000 + if (negative && topTime) sec = Math.abs(topTime/1000 - sec) + min = parseInt(sec/60) + sec = parseInt(sec - min*60) + time.min = min + time.sec = sec + } + + Timer{ + id: timer + + interval: 300 + repeat: true + running: true + onTriggered: timeChanged() + } + + Label{ + id: label + text: (negative ? '-' + min : min) + ':' + ( sec >= 0 && sec <= 9 ? '0'+sec : sec ) + font.weight: Font.DemiBold + //style: Text.Sunken + //styleColor: theme.textColor + smooth: true + verticalAlignment: Text.AlignVCenter + + Behavior on color{ ColorAnimation { duration: 250 } } + } + + MouseArea{ + id: mouseArea + anchors.fill: parent + hoverEnabled: true + enabled: false + + onEntered: label.color = theme.highlightColor + onExited: label.color = theme.textColor + onReleased: { + if (!exited || containsMouse ){ + negative = !negative + plasmoid.writeConfig('timeNegative', negative) + timeChanged() + } + } + } + +} diff --git a/plasmoid/contents/ui/TitlePopup.qml b/plasmoid/contents/ui/TitlePopup.qml new file mode 100644 index 0000000..58db00a --- /dev/null +++ b/plasmoid/contents/ui/TitlePopup.qml @@ -0,0 +1,45 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import org.kde.plasma.graphicswidgets 0.1 + +Column{ + id: title + + height: childrenRect.height + 10 + + PlasmaComponents.Label{ + id: text + + text: mpris.identity + width: parent.width + lineHeight: 1.2 + styleColor: theme.highlightColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Separator{ + orientation: Qt.Horizontal + width: parent.width + } +} diff --git a/plasmoid/contents/ui/TrackInfo.qml b/plasmoid/contents/ui/TrackInfo.qml new file mode 100644 index 0000000..9c10213 --- /dev/null +++ b/plasmoid/contents/ui/TrackInfo.qml @@ -0,0 +1,228 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import "plasmapackage:/ui/" as PlayBar + +Item{ + id: trackInfo + + property alias widthLabelArtist: artist.width + + property alias widthLabelAlbum: album.width + + property alias contentHeight: artist.height + + property alias titleFontWeight: title.font.weight + + property int albumArtistPointsize: 10 + + implicitHeight: content.height + + Column{ + id: content + clip: true + spacing: -2 + width: parent.width + height: childrenRect.height + + Label{ + id: title + + text: mpris.title + wrapMode: Text.WrapAnywhere + elide: Text.ElideRight + maximumLineCount: 1 + visible: mpris.title != "" + + font.pointSize: 14 + + width: parent.width + lineHeight: 1.2 + + property bool isWrapped: implicitWidth > width ? true : false + + function normalState(){ + wrapMode = Text.WrapAnywhere + x = 0 + state = '' + } + + states: State{ + name: 'scroll' + PropertyChanges{ + target: title + wrapMode: Text.NoWrap + x: width / 1.1 - implicitWidth + } + } + + Behavior on x{ + SequentialAnimation{ + //TODO: Change to PropertyAction + PropertyAnimation{ + property: 'wrapMode' + duration: 0 + } + SmoothedAnimation{ + property: 'x' + velocity: 60 + } + PauseAnimation{ duration: 120 } + SmoothedAnimation{ + to: 0 + property: 'x' + velocity: 70 + } + ScriptAction{ script: title.normalState() } + } + } + MouseArea{ + id: mouse + + acceptedButtons: Qt.NoButton + anchors.fill: title + hoverEnabled: true + onEntered: if(title.isWrapped) title.state = 'scroll' + } + } + + Column{ + clip: true + children: [artist, album] + } + + Label{ + id: artist + + text: i18n("By %1", mpris.artist) + wrapMode: Text.WrapAnywhere + elide: Text.ElideRight + maximumLineCount: 1 + font.pointSize: albumArtistPointsize + visible: mpris.artist != "" + + height: 12 + width: content.width + + property bool isWrapped: implicitWidth > width ? true : false + + function normalState(){ + wrapMode = Text.WrapAnywhere + x = 0 + state = "" + } + + states: State{ + name: 'scroll' + PropertyChanges{ + target: artist + wrapMode: Text.NoWrap + x: width / 1.1 - implicitWidth + } + } + + Behavior on x{ + SequentialAnimation{ + PropertyAnimation{ + property: 'wrapMode' + duration: 0 + } + SmoothedAnimation{ + property: 'x' + velocity: 60 + } + PauseAnimation { duration: 120 } + SmoothedAnimation{ + to: 0 + property: 'x' + velocity: 70 + } + ScriptAction{ script: artist.normalState() } + } + } + MouseArea{ + acceptedButtons: Qt.NoButton + anchors.fill: parent + hoverEnabled: true + onEntered: if(artist.isWrapped) artist.state = 'scroll' + } + } + + Label{ + id: album + + text: i18n("On %1", mpris.album) + wrapMode: Text.WrapAnywhere + elide: Text.ElideRight + maximumLineCount: 1 + + font.pointSize: albumArtistPointsize + + visible: mpris.album != "" + + width: content.width + + property bool isWrapped: implicitWidth > width ? true : false + + function normalState(){ + wrapMode = Text.WrapAnywhere + state = "" + } + + states: State{ + name: 'scroll' + PropertyChanges{ + target: album + wrapMode: Text.NoWrap + x: width / 1.1 - implicitWidth + } + } + + Behavior on x{ + SequentialAnimation{ + PropertyAnimation{ + property: 'wrapMode' + duration: 0 + } + SmoothedAnimation{ + property: 'x' + velocity: 60 + } + PauseAnimation { duration: 120 } + SmoothedAnimation{ + to: 0 + property: 'x' + velocity: 70 + } + ScriptAction{ script: album.normalState() } + } + } + + MouseArea{ + acceptedButtons: Qt.NoButton + anchors.fill: parent + hoverEnabled: true + onEntered: if(album.isWrapped) album.state = 'scroll' + } + } + } +} diff --git a/plasmoid/contents/ui/Volume.qml b/plasmoid/contents/ui/Volume.qml new file mode 100644 index 0000000..be1fcbf --- /dev/null +++ b/plasmoid/contents/ui/Volume.qml @@ -0,0 +1,178 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 +import "plasmapackage:/code/control.js" as Control + + +Item{ + id: volumeWidget + + property real volume: mpris.volume + + property bool muted: volume == 0 ? true : false + + property alias labelVisible: label.visible + + property bool labelAbove: true + + property alias iconVisible: icon.visible + + property alias orientation: slider.orientation + + width: childrenRect.width + + height: childrenRect.height + + Flow{ + id: content + + states: [ + State{ + when: labelAbove + PropertyChanges{ + target: content + flow: Flow.TopToBottom + spacing: -3 + } + PropertyChanges{ + target: label + width: slider.width + horizontalAlignment: Text.AlignHCenter + } + }, + State{ + when: !labelAbove + PropertyChanges{ + target: content + flow: Flow.LeftToRight + spacing: 8 + } + PropertyChanges{ + target: label + width: 32 + height: sliderWidget.height + horizontalAlignment: Text.AlignLeft + } + PropertyChanges{ + target: inline + children: [label, sliderWidget] + spacing: 8 + } + } + ] + + PlasmaComponents.Label{ + id: label + + function setLabel(value){ + text = parseInt(value * 100)+'%' + } + + text: parseInt(volume * 100)+'%' + font.weight: Font.DemiBold + width: visible ? implicitWidth : 0 + + Component.onCompleted: mpris.volumeChanged.connect(setLabel) + } + + Row{ + id: inline + } + + Row{ + id: sliderWidget + spacing: iconVisible ? 8 : 0 + + Slider{ + id: slider + + maximumValue: if(mpris.source.match('vlc.*')) 1.25 ; else 1 + + value: volume + pressAndChange: true + enabledWheel: true + intervalDragCall: 1 + + property int widthCorrection: labelAbove || !labelVisible ? 0: 43 + + width: orientation == QtVertical ? + 8 : volumeWidget.width - icon.width - parent.spacing - widthCorrection + height: orientation == QtHorizontal ? + 8 : volumeWidget.height - icon.width - parent.spacing + + onValueChanged: { + Control.setVolume(value) + Control.currentVolume = value + } + + onSliderDragged: label.setLabel(valueForPosition) + + Component.onCompleted: Control.controlBarWheelEvent = (controlBarWheelEvent) + //Component.onDestruction: Control.controlBarWheelEvent = null + + } + + IconWidget{ + id: icon + + svg: update() + size: visible ? 24 : 0 + + anchors.verticalCenter: slider.verticalCenter + property variant level: [ + "audio-volume-muted", "audio-volume-low", + "audio-volume-medium", "audio-volume-high" + ] + + property real volumePrev: 0 + + function update(){ + if(!visible) return null + if(plasmoid.readConfig("opaqueIcons") == true) + return Svg(plasmoid.readConfig("audio-opaque")) + else return Svg(plasmoid.readConfig("audio-clear")) + } + + Component.onCompleted: { + plasmoid.addEventListener('configChanged', function(){ + svg = update() + svgChanged() + }) + } + + elementId: + if (muted) level[0] + else if (volume <= 0.3) level[1] + else if (volume <= 0.6) level[2] + else level[3] + + onClicked: { + if(!muted){ + volumePrev = volume + Control.setVolume(0) + } else Control.setVolume(volumePrev) + } + } + } + } +} diff --git a/plasmoid/contents/ui/config.ui b/plasmoid/contents/ui/config.ui new file mode 100644 index 0000000..deafa4d --- /dev/null +++ b/plasmoid/contents/ui/config.ui @@ -0,0 +1,579 @@ + + + Form + + + + 0 + 0 + 360 + 386 + + + + + 0 + 0 + + + + + 360 + 386 + + + + Form + + + + + + + 75 + true + + + + General preferences + + + false + + + + + + + + + 0 + 0 + + + + + 50 + false + true + + + + Qt::LeftToRight + + + Display Stop button: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + Qt::LeftToRight + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Avoid popup close when it loses focus: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + The window behaves like a dialogue, correcting an +annoying behavior. If you use CairoDock or Plank +disable this option or create a KWin rule for "Plasma". + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Qt::LeftToRight + + + Opaque buttons: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + + + + Qt::LeftToRight + + + false + + + + + + true + + + false + + + false + + + false + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 10 + + + + + + + + + 75 + false + true + + + + Control Bar + + + false + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Qt::ImhNone + + + true + + + false + + + + + + QAbstractSpinBox::CorrectToNearestValue + + + true + + + pixels + + + + + + 16 + + + 50 + + + 2 + + + + + + + + 50 + false + + + + Flat buttons: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + + + + + + + + + 50 + false + + + + Show notifications: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Visible separator: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + + + + + + + + + + + + 50 + false + + + + Size of buttons: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 20 + 10 + + + + + + + + + 75 + true + + + + Qt::LeftToRight + + + Popup + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + false + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + false + + + 0 + + + 2 + + + false + + + + Default + + + + + ToolTip + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Style popup: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Layout: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 50 + false + false + false + + + + 3 + + + + PlayBar + + + + + Minimalist + + + + + Cool + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Expanding + + + + 20 + 0 + + + + + + + + kcfg_showStop + kcfg_windowFlagDialog + kcfg_opaqueIcons + kcfg_flatButtons + kcfg_buttonSize + kcfg_showNotifications + kcfg_separatorVisible + kcfg_popupStyle + kcfg_PlayBarLayout + + + + diff --git a/plasmoid/contents/ui/main.qml b/plasmoid/contents/ui/main.qml new file mode 100644 index 0000000..80d697b --- /dev/null +++ b/plasmoid/contents/ui/main.qml @@ -0,0 +1,293 @@ +// -*- coding: iso-8859-1 -*- +/* + * Author: audoban + * + * 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 2.3 +import org.kde.plasma.core 2.0 as PlasmaCore +import org.kde.plasma.components 2.0 as PlasmaComponents +import "plasmapackage:/code/control.js" as Control +// import org.kde.qtextracomponents 2.0 as QtExtra +// import org.kde.plasma.graphicswidgets 2.0 as PlasmaWidgets + +Item { + id: main + + property int minimumWidth: childrenRect.width + + property int minimumHeight: childrenRect.height + + property int maximumWidth: 256 + + property int maximumHeight: 256 + + property bool vertical: false + + property bool popupOpen: popup.status == PlasmaComponents.DialogStatus.Open + + property bool showNotifications: plasmoid.readConfig('showNotifications') + + opacity: !mouseArea.enabled ? 1 : 0.6 + + Behavior on opacity{ + NumberAnimation{ duration: 250 } + } + + Mpris2{ id: mpris } + + //########################### + //Context menu + function action_raise(){ + Control.startOperation('Raise') + } + + function action_quit(){ + Control.startOperation('Quit') + popup.close() + } + + function action_nextSource(){ + mpris.nextSource() + if(showNotifications) Control.sourceNotify() + } + + //TODO: open file + //########################### + + function setMaximumLoad(){ + mpris.interval = mpris.maximumLoad + } + + function setMinimumLoad(){ + mpris.interval = mpris.minimumLoad + } + + states:[ + State{ + name: "maximumLoad" + when: popupOpen + + StateChangeScript{ + script: setMaximumLoad() + } + }, + State{ + name: "minimumLoad" + when: !popupOpen + + StateChangeScript{ + script: setMinimumLoad() + } + } + ] + + Component.onCompleted:{ + plasmoid.aspectRatioMode = IgnoreAspectRatio + + + function formFactorChanged() + { + switch(plasmoid.formFactor) + { + case Planar: + vertical = false + plasmoid.backgroundHints = StandardBackground + plasmoid.resize(minimumWidth, minimumHeight) + return + case Horizontal: + plasmoid.backgroundHints = NoBackground + vertical = false + return + case Vertical: + plasmoid.backgroundHints = NoBackground + vertical = true + return + } + } + print(theme.themeName) + + plasmoid.formFactorChanged.connect(formFactorChanged) + plasmoid.resize(controlBar.width, controlBar.height) + formFactorChanged() + + plasmoid.addEventListener('configChanged', function(){ + showNotifications = plasmoid.readConfig('showNotifications') + sep.visible = plasmoid.readConfig('separatorVisible') + playbackBar.buttonSize = plasmoid.readConfig('buttonSize') + shortcuts.connectSource("Shortcuts") + } + ) + + if(plasmoid.readConfig('first-run') == true){ + plasmoid.writeConfig('first-run', 'false') + Control.autoSelectOpaqueIcons(theme.themeName) + } + } + + //ATTENTION: This will be removed in QtQuick 2.0 because will be unnecessary + // Volume Area + // DEPRECATED: + MouseArea{ + id: volumeWheelArea + + acceptedButtons: Qt.XButton1 | Qt.XButton2 + enabled: mpris.sourceActive + + anchors.fill: controlBar + + onWheel: { + if(!mpris.sourceActive) return + if(mpris.source != 'spotify'){ + Control.controlBarWheelEvent(wheel) + Control.controlBarWheelNotify() + } + } + } + //---- + + //Enabled when no source active +// MouseArea{ +// id: mouseArea +// acceptedButtons: Qt.LeftButton +// anchors.fill: controlBar +// z: 99 +// enabled: !mpris.sourceActive +// } + + Flow{ + id: controlBar + + spacing: 4 + + flow: vertical ? Flow.TopToBottom : Flow.LeftToRight + + anchors{ + centerIn: parent + } + + Item{ + children: [iconPopup, sep] + width: vertical ? playbackBar.width : height + height: vertical ? width : playbackBar.height + } + + PopupButton{ + id: iconPopup + + elementId: main.popupOpen ? opened : closed + onClicked: { main.popupOpen ? popup.close(): popup.open(); } + + anchors.centerIn: parent + + size: playbackBar.flatButtons ? playbackBar.buttonSize - 6 : playbackBar.buttonSize - 10 + } + + PlasmaWidgets.Separator{ + id: sep + + orientation: vertical ? Qt.Horizontal : Qt.Vertical + + anchors{ + top: vertical ? undefined : iconPopup.top + bottom: vertical ? parent.bottom : iconPopup.bottom + left: vertical ? iconPopup.left : undefined + right: vertical ? iconPopup.right : parent.right + leftMargin: vertical ? 0 : controlBar.spacing/2 + topMargin: vertical ? controlBar.spacing/2 : 0 + } + } + + PlaybackBar{ + id: playbackBar + + buttonSize: plasmoid.readConfig('buttonSize') + } + + Dialog{ + id: popup + + content: [ contentItem ] + title: [ titleItem ] + visualParent: iconPopup + + Component.onCompleted: contentItem.layoutChanged.connect(updateSize) + + TitlePopup{ + id: titleItem + width: contentItem.width + } + + Layout{ + id: contentItem + } + } + } + + Component{ + id: notification + + Notification{ + parent: main + maximumWidth: (vertical ? controlBar.height : controlBar.width) + minimumWidth: (vertical ? playbackBar.height : playbackBar.width) + + verticalOffset: (iconPopup.height)/2 + controlBar.spacing + (playbackBar.flatButtons ? 2 : 4) + horizontalOffset: (iconPopup.width)/2 + controlBar.spacing + (playbackBar.flatButtons ? 2 : 4) + + anchors{ + centerIn: parent + } + + Component.onCompleted: mpris.sourceChanged.connect(sourceNotify) + } + } + + //Load the notifications + Loader{ + id: loader + sourceComponent: + if(showNotifications) notification + else undefined + } + + PlasmaCore.DataSource{ + id: shortcuts + + engine: 'playbarengine' + + connectedSources: ['Provider'] + + onNewData: if(data['SourceMpris2'] != undefined) print(data['SourceMpris2']) + + function sourceChanged(source){ + var serv = serviceForSource('Provider'); + var op = serv.operationDescription('SetSource'); + op['name'] = source; + serv.startOperationCall(op); + } + Component.onCompleted: mpris.sourceChanged.connect(sourceChanged) + } + +} + + + + + + diff --git a/plasmoid/contents/ui/private/AppManager.js b/plasmoid/contents/ui/private/AppManager.js new file mode 100644 index 0000000..daed77a --- /dev/null +++ b/plasmoid/contents/ui/private/AppManager.js @@ -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:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function rootObject() { + var next = parent + while (next && next.parent) + next = next.parent + return next +} + +function findParent(child, propertyName) { + if (!child) + return null + var next = child.parent + while (next && !next.hasOwnProperty(propertyName)) + next = next.parent + return next +} + +function sceneX(item) { + // Binding may cause that this function is evaluated even when item is undefined, + // but in that case the Binding isn't active however so we can safely return 0 + var x = 0 + if (item) { + x = item.x + var p = item.parent + while (p) { + x += p.x + p = p.parent + } + } + return x +} + +function sceneY(item) { + // Binding may cause that this function is evaluated even when item is undefined, + // but in that case the Binding isn't active however so we can safely return 0 + var y = 0 + if (item) { + y = item.y + var p = item.parent + while (p) { + y += p.y + p = p.parent + } + } + return y +} diff --git a/plasmoid/contents/ui/private/InlineDialog.qml b/plasmoid/contents/ui/private/InlineDialog.qml new file mode 100644 index 0000000..42f538e --- /dev/null +++ b/plasmoid/contents/ui/private/InlineDialog.qml @@ -0,0 +1,179 @@ +/* + * Copyright 2012 Marco Martin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details + * + * You should have received a copy of the GNU Library General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import QtQuick 1.1 +import org.kde.plasma.core 0.1 as PlasmaCore +import org.kde.plasma.extras 0.1 as PlasmaExtras +import org.kde.plasma.components 0.1 as PlasmaComponents + +Item { + id: root + property Item visualParent + z: 9000 + property int status: PlasmaComponents.DialogStatus.Closed + default property alias data: contentItem.data + + function open() + { + if (root.visualParent) { + internal.parentPos = root.visualParent.mapToItem(dismissArea.parent, 0, 0) + } + root.status = PlasmaComponents.DialogStatus.Opening + appearAnimation.restart() + } + + function close() + { + root.status = PlasmaComponents.DialogStatus.Closing + appearAnimation.restart() + } + + SequentialAnimation { + id: appearAnimation + NumberAnimation { + duration: 250 + easing.type: Easing.InOutQuad + target: dismissArea + properties: "opacity" + to: root.status == PlasmaComponents.DialogStatus.Opening ? 1 : 0 + } + ScriptAction { + script: root.status == PlasmaComponents.DialogStatus.Opening ? root.status = PlasmaComponents.DialogStatus.Open : PlasmaComponents.DialogStatus.Closed + } + } + + MouseArea { + id: dismissArea + z: 9000 + anchors.fill: parent + opacity: 0 + //to not pass hover events to the background + hoverEnabled: true + + //FIXME: this is an hack: it's taking the dialog background making sure no opaque or transparent are selected + //in Plasma2 we need to have the backingstore blur there as well + PlasmaExtras.FallbackComponent { + id: fallbackComponent + basePath: "desktoptheme" + candidates: [theme.themeName, "default"] + property string svgPath: fallbackComponent.filePath("/dialogs/background.svgz") + } + Connections { + target: theme + //fallback if inline-background doesn't work + onThemeChanged: { + fallbackComponent.svgPath = fallbackComponent.filePath("/dialogs/background.svgz") + shadowFrame.visible = backgroundSvg.hasElement("shadow-top") + } + } + PlasmaCore.FrameSvgItem { + id: shadowFrame + imagePath: fallbackComponent.svgPath + prefix: "shadow" + anchors { + fill: internal + leftMargin: -margins.left + topMargin: -margins.top + rightMargin: -margins.right + bottomMargin: -margins.bottom + } + Component.onCompleted: shadowFrame.visible = backgroundSvg.hasElement("shadow-top") + } + PlasmaCore.FrameSvgItem { + id: internal + property variant parentPos + imagePath: fallbackComponent.svgPath + property bool under: root.visualParent ? internal.parentPos.y + root.visualParent.height + height < dismissArea.height : true + //bindings won't work inside anchers definition + onUnderChanged: { + if (under) { + tipSvg.anchors.top = undefined + tipSvg.anchors.bottom = tipSvg.parent.top + } else { + tipSvg.anchors.bottom = undefined + tipSvg.anchors.top = tipSvg.parent.bottom + } + } + + x: { + if (root.visualParent) { + internal.parentPos.x - internal.width/2 + root.visualParent.width/2 + } else { + dismissArea.width/2 - internal.width/2 + } + } + y: { + if (root.visualParent) { + if (under) { + internal.parentPos.y + root.visualParent.height + } else { + internal.parentPos.y - internal.height + } + } else { + dismissArea.height/2 - internal.height/2 + } + } + width: contentItem.width + margins.left + margins.right + height: contentItem.height + margins.top + margins.bottom + + PlasmaCore.SvgItem { + id: tipSvg + visible: root.visualParent != null + svg: PlasmaCore.Svg { + id: backgroundSvg + imagePath: fallbackComponent.svgPath + } + elementId: internal.under ? "balloon-tip-top" : "balloon-tip-bottom" + anchors { + horizontalCenter: parent.horizontalCenter + bottom: parent.top + top: parent.bottom + topMargin: -backgroundSvg.elementSize("hint-bottom-shadow").height - 1 + bottomMargin: -backgroundSvg.elementSize("hint-top-shadow").height - 1 + } + width: naturalSize.width + height: naturalSize.height + } + MouseArea { + id: contentItem + x: parent.margins.left + y: parent.margins.top + width: childrenRect.width + height: childrenRect.height + onClicked: mouse.accepted = true + } + } + onClicked: { + print("clic") + root.close() + } + Component.onCompleted: { + var candidate = root + while (candidate.parent) { + candidate = candidate.parent + } + if (candidate) { + dismissArea.parent = candidate + } else { + dismissArea.visible = false + } + internal.parentPos = root.mapToItem(dismissArea.parent, 0, 0) + } + } +} diff --git a/plasmoid/contents/ui/rc.js b/plasmoid/contents/ui/rc.js new file mode 100644 index 0000000..f53ae01 --- /dev/null +++ b/plasmoid/contents/ui/rc.js @@ -0,0 +1,62 @@ +// i18n: file: plasmoid/contents/ui/config.ui:26 +// i18n: ectx: property (windowTitle), widget (QWidget, Form) +i18n("Form"); +// i18n: file: plasmoid/contents/ui/config.ui:38 +// i18n: ectx: property (title), widget (QGroupBox, groupBox_1) +i18n("General preferences"); +// i18n: file: plasmoid/contents/ui/config.ui:65 +// i18n: ectx: property (text), widget (QLabel, label_1) +i18n("Display Stop button: "); +// i18n: file: plasmoid/contents/ui/config.ui:103 +// i18n: ectx: property (text), widget (QLabel, label_2) +i18n("Avoid popup close when it loses focus: "); +// i18n: file: plasmoid/contents/ui/config.ui:121 +// i18n: ectx: property (toolTip), widget (QCheckBox, kcfg_windowFlagDialog) +i18n("The window behaves like a dialogue, correcting an \n" +"annoying behavior. If you use CairoDock or Plank \n" +"disable this option or create a KWin rule for \"Plasma\"."); +// i18n: file: plasmoid/contents/ui/config.ui:146 +// i18n: ectx: property (text), widget (QLabel, label_3) +i18n("Opaque buttons: "); +// i18n: file: plasmoid/contents/ui/config.ui:218 +// i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +i18n("Control Bar"); +// i18n: file: plasmoid/contents/ui/config.ui:259 +// i18n: ectx: property (suffix), widget (QSpinBox, kcfg_buttonSize) +i18n(" pixels"); +// i18n: file: plasmoid/contents/ui/config.ui:284 +// i18n: ectx: property (text), widget (QLabel, label_4) +i18n("Flat buttons: "); +// i18n: file: plasmoid/contents/ui/config.ui:313 +// i18n: ectx: property (text), widget (QLabel, label_6) +i18n("Show notifications: "); +// i18n: file: plasmoid/contents/ui/config.ui:348 +// i18n: ectx: property (text), widget (QLabel, label_7) +i18n("Visible separator: "); +// i18n: file: plasmoid/contents/ui/config.ui:377 +// i18n: ectx: property (text), widget (QLabel, label_5) +i18n("Size of buttons: "); +// i18n: file: plasmoid/contents/ui/config.ui:417 +// i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +i18n("Popup"); +// i18n: file: plasmoid/contents/ui/config.ui:459 +// i18n: ectx: property (text), item, widget (QComboBox, kcfg_popupStyle) +i18n("Default"); +// i18n: file: plasmoid/contents/ui/config.ui:464 +// i18n: ectx: property (text), item, widget (QComboBox, kcfg_popupStyle) +i18n("ToolTip"); +// i18n: file: plasmoid/contents/ui/config.ui:484 +// i18n: ectx: property (text), widget (QLabel, label_8) +i18n("Style popup: "); +// i18n: file: plasmoid/contents/ui/config.ui:506 +// i18n: ectx: property (text), widget (QLabel, label_9) +i18n("Layout: "); +// i18n: file: plasmoid/contents/ui/config.ui:528 +// i18n: ectx: property (text), item, widget (QComboBox, kcfg_PlayBarLayout) +i18n("PlayBar"); +// i18n: file: plasmoid/contents/ui/config.ui:533 +// i18n: ectx: property (text), item, widget (QComboBox, kcfg_PlayBarLayout) +i18n("Minimalist"); +// i18n: file: plasmoid/contents/ui/config.ui:538 +// i18n: ectx: property (text), item, widget (QComboBox, kcfg_PlayBarLayout) +i18n("Cool"); diff --git a/plasmoid/locale/es/LC_MESSAGES/plasma_applet_playbar.mo b/plasmoid/locale/es/LC_MESSAGES/plasma_applet_playbar.mo new file mode 100644 index 0000000..5e2dfe4 Binary files /dev/null and b/plasmoid/locale/es/LC_MESSAGES/plasma_applet_playbar.mo differ diff --git a/plasmoid/locale/es/LC_MESSAGES/playbar.po b/plasmoid/locale/es/LC_MESSAGES/playbar.po new file mode 100644 index 0000000..572608f --- /dev/null +++ b/plasmoid/locale/es/LC_MESSAGES/playbar.po @@ -0,0 +1,130 @@ +# Header entry was created by Lokalize. +# +# smith AR , 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-09-10 21:13-0500\n" +"PO-Revision-Date: 2014-09-10 21:14-0500\n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.5\n" +"Last-Translator: smith AR \n" + +#: plasmoid/contents/ui/Mpris2.qml:51 plasmoid/contents/ui/Mpris2.qml:80 +#: plasmoid/contents/ui/Mpris2.qml:165 +msgid "No source" +msgstr "Sin medios" + +#: plasmoid/contents/ui/rc.js:3 +msgid "Form" +msgstr "Formulario" + +#: plasmoid/contents/ui/rc.js:6 +msgid "General preferences" +msgstr "Preferencias generales" + +#: plasmoid/contents/ui/rc.js:9 +msgid "Display Stop button: " +msgstr "Mostrar el botón de Stop: " + +#: plasmoid/contents/ui/rc.js:12 +msgid "Avoid popup close when it loses focus: " +msgstr "Evitar cerrar la ventana emergente cuando se pierde foco: " + +#: plasmoid/contents/ui/rc.js:15 +msgid "" +"The window behaves like a dialogue, correcting an \n" +"annoying behavior. If you use CairoDock or Plank \n" +"disable this option or create a KWin rule for \"Plasma\"." +msgstr "" +"La ventana es tratada como un dialogo corrigiendo un \n" +"comportamiento molesto. Si usa CairoDock o Plank \n" +"puede considerar deshabilitar esta opción o añadir \n" +"una regla KWin para \"plasma-desktop\"." + +#: plasmoid/contents/ui/rc.js:20 +msgid "Opaque buttons: " +msgstr "Botones opacos: " + +#: plasmoid/contents/ui/rc.js:23 +msgid "Control Bar" +msgstr "Barra de Control" + +#: plasmoid/contents/ui/rc.js:26 +msgid " pixels" +msgstr " píxeles" + +#: plasmoid/contents/ui/rc.js:29 +msgid "Flat buttons: " +msgstr "Botones planos: " + +#: plasmoid/contents/ui/rc.js:32 +msgid "Show notifications: " +msgstr "Ver notificaciones: " + +#: plasmoid/contents/ui/rc.js:35 +msgid "Visible separator: " +msgstr "Separador visible: " + +#: plasmoid/contents/ui/rc.js:38 +msgid "Size of buttons: " +msgstr "Tamaño de los botones: " + +#: plasmoid/contents/ui/rc.js:41 +msgid "Popup" +msgstr "Ventana Emergente" + +#: plasmoid/contents/ui/rc.js:44 +msgid "Default" +msgstr "Por defecto" + +#: plasmoid/contents/ui/rc.js:47 +msgid "ToolTip" +msgstr "ToolTip" + +#: plasmoid/contents/ui/rc.js:50 +msgid "Style popup: " +msgstr "Estilo de la ventana: " + +#: plasmoid/contents/ui/rc.js:53 +msgid "Layout: " +msgstr "Diseño: " + +#: plasmoid/contents/ui/rc.js:56 +msgid "PlayBar" +msgstr "PlayBar" + +#: plasmoid/contents/ui/rc.js:59 +msgid "Minimalist" +msgstr "Mínimo" + +#: plasmoid/contents/ui/rc.js:62 +msgid "Cool" +msgstr "Fresco" + +#: plasmoid/contents/ui/TrackInfo.qml:116 +msgid "By %1" +msgstr "Por %1" + +#: plasmoid/contents/ui/TrackInfo.qml:173 +msgid "On %1" +msgstr "En %1" + +#: plasmoid/contents/code/control.js:83 +msgid "Open %1" +msgstr "Abrir %1" + +#: plasmoid/contents/code/control.js:84 +msgid "Quit" +msgstr "Salir" + +#: plasmoid/contents/code/control.js:86 +msgid "Next source" +msgstr "Siguiente medio" + diff --git a/plasmoid/locale/ru/LC_MESSAGES/plasma_applet_playbar.mo b/plasmoid/locale/ru/LC_MESSAGES/plasma_applet_playbar.mo new file mode 100644 index 0000000..31cde4d Binary files /dev/null and b/plasmoid/locale/ru/LC_MESSAGES/plasma_applet_playbar.mo differ diff --git a/plasmoid/locale/ru/LC_MESSAGES/playbar.po b/plasmoid/locale/ru/LC_MESSAGES/playbar.po new file mode 100644 index 0000000..936bf4e --- /dev/null +++ b/plasmoid/locale/ru/LC_MESSAGES/playbar.po @@ -0,0 +1,132 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Salim (Fierta) , 2014. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-09-10 21:13-0500\n" +"PO-Revision-Date: 2014-09-19 22:40+0600\n" +"Last-Translator: Salim (Fierta) \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<" +"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 1.5\n" + +#: plasmoid/contents/ui/Mpris2.qml:51 plasmoid/contents/ui/Mpris2.qml:80 +#: plasmoid/contents/ui/Mpris2.qml:165 +msgid "No source" +msgstr "Нет источника" + +#: plasmoid/contents/ui/rc.js:3 +msgid "Form" +msgstr "Формуляр" + +#: plasmoid/contents/ui/rc.js:6 +msgid "General preferences" +msgstr "Общие настройки" + +#: plasmoid/contents/ui/rc.js:9 +msgid "Display Stop button: " +msgstr "Показывать кнопку стоп:" + +#: plasmoid/contents/ui/rc.js:12 +msgid "Avoid popup close when it loses focus: " +msgstr "Отключить поведение всплывающего окна как окна диалога:" + +#: plasmoid/contents/ui/rc.js:15 +msgid "" +"The window behaves like a dialogue, correcting an \n" +"annoying behavior. If you use CairoDock or Plank \n" +"disable this option or create a KWin rule for \"Plasma\"." +msgstr "" +"Всплывающее окно ведет себя как окно диалога, коррекция \n" +"Некорректное поведение. Если вы используете CairoDock или Plank \n" +"Отключить эту опцию или создать правило KWin для \"Рабочего стола Plasma\"." + +#: plasmoid/contents/ui/rc.js:20 +msgid "Opaque buttons: " +msgstr "Непрозрачные кнопки" + +#: plasmoid/contents/ui/rc.js:23 +msgid "Control Bar" +msgstr "Панель управления" + +#: plasmoid/contents/ui/rc.js:26 +msgid " pixels" +msgstr "" + +#: plasmoid/contents/ui/rc.js:29 +msgid "Flat buttons: " +msgstr "Круглые кнопки:" + +#: plasmoid/contents/ui/rc.js:32 +msgid "Show notifications: " +msgstr "Показать уведомления:" + +#: plasmoid/contents/ui/rc.js:35 +msgid "Visible separator: " +msgstr "Видимый разделитель:" + +#: plasmoid/contents/ui/rc.js:38 +msgid "Size of buttons: " +msgstr "Размер кнопок:" + +#: plasmoid/contents/ui/rc.js:41 +msgid "Popup" +msgstr "Всплывающее окно" + +#: plasmoid/contents/ui/rc.js:44 +msgid "Default" +msgstr "По умолчанию" + +#: plasmoid/contents/ui/rc.js:47 +msgid "ToolTip" +msgstr "Подсказка" + +#: plasmoid/contents/ui/rc.js:50 +msgid "Style popup: " +msgstr "Стиль всплывающего окна:" + +#: plasmoid/contents/ui/rc.js:53 +msgid "Layout: " +msgstr "Макет" + +#: plasmoid/contents/ui/rc.js:56 +msgid "PlayBar" +msgstr "PlayBar" + +#: plasmoid/contents/ui/rc.js:59 +msgid "Minimalist" +msgstr "Minimalist" + +#: plasmoid/contents/ui/rc.js:62 +msgid "Cool" +msgstr "Cool" + +#: plasmoid/contents/ui/TrackInfo.qml:116 +msgid "By %1" +msgstr "By %1" + +#: plasmoid/contents/ui/TrackInfo.qml:173 +msgid "On %1" +msgstr "On %1" + +#: plasmoid/contents/code/control.js:83 +msgid "Open %1" +msgstr "Открыть %1" + +#: plasmoid/contents/code/control.js:84 +msgid "Quit" +msgstr "Выйти" + +#: plasmoid/contents/code/control.js:86 +msgid "Next source" +msgstr "Следующий медиа источник" + + diff --git a/plasmoid/locale/template/LC_MESSAGES/messages.pot b/plasmoid/locale/template/LC_MESSAGES/messages.pot new file mode 100644 index 0000000..69a8571 --- /dev/null +++ b/plasmoid/locale/template/LC_MESSAGES/messages.pot @@ -0,0 +1,126 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2014-09-10 21:13-0500\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: plasmoid/contents/ui/Mpris2.qml:51 plasmoid/contents/ui/Mpris2.qml:80 +#: plasmoid/contents/ui/Mpris2.qml:165 +msgid "No source" +msgstr "" + +#: plasmoid/contents/ui/rc.js:3 +msgid "Form" +msgstr "" + +#: plasmoid/contents/ui/rc.js:6 +msgid "General preferences" +msgstr "" + +#: plasmoid/contents/ui/rc.js:9 +msgid "Display Stop button: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:12 +msgid "Avoid popup close when it loses focus: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:15 +msgid "" +"The window behaves like a dialogue, correcting an \n" +"annoying behavior. If you use CairoDock or Plank \n" +"disable this option or create a KWin rule for \"Plasma\"." +msgstr "" + +#: plasmoid/contents/ui/rc.js:20 +msgid "Opaque buttons: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:23 +msgid "Control Bar" +msgstr "" + +#: plasmoid/contents/ui/rc.js:26 +msgid " pixels" +msgstr "" + +#: plasmoid/contents/ui/rc.js:29 +msgid "Flat buttons: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:32 +msgid "Show notifications: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:35 +msgid "Visible separator: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:38 +msgid "Size of buttons: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:41 +msgid "Popup" +msgstr "" + +#: plasmoid/contents/ui/rc.js:44 +msgid "Default" +msgstr "" + +#: plasmoid/contents/ui/rc.js:47 +msgid "ToolTip" +msgstr "" + +#: plasmoid/contents/ui/rc.js:50 +msgid "Style popup: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:53 +msgid "Layout: " +msgstr "" + +#: plasmoid/contents/ui/rc.js:56 +msgid "PlayBar" +msgstr "" + +#: plasmoid/contents/ui/rc.js:59 +msgid "Minimalist" +msgstr "" + +#: plasmoid/contents/ui/rc.js:62 +msgid "Cool" +msgstr "" + +#: plasmoid/contents/ui/TrackInfo.qml:116 +msgid "By %1" +msgstr "" + +#: plasmoid/contents/ui/TrackInfo.qml:173 +msgid "On %1" +msgstr "" + +#: plasmoid/contents/code/control.js:83 +msgid "Open %1" +msgstr "" + +#: plasmoid/contents/code/control.js:84 +msgid "Quit" +msgstr "" + +#: plasmoid/contents/code/control.js:86 +msgid "Next source" +msgstr "" diff --git a/plasmoid/metadata.desktop b/plasmoid/metadata.desktop new file mode 100644 index 0000000..eb97ee7 --- /dev/null +++ b/plasmoid/metadata.desktop @@ -0,0 +1,28 @@ +[Desktop Entry] +Name=PlayBar +Comment=Client MPRIS2, allows you to control your favorite media player +Comment[es]=Cliente para MPRIS2, le permite controlar su reproductor de audio favorito +Comment[ru]=Клиент MPRIS2, позволяет управлять вашим любимым медиа-плеером + +Encoding=UTF-8 +Icon=applications-multimedia +Keywords=play;bar;mpris2;media;player;playbar;2; +Type=Service + +X-Plasma-API=declarativeappletscript +X-Plasma-MainScript=ui/main.qml +X-Plasma-DefaultSize=109,19 +X-Plasma-Provides=org.kde.plasma.multimediacontrols +#X-Plasma-ConfigPlugins=kcm_playbarshortcuts + +X-KDE-PluginInfo-Author=Smith AR +X-KDE-PluginInfo-Category=Multimedia +X-KDE-PluginInfo-Email=audoban@openmailbox.org +X-KDE-PluginInfo-License=GPLv3 +X-KDE-PluginInfo-Name=audoban.playbar2 +X-KDE-PluginInfo-Version=2pre +X-KDE-PluginInfo-Website=https://github.com/audoban/PlayBar2 + +X-KDE-ServiceTypes=Plasma/Applet + +