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">
<item row="1" column="1">
<widget class="QLabel" name="label_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
@ -769,8 +772,9 @@
</property>
<addaction name="actionStylePlastique"/>
<addaction name="actionStyleCleanlooks"/>
<addaction name="actionStyleWindows"/>
<addaction name="actionStyleClassic"/>
<addaction name="actionStyleWindowsVista"/>
<addaction name="actionStyleWindowsXP"/>
<addaction name="actionStyleWindowsClassic"/>
</widget>
<addaction name="actionSourceFiles"/>
<addaction name="actionOutputDirectory"/>
@ -909,20 +913,28 @@
<string>Cleanlooks</string>
</property>
</action>
<action name="actionStyleWindows">
<action name="actionStyleWindowsVista">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Windows</string>
<string>Windows Vista (&quot;Aero&quot;)</string>
</property>
</action>
<action name="actionStyleClassic">
<action name="actionStyleWindowsClassic">
<property name="checkable">
<bool>true</bool>
</property>
<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>
</action>
</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"/>
</resources>
<connections>
<connection>

View File

@ -124,8 +124,9 @@ MainWindow::MainWindow(QWidget *parent)
m_styleActionGroup = new QActionGroup(this);
m_styleActionGroup->addAction(actionStylePlastique);
m_styleActionGroup->addAction(actionStyleCleanlooks);
m_styleActionGroup->addAction(actionStyleWindows);
m_styleActionGroup->addAction(actionStyleClassic);
m_styleActionGroup->addAction(actionStyleWindowsVista);
m_styleActionGroup->addAction(actionStyleWindowsXP);
m_styleActionGroup->addAction(actionStyleWindowsClassic);
actionStylePlastique->setChecked(true);
connect(m_styleActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(styleActionActivated(QAction*)));
@ -144,6 +145,11 @@ MainWindow::MainWindow(QWidget *parent)
//Create message handler thread
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();
}
@ -153,11 +159,20 @@ MainWindow::MainWindow(QWidget *parent)
MainWindow::~MainWindow(void)
{
while(m_messageHandler->isRunning())
{
m_messageHandler->stop();
m_messageHandler->wait();
}
LAMEXP_DELETE(m_tabActionGroup);
LAMEXP_DELETE(m_styleActionGroup);
LAMEXP_DELETE(m_fileListModel);
LAMEXP_DELETE(m_banner);
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)
{
QStringList fileList;
QStringList arguments = QApplication::arguments();
qDebug("Main window is showing");
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());
if(currentFile.exists())
{
fileList << currentFile.absoluteFilePath();
m_delayedFileList->append(currentFile.absoluteFilePath());
}
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);
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();
m_delayedFileTimer->start(5000);
}
}
@ -318,6 +323,13 @@ void MainWindow::aboutButtonClicked(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!");
}
@ -505,8 +517,9 @@ void MainWindow::styleActionActivated(QAction *action)
{
if(action == actionStylePlastique) QApplication::setStyle(new QPlastiqueStyle());
else if(action == actionStyleCleanlooks) QApplication::setStyle(new QCleanlooksStyle());
else if(action == actionStyleWindows) QApplication::setStyle(new QWindowsVistaStyle());
else if(action == actionStyleClassic) QApplication::setStyle(new QWindowsStyle());
else if(action == actionStyleWindowsVista) QApplication::setStyle(new QWindowsVistaStyle());
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);
}
/*
* 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!");
}
/*
* 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 visitHomepageActionActivated(void);
void openFolderActionActivated(void);
void notifyOtherInstance(void);
void addFileDelayed(const QString &filePath);
void handleDelayedFiles(void);
protected:
void showEvent(QShowEvent *event);
@ -70,4 +73,6 @@ private:
QActionGroup *m_styleActionGroup;
WorkingBanner *m_banner;
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)
{
return true;
return 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_write_ptr);
qFatal("Failed to create system smaphore: %s", errorMessage.toUtf8().constData());
return false;
return -1;
}
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_write_ptr);
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);
@ -296,30 +296,27 @@ bool lamexp_check_instances(void)
g_lamexp_sharedmem_ptr->attach();
if(g_lamexp_sharedmem_ptr->error() == QSharedMemory::NoError)
{
lamexp_ipc_send(42, "Wurst schmeckt uns!");
return 1;
}
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
{
QString errorMessage = g_lamexp_sharedmem_ptr->errorString();
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));
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;
strcpy_s(lamexp_ipc->parameter, 4096, message);
g_lamexp_semaphore_write_ptr->acquire();
memcpy(g_lamexp_sharedmem_ptr->data(), lamexp_ipc, sizeof(lamexp_ipc_t));
g_lamexp_semaphore_read_ptr->release();
if(g_lamexp_semaphore_write_ptr->acquire())
{
memcpy(g_lamexp_sharedmem_ptr->data(), lamexp_ipc, sizeof(lamexp_ipc_t));
g_lamexp_semaphore_read_ptr->release();
}
LAMEXP_DELETE(lamexp_ipc);
}
@ -359,23 +359,48 @@ void lamexp_ipc_read(unsigned int *command, char* message, size_t buffSize)
lamexp_ipc_t *lamexp_ipc = new lamexp_ipc_t;
memset(lamexp_ipc, 0, sizeof(lamexp_ipc_t));
g_lamexp_semaphore_read_ptr->acquire();
memcpy(lamexp_ipc, g_lamexp_sharedmem_ptr->data(), sizeof(lamexp_ipc_t));
g_lamexp_semaphore_write_ptr->release();
if(!(lamexp_ipc->reserved_1 || lamexp_ipc->reserved_2))
if(g_lamexp_semaphore_read_ptr->acquire())
{
*command = lamexp_ipc->command;
strcpy_s(message, buffSize, lamexp_ipc->parameter);
}
else
{
qWarning("Malformed IPC message, will be ignored");
memcpy(lamexp_ipc, g_lamexp_sharedmem_ptr->data(), sizeof(lamexp_ipc_t));
g_lamexp_semaphore_write_ptr->release();
if(!(lamexp_ipc->reserved_1 || lamexp_ipc->reserved_2))
{
*command = lamexp_ipc->command;
strcpy_s(message, buffSize, lamexp_ipc->parameter);
}
else
{
qWarning("Malformed IPC message, will be ignored");
}
}
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
*/

