- Added default sounds (on first start and a new button in sound settings)

- Added new sound files
- Optimized SoundManager
- Saved relative path to sound file for portable version
- Updated english translation


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@8391 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
thunder2 2015-06-07 12:40:25 +00:00
parent c55e8043a5
commit acfa384f7f
19 changed files with 246 additions and 109 deletions

View File

@ -19,10 +19,19 @@
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
****************************************************************/ ****************************************************************/
#include <QApplication>
#include <QSound> #include <QSound>
#include <QDir>
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
#include <QAudio>
#include <QAudioDeviceInfo>
#endif
#include "SoundManager.h" #include "SoundManager.h"
#include "settings/rsharesettings.h" #include "settings/rsharesettings.h"
#include "retroshare/rsinit.h"
#include <retroshare/rsplugin.h>
#define GROUP_MAIN "Sound" #define GROUP_MAIN "Sound"
#define GROUP_ENABLE "Enable" #define GROUP_ENABLE "Enable"
@ -34,14 +43,18 @@ SoundEvents::SoundEvents()
{ {
} }
void SoundEvents::addEvent(const QString &groupName, const QString &eventName, const QString &event) void SoundEvents::addEvent(const QString &groupName, const QString &eventName, const QString &event, const QString &defaultFilename)
{ {
if (event.isEmpty()) {
return;
}
SoundEventInfo info; SoundEventInfo info;
info.mGroupName = groupName; info.mGroupName = groupName;
info.mEventName = eventName; info.mEventName = eventName;
info.mEvent = event; info.mDefaultFilename = defaultFilename;
mEventInfos.push_back(info); mEventInfos[event] = info;
} }
void SoundManager::create() void SoundManager::create()
@ -55,6 +68,70 @@ SoundManager::SoundManager() : QObject()
{ {
} }
void SoundManager::soundEvents(SoundEvents &events)
{
QDir baseDir = QDir(qApp->applicationDirPath());
baseDir.cd("sounds");
/* add standard events */
events.addEvent(tr("Friend"), tr("Go Online"), SOUND_USER_ONLINE, QFileInfo(baseDir, "online1.wav").absoluteFilePath());
events.addEvent(tr("Chatmessage"), tr("New Msg"), SOUND_NEW_CHAT_MESSAGE, QFileInfo(baseDir, "incomingchat.wav").absoluteFilePath());
events.addEvent(tr("Message"), tr("Message arrived"), SOUND_MESSAGE_ARRIVED, QFileInfo(baseDir, "receive.wav").absoluteFilePath());
events.addEvent(tr("Download"), tr("Download complete"), SOUND_DOWNLOAD_COMPLETE, QFileInfo(baseDir, "ft_complete.wav").absoluteFilePath());
/* add plugin events */
int pluginCount = rsPlugins->nbPlugins();
for (int i = 0; i < pluginCount; ++i) {
RsPlugin *plugin = rsPlugins->plugin(i);
if (plugin) {
plugin->qt_sound_events(events);
}
}
}
QString SoundManager::defaultFilename(const QString &event, bool check)
{
SoundEvents events;
soundEvents(events);
QMap<QString, SoundEvents::SoundEventInfo>::iterator eventIt = events.mEventInfos.find(event);
if (eventIt == events.mEventInfos.end()) {
return "";
}
QString filename = eventIt.value().mDefaultFilename;
if (filename.isEmpty()) {
return "";
}
if (!check) {
return convertFilename(filename);
}
if (QFileInfo(filename).exists()) {
return convertFilename(filename);
}
return "";
}
void SoundManager::initDefault()
{
SoundEvents events;
soundEvents(events);
QString event;
foreach (event, events.mEventInfos.keys()) {
SoundEvents::SoundEventInfo &eventInfo = events.mEventInfos[event];
if (QFileInfo(eventInfo.mDefaultFilename).exists()) {
setEventFilename(event, convertFilename(eventInfo.mDefaultFilename));
setEventEnabled(event, true);
}
}
}
void SoundManager::setMute(bool mute) void SoundManager::setMute(bool mute)
{ {
Settings->beginGroup(GROUP_MAIN); Settings->beginGroup(GROUP_MAIN);
@ -113,14 +190,34 @@ void SoundManager::setEventFilename(const QString &event, const QString &filenam
Settings->endGroup(); Settings->endGroup();
} }
QString SoundManager::convertFilename(const QString &filename)
{
if (RsInit::isPortable ()) {
// Save path relative to application path
QDir baseDir = QDir(qApp->applicationDirPath());
QString relativeFilename = baseDir.relativeFilePath(filename);
if (!relativeFilename.startsWith("..")) {
// Save only subfolders as relative path
return relativeFilename;
}
}
return filename;
}
QString SoundManager::realFilename(const QString &filename)
{
if (RsInit::isPortable ()) {
// Path relative to application path
QDir baseDir = QDir(qApp->applicationDirPath());
return baseDir.absoluteFilePath(filename);
}
return filename;
}
void SoundManager::play(const QString &event) void SoundManager::play(const QString &event)
{ {
#if QT_VERSION < QT_VERSION_CHECK (5, 0, 0)
if (!QSound::isAvailable()) {
return;
}
#endif
if (isMute() || !eventEnabled(event)) { if (isMute() || !eventEnabled(event)) {
return; return;
} }
@ -134,5 +231,14 @@ void SoundManager::playFile(const QString &filename)
if (filename.isEmpty()) { if (filename.isEmpty()) {
return; return;
} }
QSound::play(filename);
QString playFilename = realFilename(filename);
#if QT_VERSION >= QT_VERSION_CHECK (5, 0, 0)
if (!QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).isEmpty()) {
#else
if (QSound::isAvailable()) {
#endif
QSound::play(playFilename);
}
} }

View File

@ -23,6 +23,7 @@
#define SOUNDMANAGER_H #define SOUNDMANAGER_H
#include <QObject> #include <QObject>
#include <QMap>
#define SOUND_NEW_CHAT_MESSAGE "NewChatMessage" #define SOUND_NEW_CHAT_MESSAGE "NewChatMessage"
#define SOUND_USER_ONLINE "User_go_Online" #define SOUND_USER_ONLINE "User_go_Online"
@ -40,16 +41,16 @@ public:
public: public:
QString mGroupName; QString mGroupName;
QString mEventName; QString mEventName;
QString mEvent; QString mDefaultFilename;
}; };
public: public:
SoundEvents(); SoundEvents();
void addEvent(const QString &groupName, const QString &eventName, const QString &event); void addEvent(const QString &groupName, const QString &eventName, const QString &event, const QString &defaultFilename);
public: public:
QList<SoundEventInfo> mEventInfos; QMap<QString, SoundEventInfo> mEventInfos;
}; };
class SoundManager : public QObject class SoundManager : public QObject
@ -65,6 +66,13 @@ signals:
public: public:
static void create(); static void create();
void initDefault();
QString defaultFilename(const QString &event, bool check);
static QString convertFilename(const QString &filename);
static QString realFilename(const QString &filename);
void soundEvents(SoundEvents &events);
bool isMute(); bool isMute();
void play(const QString &event); void play(const QString &event);

