Mercurial > hg > sonic-visualiser
changeset 372:012fdb1d19bf macness_autotpl
Templating stuff pulled into macness_autotpl branch
author | Dan Stowell <dan.stowell@eecs.qmul.ac.uk> |
---|---|
date | Fri, 15 Oct 2010 12:16:48 +0100 |
parents | ca9f27734349 (diff) 23f2ee395cf7 (current diff) |
children | 80d91b72ae7d |
files | |
diffstat | 7 files changed, 317 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/main/MainWindow.cpp Fri Oct 15 11:59:03 2010 +0100 +++ b/main/MainWindow.cpp Fri Oct 15 12:16:48 2010 +0100 @@ -79,6 +79,9 @@ #include "widgets/ModelDataTableDialog.h" #include "rdf/PluginRDFIndexer.h" #include "rdf/RDFExporter.h" +#ifdef Q_WS_MAC + #include "osx/svitunes.h" +#endif #include "Surveyer.h" #include "framework/VersionTester.h" @@ -442,6 +445,16 @@ m_keyReference->registerShortcut(action); menu->addAction(action); +#ifdef Q_WS_MAC + action = new QAction(tr("Import current track from iTunes"), this); + action->setShortcut(tr("Ctrl+Alt+I")); + action->setStatusTip(tr("Import currently playing/selected iTunes track")); + connect(action, SIGNAL(triggered()), this, SLOT(importITunesAudio())); + //connect(this, SIGNAL(canImportITunesAudio(bool)), action, SLOT(setEnabled(bool))); + m_keyReference->registerShortcut(action); + menu->addAction(action); +#endif + action = new QAction(tr("&Export Audio File..."), this); action->setStatusTip(tr("Export selection as an audio file")); connect(action, SIGNAL(triggered()), this, SLOT(exportAudio())); @@ -2148,6 +2161,25 @@ } } +#ifdef Q_WS_MAC +void +MainWindow::importITunesAudio() +{ + QStringList nowPlaying = iTunesNowPlaying(); + QString path = nowPlaying.at(0); + QString genre = (nowPlaying.size() > 1) ? nowPlaying.at(1) : ""; + std::cerr << "MainWindow::importITunesAudio(): genre is " << genre.toStdString() << std::endl; + + if (path != "") { + if (openAudio(path, ReplaceMainModel) == FileOpenFailed) { + emit hideSplash(); + QMessageBox::critical(this, tr("Failed to open file"), + tr("<b>File open failed</b><p>Audio file \"%1\" could not be opened").arg(path)); + } + } +} +#endif + void MainWindow::exportAudio() {
--- a/main/MainWindow.h Fri Oct 15 11:59:03 2010 +0100 +++ b/main/MainWindow.h Fri Oct 15 12:16:48 2010 +0100 @@ -80,6 +80,9 @@ virtual void openSession(); virtual void importAudio(); virtual void importMoreAudio(); +#ifdef Q_WS_MAC + virtual void importITunesAudio(); +#endif virtual void openSomething(); virtual void openLocation(); virtual void openRecentFile();
--- a/main/main.cpp Fri Oct 15 11:59:03 2010 +0100 +++ b/main/main.cpp Fri Oct 15 12:16:48 2010 +0100 @@ -36,6 +36,12 @@ #include <QSplashScreen> #include <QTimer> #include <QPainter> +#include <QFileOpenEvent> +#include <QMenu> +#ifdef Q_WS_MAC + #include "osx/svitunes.h" + void qt_mac_set_dock_menu(QMenu *menu); // must declare it ourselves, weirdly enough +#endif #include "../version.h" @@ -188,7 +194,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; } @@ -202,8 +211,30 @@ if (!success) manager.cancel(); } + void handleFilepathArgument(QString path, QSplashScreen *splash); + + bool m_readyForFiles; + QStringList m_filepathQueue; + +#ifdef Q_WS_MAC + void setupDockMenu() { + std::cerr << "SV adding mac dock menu" << std::endl; + QMenu *dockMenu = new QMenu(); + QStringList nowPlaying = iTunesNowPlaying(); + QString theText = nowPlaying.at(0); + if (theText == ""){ + theText = "[[No current track in iTunes]]"; + } + dockMenu->addAction(theText); + qt_mac_set_dock_menu(dockMenu); + } +#endif + + protected: MainWindow *m_mainWindow; + bool event(QEvent *); + }; int @@ -347,59 +378,21 @@ // complete. As a lazy hack, apply it explicitly from here gui->preferenceChanged("Property Box Layout"); - bool haveSession = false; - bool haveMainModel = false; - bool havePriorCommandLineModel = false; + application.m_readyForFiles = true; // Ready to receive files from e.g. Apple Events for (QStringList::iterator i = args.begin(); i != args.end(); ++i) { - MainWindow::FileOpenStatus status = MainWindow::FileOpenFailed; - if (i == args.begin()) continue; if (i->startsWith('-')) continue; QString path = *i; - 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")); - } + 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 @@ -417,6 +410,10 @@ settings.endGroup(); #endif +#ifdef Q_WS_MAC + application.setupDockMenu(); +#endif + if (splash) splash->finish(gui); delete splash; @@ -457,3 +454,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")); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/Info.plist Fri Oct 15 12:16:48 2010 +0100 @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd"> +<plist version="0.9"> +<dict> + <key>CFBundleIconFile</key> + <string>sv-macicon.icns</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleGetInfoString</key> + <string>Created by Qt/QMake</string> + <key>CFBundleSignature</key> + <string>SNCV</string> + <key>CFBundleExecutable</key> + <string>Sonic Visualiser</string> + <key>CFBundleIdentifier</key> + <string>org.isophonics.SonicVisualiser</string> + <key>CFBundleDocumentTypes</key> + <array> + <!-- we are an 'editor' of SV files --> + <dict> + <key>CFBundleTypeExtensions</key> + <array> + <string>sv</string> + </array> + <!-- TODO + <key>CFBundleTypeIconFile</key> + <string>SVProject.icns</string> --> + <key>CFBundleTypeMIMETypes</key> + <array> + <string>application/x-sonic-visualiser-project</string> + </array> + <key>CFBundleTypeName</key> + <string>Sonic Visualiser Project</string> + <key>CFBundleTypeOSTypes</key> + <array> + <string>****</string> + </array> + <key>CFBundleTypeRole</key> + <string>Editor</string> + <key>LSHandlerRank</key> + <string>Owner</string> + <key>LSIsAppleDefaultForType</key> + <true/> + </dict> + + <!-- we are a 'viewer' of general audio files --> + <dict> + <key>CFBundleTypeExtensions</key> + <array> + <string>mp3</string> + </array> + <key>CFBundleTypeMIMETypes</key> + <array> + <string>audio/mpeg</string> + </array> + <key>CFBundleTypeName</key> + <string>MP3 Audio</string> + <key>CFBundleTypeRole</key> + <string>Viewer</string> + <key>LSIsAppleDefaultForType</key> + <false/> + <key>LSHandlerRank</key> + <string>Alternate</string> + </dict> + </array> + </dict> +</plist>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/svitunes.h Fri Oct 15 12:16:48 2010 +0100 @@ -0,0 +1,24 @@ +/* + iTunes connection for + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2010 Dan Stowell and QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include <QString> +#include <QStringList> + +//LATER: bool iTunesRunning(); + +// Returns a list containing [posixpath, genre] +QStringList iTunesNowPlaying(); + +//LATER: QStringList iTunesSelectedPaths(); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/osx/svitunes.mm Fri Oct 15 12:16:48 2010 +0100 @@ -0,0 +1,77 @@ +/* + iTunes connection for + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2010 Dan Stowell and QMUL. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "svitunes.h" + +#include <Foundation/NSAppleScript.h> + +#import <Foundation/Foundation.h> + +QString qt_mac_NSStringToQString(const NSString *nsstr) +{ + NSRange range; + range.location = 0; + range.length = [nsstr length]; + + unichar *chars = new unichar[range.length + 1]; + chars[range.length] = 0; + [nsstr getCharacters:chars range:range]; + QString result = QString::fromUtf16(chars, range.length); + delete chars; + return result; +} + +QStringList iTunesNowPlaying(){ + NSDictionary *errorDict; + NSAppleScript *scriptObject = [[NSAppleScript alloc] initWithSource:@" \ +tell application \"System Events\" to set iTunesIsRunning to (name of processes) contains \"iTunes\" \n\ +if iTunesIsRunning is false then return \"\" \n\ +\ +tell application \"iTunes\" \n\ + if player state is not stopped then \n\ + set aTrack to current track \n\ + else \n\ + set sel to selection \n\ + if sel is not {} then --and (length of sel) is 1 then \n\ + set aTrack to item 1 of sel \n\ + else \n\ + return \"\" \n\ + end if \n\ + end if \n\ + \ + return the POSIX path of (location of aTrack as text) & \"\n\" & (genre of aTrack) \n\ +end tell \n\ +" + ]; + + NSLog([scriptObject source]); + + [scriptObject compileAndReturnError: &errorDict]; + + if(![scriptObject isCompiled]){ + NSLog(@"SV ERROR: applescript object not compiled"); + NSLog([errorDict description]); + } + + NSAppleEventDescriptor *eventDesc = [scriptObject executeAndReturnError: &errorDict]; + NSString *nsResultString = [eventDesc stringValue]; + + NSLog(@"iTunesNowPlayingPath: "); + NSLog(nsResultString); + + QString resultString = qt_mac_NSStringToQString(nsResultString); + + [scriptObject release]; + return resultString.split(QChar('\n')); +}
--- a/sonic-visualiser.pro Fri Oct 15 11:59:03 2010 +0100 +++ b/sonic-visualiser.pro Fri Oct 15 12:16:48 2010 +0100 @@ -40,4 +40,10 @@ main/PreferencesDialog.cpp \ main/Surveyer.cpp +mac { + QMAKE_INFO_PLIST = osx/Info.plist + + OBJECTIVE_SOURCES += osx/svitunes.mm + LIBS += -framework Foundation +}