Actually implemented adding files from another instance.

This commit is contained in:
LoRd_MuldeR 2010-11-08 21:47:35 +01:00
parent 8e013b6aff
commit 9ce7dfc75f
8 changed files with 230 additions and 64 deletions

View File

@ -382,6 +382,9 @@
<layout class="QGridLayout" name="gridLayout_3"> <layout class="QGridLayout" name="gridLayout_3">
<item row="1" column="1"> <item row="1" column="1">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="frameShape"> <property name="frameShape">
<enum>QFrame::StyledPanel</enum> <enum>QFrame::StyledPanel</enum>
</property> </property>
@ -769,8 +772,9 @@
</property> </property>
<addaction name="actionStylePlastique"/> <addaction name="actionStylePlastique"/>
<addaction name="actionStyleCleanlooks"/> <addaction name="actionStyleCleanlooks"/>
<addaction name="actionStyleWindows"/> <addaction name="actionStyleWindowsVista"/>
<addaction name="actionStyleClassic"/> <addaction name="actionStyleWindowsXP"/>
<addaction name="actionStyleWindowsClassic"/>
</widget> </widget>
<addaction name="actionSourceFiles"/> <addaction name="actionSourceFiles"/>
<addaction name="actionOutputDirectory"/> <addaction name="actionOutputDirectory"/>
@ -909,20 +913,28 @@
<string>Cleanlooks</string> <string>Cleanlooks</string>
</property> </property>
</action> </action>
<action name="actionStyleWindows"> <action name="actionStyleWindowsVista">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Windows</string> <string>Windows Vista (&quot;Aero&quot;)</string>
</property> </property>
</action> </action>
<action name="actionStyleClassic"> <action name="actionStyleWindowsClassic">
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="text"> <property name="text">
<string>Classic</string> <string>Windows Classic</string>
</property>
</action>
<action name="actionStyleWindowsXP">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Windows XP (&quot;Luna&quot;)</string>
</property> </property>
</action> </action>
</widget> </widget>
@ -951,6 +963,10 @@
<include location="../res/Images.qrc"/> <include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/> <include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/> <include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/>
<include location="../res/Images.qrc"/>
</resources> </resources>
<connections> <connections>
<connection> <connection>

View File

