Mercurial > hg > sonic-visualiser
changeset 365:174ca518546f macness
Use QFileOpenEvent instead of native mac AppleEvent stuff: does the same job, better, neater
author | Dan Stowell <dan.stowell@eecs.qmul.ac.uk> |
---|---|
date | Mon, 11 Oct 2010 15:47:12 +0100 |
parents | 4e16d48c693d |
children | d0c5831d6528 61111a6a229f |
files | main/main.cpp |
diffstat | 1 files changed, 84 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- a/main/main.cpp Mon Oct 11 14:54:31 2010 +0100 +++ b/main/main.cpp Mon Oct 11 15:47:12 2010 +0100 @@ -23,11 +23,6 @@ #include "widgets/TipDialog.h" #include "transform/TransformFactory.h" -#ifdef Q_WS_MAC -#include <ApplicationServices/ApplicationServices.h> -#include <Carbon/Carbon.h> -#endif - #include <QMetaType> #include <QApplication> #include <QDesktopWidget> @@ -41,6 +36,7 @@ #include <QSplashScreen> #include <QTimer> #include <QPainter> +#include <QFileOpenEvent> #include "../version.h" @@ -176,7 +172,6 @@ */ static QMutex cleanupMutex; -static MainWindow *gui; static void signalHandler(int /* signal */) @@ -194,7 +189,10 @@ public: SVApplication(int &argc, char **argv) : QApplication(argc, argv), - m_mainWindow(0) { } + m_readyForFiles(false), + m_filepathQueue(QStringList()), + m_mainWindow(0) + { } virtual ~SVApplication() { } void setMainWindow(MainWindow *mw) { m_mainWindow = mw; } @@ -208,96 +206,15 @@ if (!success) manager.cancel(); } - /** Application-global handler for filepaths passed in, e.g. as command-line arguments or apple events */ - static void handleFilepathArgument(QString path, QSplashScreen *splash){ - static bool haveSession = false; - static bool haveMainModel = false; - static bool havePriorCommandLineModel = false; - - MainWindow::FileOpenStatus status = MainWindow::FileOpenFailed; - - if (path.endsWith("sv")) { - if (!haveSession) { - status = gui->openSessionFile(path); - if (status == MainWindow::FileOpenSucceeded) { - haveSession = true; - haveMainModel = true; - } - } else { - std::cerr << "WARNING: Ignoring additional session file argument \"" << path.toStdString() << "\"" << std::endl; - status = MainWindow::FileOpenSucceeded; - } - } - if (status != MainWindow::FileOpenSucceeded) { - if (!haveMainModel) { - status = gui->open(path, MainWindow::ReplaceMainModel); - if (status == MainWindow::FileOpenSucceeded) { - haveMainModel = true; - } - } else { - if (haveSession && !havePriorCommandLineModel) { - status = gui->open(path, MainWindow::AskUser); - if (status == MainWindow::FileOpenSucceeded) { - havePriorCommandLineModel = true; - } - } else { - status = gui->open(path, MainWindow::CreateAdditionalModel); - } - } - } - if (status == MainWindow::FileOpenFailed) { - if (splash) splash->hide(); - QMessageBox::critical - (gui, QMessageBox::tr("Failed to open file"), - QMessageBox::tr("File or URL \"%1\" could not be opened").arg(path)); - } else if (status == MainWindow::FileOpenWrongMode) { - if (splash) splash->hide(); - QMessageBox::critical - (gui, QMessageBox::tr("Failed to open file"), - QMessageBox::tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); - } - } - -#ifdef Q_WS_MAC - static pascal OSErr HandleOpenDocAE (const AppleEvent * theAppleEvent, AppleEvent * /* reply */, SInt32 /* handlerRefcon */) { - AEDescList docList; - FSRef theFSRef; - long count = 0; - OSErr err; - - err = AEGetParamDesc(theAppleEvent, keyDirectObject, typeAEList, &docList); - err = AECountItems(&docList, &count); - if(count == 0){ - std::cerr << "SV warning: received apple open-documents event with no documents (count==0)" << std::endl; - AEDisposeDesc(&docList); - return noErr; - } - // NB we could be passed a list of files - however, SV on Mac currently can only open one at a time, so we simply open the first. + void handleFilepathArgument(QString path, QSplashScreen *splash); - err = AEGetNthPtr(&docList, 1, typeFSRef, NULL, NULL, &theFSRef, sizeof(theFSRef), NULL); - - // Call routine to open document with current reference. - if(err == noErr){ - char uPath[1024]; - FSRefMakePath(&theFSRef, (UInt8*)uPath, 1023); - std::cerr << "SV received Apple Event request to open " << uPath << std::endl; - handleFilepathArgument(uPath, NULL); - } - - AEDisposeDesc(&docList); - return noErr; - } - static OSErr InstallMacOSEventHandlers(void) - { - OSErr err; - err = AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerUPP(HandleOpenDocAE), 0, false); - std::cerr << "HandleOpenDocAE installed. " << err << std::endl; - return err; - } -#endif // Q_WS_MAC + bool m_readyForFiles; + QStringList m_filepathQueue; protected: MainWindow *m_mainWindow; + bool event(QEvent *); + }; int @@ -409,7 +326,7 @@ qRegisterMetaType<size_t>("size_t"); qRegisterMetaType<PropertyContainer::PropertyName>("PropertyContainer::PropertyName"); - gui = new MainWindow(audioOutput, oscSupport); + MainWindow *gui = new MainWindow(audioOutput, oscSupport); application.setMainWindow(gui); if (splash) { QObject::connect(gui, SIGNAL(hideSplash()), splash, SLOT(hide())); @@ -434,10 +351,6 @@ } settings.endGroup(); -#ifdef Q_WS_MAC - application.InstallMacOSEventHandlers(); -#endif // Q_WS_MAC - gui->show(); // The MainWindow class seems to have trouble dealing with this if @@ -445,6 +358,8 @@ // complete. As a lazy hack, apply it explicitly from here gui->preferenceChanged("Property Box Layout"); + application.m_readyForFiles = true; // Ready to receive files from e.g. Apple Events + for (QStringList::iterator i = args.begin(); i != args.end(); ++i) { if (i == args.begin()) continue; @@ -452,7 +367,12 @@ QString path = *i; - SVApplication::handleFilepathArgument(path, splash); + application.handleFilepathArgument(path, splash); + } + + for (QStringList::iterator i = application.m_filepathQueue.begin(); i != application.m_filepathQueue.end(); ++i) { + QString path = *i; + application.handleFilepathArgument(path, splash); } #ifdef HAVE_FFTW3F @@ -510,3 +430,68 @@ return rv; } + +bool SVApplication::event(QEvent *event){ + QString thePath; + switch (event->type()) { + case QEvent::FileOpen: + thePath = static_cast<QFileOpenEvent *>(event)->file(); + if(m_readyForFiles) + handleFilepathArgument(thePath, NULL); + else + m_filepathQueue.append(thePath); + return true; + default: + return QApplication::event(event); + } +} + +/** Application-global handler for filepaths passed in, e.g. as command-line arguments or apple events */ +void SVApplication::handleFilepathArgument(QString path, QSplashScreen *splash){ + static bool haveSession = false; + static bool haveMainModel = false; + static bool havePriorCommandLineModel = false; + + MainWindow::FileOpenStatus status = MainWindow::FileOpenFailed; + + if (path.endsWith("sv")) { + if (!haveSession) { + status = m_mainWindow->openSessionFile(path); + if (status == MainWindow::FileOpenSucceeded) { + haveSession = true; + haveMainModel = true; + } + } else { + std::cerr << "WARNING: Ignoring additional session file argument \"" << path.toStdString() << "\"" << std::endl; + status = MainWindow::FileOpenSucceeded; + } + } + if (status != MainWindow::FileOpenSucceeded) { + if (!haveMainModel) { + status = m_mainWindow->open(path, MainWindow::ReplaceMainModel); + if (status == MainWindow::FileOpenSucceeded) { + haveMainModel = true; + } + } else { + if (haveSession && !havePriorCommandLineModel) { + status = m_mainWindow->open(path, MainWindow::AskUser); + if (status == MainWindow::FileOpenSucceeded) { + havePriorCommandLineModel = true; + } + } else { + status = m_mainWindow->open(path, MainWindow::CreateAdditionalModel); + } + } + } + if (status == MainWindow::FileOpenFailed) { + if (splash) splash->hide(); + QMessageBox::critical + (m_mainWindow, QMessageBox::tr("Failed to open file"), + QMessageBox::tr("File or URL \"%1\" could not be opened").arg(path)); + } else if (status == MainWindow::FileOpenWrongMode) { + if (splash) splash->hide(); + QMessageBox::critical + (m_mainWindow, QMessageBox::tr("Failed to open file"), + QMessageBox::tr("<b>Audio required</b><p>Please load at least one audio file before importing annotation data")); + } +}