View File

@ -22,8 +22,7 @@
#include "SoundPage.h" #include "SoundPage.h"
#include "rsharesettings.h" #include "rsharesettings.h"
#include "util/misc.h" #include "util/misc.h"
#include "gui/SoundManager.h"
#include <retroshare/rsplugin.h>
#define COLUMN_NAME 0 #define COLUMN_NAME 0
#define COLUMN_FILENAME 1 #define COLUMN_FILENAME 1
@ -44,6 +43,7 @@ SoundPage::SoundPage(QWidget * parent, Qt::WindowFlags flags)
connect(ui.eventTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(eventChanged(QTreeWidgetItem*, QTreeWidgetItem*))); connect(ui.eventTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(eventChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(ui.filenameEdit, SIGNAL(textChanged(QString)), this, SLOT(filenameChanged(QString))); connect(ui.filenameEdit, SIGNAL(textChanged(QString)), this, SLOT(filenameChanged(QString)));
connect(ui.defaultButton, SIGNAL(clicked()), this, SLOT(defaultButtonClicked()));
connect(ui.browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked())); connect(ui.browseButton, SIGNAL(clicked()), this, SLOT(browseButtonClicked()));
connect(ui.playButton, SIGNAL(clicked()), this, SLOT(playButtonClicked())); connect(ui.playButton, SIGNAL(clicked()), this, SLOT(playButtonClicked()));
@ -126,42 +126,20 @@ void SoundPage::load()
{ {
ui.eventTreeWidget->clear(); ui.eventTreeWidget->clear();
/* add standard events */ /* add sound events */
QTreeWidgetItem *groupItem = addGroup(tr("Friend"));
addItem(groupItem, tr("go Online"), SOUND_USER_ONLINE);
groupItem = addGroup(tr("Chatmessage"));
addItem(groupItem, tr("New Msg"), SOUND_NEW_CHAT_MESSAGE);
groupItem = addGroup(tr("Message"));
addItem(groupItem, tr("Message arrived"), SOUND_MESSAGE_ARRIVED);
groupItem = addGroup(tr("Download"));
addItem(groupItem, tr("Download complete"), SOUND_DOWNLOAD_COMPLETE);
/* add plugin events */
int pluginCount = rsPlugins->nbPlugins();
for (int i = 0; i < pluginCount; ++i) {
RsPlugin *plugin = rsPlugins->plugin(i);
if (plugin) {
SoundEvents events; SoundEvents events;
plugin->qt_sound_events(events); soundManager->soundEvents(events);
if (events.mEventInfos.empty()) { QString event;
continue; foreach (event, events.mEventInfos.keys()) {
} SoundEvents::SoundEventInfo &eventInfo = events.mEventInfos[event];
QList<SoundEvents::SoundEventInfo>::iterator it; QTreeWidgetItem *groupItem = addGroup(eventInfo.mGroupName);
for (it = events.mEventInfos.begin(); it != events.mEventInfos.end(); ++it) { addItem(groupItem, eventInfo.mEventName, event);
groupItem = addGroup(it->mGroupName);
addItem(groupItem, it->mEventName, it->mEvent);
}
}
} }
ui.eventTreeWidget->resizeColumnToContents(COLUMN_NAME); ui.eventTreeWidget->resizeColumnToContents(COLUMN_NAME);
ui.eventTreeWidget->sortByColumn(COLUMN_NAME, Qt::AscendingOrder);
eventChanged(NULL, NULL); eventChanged(NULL, NULL);
} }
@ -185,6 +163,9 @@ void SoundPage::eventChanged(QTreeWidgetItem *current, QTreeWidgetItem */*previo
} }
eventName += current->text(COLUMN_NAME); eventName += current->text(COLUMN_NAME);
ui.eventName->setText(eventName); ui.eventName->setText(eventName);
QString event = current->data(COLUMN_DATA, ROLE_EVENT).toString();
ui.defaultButton->setDisabled(soundManager->defaultFilename(event, true).isEmpty());
} }
void SoundPage::filenameChanged(QString filename) void SoundPage::filenameChanged(QString filename)
@ -197,13 +178,24 @@ void SoundPage::filenameChanged(QString filename)
} }
} }
void SoundPage::defaultButtonClicked()
{
QTreeWidgetItem *item = ui.eventTreeWidget->currentItem();
if (!item) {
return;
}
QString event = item->data(COLUMN_DATA, ROLE_EVENT).toString();
ui.filenameEdit->setText(soundManager->defaultFilename(event, true));
}
void SoundPage::browseButtonClicked() void SoundPage::browseButtonClicked()
{ {
QString filename; QString filename;
if (!misc::getOpenFileName(this, RshareSettings::LASTDIR_SOUNDS, tr("Open File"), "wav (*.wav)", filename)) { if (!misc::getOpenFileName(this, RshareSettings::LASTDIR_SOUNDS, tr("Open File"), "wav (*.wav)", filename)) {
return; return;
} }
ui.filenameEdit->setText(filename); ui.filenameEdit->setText(SoundManager::convertFilename(filename));
} }
void SoundPage::playButtonClicked() void SoundPage::playButtonClicked()

View File

@ -26,7 +26,6 @@
#include <retroshare-gui/configpage.h> #include <retroshare-gui/configpage.h>
#include "ui_SoundPage.h" #include "ui_SoundPage.h"
#include "gui/SoundManager.h"
class SoundPage : public ConfigPage class SoundPage : public ConfigPage
{ {
@ -50,6 +49,7 @@ public:
private slots: private slots:
void eventChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous); void eventChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void filenameChanged(QString filename); void filenameChanged(QString filename);
void defaultButtonClicked();
void browseButtonClicked(); void browseButtonClicked();
void playButtonClicked(); void playButtonClicked();

View File

@ -64,6 +64,13 @@
</property> </property>
</spacer> </spacer>
</item> </item>
<item>
<widget class="QPushButton" name="defaultButton">
<property name="text">
<string>Default</string>
</property>
</widget>
</item>
<item> <item>
<widget class="QPushButton" name="browseButton"> <widget class="QPushButton" name="browseButton">
<property name="text"> <property name="text">
@ -108,6 +115,13 @@
<header>gui/common/LineEditClear.h</header> <header>gui/common/LineEditClear.h</header>
</customwidget> </customwidget>
</customwidgets> </customwidgets>
<tabstops>
<tabstop>eventTreeWidget</tabstop>
<tabstop>filenameEdit</tabstop>
<tabstop>defaultButton</tabstop>
<tabstop>browseButton</tabstop>
<tabstop>playButton</tabstop>
</tabstops>
<resources> <resources>
<include location="../images.qrc"/> <include location="../images.qrc"/>
</resources> </resources>

View File

@ -5216,10 +5216,6 @@ p, li { white-space: pre-wrap; }
<source>Share channel admin permissions</source> <source>Share channel admin permissions</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>You can allow your friends to publish in your channel and to modify the description. Or you can send the admin permissions to another Retroshare instance. Select the friends which you want to allowed to publish in this channel. Note: it is not possible to revoke channel admin permissions.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Share forum admin permissions</source> <source>Share forum admin permissions</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -5236,6 +5232,10 @@ p, li { white-space: pre-wrap; }
<source>You can allow your friends to edit the topic. Select them in the list below. Note: it is not possible to revoke Posted admin permissions.</source> <source>You can allow your friends to edit the topic. Select them in the list below. Note: it is not possible to revoke Posted admin permissions.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>You can allow your friends to publish in your channel and to modify the description. Or you can send the admin permissions to another Retroshare instance. Select the friends which you want to be allowed to publish in this channel. Note: it is not possible to revoke channel admin permissions.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>GroupTreeWidget</name> <name>GroupTreeWidget</name>
@ -9428,10 +9428,6 @@ p, li { white-space: pre-wrap; }
<source>Your trust in this peer is none.</source> <source>Your trust in this peer is none.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>You havn&apos;t set a trust level for this key.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>This key has signed your own PGP key</source> <source>This key has signed your own PGP key</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -9456,6 +9452,10 @@ p, li { white-space: pre-wrap; }
<source>Maybe password is wrong</source> <source>Maybe password is wrong</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>You haven&apos;t set a trust level for this key.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>PeerDefs</name> <name>PeerDefs</name>
@ -12000,6 +12000,14 @@ Reducing image to %1x%2 pixels?</source>
<source>IP address %1 was added to the whitelist</source> <source>IP address %1 was added to the whitelist</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>&lt;p&gt;This is the external IP your Retroshare node thinks it is using.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;p&gt;This is the IP your friend claims it is connected to. If you just changed IPs, this is a false warning. If not, that means your connection to this friend is forwarded by an intermediate peer, which would be suspicious.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>SecurityItem</name> <name>SecurityItem</name>
@ -12774,33 +12782,13 @@ Select the Friends with which you want to Share your Channel.</source>
</message> </message>
</context> </context>
<context> <context>
<name>SoundPage</name> <name>SoundManager</name>
<message>
<source>Event:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Filename:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Browse</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Event</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Filename</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Friend</source> <source>Friend</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<source>go Online</source> <source>Go Online</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
@ -12827,6 +12815,29 @@ Select the Friends with which you want to Share your Channel.</source>
<source>Download complete</source> <source>Download complete</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
</context>
<context>
<name>SoundPage</name>
<message>
<source>Event:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Filename:</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Browse</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Event</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Filename</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Open File</source> <source>Open File</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -12835,6 +12846,10 @@ Select the Friends with which you want to Share your Channel.</source>
<source>Sound</source> <source>Sound</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Default</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>SoundStatus</name> <name>SoundStatus</name>
@ -14175,10 +14190,6 @@ Try to be patient!</source>
<source>Note: these settings do not affect retroshare-nogui. retroshare-nogui has a command line switch to active the webinterface.</source> <source>Note: these settings do not affect retroshare-nogui. retroshare-nogui has a command line switch to active the webinterface.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>&lt;h1&gt;&lt;img width=&quot;24&quot; src=&quot;:/images/64px_help.png&quot;&gt;&amp;nbsp;&amp;nbsp;Webinterface&lt;/h1&gt; &lt;p&gt;The webinterface allows to control Retroshare from the browser. Multiple devices can share control over one Retroshare instance. So you could start a conversation on a tablet omputer and later use a desktop computer to continue it.&lt;/p&gt; &lt;p&gt;Warning: don&apos;t expose the webinterface to the internet, because there is no access control and no encryption. If you want to use the webinterface over the internet, use a SSH tunnel or a proxy to secure the connection.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>Webinterface not enabled</source> <source>Webinterface not enabled</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@ -14191,6 +14202,10 @@ Try to be patient!</source>
<source>Webinterface</source> <source>Webinterface</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>&lt;h1&gt;&lt;img width=&quot;24&quot; src=&quot;:/images/64px_help.png&quot;&gt;&amp;nbsp;&amp;nbsp;Webinterface&lt;/h1&gt; &lt;p&gt;The webinterface allows to control Retroshare from the browser. Multiple devices can share control over one Retroshare instance. So you could start a conversation on a tablet computer and later use a desktop computer to continue it.&lt;/p&gt; &lt;p&gt;Warning: don&apos;t expose the webinterface to the internet, because there is no access control and no encryption. If you want to use the webinterface over the internet, use a SSH tunnel or a proxy to secure the connection.&lt;/p&gt;</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>WikiAddDialog</name> <name>WikiAddDialog</name>

View File

@ -335,6 +335,8 @@ int main(int argc, char *argv[])
Settings->setValue(QString::fromUtf8("FirstRun"), false); Settings->setValue(QString::fromUtf8("FirstRun"), false);
soundManager->initDefault();
#ifdef __APPLE__ #ifdef __APPLE__
/* For OSX, we set the default to "cleanlooks", as the AQUA style hides some input boxes /* For OSX, we set the default to "cleanlooks", as the AQUA style hides some input boxes
* only on the first run - as the user might want to change it ;) * only on the first run - as the user might want to change it ;)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.