@ -124,8 +124,9 @@ MainWindow::MainWindow(QWidget *parent)
m_styleActionGroup = new QActionGroup(this); m_styleActionGroup = new QActionGroup(this);
m_styleActionGroup->addAction(actionStylePlastique); m_styleActionGroup->addAction(actionStylePlastique);
m_styleActionGroup->addAction(actionStyleCleanlooks); m_styleActionGroup->addAction(actionStyleCleanlooks);
m_styleActionGroup->addAction(actionStyleWindows); m_styleActionGroup->addAction(actionStyleWindowsVista);
m_styleActionGroup->addAction(actionStyleClassic); m_styleActionGroup->addAction(actionStyleWindowsXP);
m_styleActionGroup->addAction(actionStyleWindowsClassic);
actionStylePlastique->setChecked(true); actionStylePlastique->setChecked(true);
connect(m_styleActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(styleActionActivated(QAction*))); connect(m_styleActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(styleActionActivated(QAction*)));
@ -144,6 +145,11 @@ MainWindow::MainWindow(QWidget *parent)
//Create message handler thread //Create message handler thread
m_messageHandler = new MessageHandlerThread(); m_messageHandler = new MessageHandlerThread();
m_delayedFileList = new QStringList();
m_delayedFileTimer = new QTimer();
connect(m_messageHandler, SIGNAL(otherInstanceDetected()), this, SLOT(notifyOtherInstance()), Qt::QueuedConnection);
connect(m_messageHandler, SIGNAL(fileReceived(QString)), this, SLOT(addFileDelayed(QString)), Qt::QueuedConnection);
connect(m_delayedFileTimer, SIGNAL(timeout()), this, SLOT(handleDelayedFiles()));
m_messageHandler->start(); m_messageHandler->start();
} }
@ -153,11 +159,20 @@ MainWindow::MainWindow(QWidget *parent)
MainWindow::~MainWindow(void) MainWindow::~MainWindow(void)
{ {
while(m_messageHandler->isRunning())
{
m_messageHandler->stop();
m_messageHandler->wait();
}
LAMEXP_DELETE(m_tabActionGroup); LAMEXP_DELETE(m_tabActionGroup);
LAMEXP_DELETE(m_styleActionGroup); LAMEXP_DELETE(m_styleActionGroup);
LAMEXP_DELETE(m_fileListModel); LAMEXP_DELETE(m_fileListModel);
LAMEXP_DELETE(m_banner); LAMEXP_DELETE(m_banner);
LAMEXP_DELETE(m_fileSystemModel); LAMEXP_DELETE(m_fileSystemModel);
LAMEXP_DELETE(m_messageHandler);
LAMEXP_DELETE(m_delayedFileList);
LAMEXP_DELETE(m_delayedFileTimer);
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -184,9 +199,7 @@ void MainWindow::showEvent(QShowEvent *event)
*/ */
void MainWindow::windowShown(void) void MainWindow::windowShown(void)
{ {
QStringList fileList;
QStringList arguments = QApplication::arguments(); QStringList arguments = QApplication::arguments();
qDebug("Main window is showing");
for(int i = 0; i < arguments.count() - 1; i++) for(int i = 0; i < arguments.count() - 1; i++)
{ {
@ -196,7 +209,7 @@ void MainWindow::windowShown(void)
qDebug("Adding file from CLI: %s", currentFile.absoluteFilePath().toUtf8().constData()); qDebug("Adding file from CLI: %s", currentFile.absoluteFilePath().toUtf8().constData());
if(currentFile.exists()) if(currentFile.exists())
{ {
fileList << currentFile.absoluteFilePath(); m_delayedFileList->append(currentFile.absoluteFilePath());
} }
else else
{ {
@ -205,17 +218,9 @@ void MainWindow::windowShown(void)
} }
} }
if(fileList.count() > 0) if(!m_delayedFileList->isEmpty() && !m_delayedFileTimer->isActive())
{ {
FileAnalyzer *analyzer = new FileAnalyzer(fileList); m_delayedFileTimer->start(5000);
connect(analyzer, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
m_banner->show("Adding file(s), please wait...", analyzer);
LAMEXP_DELETE(analyzer);
sourceFileView->scrollToBottom();
m_banner->close();
} }
} }
@ -318,6 +323,13 @@ void MainWindow::aboutButtonClicked(void)
*/ */
void MainWindow::encodeButtonClicked(void) void MainWindow::encodeButtonClicked(void)
{ {
if(m_delayedFileTimer->isActive())
{
MessageBeep(MB_ICONERROR);
return;
}
QMessageBox::warning(this, "LameXP", "Not implemented yet, please try again with a later version!"); QMessageBox::warning(this, "LameXP", "Not implemented yet, please try again with a later version!");
} }
@ -505,8 +517,9 @@ void MainWindow::styleActionActivated(QAction *action)
{ {
if(action == actionStylePlastique) QApplication::setStyle(new QPlastiqueStyle()); if(action == actionStylePlastique) QApplication::setStyle(new QPlastiqueStyle());
else if(action == actionStyleCleanlooks) QApplication::setStyle(new QCleanlooksStyle()); else if(action == actionStyleCleanlooks) QApplication::setStyle(new QCleanlooksStyle());
else if(action == actionStyleWindows) QApplication::setStyle(new QWindowsVistaStyle()); else if(action == actionStyleWindowsVista) QApplication::setStyle(new QWindowsVistaStyle());
else if(action == actionStyleClassic) QApplication::setStyle(new QWindowsStyle()); else if(action == actionStyleWindowsXP) QApplication::setStyle(new QWindowsXPStyle());
else if(action == actionStyleWindowsClassic) QApplication::setStyle(new QWindowsStyle());
} }
/* /*
@ -519,7 +532,6 @@ void MainWindow::outputFolderViewClicked(const QModelIndex &index)
outputFolderLabel->setText(selectedDir); outputFolderLabel->setText(selectedDir);
} }
/* /*
* Goto desktop button * Goto desktop button
*/ */
@ -622,3 +634,59 @@ void MainWindow::checkUpdatesActionActivated(void)
QMessageBox::information(this, "Update Check", "Your version of LameXP is still up-to-date. There are no updates available.\nPlease remember to check for updates at regular intervals!"); QMessageBox::information(this, "Update Check", "Your version of LameXP is still up-to-date. There are no updates available.\nPlease remember to check for updates at regular intervals!");
} }
/*
* Other instance detected
*/
void MainWindow::notifyOtherInstance(void)
{
if(!m_banner->isVisible())
{
QMessageBox msgBox(QMessageBox::Warning, "Already running", "LameXP is already running, please use the running instance!", QMessageBox::NoButton, this, Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowStaysOnTopHint);
msgBox.exec();
}
}
/*
* Add file from another instance
*/
void MainWindow::addFileDelayed(const QString &filePath)
{
m_delayedFileTimer->stop();
qDebug("Received file: %s", filePath.toUtf8().constData());
m_delayedFileList->append(filePath);
m_delayedFileTimer->start(5000);
}
/*
* Add all pending files
*/
void MainWindow::handleDelayedFiles(void)
{
if(m_banner->isVisible())
{
return;
}
m_delayedFileTimer->stop();
if(m_delayedFileList->isEmpty())
{
return;
}
QStringList selectedFiles;
while(!m_delayedFileList->isEmpty())
{
selectedFiles << QFileInfo(m_delayedFileList->takeFirst()).absoluteFilePath();
}
FileAnalyzer *analyzer = new FileAnalyzer(selectedFiles);
connect(analyzer, SIGNAL(fileSelected(QString)), m_banner, SLOT(setText(QString)), Qt::QueuedConnection);
connect(analyzer, SIGNAL(fileAnalyzed(AudioFileModel)), m_fileListModel, SLOT(addFile(AudioFileModel)), Qt::QueuedConnection);
m_banner->show("Adding file(s), please wait...", analyzer);
LAMEXP_DELETE(analyzer);
sourceFileView->scrollToBottom();
m_banner->close();
}

View File

@ -59,6 +59,9 @@ private slots:
void checkUpdatesActionActivated(void); void checkUpdatesActionActivated(void);
void visitHomepageActionActivated(void); void visitHomepageActionActivated(void);
void openFolderActionActivated(void); void openFolderActionActivated(void);
void notifyOtherInstance(void);
void addFileDelayed(const QString &filePath);
void handleDelayedFiles(void);
protected: protected:
void showEvent(QShowEvent *event); void showEvent(QShowEvent *event);
@ -70,4 +73,6 @@ private:
QActionGroup *m_styleActionGroup; QActionGroup *m_styleActionGroup;
WorkingBanner *m_banner; WorkingBanner *m_banner;
MessageHandlerThread *m_messageHandler; MessageHandlerThread *m_messageHandler;
QStringList *m_delayedFileList;
QTimer *m_delayedFileTimer;
}; };

