scide: Main - provide shortcut to access elements of Main singleton
[supercollider.git] / editors / sc-ide / core / main.cpp
blob685cd5ab708aff92bcdcb32eb0c8b49cc0a34943
1 /*
2 SuperCollider Qt IDE
3 Copyright (c) 2012 Jakob Leben & Tim Blechmann
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "main.hpp"
22 #include "settings/manager.hpp"
23 #include "session_manager.hpp"
24 #include "../widgets/lookup_dialog.hpp"
25 #include "../widgets/main_window.hpp"
26 #include "../widgets/code_editor/highlighter.hpp"
28 #include "SC_DirUtils.h"
30 #include <QAction>
31 #include <QApplication>
32 #include <QBuffer>
33 #include <QDataStream>
34 #include <QDir>
35 #include <QFileOpenEvent>
36 #include <QLibraryInfo>
37 #include <QTranslator>
39 using namespace ScIDE;
41 int main( int argc, char *argv[] )
43 QApplication app(argc, argv);
45 QStringList arguments (QApplication::arguments());
46 arguments.pop_front(); // application path
48 SingleInstanceGuard guard;
49 if (guard.tryConnect(arguments))
50 return 0;
52 QTranslator qtTranslator;
53 qtTranslator.load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath));
54 app.installTranslator(&qtTranslator);
56 QTranslator scideTranslator;
57 scideTranslator.load("scide_" + QLocale::system().name());
58 app.installTranslator(&scideTranslator);
60 Main * main = Main::instance();
62 MainWindow *win = new MainWindow(main);
64 // NOTE: load session after GUI is created, so that GUI can respond
65 Settings::Manager *settings = main->settings();
66 SessionManager *sessions = main->sessionManager();
68 QString startSessionName = settings->value("IDE/startWithSession").toString();
69 if (startSessionName == "last") {
70 QString lastSession = sessions->lastSession();
71 if (!lastSession.isEmpty()) {
72 sessions->openSession(lastSession);
75 else if (!startSessionName.isEmpty()) {
76 sessions->openSession(startSessionName);
79 if (!sessions->currentSession()) {
80 win->restoreWindowState();
81 sessions->newSession();
84 win->show();
86 foreach (QString argument, arguments) {
87 main->documentManager()->open(argument);
90 bool startInterpreter = settings->value("IDE/interpreter/autoStart").toBool();
91 if (startInterpreter)
92 main->scProcess()->startLanguage();
94 return app.exec();
98 bool SingleInstanceGuard::tryConnect(QStringList const & arguments)
100 const int maxNumberOfInstances = 128;
101 if (!arguments.empty()) {
102 for (int socketID = 0; socketID != maxNumberOfInstances; ++socketID) {
103 QString serverName = QString("SuperColliderIDE_Singleton_%1").arg(socketID);
104 QSharedPointer<QLocalSocket> socket (new QLocalSocket(this));
105 socket->connectToServer(serverName);
107 QStringList canonicalArguments;
108 foreach (QString path, arguments) {
109 QFileInfo info(path);
110 canonicalArguments << info.canonicalFilePath();
113 if (socket->waitForConnected(200)) {
114 QDataStream stream(socket.data());
115 stream.setVersion(QDataStream::Qt_4_6);
117 stream << QString("open");
118 stream << canonicalArguments;
119 socket->flush();
120 return true;
125 mIpcServer = new QLocalServer(this);
126 for (int socketID = 0; socketID != maxNumberOfInstances; ++socketID) {
127 QString serverName = QString("SuperColliderIDE_Singleton_%1").arg(socketID);
129 bool listening = mIpcServer->listen(serverName);
130 if (listening) {
131 connect(mIpcServer, SIGNAL(newConnection()), this, SLOT(onNewIpcConnection()));
132 return false;
135 return false;
138 void SingleInstanceGuard::onIpcData()
140 QByteArray ipcData = mIpcSocket->readAll();
142 QBuffer receivedData ( &ipcData );
143 receivedData.open ( QIODevice::ReadOnly );
145 QDataStream in ( &receivedData );
146 in.setVersion ( QDataStream::Qt_4_6 );
147 QString id;
148 in >> id;
149 if ( in.status() != QDataStream::Ok )
150 return;
152 QStringList message;
153 in >> message;
154 if ( in.status() != QDataStream::Ok )
155 return;
157 if (id == QString("open")) {
158 foreach (QString path, message)
159 Main::documentManager()->open(path);
164 static QString getSettingsFile()
166 char config_dir[PATH_MAX];
167 sc_GetUserConfigDirectory(config_dir, PATH_MAX);
168 return QString(config_dir) + SC_PATH_DELIMITER + "sc_ide_conf.yaml";
171 // NOTE: mSettings must be the first to initialize,
172 // because other members use it!
174 Main::Main(void) :
175 mSettings( new Settings::Manager( getSettingsFile(), this ) ),
176 mSCResponder( new ScResponder(this) ),
177 mSCProcess( new SCProcess(this) ),
178 mSCServer( new ScServer(this) ),
179 mDocManager( new DocumentManager(this) ),
180 mSessionManager( new SessionManager(mDocManager, this) )
182 new SyntaxHighlighterGlobals(this);
184 connect(mSCProcess, SIGNAL(response(QString,QString)), mSCResponder, SLOT(onResponse(QString,QString)));
185 connect(mSCResponder, SIGNAL(serverRunningChanged(bool,QString,int)), mSCServer, SLOT(onServerRunningChanged(bool,QString,int)));
187 qApp->installEventFilter(this);
190 void Main::quit() {
191 mSessionManager->saveSession();
192 storeSettings();
193 QApplication::quit();
196 bool Main::eventFilter(QObject *object, QEvent *event)
198 switch (event->type()) {
199 case QEvent::FileOpen:
201 // open the file dragged onto the application icon on Mac
202 QFileOpenEvent *openEvent = static_cast<QFileOpenEvent*>(event);
203 mDocManager->open(openEvent->file());
204 return true;
207 case QEvent::MouseMove:
208 QApplication::restoreOverrideCursor();
209 break;
211 default:
212 break;
215 return QObject::eventFilter(object, event);
218 void Main::openDefinition(const QString &string, QWidget * parent)
220 QString definitionString = string.trimmed();
221 if (definitionString.isEmpty())
222 return;
224 LookupDialog dialog(parent);
225 dialog.query(definitionString);
226 dialog.exec();