diff --git a/MediaInfoXP.sln b/MediaInfoXP.sln
index aa4bf36..6d73347 100644
--- a/MediaInfoXP.sln
+++ b/MediaInfoXP.sln
@@ -11,20 +11,16 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release_Static|Win32 = Release_Static|Win32
- Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Debug|Win32.ActiveCfg = Debug|Win32
{DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Debug|Win32.Build.0 = Debug|Win32
{DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Release_Static|Win32.ActiveCfg = Release_Static|Win32
{DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Release_Static|Win32.Build.0 = Release_Static|Win32
- {DCDCCABB-970A-4337-B5BB-7838EE72FE80}.Release|Win32.ActiveCfg = Release_Static|Win32
{55405FE1-149F-434C-9D72-4B64348D2A08}.Debug|Win32.ActiveCfg = Debug|Win32
{55405FE1-149F-434C-9D72-4B64348D2A08}.Debug|Win32.Build.0 = Debug|Win32
{55405FE1-149F-434C-9D72-4B64348D2A08}.Release_Static|Win32.ActiveCfg = Release_Static|Win32
{55405FE1-149F-434C-9D72-4B64348D2A08}.Release_Static|Win32.Build.0 = Release_Static|Win32
- {55405FE1-149F-434C-9D72-4B64348D2A08}.Release|Win32.ActiveCfg = Release|Win32
- {55405FE1-149F-434C-9D72-4B64348D2A08}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/MediaInfoXP.vcxproj b/MediaInfoXP.vcxproj
index 82053f8..fd59699 100644
--- a/MediaInfoXP.vcxproj
+++ b/MediaInfoXP.vcxproj
@@ -57,11 +57,13 @@
Disabled
WIN32;_DEBUG;_CONSOLE;QT_GUI_LIB;QT_CORE_LIB;QT_THREAD_SUPPORT;QT_DLL;QT_DEBUG;%(PreprocessorDefinitions)
$(QTDIR)\include;$(QTDIR)\include\QtCore;$(QTDIR)\include\QtGui;$(SolutionDir)\..\MUtilities\include;$(SolutionDir)\tmp\$(ProjectName);%(AdditionalIncludeDirectories)
+ NoExtensions
Console
true
$(SolutionDir)\..\Prerequisites\Qt4\MSVC-2013\Debug\lib;$(SolutionDir)\..\Prerequisites\Qt4\MSVC-2013\Debug\plugins\imageformats;$(SolutionDir)\..\Prerequisites\EncodePointer\lib;%(AdditionalLibraryDirectories)
+ QtCored4.lib;QtGuid4.lib;QtSvgd4.lib;Winmm.lib;imm32.lib;ws2_32.lib;Shlwapi.lib;Wininet.lib;PowrProf.lib;psapi.lib;Sensapi.lib;%(AdditionalDependencies)
diff --git a/src/Config.h b/src/Config.h
index 2374223..21df2ab 100644
--- a/src/Config.h
+++ b/src/Config.h
@@ -21,7 +21,7 @@
//Version
static unsigned int mixp_versionMajor = 2;
-static unsigned int mixp_versionMinor = 14;
+static unsigned int mixp_versionMinor = 15;
//MediaInfo Version
static unsigned int mixp_miVersionMajor = 0;
diff --git a/src/IPC.cpp b/src/IPC.cpp
index b2f0c0c..81e525e 100644
--- a/src/IPC.cpp
+++ b/src/IPC.cpp
@@ -23,6 +23,7 @@
//MUtils
#include "MUtils/Global.h"
+#include "MUtils/IPCChannel.h"
//Qt
#include
@@ -48,9 +49,9 @@ mixp_ipc_t;
// Send Thread
///////////////////////////////////////////////////////////////////////////////
-IPCSendThread::IPCSendThread(IPC *ipc, const QString &str)
+IPCSendThread::IPCSendThread(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message)
:
- m_ipc(ipc), m_str(str)
+ m_ipc(ipc), m_command(command), m_message(message)
{
m_result = false;
}
@@ -59,10 +60,11 @@ void IPCSendThread::run(void)
{
try
{
- m_result = m_ipc->pushStr(m_str);
+ m_result = m_ipc->send(m_command, 0, QStringList() << m_message);
}
catch(...)
{
+ qWarning("Exception in IPC receive thread!");
m_result = false;
}
}
@@ -72,7 +74,7 @@ void IPCSendThread::run(void)
// Receive Thread
///////////////////////////////////////////////////////////////////////////////
-IPCReceiveThread::IPCReceiveThread(IPC *ipc)
+IPCReceiveThread::IPCReceiveThread(MUtils::IPCChannel *const ipc)
:
m_ipc(ipc)
{
@@ -95,192 +97,34 @@ void IPCReceiveThread::receiveLoop(void)
{
while(!m_stopped)
{
- QString temp;
- if(m_ipc->popStr(temp))
+ quint32 command, flags;
+ QStringList params;
+ if(m_ipc->read(command, flags, params))
{
- if(!temp.isEmpty())
+ if((command != IPC::COMMAND_NONE) && (!params.isEmpty()))
{
- emit receivedStr(temp);
+ emit received(command, params.first());
}
}
}
}
+void IPCReceiveThread::stop(void)
+{
+ if(!m_stopped)
+ {
+ m_stopped = true;
+ IPC::sendAsync(m_ipc, IPC::COMMAND_NONE, "exit");
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
// IPC Class
///////////////////////////////////////////////////////////////////////////////
-IPC::IPC(void)
+bool IPC::sendAsync(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message, const quint32 &timeout)
{
- m_initialized = -1;
- m_sharedMemory = NULL;
- m_semaphoreWr = NULL;
- m_semaphoreRd = NULL;
- m_recvThread = NULL;
-}
-
-IPC::~IPC(void)
-{
- if(m_recvThread && m_recvThread->isRunning())
- {
- qWarning("Receive thread still running -> terminating!");
- m_recvThread->terminate();
- m_recvThread->wait();
- }
-
- MUTILS_DELETE(m_recvThread);
- MUTILS_DELETE(m_sharedMemory);
- MUTILS_DELETE(m_semaphoreWr);
- MUTILS_DELETE(m_semaphoreRd);
-}
-
-int IPC::initialize(void)
-{
- if(m_initialized >= 0)
- {
- return m_initialized;
- }
-
- m_semaphoreWr = new QSystemSemaphore(s_key_sema_wr, MAX_ENTRIES);
- m_semaphoreRd = new QSystemSemaphore(s_key_sema_rd, 0);
-
- if((m_semaphoreWr->error() != QSystemSemaphore::NoError) || (m_semaphoreRd->error() != QSystemSemaphore::NoError))
- {
- qWarning("IPC: Failed to created system semaphores!");
- return -1;
- }
-
- m_sharedMemory = new QSharedMemory(s_key_smemory, this);
-
- if(m_sharedMemory->create(sizeof(mixp_ipc_t)))
- {
- memset(m_sharedMemory->data(), 0, sizeof(mixp_ipc_t));
- m_initialized = 1;
- return 1;
- }
-
- if(m_sharedMemory->error() == QSharedMemory::AlreadyExists)
- {
- qDebug("Not the first instance -> attaching to existing shared memory");
- if(m_sharedMemory->attach())
- {
- m_initialized = 0;
- return 0;
- }
- }
-
- qWarning("IPC: Failed to attach to the shared memory!");
- return -1;
-}
-
-bool IPC::pushStr(const QString &str)
-{
- if(m_initialized < 0)
- {
- qWarning("Error: IPC not initialized yet!");
- return false;
- }
-
- if(!m_semaphoreWr->acquire())
- {
- qWarning("IPC: Failed to acquire semaphore!");
- return false;
- }
-
- if(!m_sharedMemory->lock())
- {
- qWarning("IPC: Failed to lock shared memory!");
- return false;
- }
-
- bool success = true;
-
- try
- {
- mixp_ipc_t *memory = (mixp_ipc_t*) m_sharedMemory->data();
- if(memory->counter < MAX_ENTRIES)
- {
- wcsncpy_s(memory->data[memory->posWr], MAX_STR_LEN, (wchar_t*)str.utf16(), _TRUNCATE);
- memory->posWr = (memory->posWr + 1) % MAX_ENTRIES;
- memory->counter++;
- }
- else
- {
- qWarning("IPC: Shared memory is full -> cannot push string!");
- success = false;
- }
- }
- catch(...)
- {
- /*ignore any exception*/
- }
-
- m_sharedMemory->unlock();
-
- if(success)
- {
- m_semaphoreRd->release();
- }
-
- return success;
-}
-
-bool IPC::popStr(QString &str)
-{
- if(m_initialized < 0)
- {
- qWarning("Error: IPC not initialized yet!");
- return false;
- }
-
- if(!m_semaphoreRd->acquire())
- {
- qWarning("IPC: Failed to acquire semaphore!");
- return false;
- }
-
- if(!m_sharedMemory->lock())
- {
- qWarning("IPC: Failed to lock shared memory!");
- return false;
- }
-
- bool success = true;
-
- try
- {
- mixp_ipc_t *memory = (mixp_ipc_t*) m_sharedMemory->data();
- if(memory->counter > 0)
- {
- memory->data[memory->posRd][MAX_STR_LEN-1] = L'\0';
- str = QString::fromUtf16((const ushort*)memory->data[memory->posRd]);
- memory->posRd = (memory->posRd + 1) % MAX_ENTRIES;
- memory->counter--;
- }
- else
- {
- qWarning("IPC: Shared memory is empty -> cannot pop string!");
- success = false;
- }
- }
- catch(...)
- {
- /*ignore any exception*/
- }
-
- m_sharedMemory->unlock();
-
- if(success)
- {
- m_semaphoreWr->release();
- }
-
- return success;
-}
-
-bool IPC::sendAsync(const QString &str, const int timeout)
-{
- IPCSendThread sendThread(this, str);
+ IPCSendThread sendThread(ipc, command, message);
sendThread.start();
if(!sendThread.wait(timeout))
@@ -293,42 +137,3 @@ bool IPC::sendAsync(const QString &str, const int timeout)
return sendThread.result();
}
-
-void IPC::startListening(void)
-{
- if(!m_recvThread)
- {
- m_recvThread = new IPCReceiveThread(this);
- connect(m_recvThread, SIGNAL(receivedStr(QString)), this, SIGNAL(receivedStr(QString)), Qt::QueuedConnection);
- }
-
- if(!m_recvThread->isRunning())
- {
- m_recvThread->start();
- }
- else
- {
- qWarning("Receive thread was already running!");
- }
-
-}
-
-void IPC::stopListening(void)
-{
- if(m_recvThread && m_recvThread->isRunning())
- {
- m_recvThread->stop();
- m_semaphoreRd->release();
-
- if(!m_recvThread->wait(5000))
- {
- qWarning("Receive thread seems deadlocked -> terminating!");
- m_recvThread->terminate();
- m_recvThread->wait();
- }
- }
- else
- {
- qWarning("Receive thread was not running!");
- }
-}
diff --git a/src/IPC.h b/src/IPC.h
index 8585747..2d2a050 100644
--- a/src/IPC.h
+++ b/src/IPC.h
@@ -23,78 +23,63 @@
#include
-class QSharedMemory;
-class QSystemSemaphore;
-class IPCSendThread;
-class IPCReceiveThread;
-
-class IPC : public QObject
+namespace MUtils
{
- Q_OBJECT
- friend class IPCReceiveThread;
- friend class IPCSendThread;
-
-public:
- IPC(void);
- ~IPC(void);
-
- int initialize(void);
- bool sendAsync(const QString &str, const int timeout = 5000);
-
-public slots:
- void startListening(void);
- void stopListening(void);
-
-signals:
- void receivedStr(const QString &str);
-
-protected:
- bool popStr(QString &str);
- bool pushStr(const QString &str);
-
- int m_initialized;
-
- QSharedMemory *m_sharedMemory;
- QSystemSemaphore *m_semaphoreRd;
- QSystemSemaphore *m_semaphoreWr;
- IPCReceiveThread *m_recvThread;
-};
+ class IPCChannel;
+}
///////////////////////////////////////////////////////////////////////////////
class IPCSendThread : public QThread
{
Q_OBJECT
- friend class IPC;
-protected:
- IPCSendThread(IPC *ipc, const QString &str);
+public:
+ IPCSendThread(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message);
inline bool result(void) { return m_result; }
virtual void run(void);
private:
volatile bool m_result;
- IPC *const m_ipc;
- const QString m_str;
+ MUtils::IPCChannel *const m_ipc;
+ const quint32 m_command;
+ const QString m_message;
};
class IPCReceiveThread : public QThread
{
Q_OBJECT
- friend class IPC;
+
+public:
+ IPCReceiveThread(MUtils::IPCChannel *const ipc);
+ void stop(void);
protected:
- IPCReceiveThread(IPC *ipc);
- inline void stop(void) { m_stopped = true; }
-
virtual void run(void);
signals:
- void receivedStr(const QString &str);
+ void received(const quint32 &command, const QString &message);
private:
void receiveLoop(void);
volatile bool m_stopped;
- IPC *const m_ipc;
+ MUtils::IPCChannel *const m_ipc;
+};
+
+class IPC
+{
+public:
+ enum
+ {
+ COMMAND_NONE = 0,
+ COMMAND_PING = 1,
+ COMMAND_OPEN = 2
+ }
+ ipc_command_t;
+
+ static bool sendAsync(MUtils::IPCChannel *const ipc, const quint32 &command, const QString &message, const quint32 &timeout = 5000);
+
+private:
+ IPC(void) { throw 666; }
};
diff --git a/src/Main.cpp b/src/Main.cpp
index 802be56..666f733 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -21,26 +21,14 @@
//MUTils
#include
+#include
#include
-
-//StdLib
-#include
-#include
-#include
-#include
-#include
-
-#pragma intrinsic(_InterlockedExchange)
+#include
//Qt
#include
#include
-
-//Win32
-#define WIN32_LEAN_AND_MEAN
-#include
-#include
-#include
+#include
#ifdef QT_NODLL
#include
@@ -54,34 +42,28 @@
#include "IPC.h"
///////////////////////////////////////////////////////////////////////////////
-// Debug Console
+// Multi-instance handling
///////////////////////////////////////////////////////////////////////////////
-bool g_bHaveConsole = false;
-
-static void init_console(void)
+static void mixp_handle_multi_instance(MUtils::IPCChannel *const ipcChannel)
{
- if(AllocConsole())
+ bool bHaveFile = false;
+
+ //We are *not* the first instance -> pass all file names to the running instance
+ const MUtils::OS::ArgumentMap arguments = MUtils::OS::arguments();
+ const QStringList files = arguments.values("open");
+ for(QStringList::ConstIterator iter = files.constBegin(); iter != files.constEnd(); iter++)
{
- int hCrtStdOut = _open_osfhandle((intptr_t) GetStdHandle(STD_OUTPUT_HANDLE), _O_WRONLY);
- int hCrtStdErr = _open_osfhandle((intptr_t) GetStdHandle(STD_ERROR_HANDLE), _O_WRONLY);
- FILE *hfStdOut = (hCrtStdOut >= 0) ? _fdopen(hCrtStdOut, "wb") : NULL;
- FILE *hfStdErr = (hCrtStdErr >= 0) ? _fdopen(hCrtStdErr, "wb") : NULL;
- if(hfStdOut) { *stdout = *hfStdOut; std::cout.rdbuf(new std::filebuf(hfStdOut)); }
- if(hfStdErr) { *stderr = *hfStdErr; std::cerr.rdbuf(new std::filebuf(hfStdErr)); }
-
- HWND hwndConsole = GetConsoleWindow();
- if((hwndConsole != NULL) && (hwndConsole != INVALID_HANDLE_VALUE))
+ if(IPC::sendAsync(ipcChannel, IPC::COMMAND_OPEN, *iter))
{
- HMENU hMenu = GetSystemMenu(hwndConsole, 0);
- EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
- RemoveMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
- SetWindowPos(hwndConsole, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
- SetWindowLong(hwndConsole, GWL_STYLE, GetWindowLong(hwndConsole, GWL_STYLE) & (~WS_MAXIMIZEBOX) & (~WS_MINIMIZEBOX));
- SetWindowPos(hwndConsole, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_FRAMECHANGED);
+ bHaveFile = true;
}
+ }
- g_bHaveConsole = true;
+ //If no file was sent, we will at least try to bring the other instance to front
+ if(!bHaveFile)
+ {
+ IPC::sendAsync(ipcChannel, IPC::COMMAND_PING, "?");
}
}
@@ -103,36 +85,19 @@ static int mixp_main(int &argc, char **argv)
QScopedPointer application(new QApplication(argc, argv));
//Create IPC
- QScopedPointer ipc(new IPC());
-
- //Is this the *first* instance?
- if(ipc->initialize() == 0)
+ QScopedPointer ipcChannel(new MUtils::IPCChannel("mediainfo-xp", qHash(QString("%0@%1").arg(QString::fromLatin1(mixp_buildDate), QString::fromLatin1(mixp_buildTime))), "instance"));
+ const int ipcMode = ipcChannel->initialize();
+ if((ipcMode != MUtils::IPCChannel::RET_SUCCESS_MASTER) && (ipcMode != MUtils::IPCChannel::RET_SUCCESS_SLAVE))
{
- //We are *not* the first instance -> pass all file names to the running instance
- const QStringList arguments = qApp->arguments();
- bool bHaveFile = false;
- for(QStringList::ConstIterator iter = arguments.constBegin(); iter != arguments.constEnd(); iter++)
- {
- if(QString::compare(*iter, "--open", Qt::CaseInsensitive) == 0)
- {
- if(++iter != arguments.constEnd())
- {
- if(ipc->sendAsync(*iter))
- {
- bHaveFile = true;
- continue;
- }
- }
- break;
- }
- }
- //If no file was sent, we will at least try to bring the other instance to front
- if(!bHaveFile)
- {
- ipc->sendAsync("?");
- }
+ qFatal("The IPC initialization has failed!");
+ return EXIT_FAILURE;
+ }
- return 42;
+ //Handle multiple instances
+ if(ipcMode == MUtils::IPCChannel::RET_SUCCESS_SLAVE)
+ {
+ mixp_handle_multi_instance(ipcChannel.data());
+ return EXIT_SUCCESS;
}
//Get temp folder
@@ -140,15 +105,12 @@ static int mixp_main(int &argc, char **argv)
qDebug("TEMP folder is:\n%s\n", QDir::toNativeSeparators(tempFolder).toUtf8().constData());
//Create main window
- QScopedPointer mainWindow(new CMainWindow(tempFolder, ipc.data()));
+ QScopedPointer mainWindow(new CMainWindow(tempFolder, ipcChannel.data()));
mainWindow->show();
//Run application
const int exit_code = application->exec();
qDebug("\nTime to say goodbye... (%d)\n", exit_code);
-
- //Stop IPC
- ipc->stopListening();
return exit_code;
}
diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp
index 9d781d3..6b285d0 100644
--- a/src/MainWindow.cpp
+++ b/src/MainWindow.cpp
@@ -82,11 +82,11 @@ static const int FILE_RECEIVE_DELAY = 1750;
// Constructor
////////////////////////////////////////////////////////////
-CMainWindow::CMainWindow(const QString &tempFolder, IPC *const ipc, QWidget *parent)
+CMainWindow::CMainWindow(const QString &tempFolder, MUtils::IPCChannel *const ipc, QWidget *parent)
:
QMainWindow(parent),
m_tempFolder(tempFolder),
- m_ipc(ipc),
+ m_ipcThread(new IPCReceiveThread(ipc)),
m_htmlEscape(HTML_ESCAPE()),
m_status(APP_STATUS_STARTING),
ui(new Ui::MainWindow)
@@ -100,23 +100,23 @@ CMainWindow::CMainWindow(const QString &tempFolder, IPC *const ipc, QWidget *par
MUtils::GUI::set_window_icon(this, QIcon(":/res/logo.png"), true);
//Setup links
- ui->actionLink_MuldeR->setData(QVariant(QString::fromLatin1(LINK_MULDER)));
+ ui->actionLink_MuldeR ->setData(QVariant(QString::fromLatin1(LINK_MULDER)));
ui->actionLink_MediaInfo->setData(QVariant(QString::fromLatin1(LINK_MEDIAINFO)));
- ui->actionLink_Discuss->setData(QVariant(QString::fromLatin1(LINK_DISCUSS)));
+ ui->actionLink_Discuss ->setData(QVariant(QString::fromLatin1(LINK_DISCUSS)));
//Setup connections
- connect(ui->analyzeButton, SIGNAL(clicked()), this, SLOT(analyzeButtonClicked()));
- connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(analyzeButtonClicked()));
- connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(saveButtonClicked()));
- connect(ui->actionCopyToClipboard, SIGNAL(triggered()), this, SLOT(copyToClipboardButtonClicked()));
- connect(ui->actionClear, SIGNAL(triggered()), this, SLOT(clearButtonClicked()));
- connect(ui->actionLink_MuldeR, SIGNAL(triggered()), this, SLOT(linkTriggered()));
- connect(ui->actionLink_MediaInfo, SIGNAL(triggered()), this, SLOT(linkTriggered()));
- connect(ui->actionLink_Discuss, SIGNAL(triggered()), this, SLOT(linkTriggered()));
- connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(showAboutScreen()));
- connect(ui->actionShellExtension, SIGNAL(toggled(bool)), this, SLOT(updateShellExtension(bool)));
- connect(ui->actionLineWrapping, SIGNAL(toggled(bool)), this, SLOT(updateLineWrapping(bool)));
- connect(m_ipc, SIGNAL(receivedStr(QString)), this, SLOT(fileReceived(QString)));
+ connect(ui->analyzeButton, SIGNAL(clicked()), this, SLOT(analyzeButtonClicked()));
+ connect(ui->actionOpen, SIGNAL(triggered()), this, SLOT(analyzeButtonClicked()));
+ connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(saveButtonClicked()));
+ connect(ui->actionCopyToClipboard, SIGNAL(triggered()), this, SLOT(copyToClipboardButtonClicked()));
+ connect(ui->actionClear, SIGNAL(triggered()), this, SLOT(clearButtonClicked()));
+ connect(ui->actionLink_MuldeR, SIGNAL(triggered()), this, SLOT(linkTriggered()));
+ connect(ui->actionLink_MediaInfo, SIGNAL(triggered()), this, SLOT(linkTriggered()));
+ connect(ui->actionLink_Discuss, SIGNAL(triggered()), this, SLOT(linkTriggered()));
+ connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(showAboutScreen()));
+ connect(ui->actionShellExtension, SIGNAL(toggled(bool)), this, SLOT(updateShellExtension(bool)));
+ connect(ui->actionLineWrapping, SIGNAL(toggled(bool)), this, SLOT(updateLineWrapping(bool)));
+ connect(m_ipcThread.data(), SIGNAL(received(quint32, QString)), this, SLOT(received(quint32, QString)));
ui->versionLabel->installEventFilter(this);
//Context menu
@@ -124,7 +124,7 @@ CMainWindow::CMainWindow(const QString &tempFolder, IPC *const ipc, QWidget *par
ui->textBrowser->insertActions(0, ui->menuFile->actions());
//Create label
- m_floatingLabel = new QLabel(ui->textBrowser);
+ m_floatingLabel.reset(new QLabel(ui->textBrowser));
m_floatingLabel->setText(QString::fromLatin1(STATUS_BLNK));
m_floatingLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
m_floatingLabel->show();
@@ -132,10 +132,6 @@ CMainWindow::CMainWindow(const QString &tempFolder, IPC *const ipc, QWidget *par
SET_FONT_BOLD(m_floatingLabel, true);
m_floatingLabel->setContextMenuPolicy(Qt::ActionsContextMenu);
m_floatingLabel->insertActions(0, ui->textBrowser->actions());
-
- //Clear
- m_mediaInfoHandle = NULL;
- m_process = NULL;
//Randomize
qsrand((uint) time(NULL));
@@ -147,13 +143,21 @@ CMainWindow::CMainWindow(const QString &tempFolder, IPC *const ipc, QWidget *par
CMainWindow::~CMainWindow(void)
{
- if(m_mediaInfoHandle)
+ if(!m_ipcThread.isNull())
+ {
+ m_ipcThread->stop();
+ if(!m_ipcThread->wait(5000))
+ {
+ qWarning("IPC thread doesn't respond -> terminating!");
+ m_ipcThread->terminate();
+ m_ipcThread->wait();
+ }
+ }
+
+ if(!m_mediaInfoHandle.isNull())
{
m_mediaInfoHandle->remove();
- MUTILS_DELETE(m_mediaInfoHandle);
}
- MUTILS_DELETE(m_process);
- MUTILS_DELETE(m_floatingLabel);
}
////////////////////////////////////////////////////////////
@@ -178,21 +182,14 @@ void CMainWindow::showEvent(QShowEvent *event)
if(m_status == APP_STATUS_STARTING)
{
- const QStringList arguments = qApp->arguments();
- for(QStringList::ConstIterator iter = arguments.constBegin(); iter != arguments.constEnd(); iter++)
+ const MUtils::OS::ArgumentMap arguments = MUtils::OS::arguments();
+ const QStringList files = arguments.values("open");
+ for(QStringList::ConstIterator iter = files.constBegin(); iter != files.constEnd(); iter++)
{
- if(QString::compare(*iter, "--open", Qt::CaseInsensitive) == 0)
+ QFileInfo currentFile = QFileInfo(*iter);
+ if(currentFile.exists() && currentFile.isFile())
{
- if(++iter != arguments.constEnd())
- {
- QFileInfo currentFile = QFileInfo(*iter);
- if(currentFile.exists() && currentFile.isFile())
- {
- m_pendingFiles << currentFile.canonicalFilePath();
- }
- continue;
- }
- break;
+ m_pendingFiles << currentFile.canonicalFilePath();
}
}
if(!m_pendingFiles.empty())
@@ -201,9 +198,9 @@ void CMainWindow::showEvent(QShowEvent *event)
QTimer::singleShot(FILE_RECEIVE_DELAY, this, SLOT(analyzeFiles()));
}
- QTimer::singleShot(125, m_ipc, SLOT(startListening()));
QTimer::singleShot(250, this, SLOT(initShellExtension()));
-
+ m_ipcThread->start();
+
if(m_status == APP_STATUS_STARTING)
{
m_status = APP_STATUS_IDLE;
@@ -313,15 +310,15 @@ void CMainWindow::analyzeFiles(void)
}
//Create process, if not done yet
- if(!m_process)
+ if(m_process.isNull())
{
- m_process = new QProcess();
+ m_process.reset(new QProcess());
m_process->setProcessChannelMode(QProcess::MergedChannels);
m_process->setReadChannel(QProcess::StandardOutput);
- connect(m_process, SIGNAL(readyReadStandardError()), this, SLOT(outputAvailable()));
- connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(outputAvailable()));
- connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished()));
- connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processFinished()));
+ connect(m_process.data(), SIGNAL(readyReadStandardError()), this, SLOT(outputAvailable()));
+ connect(m_process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(outputAvailable()));
+ connect(m_process.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished()));
+ connect(m_process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(processFinished()));
}
//Still running?
@@ -686,13 +683,16 @@ void CMainWindow::updateSize(void)
}
}
-void CMainWindow::fileReceived(const QString &str)
+void CMainWindow::received(const quint32 &command, const QString &message)
{
- MUtils::GUI::bring_to_front(this);
-
- if(str.compare("?") != 0)
+ if((command == IPC::COMMAND_PING) || (command == IPC::COMMAND_OPEN))
{
- qDebug("Received file: %s", str.toUtf8().constData());
+ MUtils::GUI::bring_to_front(this);
+ }
+
+ if((command == IPC::COMMAND_OPEN) && (!message.isEmpty()))
+ {
+ qDebug("Received file: %s", message.toUtf8().constData());
if((m_status != APP_STATUS_IDLE) && (m_status != APP_STATUS_AWAITING))
{
@@ -700,7 +700,7 @@ void CMainWindow::fileReceived(const QString &str)
return;
}
- const QString absPath = QFileInfo(QDir::fromNativeSeparators(str)).absoluteFilePath();
+ const QString absPath = QFileInfo(QDir::fromNativeSeparators(message)).absoluteFilePath();
QFileInfo fileInfo(absPath);
if(fileInfo.exists() && fileInfo.isFile())
{
@@ -712,10 +712,6 @@ void CMainWindow::fileReceived(const QString &str)
}
}
}
- else
- {
- qDebug("Received ping from another instance!");
- }
}
////////////////////////////////////////////////////////////
@@ -752,19 +748,18 @@ QString CMainWindow::getMediaInfoPath(void)
}
//Validate file content, if already extracted
- if(m_mediaInfoHandle)
+ if(!m_mediaInfoHandle.isNull())
{
- if(VALIDATE_MEDIAINFO(m_mediaInfoHandle))
+ if(VALIDATE_MEDIAINFO(m_mediaInfoHandle.data()))
{
return m_mediaInfoHandle->fileName();
}
m_mediaInfoHandle->remove();
- MUTILS_DELETE(m_mediaInfoHandle);
}
//Extract MediaInfo binary now!
qDebug("MediaInfo binary not existing yet, going to extract now...\n");
- m_mediaInfoHandle = new QFile(QString("%1/MediaInfo_%2.exe").arg(m_tempFolder, QString().sprintf("%04x", qrand() % 0xFFFF)));
+ m_mediaInfoHandle.reset(new QFile(QString("%1/MediaInfo_%2.exe").arg(m_tempFolder, QString().sprintf("%04x", qrand() % 0xFFFF))));
if(m_mediaInfoHandle->open(QIODevice::ReadWrite | QIODevice::Truncate))
{
if(m_mediaInfoHandle->write(reinterpret_cast(mediaInfoRes.data()), mediaInfoRes.size()) == mediaInfoRes.size())
@@ -775,31 +770,27 @@ QString CMainWindow::getMediaInfoPath(void)
{
qWarning("Failed to open MediaInfo binary for reading!\n");
m_mediaInfoHandle->remove();
- MUTILS_DELETE(m_mediaInfoHandle);
}
}
else
{
qWarning("Failed to write data to MediaInfo binary file!\n");
m_mediaInfoHandle->remove();
- MUTILS_DELETE(m_mediaInfoHandle);
}
}
else
{
qWarning("Failed to open MediaInfo binary for writing!\n");
- MUTILS_DELETE(m_mediaInfoHandle);
}
//Validate file content, after it has been extracted
- if(m_mediaInfoHandle)
+ if(!m_mediaInfoHandle.isNull())
{
- if(VALIDATE_MEDIAINFO(m_mediaInfoHandle))
+ if(VALIDATE_MEDIAINFO(m_mediaInfoHandle.data()))
{
return m_mediaInfoHandle->fileName();
}
m_mediaInfoHandle->remove();
- MUTILS_DELETE(m_mediaInfoHandle);
}
return QString();
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 2f7d29e..5e2929b 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -25,14 +25,18 @@
#include
//UIC forward declartion
-namespace Ui {
+namespace Ui
+{
class MainWindow;
}
+namespace MUtils
+{
+ class IPCChannel;
+}
class QProcess;
class QLabel;
class QFile;
-class mixp_icon_t;
-class IPC;
+class IPCReceiveThread;
//MainWindow class
class CMainWindow: public QMainWindow
@@ -40,7 +44,7 @@ class CMainWindow: public QMainWindow
Q_OBJECT
public:
- CMainWindow(const QString &tempFolder, IPC *const ipc, QWidget *parent = 0);
+ CMainWindow(const QString &tempFolder, MUtils::IPCChannel *const ipc, QWidget *parent = 0);
~CMainWindow(void);
private slots:
@@ -58,7 +62,7 @@ private slots:
void initShellExtension(void);
void updateShellExtension(bool checked);
void updateLineWrapping(bool checked);
- void fileReceived(const QString &path);
+ void received(const quint32 &command, const QString &message);
protected:
virtual void showEvent(QShowEvent *event);
@@ -85,14 +89,13 @@ private:
int m_status;
const QString &m_tempFolder;
- QFile *m_mediaInfoHandle;
- QProcess *m_process;
- QLabel *m_floatingLabel;
+ QScopedPointer m_ipcThread;
+ QScopedPointer m_mediaInfoHandle;
+ QScopedPointer m_process;
+ QScopedPointer m_floatingLabel;
QStringList m_pendingFiles;
QStringList m_outputLines;
- mixp_icon_t *m_icon;
- IPC *const m_ipc;
-
+
const QList> m_htmlEscape;
QString getMediaInfoPath(void);
diff --git a/src/ShellExtension.cpp b/src/ShellExtension.cpp
index 0779cdf..28cc9b1 100644
--- a/src/ShellExtension.cpp
+++ b/src/ShellExtension.cpp
@@ -52,7 +52,7 @@ bool ShellExtension::setEnabled(bool enabled)
if(MUtils::Registry::reg_value_write(MUtils::Registry::root_user, MIXP_REGISTRY_KEY, QString(), tr("Analyze file with MediaInfoXP")))
{
const QString appPath = QDir::toNativeSeparators(QApplication::applicationFilePath());
- const QString command = QString().sprintf("\"%ls\" --open \"%%1\"", appPath.utf16());
+ const QString command = QString().sprintf("\"%ls\" --open=\"%%1\"", appPath.utf16());
if(MUtils::Registry::reg_value_write(MUtils::Registry::root_user, MIXP_REGISTRY_KEY"\\command", QString(), command))
{
if(MUtils::Registry::reg_value_write(MUtils::Registry::root_user, MIXP_REGISTRY_KEY, MIXP_REGISTRY_VAL, 1))