View File

@ -258,13 +258,13 @@ bool lamexp_init_qt(int argc, char* argv[])
} }
/* /*
* Check for running instances of LameXP * Initialize IPC
*/ */
bool lamexp_check_instances(void) int lamexp_init_ipc(void)
{ {
if(g_lamexp_sharedmem_ptr && g_lamexp_semaphore_read_ptr && g_lamexp_semaphore_write_ptr) if(g_lamexp_sharedmem_ptr && g_lamexp_semaphore_read_ptr && g_lamexp_semaphore_write_ptr)
{ {
return true; return 0;
} }
g_lamexp_semaphore_read_ptr = new QSystemSemaphore(g_lamexp_semaphore_read_uuid, 0); g_lamexp_semaphore_read_ptr = new QSystemSemaphore(g_lamexp_semaphore_read_uuid, 0);
@ -276,7 +276,7 @@ bool lamexp_check_instances(void)
LAMEXP_DELETE(g_lamexp_semaphore_read_ptr); LAMEXP_DELETE(g_lamexp_semaphore_read_ptr);
LAMEXP_DELETE(g_lamexp_semaphore_write_ptr); LAMEXP_DELETE(g_lamexp_semaphore_write_ptr);
qFatal("Failed to create system smaphore: %s", errorMessage.toUtf8().constData()); qFatal("Failed to create system smaphore: %s", errorMessage.toUtf8().constData());
return false; return -1;
} }
if(g_lamexp_semaphore_write_ptr->error() != QSystemSemaphore::NoError) if(g_lamexp_semaphore_write_ptr->error() != QSystemSemaphore::NoError)
{ {
@ -284,7 +284,7 @@ bool lamexp_check_instances(void)
LAMEXP_DELETE(g_lamexp_semaphore_read_ptr); LAMEXP_DELETE(g_lamexp_semaphore_read_ptr);
LAMEXP_DELETE(g_lamexp_semaphore_write_ptr); LAMEXP_DELETE(g_lamexp_semaphore_write_ptr);
qFatal("Failed to create system smaphore: %s", errorMessage.toUtf8().constData()); qFatal("Failed to create system smaphore: %s", errorMessage.toUtf8().constData());
return false; return -1;
} }
g_lamexp_sharedmem_ptr = new QSharedMemory(g_lamexp_sharedmem_uuid, NULL); g_lamexp_sharedmem_ptr = new QSharedMemory(g_lamexp_sharedmem_uuid, NULL);
@ -296,30 +296,27 @@ bool lamexp_check_instances(void)
g_lamexp_sharedmem_ptr->attach(); g_lamexp_sharedmem_ptr->attach();
if(g_lamexp_sharedmem_ptr->error() == QSharedMemory::NoError) if(g_lamexp_sharedmem_ptr->error() == QSharedMemory::NoError)
{ {
lamexp_ipc_send(42, "Wurst schmeckt uns!"); return 1;
} }
else else
{ {
qWarning("Failed to attach to the existing shared memory!"); QString errorMessage = g_lamexp_sharedmem_ptr->errorString();
qFatal("Failed to attach to shared memory: %s", errorMessage.toUtf8().constData());
return -1;
} }
qWarning("Another instance of LameXP is already running on this computer!");
QMessageBox::warning(NULL, "LameXP", "LameXP is already running. Please use the running instance!");
} }
else else
{ {
QString errorMessage = g_lamexp_sharedmem_ptr->errorString(); QString errorMessage = g_lamexp_sharedmem_ptr->errorString();
qFatal("Failed to create shared memory: %s", errorMessage.toUtf8().constData()); qFatal("Failed to create shared memory: %s", errorMessage.toUtf8().constData());
return -1;
} }
LAMEXP_DELETE(g_lamexp_semaphore_read_ptr);
LAMEXP_DELETE(g_lamexp_semaphore_write_ptr);
LAMEXP_DELETE(g_lamexp_sharedmem_ptr);
return false;
} }
memset(g_lamexp_sharedmem_ptr->data(), 0, sizeof(lamexp_ipc_t)); memset(g_lamexp_sharedmem_ptr->data(), 0, sizeof(lamexp_ipc_t));
g_lamexp_semaphore_write_ptr->release(); g_lamexp_semaphore_write_ptr->release();
return true; return 0;
} }
/* /*
@ -337,9 +334,12 @@ void lamexp_ipc_send(unsigned int command, const char* message)
lamexp_ipc->command = command; lamexp_ipc->command = command;
strcpy_s(lamexp_ipc->parameter, 4096, message); strcpy_s(lamexp_ipc->parameter, 4096, message);
g_lamexp_semaphore_write_ptr->acquire(); if(g_lamexp_semaphore_write_ptr->acquire())
{
memcpy(g_lamexp_sharedmem_ptr->data(), lamexp_ipc, sizeof(lamexp_ipc_t)); memcpy(g_lamexp_sharedmem_ptr->data(), lamexp_ipc, sizeof(lamexp_ipc_t));
g_lamexp_semaphore_read_ptr->release(); g_lamexp_semaphore_read_ptr->release();
}
LAMEXP_DELETE(lamexp_ipc); LAMEXP_DELETE(lamexp_ipc);
} }
@ -359,7 +359,8 @@ void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize)
lamexp_ipc_t *lamexp_ipc = new lamexp_ipc_t; lamexp_ipc_t *lamexp_ipc = new lamexp_ipc_t;
memset(lamexp_ipc, 0, sizeof(lamexp_ipc_t)); memset(lamexp_ipc, 0, sizeof(lamexp_ipc_t));
g_lamexp_semaphore_read_ptr->acquire(); if(g_lamexp_semaphore_read_ptr->acquire())
{
memcpy(lamexp_ipc, g_lamexp_sharedmem_ptr->data(), sizeof(lamexp_ipc_t)); memcpy(lamexp_ipc, g_lamexp_sharedmem_ptr->data(), sizeof(lamexp_ipc_t));
g_lamexp_semaphore_write_ptr->release(); g_lamexp_semaphore_write_ptr->release();
@ -372,10 +373,34 @@ void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize)
{ {
qWarning("Malformed IPC message, will be ignored"); qWarning("Malformed IPC message, will be ignored");
} }
}
LAMEXP_DELETE(lamexp_ipc); LAMEXP_DELETE(lamexp_ipc);
} }
/*
* Communicate with running instance
*/
void lamexp_handle_multiple_instanced(void)
{
QStringList arguments = QApplication::arguments();
bool bSentFiles = false;
for(int i = 0; i < arguments.count() - 1; i++)
{
if(!arguments[i].compare("--add", Qt::CaseInsensitive))
{
lamexp_ipc_send(1, arguments[++i].toUtf8().constData());
bSentFiles = true;
}
}
if(!bSentFiles)
{
lamexp_ipc_send(UINT_MAX, "Use running instance!");
}
}
/* /*
* Get LameXP temp folder * Get LameXP temp folder
*/ */

