To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / main / main.cpp @ 1:f78d846bf880
History | View | Annotate | Download (7.67 KB)
| 1 |
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
|---|---|
| 2 |
|
| 3 |
/*
|
| 4 |
Sonic Visualiser
|
| 5 |
An audio file viewer and annotation editor.
|
| 6 |
Centre for Digital Music, Queen Mary, University of London.
|
| 7 |
This file copyright 2006 Chris Cannam and QMUL.
|
| 8 |
|
| 9 |
This program is free software; you can redistribute it and/or
|
| 10 |
modify it under the terms of the GNU General Public License as
|
| 11 |
published by the Free Software Foundation; either version 2 of the
|
| 12 |
License, or (at your option) any later version. See the file
|
| 13 |
COPYING included with this distribution for more information.
|
| 14 |
*/
|
| 15 |
|
| 16 |
#include "MainWindow.h" |
| 17 |
|
| 18 |
#include "system/System.h" |
| 19 |
#include "system/Init.h" |
| 20 |
#include "base/TempDirectory.h" |
| 21 |
#include "base/PropertyContainer.h" |
| 22 |
#include "base/Preferences.h" |
| 23 |
#include "widgets/TipDialog.h" |
| 24 |
|
| 25 |
#include <QMetaType> |
| 26 |
#include <QApplication> |
| 27 |
#include <QDesktopWidget> |
| 28 |
#include <QMessageBox> |
| 29 |
#include <QTranslator> |
| 30 |
#include <QLocale> |
| 31 |
#include <QSettings> |
| 32 |
#include <QIcon> |
| 33 |
#include <QSessionManager> |
| 34 |
#include <QDir> |
| 35 |
|
| 36 |
#include <iostream> |
| 37 |
#include <signal.h> |
| 38 |
|
| 39 |
static QMutex cleanupMutex;
|
| 40 |
|
| 41 |
static void |
| 42 |
signalHandler(int /* signal */) |
| 43 |
{
|
| 44 |
// Avoid this happening more than once across threads
|
| 45 |
|
| 46 |
cleanupMutex.lock(); |
| 47 |
std::cerr << "signalHandler: cleaning up and exiting" << std::endl;
|
| 48 |
TempDirectory::getInstance()->cleanup(); |
| 49 |
exit(0); // without releasing mutex |
| 50 |
} |
| 51 |
|
| 52 |
class VectApplication : public QApplication |
| 53 |
{
|
| 54 |
public:
|
| 55 |
VectApplication(int argc, char **argv) : |
| 56 |
QApplication(argc, argv), |
| 57 |
m_mainWindow(0) { }
|
| 58 |
virtual ~VectApplication() { }
|
| 59 |
|
| 60 |
void setMainWindow(MainWindow *mw) { m_mainWindow = mw; }
|
| 61 |
void releaseMainWindow() { m_mainWindow = 0; } |
| 62 |
|
| 63 |
virtual void commitData(QSessionManager &manager) { |
| 64 |
if (!m_mainWindow) return; |
| 65 |
bool mayAskUser = manager.allowsInteraction();
|
| 66 |
bool success = m_mainWindow->commitData(mayAskUser);
|
| 67 |
manager.release(); |
| 68 |
if (!success) manager.cancel();
|
| 69 |
} |
| 70 |
|
| 71 |
protected:
|
| 72 |
MainWindow *m_mainWindow; |
| 73 |
}; |
| 74 |
|
| 75 |
int
|
| 76 |
main(int argc, char **argv) |
| 77 |
{
|
| 78 |
StoreStartupLocale(); |
| 79 |
|
| 80 |
VectApplication application(argc, argv); |
| 81 |
|
| 82 |
QStringList args = application.arguments(); |
| 83 |
|
| 84 |
signal(SIGINT, signalHandler); |
| 85 |
signal(SIGTERM, signalHandler); |
| 86 |
|
| 87 |
#ifndef Q_WS_WIN32
|
| 88 |
signal(SIGHUP, signalHandler); |
| 89 |
signal(SIGQUIT, signalHandler); |
| 90 |
#endif
|
| 91 |
|
| 92 |
svSystemSpecificInitialisation(); |
| 93 |
|
| 94 |
bool audioOutput = true; |
| 95 |
bool oscSupport = false; |
| 96 |
|
| 97 |
if (args.contains("--help") || args.contains("-h") || args.contains("-?")) { |
| 98 |
std::cerr << QApplication::tr( |
| 99 |
"\nSonic Visualiser is a program for viewing and exploring audio data\nfor semantic music analysis and annotation.\n\nUsage:\n\n %1 [--no-audio] [--no-osc] [<file> ...]\n\n --no-audio: Do not attempt to open an audio output device\n --no-osc: Do not provide an Open Sound Control port for remote control\n <file>: One or more Sonic Visualiser (.sv) and audio files may be provided.\n").arg(argv[0]).toStdString() << std::endl; |
| 100 |
exit(2);
|
| 101 |
} |
| 102 |
|
| 103 |
if (args.contains("--no-audio")) audioOutput = false; |
| 104 |
// if (args.contains("--no-osc")) oscSupport = false;
|
| 105 |
|
| 106 |
QApplication::setOrganizationName("sonic-visualiser");
|
| 107 |
QApplication::setOrganizationDomain("sonicvisualiser.org");
|
| 108 |
QApplication::setApplicationName("Sonic Segmenter");
|
| 109 |
|
| 110 |
QIcon icon; |
| 111 |
int sizes[] = { 16, 22, 24, 32, 48, 64, 128 }; |
| 112 |
for (int i = 0; i < sizeof(sizes)/sizeof(sizes[0]); ++i) { |
| 113 |
icon.addFile(QString(":icons/sv-%1x%2.png").arg(sizes[i]).arg(sizes[i]));
|
| 114 |
} |
| 115 |
QApplication::setWindowIcon(icon); |
| 116 |
|
| 117 |
QString language = QLocale::system().name(); |
| 118 |
|
| 119 |
QTranslator qtTranslator; |
| 120 |
QString qtTrName = QString("qt_%1").arg(language);
|
| 121 |
std::cerr << "Loading " << qtTrName.toStdString() << "..." << std::endl; |
| 122 |
bool success = false; |
| 123 |
if (!(success = qtTranslator.load(qtTrName))) {
|
| 124 |
QString qtDir = getenv("QTDIR");
|
| 125 |
if (qtDir != "") { |
| 126 |
success = qtTranslator.load |
| 127 |
(qtTrName, QDir(qtDir).filePath("translations"));
|
| 128 |
} |
| 129 |
} |
| 130 |
if (!success) {
|
| 131 |
std::cerr << "Failed to load Qt translation for locale" << std::endl;
|
| 132 |
} |
| 133 |
application.installTranslator(&qtTranslator); |
| 134 |
|
| 135 |
//!!! load sv translations, plus vect translations
|
| 136 |
QTranslator svTranslator; |
| 137 |
QString svTrName = QString("sonic-visualiser_%1").arg(language);
|
| 138 |
std::cerr << "Loading " << svTrName.toStdString() << "..." << std::endl; |
| 139 |
svTranslator.load(svTrName, ":i18n");
|
| 140 |
application.installTranslator(&svTranslator); |
| 141 |
|
| 142 |
// Permit size_t and PropertyName to be used as args in queued signal calls
|
| 143 |
qRegisterMetaType<size_t>("size_t");
|
| 144 |
qRegisterMetaType<PropertyContainer::PropertyName>("PropertyContainer::PropertyName");
|
| 145 |
|
| 146 |
MainWindow gui(audioOutput, oscSupport); |
| 147 |
application.setMainWindow(&gui); |
| 148 |
|
| 149 |
QDesktopWidget *desktop = QApplication::desktop(); |
| 150 |
QRect available = desktop->availableGeometry(); |
| 151 |
|
| 152 |
int width = available.width() * 2 / 3; |
| 153 |
int height = available.height() / 2; |
| 154 |
if (height < 450) height = available.height() * 2 / 3; |
| 155 |
if (width > height * 2) width = height * 2; |
| 156 |
|
| 157 |
QSettings settings; |
| 158 |
settings.beginGroup("MainWindow");
|
| 159 |
QSize size = settings.value("size", QSize(width, height)).toSize();
|
| 160 |
gui.resize(size); |
| 161 |
if (settings.contains("position")) { |
| 162 |
gui.move(settings.value("position").toPoint());
|
| 163 |
} |
| 164 |
settings.endGroup(); |
| 165 |
|
| 166 |
gui.show(); |
| 167 |
|
| 168 |
bool haveSession = false; |
| 169 |
bool haveMainModel = false; |
| 170 |
bool havePriorCommandLineModel = false; |
| 171 |
|
| 172 |
for (QStringList::iterator i = args.begin(); i != args.end(); ++i) {
|
| 173 |
|
| 174 |
MainWindow::FileOpenStatus status = MainWindow::FileOpenFailed; |
| 175 |
|
| 176 |
if (i == args.begin()) continue; |
| 177 |
if (i->startsWith('-')) continue; |
| 178 |
|
| 179 |
if (i->startsWith("http:") || i->startsWith("ftp:")) { |
| 180 |
std::cerr << "opening URL: \"" << i->toStdString() << "\"..." << std::endl; |
| 181 |
status = gui.open(*i); |
| 182 |
continue;
|
| 183 |
} |
| 184 |
|
| 185 |
QString path = *i; |
| 186 |
|
| 187 |
if (path.endsWith("sv")) { |
| 188 |
if (!haveSession) {
|
| 189 |
status = gui.openSessionFile(path); |
| 190 |
if (status == MainWindow::FileOpenSucceeded) {
|
| 191 |
haveSession = true;
|
| 192 |
haveMainModel = true;
|
| 193 |
} |
| 194 |
} else {
|
| 195 |
std::cerr << "WARNING: Ignoring additional session file argument \"" << path.toStdString() << "\"" << std::endl; |
| 196 |
status = MainWindow::FileOpenSucceeded; |
| 197 |
} |
| 198 |
} |
| 199 |
if (status != MainWindow::FileOpenSucceeded) {
|
| 200 |
if (!haveMainModel) {
|
| 201 |
status = gui.open(path, MainWindow::ReplaceMainModel); |
| 202 |
if (status == MainWindow::FileOpenSucceeded) {
|
| 203 |
haveMainModel = true;
|
| 204 |
} |
| 205 |
} else {
|
| 206 |
if (haveSession && !havePriorCommandLineModel) {
|
| 207 |
status = gui.open(path, MainWindow::AskUser); |
| 208 |
if (status == MainWindow::FileOpenSucceeded) {
|
| 209 |
havePriorCommandLineModel = true;
|
| 210 |
} |
| 211 |
} else {
|
| 212 |
status = gui.open(path, MainWindow::CreateAdditionalModel); |
| 213 |
} |
| 214 |
} |
| 215 |
} |
| 216 |
if (status == MainWindow::FileOpenFailed) {
|
| 217 |
QMessageBox::critical |
| 218 |
(&gui, QMessageBox::tr("Failed to open file"),
|
| 219 |
QMessageBox::tr("File \"%1\" could not be opened").arg(path));
|
| 220 |
} |
| 221 |
} |
| 222 |
|
| 223 |
|
| 224 |
|
| 225 |
/*
|
| 226 |
TipDialog tipDialog;
|
| 227 |
if (tipDialog.isOK()) {
|
| 228 |
tipDialog.exec();
|
| 229 |
}
|
| 230 |
*/
|
| 231 |
int rv = application.exec();
|
| 232 |
// std::cerr << "application.exec() returned " << rv << std::endl;
|
| 233 |
|
| 234 |
cleanupMutex.lock(); |
| 235 |
TempDirectory::getInstance()->cleanup(); |
| 236 |
application.releaseMainWindow(); |
| 237 |
|
| 238 |
return rv;
|
| 239 |
} |