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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2631 - (show annotations) (download)
Sun Jun 15 00:27:04 2014 UTC (6 years, 4 months ago) by capela
File size: 11244 byte(s)
* Translations install directory change. (EXPERIMENTAL)
1 // qsampler.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2014, rncbc aka Rui Nuno Capela. All rights reserved.
5 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
32 #if defined(__APPLE__) // Toshi Nagata 20080105
33 #include <QDir>
34 #endif
35
36 #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 #if WIN32
46 #define RELATIVE_LOCALE_DIR "/share/locale"
47 #elif defined(__APPLE__)
48 #define RELATIVE_LOCALE_DIR "/../Resources"
49 #endif
50
51
52 //-------------------------------------------------------------------------
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 #ifdef RELATIVE_LOCALE_DIR
86 sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
87 if (m_pQtTranslator->load(sLocName, sLocPath)) {
88 QApplication::installTranslator(m_pQtTranslator);
89 } else {
90 #endif
91 delete m_pQtTranslator;
92 m_pQtTranslator = 0;
93 #ifdef CONFIG_DEBUG
94 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 #endif
99 #ifdef RELATIVE_LOCALE_DIR
100 }
101 #endif
102 }
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 #ifdef RELATIVE_LOCALE_DIR
110 sLocPath = QApplication::applicationDirPath() + RELATIVE_LOCALE_DIR;
111 #else
112 sLocPath = CONFIG_DATADIR "/qsampler/translations";
113 #endif
114 if (m_pMyTranslator->load(sLocName, sLocPath)) {
115 QApplication::installTranslator(m_pMyTranslator);
116 } else {
117 delete m_pMyTranslator;
118 m_pMyTranslator = 0;
119 #ifdef CONFIG_DEBUG
120 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 #endif
125 }
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 #include <unistd.h>
272 #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 static const char *format = "gdb -q --batch --pid=%d"
286 " --eval-command='thread apply all bt'";
287
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 #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 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 int iBaseFontSize = app.font().pointSize();
397 if (options.iBaseFontSize > 0)
398 iBaseFontSize = options.iBaseFontSize;
399 app.setFont(QFont(app.font().family(), iBaseFontSize));
400
401 // Construct, setup and show the main form.
402 QSampler::MainForm w;
403 w.setup(&options);
404 w.show();
405
406 // Settle this one as application main widget...
407 app.setMainWidget(&w);
408
409 // Register the quit signal/slot.
410 // app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
411
412 return app.exec();
413 }
414
415
416 // end of qsampler.cpp

  ViewVC Help
Powered by ViewVC