diff --git a/MUtilities_VS2013.vcxproj b/MUtilities_VS2013.vcxproj
index 4c86384..16a7da4 100644
--- a/MUtilities_VS2013.vcxproj
+++ b/MUtilities_VS2013.vcxproj
@@ -25,6 +25,7 @@
+
@@ -38,6 +39,7 @@
+
@@ -143,7 +145,7 @@
Windows
true
$(QTDIR)\lib;$(SolutionDir)\..\Prerequisites\VisualLeakDetector\lib\Win32
- QtCored4.lib;QtGuid4.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;%(AdditionalDependencies)
+ QtCored4.lib;QtGuid4.lib;Winmm.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;%(AdditionalDependencies)
@@ -172,7 +174,7 @@
true
true
$(QTDIR)\lib;$(SolutionDir)\..\Prerequisites\VisualLeakDetector\lib\Win32
- QtCore4.lib;QtGui4.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;%(AdditionalDependencies)
+ QtCore4.lib;QtGui4.lib;Winmm.lib;Psapi.lib;Sensapi.lib;PowrProf.lib;%(AdditionalDependencies)
false
diff --git a/MUtilities_VS2013.vcxproj.filters b/MUtilities_VS2013.vcxproj.filters
index 17a0908..d4318a0 100644
--- a/MUtilities_VS2013.vcxproj.filters
+++ b/MUtilities_VS2013.vcxproj.filters
@@ -69,6 +69,9 @@
Source Files\Generated
+
+ Source Files
+
@@ -116,6 +119,9 @@
Header Files\3rd Party
+
+ Public Headers
+
diff --git a/include/MUtils/Global.h b/include/MUtils/Global.h
index 16029ca..07750a7 100644
--- a/include/MUtils/Global.h
+++ b/include/MUtils/Global.h
@@ -91,6 +91,10 @@ namespace MUtils
//String sorting
MUTILS_API void natural_string_sort(QStringList &list, const bool bIgnoreCase);
+ //Clean file path
+ MUTILS_API QString clean_file_name(const QString &name);
+ MUTILS_API QString clean_file_path(const QString &path);
+
//Internal
namespace Internal
{
diff --git a/include/MUtils/Sound.h b/include/MUtils/Sound.h
new file mode 100644
index 0000000..7895d11
--- /dev/null
+++ b/include/MUtils/Sound.h
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// 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
+//
+// http://www.gnu.org/licenses/lgpl-2.1.txt
+//////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+//MUtils
+#include
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace MUtils
+{
+ namespace Sound
+ {
+ enum beep_t
+ {
+ BEEP_NFO = 0,
+ BEEP_WRN = 1,
+ BEEP_ERR = 2
+ };
+
+ //Simple beep
+ MUTILS_API bool beep(beep_t beepType);
+
+ //Play built-in sound by name
+ MUTILS_API bool play_sound(const QString &name, const bool bAsync);
+
+ //Play system sound by name
+ MUTILS_API bool play_system_sound(const QString &alias, const bool bAsync);
+
+ //Play sound from file
+ MUTILS_API bool play_sound_file(const QString &library, const unsigned short uiSoundIdx);
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
diff --git a/src/Global.cpp b/src/Global.cpp
index 7206d77..984b56d 100644
--- a/src/Global.cpp
+++ b/src/Global.cpp
@@ -326,6 +326,58 @@ void MUtils::natural_string_sort(QStringList &list, const bool bIgnoreCase)
qSort(list.begin(), list.end(), bIgnoreCase ? natural_string_sort_helper_fold_case : natural_string_sort_helper);
}
+///////////////////////////////////////////////////////////////////////////////
+// CLEAN FILE PATH
+///////////////////////////////////////////////////////////////////////////////
+
+static const struct
+{
+ const char *const search;
+ const char *const replace;
+}
+CLEAN_FILE_NAME[] =
+{
+ { "\\", "-" },
+ { " / ", ", " },
+ { "/", "," },
+ { ":", "-" },
+ { "*", "x" },
+ { "?", "!" },
+ { "<", "[" },
+ { ">", "]" },
+ { "|", "!" },
+ { "\"", "'" },
+ { NULL, NULL }
+};
+
+QString MUtils::clean_file_name(const QString &name)
+{
+ QString str = name.simplified();
+
+ for(size_t i = 0; CLEAN_FILE_NAME[i].search; i++)
+ {
+ str.replace(CLEAN_FILE_NAME[i].search, CLEAN_FILE_NAME[i].replace);
+ }
+
+ QRegExp regExp("\"(.+)\"");
+ regExp.setMinimal(true);
+ str.replace(regExp, "`\\1´");
+
+ return str.simplified();
+}
+
+QString MUtils::clean_file_path(const QString &path)
+{
+ QStringList parts = path.simplified().replace("\\", "/").split("/", QString::SkipEmptyParts);
+
+ for(int i = 0; i < parts.count(); i++)
+ {
+ parts[i] = MUtils::clean_file_name(parts[i]);
+ }
+
+ return parts.join("/");
+}
+
///////////////////////////////////////////////////////////////////////////////
// SELF-TEST
///////////////////////////////////////////////////////////////////////////////
diff --git a/src/Sound_Win32.cpp b/src/Sound_Win32.cpp
new file mode 100644
index 0000000..ba6b798
--- /dev/null
+++ b/src/Sound_Win32.cpp
@@ -0,0 +1,148 @@
+///////////////////////////////////////////////////////////////////////////////
+// MuldeR's Utilities for Qt
+// Copyright (C) 2004-2014 LoRd_MuldeR
+//
+// 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
+//
+// http://www.gnu.org/licenses/lgpl-2.1.txt
+//////////////////////////////////////////////////////////////////////////////////
+
+//Win32 API
+#define WIN32_LEAN_AND_MEAN 1
+#include
+#include
+
+//MUtils
+#include
+#include
+
+//Qt
+#include
+#include
+#include
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////////
+// BEEP
+///////////////////////////////////////////////////////////////////////////////
+
+bool MUtils::Sound::beep(MUtils::Sound::beep_t beepType)
+{
+ switch(beepType)
+ {
+ case BEEP_NFO: return MessageBeep(MB_ICONASTERISK) == TRUE; break;
+ case BEEP_WRN: return MessageBeep(MB_ICONEXCLAMATION) == TRUE; break;
+ case BEEP_ERR: return MessageBeep(MB_ICONHAND) == TRUE; break;
+ default: return false;
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// PLAY SOUND
+///////////////////////////////////////////////////////////////////////////////
+
+typedef QHash SoundDB;
+
+static QReadWriteLock g_sound_lock;
+static QScopedPointer g_sound_db;
+
+static const unsigned char *get_sound_from_cache(const QString &name)
+{
+ //Try to look-up the sound in the cache first
+ QReadLocker readLock(&g_sound_lock);
+ if((!g_sound_db.isNull()) && g_sound_db->contains(name))
+ {
+ return g_sound_db->value(name);
+ }
+
+ //Get the write lock now
+ readLock.unlock();
+ QWriteLocker writeLock(&g_sound_lock);
+
+ //Is sound still not in cache?
+ if((!g_sound_db.isNull()) && g_sound_db->contains(name))
+ {
+ return g_sound_db->value(name);
+ }
+
+ //If data not found in cache, try to load from resource!
+ QResource resource(QString(":/sounds/%1.wav").arg(name));
+ if(resource.isValid())
+ {
+ if(const unsigned char *data = resource.data())
+ {
+ if(g_sound_db.isNull())
+ {
+ g_sound_db.reset(new SoundDB());
+ }
+ g_sound_db->insert(name, data);
+ return data;
+ }
+ }
+
+ qWarning("Sound effect \"%s\" not found!", MUTILS_UTF8(name));
+ return NULL;
+}
+
+bool MUtils::Sound::play_sound(const QString &name, const bool bAsync)
+{
+ if(!name.isEmpty())
+ {
+ if(const unsigned char *data = get_sound_from_cache(name))
+ {
+ return PlaySound(LPCWSTR(data), NULL, (SND_MEMORY | (bAsync ? SND_ASYNC : SND_SYNC))) != FALSE;
+ }
+ }
+
+ return false;
+}
+
+bool MUtils::Sound::play_system_sound(const QString &alias, const bool bAsync)
+{
+ return PlaySound(MUTILS_WCHR(alias), GetModuleHandle(NULL), (SND_ALIAS | (bAsync ? SND_ASYNC : SND_SYNC))) != FALSE;
+}
+
+bool MUtils::Sound::play_sound_file(const QString &library, const unsigned short uiSoundIdx)
+{
+ bool result = false;
+
+ QFileInfo libraryFile(library);
+ if(!libraryFile.isAbsolute())
+ {
+ const QString &systemDir = MUtils::OS::known_folder(MUtils::OS::FOLDER_SYSTEMFOLDER);
+ if(!systemDir.isEmpty())
+ {
+ libraryFile.setFile(QDir(systemDir), libraryFile.fileName());
+ }
+ }
+
+ if(libraryFile.exists() && libraryFile.isFile())
+ {
+ if(const HMODULE module = LoadLibraryW(MUTILS_WCHR(QDir::toNativeSeparators(libraryFile.canonicalFilePath()))))
+ {
+ result = (PlaySound(MAKEINTRESOURCE(uiSoundIdx), module, (SND_RESOURCE | SND_SYNC)) != FALSE);
+ FreeLibrary(module);
+ }
+ }
+ else
+ {
+ qWarning("PlaySound: File \"%s\" could not be found!", MUTILS_UTF8(libraryFile.absoluteFilePath()));
+ }
+
+ return result;
+}
+
+///////////////////////////////////////////////////////////////////////////////