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

Contents of /qsampler/trunk/src/qsampler.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4098 - (show 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 // qsampler.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2024, rncbc aka Rui Nuno Capela. All rights reserved.
5 Copyright (C) 2007,2008,2015,2019 Christian Schoenebeck
6
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 #include "qsampler.h"
24
25 #include "qsamplerOptions.h"
26 #include "qsamplerMainForm.h"
27
28 #include "qsamplerPaletteForm.h"
29
30 #include <QDir>
31
32 #include <QStyleFactory>
33
34 #include <QLibraryInfo>
35 #include <QTranslator>
36 #include <QLocale>
37
38 #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 #if defined(__APPLE__) // Toshi Nagata 20080105
53 #include <QDir>
54 #endif
55
56 #ifndef CONFIG_PREFIX
57 #define CONFIG_PREFIX "/usr/local"
58 #endif
59
60 #ifndef CONFIG_BINDIR
61 #define CONFIG_BINDIR CONFIG_PREFIX "/bin"
62 #endif
63
64 #ifndef CONFIG_DATADIR
65 #define CONFIG_DATADIR CONFIG_PREFIX "/share"
66 #endif
67
68 #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 #elif QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
79 #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt5/plugins"
80 #else
81 #define CONFIG_PLUGINSDIR CONFIG_LIBDIR "/qt6/plugins"
82 #endif
83
84 #if defined(__WIN32__) || defined(_WIN32) || defined(WIN32)
85 #define RELATIVE_LOCALE_DIR "/share/locale"
86 #elif defined(__APPLE__)
87 #define RELATIVE_LOCALE_DIR "/../Resources"
88 #endif
89
90
91 //-------------------------------------------------------------------------
92 // Singleton application instance stuff (Qt/X11 only atm.)
93 //
94
95 #ifdef CONFIG_XUNIQUE
96
97 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
98 #ifdef CONFIG_X11
99
100 #define QSAMPLER_XUNIQUE "qsamplerApplication"
101
102 #include <unistd.h> /* for gethostname() */
103
104 #include <X11/Xatom.h>
105 #include <X11/Xlib.h>
106
107 #endif // CONFIG_X11
108 #else
109 #include <QSharedMemory>
110 #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
111 #include <QNativeIpcKey>
112 #endif
113 #include <QLocalServer>
114 #include <QLocalSocket>
115 #include <QHostInfo>
116 #endif
117
118 #endif // CONFIG_XUNIQUE
119
120
121 // Constructor.
122 qsamplerApplication::qsamplerApplication ( int& argc, char **argv )
123 : QApplication(argc, argv),
124 m_pQtTranslator(nullptr), m_pMyTranslator(nullptr), m_pWidget(nullptr)
125 #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 {
138 #if QT_VERSION >= QT_VERSION_CHECK(5, 1, 0)
139 QApplication::setApplicationName(QSAMPLER_TITLE);
140 QApplication::setApplicationDisplayName(QSAMPLER_TITLE);
141 // QSAMPLER_TITLE " - " + QObject::tr(QSAMPLER_SUBTITLE));
142 #if QT_VERSION >= QT_VERSION_CHECK(5, 7, 0)
143 QApplication::setDesktopFileName(
144 QString("org.rncbc.%1").arg(PROJECT_NAME));
145 #endif
146 QString sVersion(PROJECT_VERSION);
147 sVersion += '\n';
148 sVersion += QString("Qt: %1").arg(qVersion());
149 #if defined(QT_STATIC)
150 sVersion += "-static";
151 #endif
152 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 // 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 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
171 QString sLocPath = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
172 #else
173 QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
174 #endif
175 if (m_pQtTranslator->load(sLocName, sLocPath)) {
176 QApplication::installTranslator(m_pQtTranslator);
177 } else {
178 sLocPath = QApplication::applicationDirPath();
179 #ifdef RELATIVE_LOCALE_DIR
180 sLocPath.append(RELATIVE_LOCALE_DIR);
181 #else
182 sLocPath.remove(CONFIG_BINDIR);
183 sLocPath.append(CONFIG_DATADIR "/qsampler/translations");
184 #endif
185 if (m_pQtTranslator->load(sLocName, sLocPath)) {
186 QApplication::installTranslator(m_pQtTranslator);
187 } else {
188 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 }
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 m_pMyTranslator = nullptr;
214 #ifdef CONFIG_DEBUG
215 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 #endif
220 }
221 }
222 }
223 }
224
225
226 // Destructor.
227 qsamplerApplication::~qsamplerApplication (void)
228 {
229 #ifdef CONFIG_XUNIQUE
230 #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
231 clearServer();
232 #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 #ifdef CONFIG_XUNIQUE
244 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
245 #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 }
252 #endif // CONFIG_X11
253 #endif
254 #endif // CONFIG_XUNIQUE
255 }
256
257
258 // Check if another instance is running,
259 // and raise its proper main widget...
260 bool qsamplerApplication::setup (void)
261 {
262 #ifdef CONFIG_XUNIQUE
263 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
264 #ifdef CONFIG_X11
265 m_pDisplay = QX11Info::display();
266 if (m_pDisplay) {
267 QString sUnique = QSAMPLER_XUNIQUE;
268 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 char szHostName[255];
276 if (::gethostname(szHostName, sizeof(szHostName)) == 0) {
277 sUnique += '@';
278 sUnique += QString::fromUtf8(szHostName);
279 }
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 // 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 // by QApplication::native/x11EventFilter...
308 const QByteArray value = QSAMPLER_XUNIQUE;
309 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 #endif // CONFIG_X11
322 return false;
323 #else
324 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 m_sUnique = QCoreApplication::applicationName();
393 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 m_sUnique += '@';
401 m_sUnique += QHostInfo::localHostName();
402 #if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
403 const QNativeIpcKey nativeKey
404 = QSharedMemory::legacyNativeKey(m_sUnique);
405 #if defined(Q_OS_UNIX)
406 m_pMemory = new QSharedMemory(nativeKey);
407 m_pMemory->attach();
408 delete m_pMemory;
409 #endif
410 m_pMemory = new QSharedMemory(nativeKey);
411 #else
412 #if defined(Q_OS_UNIX)
413 m_pMemory = new QSharedMemory(m_sUnique);
414 m_pMemory->attach();
415 delete m_pMemory;
416 #endif
417 m_pMemory = new QSharedMemory(m_sUnique);
418 #endif
419
420 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
441 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 SIGNAL(newConnection()),
448 SLOT(newConnectionSlot()));
449 } 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
461 return !bServer;
462 }
463
464
465 // Local server/shmem cleanup.
466 void qsamplerApplication::clearServer (void)
467 {
468 if (m_pServer) {
469 m_pServer->close();
470 delete m_pServer;
471 m_pServer = nullptr;
472 }
473
474 if (m_pMemory) {
475 delete m_pMemory;
476 m_pMemory = nullptr;
477 }
478
479 m_sUnique.clear();
480 }
481
482
483 // 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
492 // 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 const QByteArray data = pSocket->read(nread);
500 // Just make it always shows up fine...
501 if (m_pWidget) {
502 m_pWidget->showNormal();
503 m_pWidget->raise();
504 m_pWidget->activateWindow();
505 }
506 // Reset the server...
507 setupServer();
508 }
509 }
510 }
511
512 #endif
513 #endif // CONFIG_XUNIQUE
514
515
516 //-------------------------------------------------------------------------
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 #include <unistd.h>
527 #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 ::signal(signo, SIG_DFL);
538
539 static const char *shell = "/bin/sh";
540 static const char *format = "gdb -q --batch --pid=%d"
541 " --eval-command='thread apply all bt'";
542
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 execl(shell, shell, "-c", cmd, nullptr);
554 _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 ::signal(SIGILL, stacktrace);
584 ::signal(SIGFPE, stacktrace);
585 ::signal(SIGSEGV, stacktrace);
586 ::signal(SIGABRT, stacktrace);
587 ::signal(SIGBUS, stacktrace);
588 #endif
589 #endif
590 #if defined(Q_OS_LINUX) && !defined(CONFIG_WAYLAND)
591 ::setenv("QT_QPA_PLATFORM", "xcb", 0);
592 #endif
593 #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
594 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
595 QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
596 #endif
597 #endif
598 qsamplerApplication app(argc, argv);
599
600 #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 // 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 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 QPalette pal(app.palette());
660 if (QSampler::PaletteForm::namedPalette(
661 &options.settings(), options.sCustomColorTheme, pal))
662 app.setPalette(pal);
663
664 // Set default base font...
665 if (options.iBaseFontSize > 0)
666 app.setFont(QFont(app.font().family(), options.iBaseFontSize));
667
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

  ViewVC Help
Powered by ViewVC