00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "MainWindow.h"
00017
00018 #include "system/System.h"
00019 #include "system/Init.h"
00020 #include "base/TempDirectory.h"
00021 #include "base/PropertyContainer.h"
00022 #include "base/Preferences.h"
00023 #include "widgets/TipDialog.h"
00024
00025 #include <QMetaType>
00026 #include <QApplication>
00027 #include <QDesktopWidget>
00028 #include <QMessageBox>
00029 #include <QTranslator>
00030 #include <QLocale>
00031 #include <QSettings>
00032 #include <QIcon>
00033 #include <QSessionManager>
00034 #include <QDir>
00035 #include <QSplashScreen>
00036
00037 #include <iostream>
00038 #include <signal.h>
00039
00040 #ifdef HAVE_FFTW3F
00041 #include <fftw3.h>
00042 #endif
00043
00168 static QMutex cleanupMutex;
00169
00170 static void
00171 signalHandler(int )
00172 {
00173
00174
00175 cleanupMutex.lock();
00176 std::cerr << "signalHandler: cleaning up and exiting" << std::endl;
00177 TempDirectory::getInstance()->cleanup();
00178 exit(0);
00179 }
00180
00181 class SVApplication : public QApplication
00182 {
00183 public:
00184 SVApplication(int argc, char **argv) :
00185 QApplication(argc, argv),
00186 m_mainWindow(0) { }
00187 virtual ~SVApplication() { }
00188
00189 void setMainWindow(MainWindow *mw) { m_mainWindow = mw; }
00190 void releaseMainWindow() { m_mainWindow = 0; }
00191
00192 virtual void commitData(QSessionManager &manager) {
00193 if (!m_mainWindow) return;
00194 bool mayAskUser = manager.allowsInteraction();
00195 bool success = m_mainWindow->commitData(mayAskUser);
00196 manager.release();
00197 if (!success) manager.cancel();
00198 }
00199
00200 protected:
00201 MainWindow *m_mainWindow;
00202 };
00203
00204 int
00205 main(int argc, char **argv)
00206 {
00207 SVApplication application(argc, argv);
00208
00209 QStringList args = application.arguments();
00210
00211 signal(SIGINT, signalHandler);
00212 signal(SIGTERM, signalHandler);
00213
00214 #ifndef Q_WS_WIN32
00215 signal(SIGHUP, signalHandler);
00216 signal(SIGQUIT, signalHandler);
00217 #endif
00218
00219 svSystemSpecificInitialisation();
00220
00221 bool audioOutput = true;
00222 bool oscSupport = true;
00223
00224 if (args.contains("--help") || args.contains("-h") || args.contains("-?")) {
00225 std::cerr << QApplication::tr(
00226 "\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;
00227 exit(2);
00228 }
00229
00230 if (args.contains("--no-audio")) audioOutput = false;
00231 if (args.contains("--no-osc")) oscSupport = false;
00232
00233 QApplication::setOrganizationName("sonic-visualiser");
00234 QApplication::setOrganizationDomain("sonicvisualiser.org");
00235 QApplication::setApplicationName(QApplication::tr("Sonic Visualiser"));
00236
00237 QPixmap pixmap(":/icons/sv-splash.png");
00238 QSplashScreen splash(pixmap);
00239
00240 QSettings settings;
00241
00242 settings.beginGroup("Preferences");
00243 if (settings.value("show-splash", true).toBool()) {
00244 splash.show();
00245 application.processEvents();
00246 }
00247 settings.endGroup();
00248
00249 QIcon icon;
00250 int sizes[] = { 16, 22, 24, 32, 48, 64, 128 };
00251 for (int i = 0; i < sizeof(sizes)/sizeof(sizes[0]); ++i) {
00252 icon.addFile(QString(":icons/sv-%1x%2.png").arg(sizes[i]).arg(sizes[i]));
00253 }
00254 QApplication::setWindowIcon(icon);
00255
00256 QString language = QLocale::system().name();
00257
00258 QTranslator qtTranslator;
00259 QString qtTrName = QString("qt_%1").arg(language);
00260 std::cerr << "Loading " << qtTrName.toStdString() << "..." << std::endl;
00261 bool success = false;
00262 if (!(success = qtTranslator.load(qtTrName))) {
00263 QString qtDir = getenv("QTDIR");
00264 if (qtDir != "") {
00265 success = qtTranslator.load
00266 (qtTrName, QDir(qtDir).filePath("translations"));
00267 }
00268 }
00269 if (!success) {
00270 std::cerr << "Failed to load Qt translation for locale" << std::endl;
00271 }
00272 application.installTranslator(&qtTranslator);
00273
00274 QTranslator svTranslator;
00275 QString svTrName = QString("sonic-visualiser_%1").arg(language);
00276 std::cerr << "Loading " << svTrName.toStdString() << "..." << std::endl;
00277 svTranslator.load(svTrName, ":i18n");
00278 application.installTranslator(&svTranslator);
00279
00280 StoreStartupLocale();
00281
00282
00283 qRegisterMetaType<size_t>("size_t");
00284 qRegisterMetaType<PropertyContainer::PropertyName>("PropertyContainer::PropertyName");
00285
00286 MainWindow *gui = new MainWindow(audioOutput, oscSupport);
00287 application.setMainWindow(gui);
00288
00289 QDesktopWidget *desktop = QApplication::desktop();
00290 QRect available = desktop->availableGeometry();
00291
00292 int width = available.width() * 2 / 3;
00293 int height = available.height() / 2;
00294 if (height < 450) height = available.height() * 2 / 3;
00295 if (width > height * 2) width = height * 2;
00296
00297 settings.beginGroup("MainWindow");
00298 QSize size = settings.value("size", QSize(width, height)).toSize();
00299 gui->resize(size);
00300 if (settings.contains("position")) {
00301 gui->move(settings.value("position").toPoint());
00302 }
00303 settings.endGroup();
00304
00305 gui->show();
00306
00307
00308
00309
00310 gui->preferenceChanged("Property Box Layout");
00311
00312 bool haveSession = false;
00313 bool haveMainModel = false;
00314 bool havePriorCommandLineModel = false;
00315
00316 for (QStringList::iterator i = args.begin(); i != args.end(); ++i) {
00317
00318 MainWindow::FileOpenStatus status = MainWindow::FileOpenFailed;
00319
00320 if (i == args.begin()) continue;
00321 if (i->startsWith('-')) continue;
00322
00323 QString path = *i;
00324
00325 if (path.endsWith("sv")) {
00326 if (!haveSession) {
00327 status = gui->openSessionFile(path);
00328 if (status == MainWindow::FileOpenSucceeded) {
00329 haveSession = true;
00330 haveMainModel = true;
00331 }
00332 } else {
00333 std::cerr << "WARNING: Ignoring additional session file argument \"" << path.toStdString() << "\"" << std::endl;
00334 status = MainWindow::FileOpenSucceeded;
00335 }
00336 }
00337 if (status != MainWindow::FileOpenSucceeded) {
00338 if (!haveMainModel) {
00339 status = gui->open(path, MainWindow::ReplaceMainModel);
00340 if (status == MainWindow::FileOpenSucceeded) {
00341 haveMainModel = true;
00342 }
00343 } else {
00344 if (haveSession && !havePriorCommandLineModel) {
00345 status = gui->open(path, MainWindow::AskUser);
00346 if (status == MainWindow::FileOpenSucceeded) {
00347 havePriorCommandLineModel = true;
00348 }
00349 } else {
00350 status = gui->open(path, MainWindow::CreateAdditionalModel);
00351 }
00352 }
00353 }
00354 if (status == MainWindow::FileOpenFailed) {
00355 QMessageBox::critical
00356 (gui, QMessageBox::tr("Failed to open file"),
00357 QMessageBox::tr("File or URL \"%1\" could not be opened").arg(path));
00358 }
00359 }
00360
00361 #ifdef HAVE_FFTW3F
00362 settings.beginGroup("FFTWisdom");
00363 QString wisdom = settings.value("wisdom").toString();
00364 if (wisdom != "") {
00365 fftwf_import_wisdom_from_string(wisdom.toLocal8Bit().data());
00366 }
00367 settings.endGroup();
00368 #endif
00369
00370 splash.finish(gui);
00371
00372
00373
00374
00375
00376
00377
00378 int rv = application.exec();
00379 std::cerr << "application.exec() returned " << rv << std::endl;
00380
00381 cleanupMutex.lock();
00382 TempDirectory::getInstance()->cleanup();
00383
00384 application.releaseMainWindow();
00385
00386 #ifdef HAVE_FFTW3F
00387 char *cwisdom = fftwf_export_wisdom_to_string();
00388 if (cwisdom) {
00389 settings.beginGroup("FFTWisdom");
00390 settings.setValue("wisdom", cwisdom);
00391 settings.endGroup();
00392 fftwf_free(cwisdom);
00393 }
00394 #endif
00395
00396 delete gui;
00397
00398 return rv;
00399 }