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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1740 - (hide annotations) (download)
Fri May 23 23:35:55 2008 UTC (15 years, 11 months ago) by capela
File size: 7888 byte(s)
* Attempt to load Qt's own translation support and get rid of
  the ever warning startup message, unless built in debug mode.
  (transaction by Guido Scholz, while on qsynth-devel, thanks).

* Only one application instance is now allowed to be up and running,
  with immediate but graceful termination upon startup iif an already
  running instance is detected, which will see its main widget shown
  up automatically (Qt/X11 platform only).

1 capela 73 // main.cpp
2     //
3     /****************************************************************************
4 capela 1740 Copyright (C) 2004-2008, rncbc aka Rui Nuno Capela. All rights reserved.
5 schoenebeck 1667 Copyright (C) 2007, 2008 Christian Schoenebeck
6 capela 73
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 capela 920 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 capela 73
21     *****************************************************************************/
22    
23     #include "qsamplerAbout.h"
24     #include "qsamplerOptions.h"
25     #include "qsamplerMainForm.h"
26    
27 capela 1473 #include <QApplication>
28 capela 1740 #include <QLibraryInfo>
29 capela 1473 #include <QTranslator>
30     #include <QLocale>
31 nagata 1643 #if defined(__APPLE__) // Toshi Nagata 20080105
32     #include <QDir>
33     #endif
34 capela 1473
35 capela 1740 #if defined(Q_WS_X11)
36    
37 capela 73 //-------------------------------------------------------------------------
38 capela 1740 // Single application instance stuff (Qt/X11 only atm.)
39 capela 73 //
40    
41 capela 1740 #include <QX11Info>
42    
43     #include <X11/Xatom.h>
44     #include <X11/Xlib.h>
45    
46     #define QSAMPLER_XUNIQUE "qsamplerMainForm_xunique"
47    
48     #endif
49    
50     class qsamplerApplication : public QApplication
51 capela 73 {
52 capela 1740 public:
53 schoenebeck 1667
54 capela 1740 // Constructor.
55     qsamplerApplication(int& argc, char **argv) : QApplication(argc, argv),
56     m_pQtTranslator(0), m_pMyTranslator(0), m_pWidget(0)
57     {
58     // Load translation support.
59     QLocale loc;
60     if (loc.language() != QLocale::C) {
61     // Try own Qt translation...
62     m_pQtTranslator = new QTranslator(this);
63     QString sLocName = "qt_" + loc.name();
64     QString sLocPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
65     if (m_pQtTranslator->load(sLocName, sLocPath)) {
66     QApplication::installTranslator(m_pQtTranslator);
67     } else {
68     delete m_pQtTranslator;
69     m_pQtTranslator = 0;
70     #ifdef CONFIG_DEBUG
71     qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
72     loc.name().toUtf8().constData(),
73 capela 1473 sLocPath.toUtf8().constData(),
74     sLocName.toUtf8().constData());
75 capela 1740 #endif
76     }
77     // Try own application translation...
78     m_pMyTranslator = new QTranslator(this);
79     sLocName = "qsampler_" + loc.name();
80     if (m_pMyTranslator->load(sLocName, sLocPath)) {
81     QApplication::installTranslator(m_pMyTranslator);
82     } else {
83     sLocPath = CONFIG_PREFIX "/share/locale";
84     if (m_pMyTranslator->load(sLocName, sLocPath)) {
85     QApplication::installTranslator(m_pMyTranslator);
86     } else {
87     delete m_pMyTranslator;
88     m_pMyTranslator = 0;
89     #ifdef CONFIG_DEBUG
90     qWarning("Warning: no translation found for '%s' locale: %s/%s.qm",
91     loc.name().toUtf8().constData(),
92     sLocPath.toUtf8().constData(),
93     sLocName.toUtf8().constData());
94     #endif
95     }
96     }
97 capela 1473 }
98 capela 1740 #if defined(Q_WS_X11)
99     m_pDisplay = QX11Info::display();
100     m_aUnique = XInternAtom(m_pDisplay, QSAMPLER_XUNIQUE, false);
101     XGrabServer(m_pDisplay);
102     m_wOwner = XGetSelectionOwner(m_pDisplay, m_aUnique);
103     XUngrabServer(m_pDisplay);
104     #endif
105 capela 1473 }
106 capela 73
107 capela 1740 // Destructor.
108     ~qsamplerApplication()
109     {
110     if (m_pMyTranslator) delete m_pMyTranslator;
111     if (m_pQtTranslator) delete m_pQtTranslator;
112     }
113    
114     // Main application widget accessors.
115     void setMainWidget(QWidget *pWidget)
116     {
117     m_pWidget = pWidget;
118     #if defined(Q_WS_X11)
119     XGrabServer(m_pDisplay);
120     m_wOwner = m_pWidget->winId();
121     XSetSelectionOwner(m_pDisplay, m_aUnique, m_wOwner, CurrentTime);
122     XUngrabServer(m_pDisplay);
123     #endif
124     }
125    
126     QWidget *mainWidget() const { return m_pWidget; }
127    
128     // Check if another instance is running,
129     // and raise its proper main widget...
130     bool setup()
131     {
132     #if defined(Q_WS_X11)
133     if (m_wOwner != None) {
134     // First, notify any freedesktop.org WM
135     // that we're about to show the main widget...
136     Screen *pScreen = XDefaultScreenOfDisplay(m_pDisplay);
137     int iScreen = XScreenNumberOfScreen(pScreen);
138     XEvent ev;
139     memset(&ev, 0, sizeof(ev));
140     ev.xclient.type = ClientMessage;
141     ev.xclient.display = m_pDisplay;
142     ev.xclient.window = m_wOwner;
143     ev.xclient.message_type = XInternAtom(m_pDisplay, "_NET_ACTIVE_WINDOW", false);
144     ev.xclient.format = 32;
145     ev.xclient.data.l[0] = 0; // Source indication.
146     ev.xclient.data.l[1] = 0; // Timestamp.
147     ev.xclient.data.l[2] = 0; // Requestor's currently active window (none)
148     ev.xclient.data.l[3] = 0;
149     ev.xclient.data.l[4] = 0;
150     XSelectInput(m_pDisplay, m_wOwner, StructureNotifyMask);
151     XSendEvent(m_pDisplay, RootWindow(m_pDisplay, iScreen), false,
152     (SubstructureNotifyMask | SubstructureRedirectMask), &ev);
153     XSync(m_pDisplay, false);
154     XRaiseWindow(m_pDisplay, m_wOwner);
155     // And then, let it get caught on destination
156     // by QApplication::x11EventFilter...
157     QByteArray value = QSAMPLER_XUNIQUE;
158     XChangeProperty(
159     m_pDisplay,
160     m_wOwner,
161     m_aUnique,
162     m_aUnique, 8,
163     PropModeReplace,
164     (unsigned char *) value.data(),
165     value.length());
166     // Done.
167     return true;
168     }
169     #endif
170     return false;
171     }
172    
173     #if defined(Q_WS_X11)
174     bool x11EventFilter(XEvent *pEv)
175     {
176     if (m_pWidget && m_wOwner != None
177     && pEv->type == PropertyNotify
178     && pEv->xproperty.window == m_wOwner
179     && pEv->xproperty.state == PropertyNewValue) {
180     // Always check whether our property-flag is still around...
181     Atom aType;
182     int iFormat = 0;
183     unsigned long iItems = 0;
184     unsigned long iAfter = 0;
185     unsigned char *pData = 0;
186     if (XGetWindowProperty(
187     m_pDisplay,
188     m_wOwner,
189     m_aUnique,
190     0, 1024,
191     false,
192     m_aUnique,
193     &aType,
194     &iFormat,
195     &iItems,
196     &iAfter,
197     &pData) == Success
198     && aType == m_aUnique && iItems > 0 && iAfter == 0) {
199     // Avoid repeating it-self...
200     XDeleteProperty(m_pDisplay, m_wOwner, m_aUnique);
201     // Just make it always shows up fine...
202     m_pWidget->show();
203     m_pWidget->raise();
204     m_pWidget->activateWindow();
205     }
206     // Free any left-overs...
207     if (iItems > 0 && pData)
208     XFree(pData);
209     }
210     return QApplication::x11EventFilter(pEv);
211     }
212     #endif
213    
214     private:
215    
216     // Translation support.
217     QTranslator *m_pQtTranslator;
218     QTranslator *m_pMyTranslator;
219    
220     // Instance variables.
221     QWidget *m_pWidget;
222    
223     #if defined(Q_WS_X11)
224     Display *m_pDisplay;
225     Atom m_aUnique;
226     Window m_wOwner;
227     #endif
228     };
229    
230    
231     //-------------------------------------------------------------------------
232     // main - The main program trunk.
233     //
234    
235     int main ( int argc, char **argv )
236     {
237     Q_INIT_RESOURCE(qsampler);
238    
239     qsamplerApplication app(argc, argv);
240    
241 nagata 1643 #if defined(__APPLE__) // Toshi Nagata 20080105
242     {
243     // Set the plugin path to @exetutable_path/../plugins
244     QDir dir(QApplication::applicationDirPath());
245     dir.cdUp(); // "Contents" directory
246     QApplication::setLibraryPaths(QStringList(dir.absolutePath() + "/plugins"));
247    
248     // Set the PATH environment variable to include @executable_path/../../..
249     dir.cdUp();
250     dir.cdUp();
251     QString path(getenv("PATH"));
252     path = dir.absolutePath() + ":" + path;
253     setenv("PATH", path.toUtf8().constData(), 1);
254     }
255     #endif
256    
257 capela 1473 // Construct default settings; override with command line arguments.
258 capela 1558 QSampler::Options options;
259 capela 1473 if (!options.parse_args(app.argc(), app.argv())) {
260     app.quit();
261     return 1;
262     }
263 capela 752
264 capela 1740 // Have another instance running?
265     if (app.setup()) {
266     app.quit();
267     return 2;
268     }
269    
270 capela 1473 // Construct, setup and show the main form.
271     QSampler::MainForm w;
272     w.setup(&options);
273     w.show();
274 capela 73
275 capela 1740 // Settle this one as application main widget...
276     app.setMainWidget(&w);
277    
278 capela 1473 // Register the quit signal/slot.
279     // app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
280 capela 73
281 capela 1473 return app.exec();
282 capela 73 }
283    
284 capela 1464
285 capela 73 // end of main.cpp

  ViewVC Help
Powered by ViewVC