Commandline options support. Fixes issue #189

This commit is contained in:
David Sansome 2010-04-12 22:44:29 +00:00
parent 57bd1b0227
commit 2ec6ca45c8
20 changed files with 651 additions and 52 deletions

View File

@ -136,7 +136,7 @@ bool QtLocalPeer::isClient()
}
bool QtLocalPeer::sendMessage(const QString &message, int timeout)
bool QtLocalPeer::sendMessage(const QByteArray &message, int timeout)
{
if (!isClient())
return false;
@ -160,9 +160,8 @@ bool QtLocalPeer::sendMessage(const QString &message, int timeout)
if (!connOk)
return false;
QByteArray uMsg(message.toUtf8());
QDataStream ds(&socket);
ds.writeBytes(uMsg.constData(), uMsg.size());
ds.writeBytes(message.constData(), message.size());
bool res = socket.waitForBytesWritten(timeout);
res &= socket.waitForReadyRead(timeout); // wait for ack
res &= (socket.read(qstrlen(ack)) == ack);
@ -195,9 +194,8 @@ void QtLocalPeer::receiveConnection()
delete socket;
return;
}
QString message(QString::fromUtf8(uMsg));
socket->write(ack, qstrlen(ack));
socket->waitForBytesWritten(1000);
delete socket;
emit messageReceived(message); //### (might take a long time to return)
emit messageReceived(uMsg); //### (might take a long time to return)
}

View File

@ -60,12 +60,12 @@ class QtLocalPeer : public QObject
public:
QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
bool isClient();
bool sendMessage(const QString &message, int timeout);
bool sendMessage(const QByteArray &message, int timeout);
QString applicationId() const
{ return id; }
Q_SIGNALS:
void messageReceived(const QString &message);
void messageReceived(const QByteArray &message);
protected Q_SLOTS:
void receiveConnection();

View File

@ -143,7 +143,7 @@ void QtSingleApplication::sysInit(const QString &appId)
{
actWin = 0;
peer = new QtLocalPeer(this, appId);
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
}
@ -260,7 +260,7 @@ bool QtSingleApplication::isRunning()
\sa isRunning(), messageReceived()
*/
bool QtSingleApplication::sendMessage(const QString &message, int timeout)
bool QtSingleApplication::sendMessage(const QByteArray &message, int timeout)
{
return peer->sendMessage(message, timeout);
}
@ -292,9 +292,9 @@ void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessag
{
actWin = aw;
if (activateOnMessage)
connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
connect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow()));
else
disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
disconnect(peer, SIGNAL(messageReceived(const QByteArray&)), this, SLOT(activateWindow()));
}

View File

@ -90,12 +90,12 @@ public:
{ isRunning(); Q_UNUSED(dummy) }
public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000);
bool sendMessage(const QByteArray &message, int timeout = 5000);
void activateWindow();
Q_SIGNALS:
void messageReceived(const QString &message);
void messageReceived(const QByteArray &message);
private:

View File

@ -80,7 +80,7 @@ QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this);
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
}
@ -93,7 +93,7 @@ QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc
: QCoreApplication(argc, argv)
{
peer = new QtLocalPeer(this, appId);
connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
connect(peer, SIGNAL(messageReceived(const QByteArray&)), SIGNAL(messageReceived(const QByteArray&)));
}
@ -128,7 +128,7 @@ bool QtSingleCoreApplication::isRunning()
\sa isRunning(), messageReceived()
*/
bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout)
bool QtSingleCoreApplication::sendMessage(const QByteArray &message, int timeout)
{
return peer->sendMessage(message, timeout);
}

View File

@ -61,11 +61,11 @@ public:
QString id() const;
public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000);
bool sendMessage(const QByteArray &message, int timeout = 5000);
Q_SIGNALS:
void messageReceived(const QString &message);
void messageReceived(const QByteArray &message);
private:

View File

@ -74,6 +74,7 @@ set(CLEMENTINE-SOURCES
equalizerslider.cpp
tracksliderslider.cpp
stickyslider.cpp
commandlineoptions.cpp
)
# Header files that have Q_OBJECT in

