/[svn]/qsampler/trunk/src/qsampler.cpp
ViewVC logotype

Annotation of /qsampler/trunk/src/qsampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4098 - (hide annotations) (download)
Sun Mar 3 10:13:39 2024 UTC (6 weeks, 4 days ago) by capela
File size: 17979 byte(s)
- Custom color themes are now file based (*.conf);
  legacy preserved ntl. (EXPERIMENTAL)
1 capela 2074 // qsampler.cpp
2     //
3     /****************************************************************************
4 capela 4070 Copyright (C) 2004-2024, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 3681 Copyright (C) 2007,2008,2015,2019 Christian Schoenebeck
6 capela 2074
7     This program is free software; you can redistribute it and/or
8     modify it under the terms of the GNU General Public License
9     as published by the Free Software Foundation; either version 2
10     of the License, or (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21     *****************************************************************************/
22    
23 capela 3493 #include "qsampler.h"
24    
25 capela 2074 #include "qsamplerOptions.h"
26     #include "qsamplerMainForm.h"
27    
28 capela 3648 #include "qsamplerPaletteForm.h"
29    
30     #include <QDir>
31    
32     #include <QStyleFactory>
33    
34 capela 2074 #include <QLibraryInfo>
35     #include <QTranslator>
36     #include <QLocale>
37 capela 2459
38 capela 4024 #if QT_VERSION >= QT_VERSION_CHECK(5, 2, 0)
39     #include <lscp/client.h>
40     #ifdef CONFIG_LIBGIG
41     #if defined(Q_CC_GNU) || defined(Q_CC_MINGW)
42     #pragma GCC diagnostic push
43     #pragma GCC diagnostic ignored "-Wunused-parameter"
44     #endif
45     #include <gig.h>
46     #if defined(Q_CC_GNU) || defined(Q_CC_MINGW)
47     #pragma GCC diagnostic pop
48     #endif
49     #endif
50     #endif
51    
52 capela 2074 #if defined(__APPLE__) // Toshi Nagata 20080105
53     #include <QDir>
54     #endif
55    
56 capela 2998 #ifndef CONFIG_PREFIX
57     #define CONFIG_PREFIX "/usr/local"
58     #endif
59    
60 capela 4024 #ifndef CONFIG_BINDIR
61     #define CONFIG_BINDIR CONFIG_PREFIX "/bin"
62     #endif
63    
64 capela 2998 #ifndef CONFIG_DATADIR
65     #define CONFIG_DATADIR CONFIG_PREFIX "/share"
66     #endif
67    
68 capela 3648 #ifndef CONFIG_LIBDIR
69     #if defined(__x86_64__)
70     #define CONFIG_LIBDIR CONFIG_PREFIX "/lib64"
71     #else
72     #define CONFIG_LIBDIR CONFIG_PREFIX "/lib"
73     #endif
74     #endif
75    
76     #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
77     #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt4/plugins"
78 capela 3996 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
79     #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt5/plugins"
80 capela 3648 #else
81 capela 3996 #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt6/plugins"
82 capela 3648 #endif
83    
84 capela 3358 #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
85 persson 2210 #define RELATIVE_LOCALE_DIR "/share/locale"
86     #elif defined(__APPLE__)
87     #define RELATIVE_LOCALE_DIR "/../Resources"
88     #endif
89 capela 2074
90 persson 2210
91 capela 2074 //-------------------------------------------------------------------------
92     // Singleton application instance stuff (Qt/X11 only atm.)
93     //
94    
95 capela 2839 #ifdef CONFIG_XUNIQUE
96    
97 capela 3520 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
98 capela 3496 #ifdef CONFIG_X11
99    
100 capela 4067 #define QSAMPLER_XUNIQUE "qsamplerApplication"
101    
102 capela 3493 #include <unistd.h> /* for gethostname() */
103 capela 2074
104     #include <X11/Xatom.h>
105     #include <X11/Xlib.h>
106    
107 capela 3496 #endif // CONFIG_X11
108     #else
109     #include <QSharedMemory>
110 capela 4062 #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
111     #include <QNativeIpcKey>
112     #endif
113 capela 3496 #include <QLocalServer>
114     #include <QLocalSocket>
115     #include <QHostInfo>
116 capela 2074 #endif
117    
118 capela 2839 #endif // CONFIG_XUNIQUE
119    
120    
121 capela 3493 // Constructor.
122     qsamplerApplication::qsamplerApplication ( int& argc, char **argv )
123     : QApplication(argc, argv),
124 capela 3555 m_pQtTranslator(nullptr), m_pMyTranslator(nullptr), m_pWidget(nullptr)
125 capela 4067 #ifdef CONFIG_XUNIQUE
126     #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
127     #ifdef CONFIG_X11
128     , m_pDisplay(nullptr)
129     , m_aUnique(0)
130     , m_wOwner(0)
131     #endif // CONFIG_X11
132     #else
133     , m_pMemory(nullptr)
134     , m_pServer(nullptr)
135     #endif
136     #endif // CONFIG_XUNIQUE
137 capela 2074 {
138 capela 3558 #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
139     QApplication::setApplicationName(QSAMPLER_TITLE);
140 capela 3560 QApplication::setApplicationDisplayName(QSAMPLER_TITLE);
141     // QSAMPLER_TITLE " - " + QObject::tr(QSAMPLER_SUBTITLE));
142 capela 4030 #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
143     QApplication::setDesktopFileName(
144 capela 4070 QString("org.rncbc.%1").arg(PROJECT_NAME));
145 capela 4030 #endif
146 capela 4070 QString sVersion(PROJECT_VERSION);
147 capela 4024 sVersion += '\n';
148     sVersion += QString("Qt: %1").arg(qVersion());
149     #if defined(QT_STATIC)
150     sVersion += "-static";
151 capela 3558 #endif
152 capela 4024 sVersion += '\n';
153     #ifdef CONFIG_LIBGIG
154     sVersion += QString("%1: %2")
155     .arg(gig::libraryName().c_str())
156     .arg(gig::libraryVersion().c_str());
157     sVersion += '\n';
158     #endif
159     sVersion += QString("%1: %2")
160     .arg(::lscp_client_package())
161     .arg(::lscp_client_version());
162     QApplication::setApplicationVersion(sVersion);
163     #endif
164 capela 3493 // Load translation support.
165     QLocale loc;
166     if (loc.language() != QLocale::C) {
167     // Try own Qt translation...
168     m_pQtTranslator = new QTranslator(this);
169     QString sLocName = "qt_" + loc.name();
170 capela 3823 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
171     QString sLocPath = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
172     #else
173 capela 3493 QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
174 capela 3823 #endif
175 capela 3493 if (m_pQtTranslator->load(sLocName, sLocPath)) {
176     QApplication::installTranslator(m_pQtTranslator);
177     } else {
178 capela 4024 sLocPath = QApplication::applicationDirPath();
179 capela 3493 #ifdef RELATIVE_LOCALE_DIR
180 capela 4024 sLocPath.append(RELATIVE_LOCALE_DIR);
181     #else
182     sLocPath.remove(CONFIG_BINDIR);
183     sLocPath.append(CONFIG_DATADIR "/qsampler/translations");
184     #endif
185 capela 2074 if (m_pQtTranslator->load(sLocName, sLocPath)) {
186     QApplication::installTranslator(m_pQtTranslator);
187     } else {
188 capela 4024 delete m_pQtTranslator;
189     m_pQtTranslator = nullptr;
190     #ifdef CONFIG_DEBUG
191     qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
192     loc.name().toUtf8().constData(),
193     sLocPath.toUtf8().constData(),
194     sLocName.toUtf8().constData());
195     #endif
196 capela 3493 }
197     }
198     // Try own application translation...
199     m_pMyTranslator = new QTranslator(this);
200     sLocName = "qsampler_" + loc.name();
201     if (m_pMyTranslator->load(sLocName, sLocPath)) {
202     QApplication::installTranslator(m_pMyTranslator);
203     } else {
204     #ifdef RELATIVE_LOCALE_DIR
205     sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
206     #else
207     sLocPath = CONFIG_DATADIR "/qsampler/translations";
208     #endif
209     if (m_pMyTranslator->load(sLocName, sLocPath)) {
210     QApplication::installTranslator(m_pMyTranslator);
211     } else {
212     delete m_pMyTranslator;
213 capela 3835 m_pMyTranslator = nullptr;
214 capela 2631 #ifdef CONFIG_DEBUG
215 capela 2074 qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
216     loc.name().toUtf8().constData(),
217     sLocPath.toUtf8().constData(),
218     sLocName.toUtf8().constData());
219 capela 2631 #endif
220 capela 2074 }
221     }
222     }
223 capela 3493 }
224 capela 2074
225    
226 capela 3493 // Destructor.
227     qsamplerApplication::~qsamplerApplication (void)
228     {
229     #ifdef CONFIG_XUNIQUE
230 capela 3520 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
231 capela 4067 clearServer();
232 capela 3493 #endif
233     #endif // CONFIG_XUNIQUE
234     if (m_pMyTranslator) delete m_pMyTranslator;
235     if (m_pQtTranslator) delete m_pQtTranslator;
236     }
237    
238    
239     // Main application widget accessors.
240     void qsamplerApplication::setMainWidget ( QWidget *pWidget )
241     {
242     m_pWidget = pWidget;
243 capela 3496 #ifdef CONFIG_XUNIQUE
244 capela 3520 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
245 capela 3493 #ifdef CONFIG_X11
246     m_wOwner = m_pWidget->winId();
247     if (m_pDisplay && m_wOwner) {
248     XGrabServer(m_pDisplay);
249     XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);
250     XUngrabServer(m_pDisplay);
251 capela 2074 }
252 capela 3496 #endif // CONFIG_X11
253     #endif
254 capela 3493 #endif // CONFIG_XUNIQUE
255     }
256 capela 2074
257    
258 capela 3493 // Check if another instance is running,
259     // and raise its proper main widget...
260     bool qsamplerApplication::setup (void)
261     {
262 capela 3496 #ifdef CONFIG_XUNIQUE
263 capela 3520 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
264 capela 3493 #ifdef CONFIG_X11
265     m_pDisplay = QX11Info::display();
266     if (m_pDisplay) {
267     QString sUnique = QSAMPLER_XUNIQUE;
268 capela 4040 QString sUserName = QString::fromUtf8(::getenv("USER"));
269     if (sUserName.isEmpty())
270     sUserName = QString::fromUtf8(::getenv("USERNAME"));
271     if (!sUserName.isEmpty()) {
272     sUnique += ':';
273     sUnique += sUserName;
274     }
275 capela 3493 char szHostName[255];
276     if (::gethostname(szHostName, sizeof(szHostName)) == 0) {
277     sUnique += '@';
278 capela 4040 sUnique += QString::fromUtf8(szHostName);
279 capela 3493 }
280     m_aUnique = XInternAtom(m_pDisplay, sUnique.toUtf8().constData(), false);
281     XGrabServer(m_pDisplay);
282     m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique);
283     XUngrabServer(m_pDisplay);
284     if (m_wOwner != None) {
285 capela 2074 // First, notify any freedesktop.org WM
286     // that we're about to show the main widget...
287     Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);
288     int iScreen = XScreenNumberOfScreen(pScreen);
289     XEvent ev;
290     memset(&ev, 0, sizeof(ev));
291     ev.xclient.type = ClientMessage;
292     ev.xclient.display = m_pDisplay;
293     ev.xclient.window = m_wOwner;
294     ev.xclient.message_type = XInternAtom(m_pDisplay, "_NET_ACTIVE_WINDOW", false);
295     ev.xclient.format = 32;
296     ev.xclient.data.l[0] = 0; // Source indication.
297     ev.xclient.data.l[1] = 0; // Timestamp.
298     ev.xclient.data.l[2] = 0; // Requestor's currently active window (none)
299     ev.xclient.data.l[3] = 0;
300     ev.xclient.data.l[4] = 0;
301     XSelectInput(m_pDisplay, m_wOwner, StructureNotifyMask);
302     XSendEvent(m_pDisplay, RootWindow(m_pDisplay, iScreen), false,
303     (SubstructureNotifyMask | SubstructureRedirectMask), &ev);
304     XSync(m_pDisplay, false);
305     XRaiseWindow(m_pDisplay, m_wOwner);
306     // And then, let it get caught on destination
307 capela 2839 // by QApplication::native/x11EventFilter...
308     const QByteArray value = QSAMPLER_XUNIQUE;
309 capela 2074 XChangeProperty(
310     m_pDisplay,
311     m_wOwner,
312     m_aUnique,
313     m_aUnique, 8,
314     PropModeReplace,
315     (unsigned char *) value.data(),
316     value.length());
317     // Done.
318     return true;
319     }
320     }
321 capela 2839 #endif // CONFIG_X11
322 capela 3493 return false;
323 capela 3496 #else
324 capela 4067 return setupServer();
325     #endif
326     #else
327     return false;
328     #endif // !CONFIG_XUNIQUE
329     }
330    
331    
332     #ifdef CONFIG_XUNIQUE
333     #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
334     #ifdef CONFIG_X11
335    
336     void qsamplerApplication::x11PropertyNotify ( Window w )
337     {
338     if (m_pDisplay && m_pWidget && m_wOwner == w) {
339     // Always check whether our property-flag is still around...
340     Atom aType;
341     int iFormat = 0;
342     unsigned long iItems = 0;
343     unsigned long iAfter = 0;
344     unsigned char *pData = 0;
345     if (XGetWindowProperty(
346     m_pDisplay,
347     m_wOwner,
348     m_aUnique,
349     0, 1024,
350     false,
351     m_aUnique,
352     &aType,
353     &iFormat,
354     &iItems,
355     &iAfter,
356     &pData) == Success
357     && aType == m_aUnique && iItems > 0 && iAfter == 0) {
358     // Avoid repeating it-self...
359     XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);
360     // Just make it always shows up fine...
361     m_pWidget->showNormal();
362     m_pWidget->raise();
363     m_pWidget->activateWindow();
364     // FIXME: Do our best speciality, although it should be
365     // done iif configuration says so, we'll do it anyway!
366     qsamplerMainForm *pMainForm = qsamplerMainForm::getInstance();
367     if (pMainForm)
368     pMainForm->startAllEngines();
369     }
370     // Free any left-overs...
371     if (iItems > 0 && pData)
372     XFree(pData);
373     }
374     }
375    
376     bool qsamplerApplication::x11EventFilter ( XEvent *pEv )
377     {
378     if (pEv->type == PropertyNotify
379     && pEv->xproperty.state == PropertyNewValue)
380     x11PropertyNotify(pEv->xproperty.window);
381     return QApplication::x11EventFilter(pEv);
382     }
383    
384     #endif // CONFIG_X11
385     #else
386    
387     // Local server/shmem setup.
388     bool qsamplerApplication::setupServer (void)
389     {
390     clearServer();
391    
392 capela 3496 m_sUnique = QCoreApplication::applicationName();
393 capela 4040 QString sUserName = QString::fromUtf8(::getenv("USER"));
394     if (sUserName.isEmpty())
395     sUserName = QString::fromUtf8(::getenv("USERNAME"));
396     if (!sUserName.isEmpty()) {
397     m_sUnique += ':';
398     m_sUnique += sUserName;
399     }
400 capela 3496 m_sUnique += '@';
401     m_sUnique += QHostInfo::localHostName();
402 capela 4062 #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
403     const QNativeIpcKey nativeKey
404 capela 4067 = QSharedMemory::legacyNativeKey(m_sUnique);
405     #if defined(Q_OS_UNIX)
406 capela 4062 m_pMemory = new QSharedMemory(nativeKey);
407 capela 4067 m_pMemory->attach();
408     delete m_pMemory;
409     #endif
410     m_pMemory = new QSharedMemory(nativeKey);
411 capela 4062 #else
412     #if defined(Q_OS_UNIX)
413 capela 3496 m_pMemory = new QSharedMemory(m_sUnique);
414     m_pMemory->attach();
415     delete m_pMemory;
416     #endif
417     m_pMemory = new QSharedMemory(m_sUnique);
418 capela 4062 #endif
419 capela 4067
420 capela 3496 bool bServer = false;
421     const qint64 pid = QCoreApplication::applicationPid();
422     struct Data { qint64 pid; };
423     if (m_pMemory->create(sizeof(Data))) {
424     m_pMemory->lock();
425     Data *pData = static_cast<Data *> (m_pMemory->data());
426     if (pData) {
427     pData->pid = pid;
428     bServer = true;
429     }
430     m_pMemory->unlock();
431     }
432     else
433     if (m_pMemory->attach()) {
434     m_pMemory->lock(); // maybe not necessary?
435     Data *pData = static_cast<Data *> (m_pMemory->data());
436     if (pData)
437     bServer = (pData->pid == pid);
438     m_pMemory->unlock();
439     }
440 capela 4067
441 capela 3496 if (bServer) {
442     QLocalServer::removeServer(m_sUnique);
443     m_pServer = new QLocalServer();
444     m_pServer->setSocketOptions(QLocalServer::UserAccessOption);
445     m_pServer->listen(m_sUnique);
446     QObject::connect(m_pServer,
447 capela 4067 SIGNAL(newConnection()),
448     SLOT(newConnectionSlot()));
449 capela 3496 } else {
450     QLocalSocket socket;
451     socket.connectToServer(m_sUnique);
452     if (socket.state() == QLocalSocket::ConnectingState)
453     socket.waitForConnected(200);
454     if (socket.state() == QLocalSocket::ConnectedState) {
455     socket.write(QCoreApplication::arguments().join(' ').toUtf8());
456     socket.flush();
457     socket.waitForBytesWritten(200);
458     }
459     }
460 capela 4067
461 capela 3496 return !bServer;
462 capela 3493 }
463 capela 2074
464    
465 capela 4067 // Local server/shmem cleanup.
466     void qsamplerApplication::clearServer (void)
467 capela 3493 {
468 capela 4067 if (m_pServer) {
469     m_pServer->close();
470     delete m_pServer;
471     m_pServer = nullptr;
472 capela 3493 }
473 capela 2074
474 capela 4067 if (m_pMemory) {
475     delete m_pMemory;
476     m_pMemory = nullptr;
477     }
478 capela 2074
479 capela 4067 m_sUnique.clear();
480 capela 2839 }
481 capela 3493
482 capela 2839
483 capela 3496 // Local server conection slot.
484     void qsamplerApplication::newConnectionSlot (void)
485     {
486     QLocalSocket *pSocket = m_pServer->nextPendingConnection();
487     QObject::connect(pSocket,
488     SIGNAL(readyRead()),
489     SLOT(readyReadSlot()));
490     }
491 capela 2839
492 capela 3496 // Local server data-ready slot.
493     void qsamplerApplication::readyReadSlot (void)
494     {
495     QLocalSocket *pSocket = qobject_cast<QLocalSocket *> (sender());
496     if (pSocket) {
497     const qint64 nread = pSocket->bytesAvailable();
498     if (nread > 0) {
499 capela 3556 const QByteArray data = pSocket->read(nread);
500 capela 3496 // Just make it always shows up fine...
501 capela 4062 if (m_pWidget) {
502     m_pWidget->showNormal();
503     m_pWidget->raise();
504     m_pWidget->activateWindow();
505     }
506 capela 4067 // Reset the server...
507     setupServer();
508 capela 3496 }
509     }
510     }
511    
512     #endif
513     #endif // CONFIG_XUNIQUE
514    
515    
516 capela 2074 //-------------------------------------------------------------------------
517     // stacktrace - Signal crash handler.
518     //
519    
520     #ifdef CONFIG_STACKTRACE
521     #if defined(__GNUC__) && defined(Q_OS_LINUX)
522    
523     #include <stdio.h>
524     #include <errno.h>
525     #include <signal.h>
526 capela 2341 #include <unistd.h>
527 capela 2074 #include <sys/wait.h>
528    
529     void stacktrace ( int signo )
530     {
531     pid_t pid;
532     int rc;
533     int status = 0;
534     char cmd[80];
535    
536     // Reinstall default handler; prevent race conditions...
537 capela 3508 ::signal(signo, SIG_DFL);
538 capela 2074
539     static const char *shell = "/bin/sh";
540 capela 2181 static const char *format = "gdb -q --batch --pid=%d"
541     " --eval-command='thread apply all bt'";
542 capela 2074
543     snprintf(cmd, sizeof(cmd), format, (int) getpid());
544    
545     pid = fork();
546    
547     // Fork failure!
548     if (pid < 0)
549     return;
550    
551     // Fork child...
552     if (pid == 0) {
553 capela 3555 execl(shell, shell, "-c", cmd, nullptr);
554 capela 2074 _exit(1);
555     return;
556     }
557    
558     // Parent here: wait for child to terminate...
559     do { rc = waitpid(pid, &status, 0); }
560     while ((rc < 0) && (errno == EINTR));
561    
562     // Dispatch any logging, if any...
563     QApplication::processEvents(QEventLoop::AllEvents, 3000);
564    
565     // Make sure everyone terminates...
566     kill(pid, SIGTERM);
567     _exit(1);
568     }
569    
570     #endif
571     #endif
572    
573    
574     //-------------------------------------------------------------------------
575     // main - The main program trunk.
576     //
577    
578     int main ( int argc, char **argv )
579     {
580     Q_INIT_RESOURCE(qsampler);
581     #ifdef CONFIG_STACKTRACE
582     #if defined(__GNUC__) && defined(Q_OS_LINUX)
583 capela 3508 ::signal(SIGILL, stacktrace);
584     ::signal(SIGFPE, stacktrace);
585     ::signal(SIGSEGV, stacktrace);
586     ::signal(SIGABRT, stacktrace);
587     ::signal(SIGBUS, stacktrace);
588 capela 2074 #endif
589     #endif
590 capela 4029 #if defined(Q_OS_LINUX) && !defined(CONFIG_WAYLAND)
591 capela 3910 ::setenv("QT_QPA_PLATFORM", "xcb", 0);
592 capela 3911 #endif
593 capela 3520 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
594 capela 3823 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
595 capela 3558 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
596 capela 3465 #endif
597 capela 3823 #endif
598 capela 3558 qsamplerApplication app(argc, argv);
599    
600 capela 2074 #if defined(__APPLE__) // Toshi Nagata 20080105
601     {
602     // Set the plugin path to @exetutable_path/../plugins
603     QDir dir(QApplication::applicationDirPath());
604     dir.cdUp(); // "Contents" directory
605     QApplication::setLibraryPaths(QStringList(dir.absolutePath() + "/plugins"));
606    
607     // Set the PATH environment variable to include @executable_path/../../..
608     dir.cdUp();
609     dir.cdUp();
610     QString path(getenv("PATH"));
611     path = dir.absolutePath() + ":" + path;
612     setenv("PATH", path.toUtf8().constData(), 1);
613     }
614     #endif
615    
616     // Construct default settings; override with command line arguments.
617     QSampler::Options options;
618     if (!options.parse_args(app.arguments())) {
619     app.quit();
620     return 1;
621     }
622    
623     // Have another instance running?
624     if (app.setup()) {
625     app.quit();
626     return 2;
627     }
628    
629 capela 3648 // Special custom styles...
630     if (QDir(CONFIG_PLUGINSDIR).exists())
631     app.addLibraryPath(CONFIG_PLUGINSDIR);
632     if (!options.sCustomStyleTheme.isEmpty())
633     app.setStyle(QStyleFactory::create(options.sCustomStyleTheme));
634    
635     // Custom color theme (eg. "KXStudio")...
636 capela 4098 const QChar sep = QDir::separator();
637     QString sPalettePath = QApplication::applicationDirPath();
638     sPalettePath.remove(CONFIG_BINDIR);
639     sPalettePath.append(CONFIG_DATADIR);
640     sPalettePath.append(sep);
641     sPalettePath.append(PROJECT_NAME);
642     sPalettePath.append(sep);
643     sPalettePath.append("palette");
644     if (QDir(sPalettePath).exists()) {
645     QStringList names;
646     names.append("KXStudio");
647     names.append("Wonton Soup");
648     QStringListIterator name_iter(names);
649     while (name_iter.hasNext()) {
650     const QString& name = name_iter.next();
651     const QFileInfo fi(sPalettePath, name + ".conf");
652     if (fi.isReadable()) {
653     QSampler::PaletteForm::addNamedPaletteConf(
654     &options.settings(), name, fi.absoluteFilePath());
655     }
656     }
657     }
658    
659 capela 2074 QPalette pal(app.palette());
660 capela 3648 if (QSampler::PaletteForm::namedPalette(
661     &options.settings(), options.sCustomColorTheme, pal))
662 capela 2074 app.setPalette(pal);
663    
664     // Set default base font...
665     if (options.iBaseFontSize > 0)
666 capela 2677 app.setFont(QFont(app.font().family(), options.iBaseFontSize));
667 capela 2074
668     // Construct, setup and show the main form.
669     QSampler::MainForm w;
670     w.setup(&options);
671     w.show();
672    
673     // Settle this one as application main widget...
674     app.setMainWidget(&w);
675    
676     // Register the quit signal/slot.
677     // app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
678    
679     return app.exec();
680     }
681    
682    
683     // end of qsampler.cpp
684 capela 3065

  ViewVC Help
Powered by ViewVC