View File

@ -47,7 +47,8 @@ bool lamexp_version_demo(void);
//Public functions //Public functions
void lamexp_init_console(int argc, char* argv[]); void lamexp_init_console(int argc, char* argv[]);
bool lamexp_init_qt(int argc, char* argv[]); bool lamexp_init_qt(int argc, char* argv[]);
bool lamexp_check_instances(void); int lamexp_init_ipc(void);
void lamexp_handle_multiple_instanced(void);
void lamexp_register_tool(const QString &toolName, LockedFile *file); void lamexp_register_tool(const QString &toolName, LockedFile *file);
const QString lamexp_lookup_tool(const QString &toolName); const QString lamexp_lookup_tool(const QString &toolName);
void lamexp_finalization(void); void lamexp_finalization(void);

View File

@ -68,8 +68,18 @@ int lamexp_main(int argc, char* argv[])
} }
} }
//Check for multiple instances //Check for multiple instances of LameXP
if(!lamexp_check_instances()) return 0; int iResult = lamexp_init_ipc();
if(iResult > 0)
{
qDebug("LameXP is already running, connecting to running instance...");
lamexp_handle_multiple_instanced();
return 0;
}
else if(iResult < 0)
{
return -1;
}
//Show splash screen //Show splash screen
InitializationThread *poInitializationThread = new InitializationThread(); InitializationThread *poInitializationThread = new InitializationThread();
@ -79,7 +89,7 @@ int lamexp_main(int argc, char* argv[])
//Show main window //Show main window
MainWindow *poMainWindow = new MainWindow(); MainWindow *poMainWindow = new MainWindow();
poMainWindow->show(); poMainWindow->show();
int iResult = QApplication::instance()->exec(); iResult = QApplication::instance()->exec();
LAMEXP_DELETE(poMainWindow); LAMEXP_DELETE(poMainWindow);
//Final clean-up //Final clean-up