158
src/commandlineoptions.cpp Normal file
View File

@ -0,0 +1,158 @@
/* This file is part of Clementine.
Clementine 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.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "commandlineoptions.h"
#include <cstdlib>
#include <getopt.h>
#include <iostream>
#include <QFileInfo>
#include <QBuffer>
const char* CommandlineOptions::kHelpText =
"%1: clementine [%2] [%3]\n"
"\n"
"%4:\n"
" -p, --play %5\n"
" -t, --play-pause %6\n"
" -u, --pause %7\n"
" -s, --stop %8\n"
" -r, --previous %9\n"
" -f, --next %10\n"
"\n"
"%11:\n"
" -a, --append %12\n"
" -l, --load %13\n";
CommandlineOptions::CommandlineOptions(int argc, char** argv)
: argc_(argc),
argv_(argv),
url_list_action_(UrlList_Append),
player_action_(Player_None)
{
}
bool CommandlineOptions::Parse() {
static const struct option kOptions[] = {
{"help", no_argument, 0, 'h'},
{"append", no_argument, 0, 'a'},
{"load", no_argument, 0, 'l'},
{"play", no_argument, 0, 'p'},
{"play-pause", no_argument, 0, 't'},
{"pause", no_argument, 0, 'u'},
{"stop", no_argument, 0, 's'},
{"previous", no_argument, 0, 'r'},
{"next", no_argument, 0, 'f'},
{0, 0, 0, 0}
};
// Parse the arguments
int option_index = 0;
forever {
int c = getopt_long(argc_, argv_, "", kOptions, &option_index);
// End of the options
if (c == -1)
break;
switch (c) {
case 'h': {
QString translated_help_text = QString(kHelpText).arg(
tr("Usage"), tr("options"), tr("files or URL(s)"), tr("Options"),
tr("Start the playlist currently playing"),
tr("Play if stopped, pause if playing"),
tr("Pause playback"),
tr("Stop playback"),
tr("Skip backwards in playlist")).arg(
tr("Skip forwards in playlist"),
tr("Additional options"),
tr("Append files/URLs to the playlist"),
tr("Loads files/URLs, replacing current playlist"));
std::cout << translated_help_text.toLocal8Bit().constData();
return false;
}
case 'a': url_list_action_ = UrlList_Append; break;
case 'l': url_list_action_ = UrlList_Load; break;
case 'p': player_action_ = Player_Play; break;
case 't': player_action_ = Player_PlayPause; break;
case 'u': player_action_ = Player_Pause; break;
case 's': player_action_ = Player_Stop; break;
case 'r': player_action_ = Player_Previous; break;
case 'f': player_action_ = Player_Next; break;
case '?':
default:
return false;
}
}
// Get any filenames or URLs following the arguments
for (int i=option_index+1 ; i<argc_ ; ++i) {
QString value = QString::fromLocal8Bit(argv_[i]);
if (value.contains("://"))
urls_ << value;
else
urls_ << QUrl::fromLocalFile(QFileInfo(value).absoluteFilePath());
}
return true;
}
QByteArray CommandlineOptions::Serialize() const {
QBuffer buf;
buf.open(QIODevice::WriteOnly);
QDataStream s(&buf);
s << *this;
buf.close();
return buf.data();
}
void CommandlineOptions::Load(const QByteArray &serialized) {
QByteArray copy(serialized);
QBuffer buf(&copy);
buf.open(QIODevice::ReadOnly);
QDataStream s(&buf);
s >> *this;
}
QString CommandlineOptions::tr(const char *source_text) {
return QObject::tr(source_text);
}
QDataStream& operator<<(QDataStream& s, const CommandlineOptions& a) {
s << qint32(a.player_action_)
<< qint32(a.url_list_action_)
<< a.urls_;
return s;
}
QDataStream& operator>>(QDataStream& s, CommandlineOptions& a) {
s >> reinterpret_cast<qint32&>(a.player_action_)
>> reinterpret_cast<qint32&>(a.url_list_action_)
>> a.urls_;
return s;
}

74
src/commandlineoptions.h Normal file
View File

@ -0,0 +1,74 @@
/* This file is part of Clementine.
Clementine 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.
Clementine 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 Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef COMMANDLINEOPTIONS_H
#define COMMANDLINEOPTIONS_H
#include <QList>
#include <QUrl>
#include <QDataStream>
class CommandlineOptions {
friend QDataStream& operator<<(QDataStream& s, const CommandlineOptions& a);
friend QDataStream& operator>>(QDataStream& s, CommandlineOptions& a);
public:
CommandlineOptions(int argc = 0, char** argv = NULL);
static const char* kHelpText;
// Don't change the values or order, these get serialised and sent to
// possibly a different version of Clementine
enum UrlListAction {
UrlList_Append = 0,
UrlList_Load = 1,
};
enum PlayerAction {
Player_None = 0,
Player_Play = 1,
Player_PlayPause = 2,
Player_Pause = 3,
Player_Stop = 4,
Player_Previous = 5,
Player_Next = 6,
};
bool Parse();
UrlListAction url_list_action() const { return url_list_action_; }
PlayerAction player_action() const { return player_action_; }
QList<QUrl> urls() const { return urls_; }
QByteArray Serialize() const;
void Load(const QByteArray& serialized);
private:
QString tr(const char* source_text);
private:
int argc_;
char** argv_;
UrlListAction url_list_action_;
PlayerAction player_action_;
QList<QUrl> urls_;
};
QDataStream& operator<<(QDataStream& s, const CommandlineOptions& a);
QDataStream& operator>>(QDataStream& s, CommandlineOptions& a);
#endif // COMMANDLINEOPTIONS_H

View File

@ -27,6 +27,7 @@
#include "song.h"
#include "equalizer.h"
#include "potranslator.h"
#include "commandlineoptions.h"
#include <QtSingleApplication>
#include <QtDebug>
@ -87,13 +88,6 @@ int main(int argc, char *argv[]) {
QtSingleApplication a(argc, argv);
a.setQuitOnLastWindowClosed(false);
if (a.isRunning()) {
qDebug() << "Clementine is already running - activating existing window";
if (a.sendMessage("wake up!"))
return 0;
// Couldn't send the message so start anyway
}
// Resources
Q_INIT_RESOURCE(data);
Q_INIT_RESOURCE(translations);
@ -104,6 +98,18 @@ int main(int argc, char *argv[]) {
LoadTranslation("clementine", a.applicationDirPath());
LoadTranslation("clementine", QDir::currentPath());
CommandlineOptions options(argc, argv);
if (!options.Parse())
return 1;
if (a.isRunning()) {
qDebug() << "Clementine is already running - activating existing window";
if (a.sendMessage(options.Serialize()))
return 0;
// Couldn't send the message so start anyway
}
QNetworkAccessManager network;
// MPRIS DBus interface.
@ -122,12 +128,14 @@ int main(int argc, char *argv[]) {
setenv("GST_PLUGIN_PATH", plugin_path.toAscii().constData(), 1);
#endif
// Window
MainWindow w(&network);;
MainWindow w(&network);
a.setActivationWindow(&w);
QObject::connect(&a, SIGNAL(messageReceived(QString)), &w, SLOT(show()));
QObject::connect(&a, SIGNAL(messageReceived(QByteArray)), &w, SLOT(show()));
QObject::connect(&a, SIGNAL(messageReceived(QByteArray)), &w, SLOT(CommandlineOptionsReceived(QByteArray)));
w.CommandlineOptionsReceived(options);
return a.exec();
}

View File

@ -40,6 +40,7 @@
#include "groupbydialog.h"
#include "engines/gstengine.h"
#include "equalizer.h"
#include "commandlineoptions.h"
#include "globalshortcuts/globalshortcuts.h"
@ -874,3 +875,51 @@ void MainWindow::PlaylistEditFinished(const QModelIndex& index) {
if (index == playlist_menu_index_)
SelectionSetValue();
}
void MainWindow::CommandlineOptionsReceived(const QByteArray& serialized_options) {
if (serialized_options == "wake up!") {
// Old versions of Clementine sent this - just ignore it
return;
}
CommandlineOptions options;
options.Load(serialized_options);
CommandlineOptionsReceived(options);
}
void MainWindow::CommandlineOptionsReceived(const CommandlineOptions &options) {
switch (options.player_action()) {
case CommandlineOptions::Player_Play:
player_->Play();
break;
case CommandlineOptions::Player_PlayPause:
player_->PlayPause();
break;
case CommandlineOptions::Player_Pause:
player_->Pause();
break;
case CommandlineOptions::Player_Stop:
player_->Stop();
break;
case CommandlineOptions::Player_Previous:
player_->Previous();
break;
case CommandlineOptions::Player_Next:
player_->Next(Engine::Manual);
break;
case CommandlineOptions::Player_None:
break;
}
switch (options.url_list_action()) {
case CommandlineOptions::UrlList_Load:
playlist_->Clear();
// fallthrough
case CommandlineOptions::UrlList_Append:
playlist_->InsertPaths(options.urls(), -1);
break;
}
}

View File

@ -42,6 +42,7 @@ class PlaylistSequence;
class GlobalShortcuts;
class GroupByDialog;
class Equalizer;
class CommandlineOptions;
class QSortFilterProxyModel;
class SystemTrayIcon;
@ -65,6 +66,7 @@ class MainWindow : public QMainWindow {
};
void SetHiddenInTray(bool hidden);
void CommandlineOptionsReceived(const CommandlineOptions& options);
protected:
void resizeEvent(QResizeEvent* event);
@ -117,6 +119,8 @@ class MainWindow : public QMainWindow {
void AddStream();
void AddStreamAccepted();
void CommandlineOptionsReceived(const QByteArray& serialized_options);
private:
void SaveGeometry();

View File

@ -483,6 +483,48 @@ msgstr ""
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr ""
msgid "Usage"
msgstr ""
#, fuzzy
msgid "options"
msgstr "Upozornění"
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr ""
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
#, fuzzy
msgid "Pause playback"
msgstr "Přehrávání"
#, fuzzy
msgid "Stop playback"
msgstr "Přehrávání"
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr "Clementine"
@ -633,9 +675,6 @@ msgstr "Přidat novou složku..."
msgid "Remove folder"
msgstr "Odstranit složku"
msgid "Options"
msgstr ""
msgid "Automatically open single categories in the library tree"
msgstr ""

View File

@ -486,6 +486,48 @@ msgstr "Διαγραφή προκαθορισμένων"
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr "Είστε σίγουροι πως θέλετε να διαγράψετε το \"%1\" προκαθορισμένο;"
msgid "Usage"
msgstr ""
#, fuzzy
msgid "options"
msgstr "Επιλογές"
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr "Επιλογές"
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
#, fuzzy
msgid "Pause playback"
msgstr "Αναπαραγωγή"
#, fuzzy
msgid "Stop playback"
msgstr "Αναπαραγωγή"
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr "Clementine"
@ -636,9 +678,6 @@ msgstr "Προσθήκη νέου φακέλου..."
msgid "Remove folder"
msgstr "Αφαίρεση φακέλου"
msgid "Options"
msgstr "Επιλογές"
msgid "Automatically open single categories in the library tree"
msgstr "Άνοιξε αυτόμα τις μόνες κατηγορίες του δέντρου της βιβλιοθήκης"

View File

@ -485,6 +485,48 @@ msgstr "Nueva lista de reproducción"
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr ""
msgid "Usage"
msgstr ""
#, fuzzy
msgid "options"
msgstr "Opciones"
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr "Opciones"
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
#, fuzzy
msgid "Pause playback"
msgstr "Reproducción"
#, fuzzy
msgid "Stop playback"
msgstr "Reproducción"
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr "Clementine"
@ -636,9 +678,6 @@ msgstr "Añadir nueva carpeta..."
msgid "Remove folder"
msgstr "Remover carpeta"
msgid "Options"
msgstr "Opciones"
msgid "Automatically open single categories in the library tree"
msgstr ""
"Automaticamente expandir los artitas con un solo disco en el arbol de la "

View File

@ -485,6 +485,48 @@ msgstr ""
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr ""
msgid "Usage"
msgstr ""
#, fuzzy
msgid "options"
msgstr "Notifications"
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr ""
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
#, fuzzy
msgid "Pause playback"
msgstr "Lecture sonore"
#, fuzzy
msgid "Stop playback"
msgstr "Lecture sonore"
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr "Clementine"
@ -637,9 +679,6 @@ msgstr "Ajouter un nouveau dossier..."
msgid "Remove folder"
msgstr "Supprimer un dossier"
msgid "Options"
msgstr ""
msgid "Automatically open single categories in the library tree"
msgstr ""

View File

@ -481,6 +481,48 @@ msgstr ""
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr ""
msgid "Usage"
msgstr ""
#, fuzzy
msgid "options"
msgstr "Opcje"
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr "Opcje"
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
#, fuzzy
msgid "Pause playback"
msgstr "Odtwarzanie"
#, fuzzy
msgid "Stop playback"
msgstr "Odtwarzanie"
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr ""
@ -631,9 +673,6 @@ msgstr "Dodaj nowy katalog..."
msgid "Remove folder"
msgstr "Usuń katalog"
msgid "Options"
msgstr "Opcje"
msgid "Automatically open single categories in the library tree"
msgstr "Automatycznie otwieraj pojedyńcze kategorie w drzewie Biblioteki"

View File

@ -481,6 +481,48 @@ msgstr ""
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr ""
msgid "Usage"
msgstr ""
#, fuzzy
msgid "options"
msgstr "Уведомления"
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr ""
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
#, fuzzy
msgid "Pause playback"
msgstr "Воспроизведение"
#, fuzzy
msgid "Stop playback"
msgstr "Воспроизведение"
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr "Clementine"
@ -632,9 +674,6 @@ msgstr "Добавить каталог..."
msgid "Remove folder"
msgstr "Удалить каталог"
msgid "Options"
msgstr ""
msgid "Automatically open single categories in the library tree"
msgstr ""

View File

@ -484,6 +484,46 @@ msgstr "Nový playlist"
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr ""
msgid "Usage"
msgstr ""
#, fuzzy
msgid "options"
msgstr "Možnosti"
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr "Možnosti"
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
msgid "Pause playback"
msgstr ""
msgid "Stop playback"
msgstr ""
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr ""
@ -634,9 +674,6 @@ msgstr "Pridať nový priečinok..."
msgid "Remove folder"
msgstr "Odobrať priečinok"
msgid "Options"
msgstr "Možnosti"
msgid "Automatically open single categories in the library tree"
msgstr "Automaticky otvoriť jednotlivé kategórie v strome zbierky"

View File

@ -477,6 +477,45 @@ msgstr ""
msgid "Are you sure you want to delete the \"%1\" preset?"
msgstr ""
msgid "Usage"
msgstr ""
msgid "options"
msgstr ""
msgid "files or URL(s)"
msgstr ""
msgid "Options"
msgstr ""
msgid "Start the playlist currently playing"
msgstr ""
msgid "Play if stopped, pause if playing"
msgstr ""
msgid "Pause playback"
msgstr ""
msgid "Stop playback"
msgstr ""
msgid "Skip backwards in playlist"
msgstr ""
msgid "Skip forwards in playlist"
msgstr ""
msgid "Additional options"
msgstr ""
msgid "Append files/URLs to the playlist"
msgstr ""
msgid "Loads files/URLs, replacing current playlist"
msgstr ""
msgid "Clementine"
msgstr ""
@ -627,9 +666,6 @@ msgstr ""
msgid "Remove folder"
msgstr ""
msgid "Options"
msgstr ""
msgid "Automatically open single categories in the library tree"
msgstr ""