View File

@ -47,7 +47,8 @@ bool lamexp_version_demo(void);
//Public functions
void lamexp_init_console(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);
const QString lamexp_lookup_tool(const QString &toolName);
void lamexp_finalization(void);

View File

@ -68,8 +68,18 @@ int lamexp_main(int argc, char* argv[])
}
}
//Check for multiple instances
if(!lamexp_check_instances()) return 0;
//Check for multiple instances of LameXP
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
InitializationThread *poInitializationThread = new InitializationThread();
@ -79,7 +89,7 @@ int lamexp_main(int argc, char* argv[])
//Show main window
MainWindow *poMainWindow = new MainWindow();
poMainWindow->show();
int iResult = QApplication::instance()->exec();
iResult = QApplication::instance()->exec();
LAMEXP_DELETE(poMainWindow);
//Final clean-up

View File

@ -25,6 +25,9 @@
#include <QSharedMemory>
#include <QSystemSemaphore>
#include <QMessageBox>
#include <limits.h>
////////////////////////////////////////////////////////////
// Constructor
@ -32,21 +35,49 @@
MessageHandlerThread::MessageHandlerThread(void)
{
m_aborted = false;
m_parameter = new char[4096];
}
MessageHandlerThread::~MessageHandlerThread(void)
{
delete [] m_parameter;
}
void MessageHandlerThread::run()
{
unsigned int command = 0;
char *parameter = new char[4096];
while(true)
m_aborted = false;
setTerminationEnabled(true);
while(!m_aborted)
{
qDebug("MessageHandlerThread: Waiting...");
lamexp_ipc_read(&command, parameter, 4096);
qDebug("MessageHandlerThread: command=%u, parameter='%s'", command, parameter);
unsigned int command = 0;
lamexp_ipc_read(&command, m_parameter, 4096);
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:
MessageHandlerThread(void);
~MessageHandlerThread(void);
void run();
void stop(void);
private:
char *m_parameter;
bool m_aborted;
signals:
void otherInstanceDetected(void);
void fileReceived(const QString &filePath);
};