View File

@ -25,6 +25,9 @@
#include <QSharedMemory> #include <QSharedMemory>
#include <QSystemSemaphore> #include <QSystemSemaphore>
#include <QMessageBox>
#include <limits.h>
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Constructor // Constructor
@ -32,21 +35,49 @@
MessageHandlerThread::MessageHandlerThread(void) MessageHandlerThread::MessageHandlerThread(void)
{ {
m_aborted = false;
m_parameter = new char[4096];
}
MessageHandlerThread::~MessageHandlerThread(void)
{
delete [] m_parameter;
} }
void MessageHandlerThread::run() void MessageHandlerThread::run()
{ {
unsigned int command = 0; m_aborted = false;
char *parameter = new char[4096]; setTerminationEnabled(true);
while(true) while(!m_aborted)
{ {
qDebug("MessageHandlerThread: Waiting..."); unsigned int command = 0;
lamexp_ipc_read(&command, parameter, 4096); lamexp_ipc_read(&command, m_parameter, 4096);
qDebug("MessageHandlerThread: command=%u, parameter='%s'", command, parameter); if(!command) continue;
switch(command)
{
case 1:
emit fileReceived(QString::fromUtf8(m_parameter));
break;
case UINT_MAX:
emit otherInstanceDetected();
break;
default:
qWarning("Received an unknown IPC message! (command=%u)", command);
break;
}
}
}
void MessageHandlerThread::stop(void)
{
if(!m_aborted)
{
m_aborted = true;
lamexp_ipc_send(0, "");
} }
delete [] parameter;
} }
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -29,5 +29,15 @@ class MessageHandlerThread: public QThread
public: public:
MessageHandlerThread(void); MessageHandlerThread(void);
~MessageHandlerThread(void);
void run(); void run();
void stop(void);
private:
char *m_parameter;
bool m_aborted;
signals:
void otherInstanceDetected(void);
void fileReceived(const QString &filePath);
}; };