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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2677 - (hide annotations) (download)
Thu Oct 9 08:50:14 2014 UTC (9 years, 5 months ago) by capela
File size: 11167 byte(s)
- Initial base font size one-liner optimize.
1 capela 2074 // qsampler.cpp
2     //
3     /****************************************************************************
4 capela 2631 Copyright (C) 2004-2014, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 2074 Copyright (C) 2007, 2008 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 "qsamplerAbout.h"
24     #include "qsamplerOptions.h"
25     #include "qsamplerMainForm.h"
26    
27     #include <QApplication>
28     #include <QLibraryInfo>
29     #include <QTranslator>
30     #include <QLocale>
31 capela 2459
32 capela 2074 #if defined(__APPLE__) // Toshi Nagata 20080105
33     #include <QDir>
34     #endif
35    
36 capela 2282 #define CONFIG_QUOTE1(x) #x
37     #define CONFIG_QUOTED(x) CONFIG_QUOTE1(x)
38    
39     #if defined(DATADIR)
40     #define CONFIG_DATADIR CONFIG_QUOTED(DATADIR)
41     #else
42     #define CONFIG_DATADIR CONFIG_PREFIX "/share"
43     #endif
44    
45 persson 2210 #if WIN32
46     #define RELATIVE_LOCALE_DIR "/share/locale"
47     #elif defined(__APPLE__)
48     #define RELATIVE_LOCALE_DIR "/../Resources"
49     #endif
50 capela 2074
51 persson 2210
52 capela 2074 //-------------------------------------------------------------------------
53     // Singleton application instance stuff (Qt/X11 only atm.)
54     //
55    
56     #if defined(Q_WS_X11)
57    
58     #include <QX11Info>
59    
60     #include <X11/Xatom.h>
61     #include <X11/Xlib.h>
62    
63     #define QSAMPLER_XUNIQUE "qsamplerMainForm_xunique"
64    
65     #endif
66    
67     class qsamplerApplication : public QApplication
68     {
69     public:
70    
71     // Constructor.
72     qsamplerApplication(int& argc, char **argv) : QApplication(argc, argv),
73     m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0)
74     {
75     // Load translation support.
76     QLocale loc;
77     if (loc.language() != QLocale::C) {
78     // Try own Qt translation...
79     m_pQtTranslator = new QTranslator(this);
80     QString sLocName = "qt_" + loc.name();
81     QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
82     if (m_pQtTranslator->load(sLocName, sLocPath)) {
83     QApplication::installTranslator(m_pQtTranslator);
84     } else {
85 capela 2631 #ifdef RELATIVE_LOCALE_DIR
86 persson 2210 sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
87 persson 2144 if (m_pQtTranslator->load(sLocName, sLocPath)) {
88     QApplication::installTranslator(m_pQtTranslator);
89     } else {
90 capela 2631 #endif
91 capela 2074 delete m_pQtTranslator;
92     m_pQtTranslator = 0;
93 capela 2631 #ifdef CONFIG_DEBUG
94 capela 2074 qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
95     loc.name().toUtf8().constData(),
96     sLocPath.toUtf8().constData(),
97     sLocName.toUtf8().constData());
98 capela 2631 #endif
99     #ifdef RELATIVE_LOCALE_DIR
100 persson 2144 }
101 capela 2631 #endif
102 capela 2074 }
103     // Try own application translation...
104     m_pMyTranslator = new QTranslator(this);
105     sLocName = "qsampler_" + loc.name();
106     if (m_pMyTranslator->load(sLocName, sLocPath)) {
107     QApplication::installTranslator(m_pMyTranslator);
108     } else {
109 capela 2631 #ifdef RELATIVE_LOCALE_DIR
110 persson 2210 sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
111 capela 2631 #else
112     sLocPath = CONFIG_DATADIR "/qsampler/translations";
113     #endif
114 capela 2074 if (m_pMyTranslator->load(sLocName, sLocPath)) {
115     QApplication::installTranslator(m_pMyTranslator);
116     } else {
117     delete m_pMyTranslator;
118     m_pMyTranslator = 0;
119 capela 2631 #ifdef CONFIG_DEBUG
120 capela 2074 qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
121     loc.name().toUtf8().constData(),
122     sLocPath.toUtf8().constData(),
123     sLocName.toUtf8().constData());
124 capela 2631 #endif
125 capela 2074 }
126     }
127     }
128     #if defined(Q_WS_X11)
129     m_pDisplay = QX11Info::display();
130     m_aUnique = XInternAtom(m_pDisplay, QSAMPLER_XUNIQUE, false);
131     XGrabServer(m_pDisplay);
132     m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique);
133     XUngrabServer(m_pDisplay);
134     #endif
135     }
136    
137     // Destructor.
138     ~qsamplerApplication()
139     {
140     if (m_pMyTranslator) delete m_pMyTranslator;
141     if (m_pQtTranslator) delete m_pQtTranslator;
142     }
143    
144     // Main application widget accessors.
145     void setMainWidget(QWidget *pWidget)
146     {
147     m_pWidget = pWidget;
148     #if defined(Q_WS_X11)
149     XGrabServer(m_pDisplay);
150     m_wOwner = m_pWidget->winId();
151     XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);
152     XUngrabServer(m_pDisplay);
153     #endif
154     }
155    
156     QWidget *mainWidget() const { return m_pWidget; }
157    
158     // Check if another instance is running,
159     // and raise its proper main widget...
160     bool setup()
161     {
162     #if defined(Q_WS_X11)
163     if (m_wOwner != None) {
164     // First, notify any freedesktop.org WM
165     // that we're about to show the main widget...
166     Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);
167     int iScreen = XScreenNumberOfScreen(pScreen);
168     XEvent ev;
169     memset(&ev, 0, sizeof(ev));
170     ev.xclient.type = ClientMessage;
171     ev.xclient.display = m_pDisplay;
172     ev.xclient.window = m_wOwner;
173     ev.xclient.message_type = XInternAtom(m_pDisplay, "_NET_ACTIVE_WINDOW", false);
174     ev.xclient.format = 32;
175     ev.xclient.data.l[0] = 0; // Source indication.
176     ev.xclient.data.l[1] = 0; // Timestamp.
177     ev.xclient.data.l[2] = 0; // Requestor's currently active window (none)
178     ev.xclient.data.l[3] = 0;
179     ev.xclient.data.l[4] = 0;
180     XSelectInput(m_pDisplay, m_wOwner, StructureNotifyMask);
181     XSendEvent(m_pDisplay, RootWindow(m_pDisplay, iScreen), false,
182     (SubstructureNotifyMask | SubstructureRedirectMask), &ev);
183     XSync(m_pDisplay, false);
184     XRaiseWindow(m_pDisplay, m_wOwner);
185     // And then, let it get caught on destination
186     // by QApplication::x11EventFilter...
187     QByteArray value = QSAMPLER_XUNIQUE;
188     XChangeProperty(
189     m_pDisplay,
190     m_wOwner,
191     m_aUnique,
192     m_aUnique, 8,
193     PropModeReplace,
194     (unsigned char *) value.data(),
195     value.length());
196     // Done.
197     return true;
198     }
199     #endif
200     return false;
201     }
202    
203     #if defined(Q_WS_X11)
204     bool x11EventFilter(XEvent *pEv)
205     {
206     if (m_pWidget && m_wOwner != None
207     && pEv->type == PropertyNotify
208     && pEv->xproperty.window == m_wOwner
209     && pEv->xproperty.state == PropertyNewValue) {
210     // Always check whether our property-flag is still around...
211     Atom aType;
212     int iFormat = 0;
213     unsigned long iItems = 0;
214     unsigned long iAfter = 0;
215     unsigned char *pData = 0;
216     if (XGetWindowProperty(
217     m_pDisplay,
218     m_wOwner,
219     m_aUnique,
220     0, 1024,
221     false,
222     m_aUnique,
223     &aType,
224     &iFormat,
225     &iItems,
226     &iAfter,
227     &pData) == Success
228     && aType == m_aUnique && iItems > 0 && iAfter == 0) {
229     // Avoid repeating it-self...
230     XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);
231     // Just make it always shows up fine...
232     m_pWidget->show();
233     m_pWidget->raise();
234     m_pWidget->activateWindow();
235     }
236     // Free any left-overs...
237     if (iItems > 0 && pData)
238     XFree(pData);
239     }
240     return QApplication::x11EventFilter(pEv);
241     }
242     #endif
243    
244     private:
245    
246     // Translation support.
247     QTranslator *m_pQtTranslator;
248     QTranslator *m_pMyTranslator;
249    
250     // Instance variables.
251     QWidget *m_pWidget;
252    
253     #if defined(Q_WS_X11)
254     Display *m_pDisplay;
255     Atom m_aUnique;
256     Window m_wOwner;
257     #endif
258     };
259    
260    
261     //-------------------------------------------------------------------------
262     // stacktrace - Signal crash handler.
263     //
264    
265     #ifdef CONFIG_STACKTRACE
266     #if defined(__GNUC__) && defined(Q_OS_LINUX)
267    
268     #include <stdio.h>
269     #include <errno.h>
270     #include <signal.h>
271 capela 2341 #include <unistd.h>
272 capela 2074 #include <sys/wait.h>
273    
274     void stacktrace ( int signo )
275     {
276     pid_t pid;
277     int rc;
278     int status = 0;
279     char cmd[80];
280    
281     // Reinstall default handler; prevent race conditions...
282     signal(signo, SIG_DFL);
283    
284     static const char *shell = "/bin/sh";
285 capela 2181 static const char *format = "gdb -q --batch --pid=%d"
286     " --eval-command='thread apply all bt'";
287 capela 2074
288     snprintf(cmd, sizeof(cmd), format, (int) getpid());
289    
290     pid = fork();
291    
292     // Fork failure!
293     if (pid < 0)
294     return;
295    
296     // Fork child...
297     if (pid == 0) {
298     execl(shell, shell, "-c", cmd, NULL);
299     _exit(1);
300     return;
301     }
302    
303     // Parent here: wait for child to terminate...
304     do { rc = waitpid(pid, &status, 0); }
305     while ((rc < 0) && (errno == EINTR));
306    
307     // Dispatch any logging, if any...
308     QApplication::processEvents(QEventLoop::AllEvents, 3000);
309    
310     // Make sure everyone terminates...
311     kill(pid, SIGTERM);
312     _exit(1);
313     }
314    
315     #endif
316     #endif
317    
318    
319     //-------------------------------------------------------------------------
320     // main - The main program trunk.
321     //
322    
323     int main ( int argc, char **argv )
324     {
325     Q_INIT_RESOURCE(qsampler);
326     #ifdef CONFIG_STACKTRACE
327     #if defined(__GNUC__) && defined(Q_OS_LINUX)
328     signal(SIGILL, stacktrace);
329     signal(SIGFPE, stacktrace);
330     signal(SIGSEGV, stacktrace);
331     signal(SIGABRT, stacktrace);
332     signal(SIGBUS, stacktrace);
333     #endif
334     #endif
335     qsamplerApplication app(argc, argv);
336    
337     #if defined(__APPLE__) // Toshi Nagata 20080105
338     {
339     // Set the plugin path to @exetutable_path/../plugins
340     QDir dir(QApplication::applicationDirPath());
341     dir.cdUp(); // "Contents" directory
342     QApplication::setLibraryPaths(QStringList(dir.absolutePath() + "/plugins"));
343    
344     // Set the PATH environment variable to include @executable_path/../../..
345     dir.cdUp();
346     dir.cdUp();
347     QString path(getenv("PATH"));
348     path = dir.absolutePath() + ":" + path;
349     setenv("PATH", path.toUtf8().constData(), 1);
350     }
351     #endif
352    
353     // Construct default settings; override with command line arguments.
354     QSampler::Options options;
355     if (!options.parse_args(app.arguments())) {
356     app.quit();
357     return 1;
358     }
359    
360     // Have another instance running?
361     if (app.setup()) {
362     app.quit();
363     return 2;
364     }
365    
366     // Dark themes grayed/disabled color group fix...
367     QPalette pal(app.palette());
368     if (pal.base().color().value() < 0x7f) {
369 capela 2415 #if QT_VERSION >= 0x050000
370     const QColor& color = pal.window().color();
371     const int iGroups = int(QPalette::Active | QPalette::Inactive) + 1;
372     for (int i = 0; i < iGroups; ++i) {
373     const QPalette::ColorGroup group = QPalette::ColorGroup(i);
374     pal.setBrush(group, QPalette::Light, color.lighter(150));
375     pal.setBrush(group, QPalette::Midlight, color.lighter(120));
376     pal.setBrush(group, QPalette::Dark, color.darker(150));
377     pal.setBrush(group, QPalette::Mid, color.darker(120));
378     pal.setBrush(group, QPalette::Shadow, color.darker(200));
379     }
380     // pal.setColor(QPalette::Disabled, QPalette::ButtonText, pal.mid().color());
381     #endif
382 capela 2074 pal.setColorGroup(QPalette::Disabled,
383     pal.windowText().color().darker(),
384     pal.button(),
385     pal.light(),
386     pal.dark(),
387     pal.mid(),
388     pal.text().color().darker(),
389     pal.text().color().lighter(),
390     pal.base(),
391     pal.window());
392     app.setPalette(pal);
393     }
394    
395     // Set default base font...
396     if (options.iBaseFontSize > 0)
397 capela 2677 app.setFont(QFont(app.font().family(), options.iBaseFontSize));
398 capela 2074
399     // Construct, setup and show the main form.
400     QSampler::MainForm w;
401     w.setup(&options);
402     w.show();
403    
404     // Settle this one as application main widget...
405     app.setMainWidget(&w);
406    
407     // Register the quit signal/slot.
408     // app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
409    
410     return app.exec();
411     }
412    
413    
414     // end of qsampler.cpp

  ViewVC Help
Powered by ViewVC