Skip to content

Commit f963d24

Browse files
author
telwertowski
committedMar 10, 2011
Use QFileOpenEvent to handle double clicking a file icon in the Mac OS X Finder. This works for both Cocoa and Carbon. Remove Carbon-only OpenDocument code.
git-svn-id: http://svn.osgeo.org/qgis/trunk@15410 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent cd5467b commit f963d24

File tree

5 files changed

+113
-90
lines changed

5 files changed

+113
-90
lines changed
 

‎src/app/main.cpp

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -129,70 +129,6 @@ static QString myProjectFileName = "";
129129
static QStringList myFileList;
130130

131131

132-
#ifdef Q_OS_MACX
133-
/* Mac OS OpenDocuments AppleEvent handler called when files are double-clicked.
134-
* May be called at startup before application is initialized as well as
135-
* at any time while the application is running.
136-
*/
137-
OSErr openDocumentsAEHandler( const AppleEvent *event, AppleEvent *reply, SRefCon refCon )
138-
{
139-
AEDescList docs;
140-
if ( AEGetParamDesc( event, keyDirectObject, typeAEList, &docs ) == noErr )
141-
{
142-
// Get count of files to open
143-
long count = 0;
144-
AECountItems( &docs, &count );
145-
146-
// Examine files and load first project file followed by all other non-project files
147-
myProjectFileName.truncate( 0 );
148-
myFileList.clear();
149-
for ( int i = 0; i < count; i++ )
150-
{
151-
FSRef ref;
152-
UInt8 strBuffer[256];
153-
if ( AEGetNthPtr( &docs, i + 1, typeFSRef, 0, 0, &ref, sizeof( ref ), 0 ) == noErr &&
154-
FSRefMakePath( &ref, strBuffer, 256 ) == noErr )
155-
{
156-
QString fileName( QString::fromUtf8( reinterpret_cast<char *>( strBuffer ) ) );
157-
if ( fileName.endsWith( ".qgs" ) )
158-
{
159-
// Load first project file and ignore all other project files
160-
if ( myProjectFileName.isEmpty() )
161-
{
162-
myProjectFileName = fileName;
163-
}
164-
}
165-
else
166-
{
167-
// Load all non-project files
168-
myFileList.append( fileName );
169-
}
170-
}
171-
}
172-
173-
// Open files now if application has been fully initialized (has objectName).
174-
// Otherwise (if this routine is called by processEvents inside the QgisApp constructor
175-
// at startup) wait for the command line file loader to notice these files.
176-
QgisApp *qgis = QgisApp::instance();
177-
if ( qgis && qgis->objectName() == "QgisApp" )
178-
{
179-
if ( !myProjectFileName.isEmpty() )
180-
{
181-
qgis->openProject( myProjectFileName );
182-
}
183-
for ( QStringList::Iterator myIterator = myFileList.begin();
184-
myIterator != myFileList.end(); ++myIterator )
185-
{
186-
QString fileName = *myIterator;
187-
qgis->openLayer( fileName );
188-
}
189-
}
190-
}
191-
return noErr;
192-
}
193-
#endif
194-
195-
196132
/* Test to determine if this program was started on Mac OS X by double-clicking
197133
* the application bundle rather then from a command line. If clicked, argv[1]
198134
* contains a process serial number in the form -psn_0_1234567. Don't process
@@ -512,13 +448,6 @@ int main( int argc, char *argv[] )
512448
QCoreApplication::setApplicationName( "QGIS" );
513449
QCoreApplication::setAttribute( Qt::AA_DontShowIconsInMenus, false );
514450
#ifdef Q_OS_MACX
515-
// Install OpenDocuments AppleEvent handler after application object is initialized
516-
// but before any other event handling (including dialogs or splash screens) occurs.
517-
// If an OpenDocuments event has been created before the application was launched,
518-
// it must be handled before some other event handler runs and dismisses it as unknown.
519-
// If run at startup, the handler will set either or both of myProjectFileName and myFileList.
520-
AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, openDocumentsAEHandler, 0, false );
521-
522451
// If the GDAL plugins are bundled with the application and GDAL_DRIVER_PATH
523452
// is not already defined, use the GDAL plugins in the application bundle.
524453
QString gdalPlugins( QCoreApplication::applicationDirPath().append( "/lib/gdalplugins" ) );

‎src/app/qgisapp.cpp

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,9 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, QWidget * parent,
570570
QgsDebugMsg( QgsApplication::showSettings() );
571571
QgsDebugMsg( "\n--------------------------\n\n\n" );
572572

573+
// request notification of FileOpen events (double clicking a file icon in Mac OS X Finder)
574+
QgsApplication::setFileOpenEventReceiver( this );
575+
573576
} // QgisApp ctor
574577

575578

@@ -622,6 +625,9 @@ QgisApp::~QgisApp()
622625
deletePrintComposers();
623626
removeAnnotationItems();
624627

628+
// cancel request for FileOpen events
629+
QgsApplication::setFileOpenEventReceiver( nil );
630+
625631
// delete map layer registry and provider registry
626632
QgsApplication::exitQgis();
627633
}
@@ -646,23 +652,30 @@ void QgisApp::dropEvent( QDropEvent *event )
646652
// so we test for length to make sure we have something
647653
if ( !fileName.isEmpty() )
648654
{
649-
// check to see if we are opening a project file
650-
QFileInfo fi( fileName );
651-
if ( fi.completeSuffix() == "qgs" )
652-
{
653-
QgsDebugMsg( "Opening project " + fileName );
654-
openProject( fileName );
655-
}
656-
else
657-
{
658-
QgsDebugMsg( "Adding " + fileName + " to the map canvas" );
659-
openLayer( fileName, true );
660-
}
655+
openFile( fileName );
661656
}
662657
}
663658
event->acceptProposedAction();
664659
}
665660

661+
bool QgisApp::event( QEvent * event )
662+
{
663+
bool done = false;
664+
if ( event->type() == QEvent::FileOpen )
665+
{
666+
// handle FileOpen event (double clicking a file icon in Mac OS X Finder)
667+
QFileOpenEvent *foe = static_cast<QFileOpenEvent *>( event );
668+
openFile( foe->file() );
669+
done = true;
670+
}
671+
else
672+
{
673+
// pass other events to base class
674+
done = QMainWindow::event( event );
675+
}
676+
return done;
677+
}
678+
666679

667680
// restore any application settings stored in QSettings
668681
void QgisApp::readSettings()
@@ -2970,6 +2983,25 @@ bool QgisApp::openLayer( const QString & fileName, bool allowInteractive )
29702983
return ok;
29712984
}
29722985

2986+
2987+
// Open a file specified by a commandline argument, Drop or FileOpen event.
2988+
void QgisApp::openFile( const QString & fileName )
2989+
{
2990+
// check to see if we are opening a project file
2991+
QFileInfo fi( fileName );
2992+
if ( fi.completeSuffix() == "qgs" )
2993+
{
2994+
QgsDebugMsg( "Opening project " + fileName );
2995+
openProject( fileName );
2996+
}
2997+
else
2998+
{
2999+
QgsDebugMsg( "Adding " + fileName + " to the map canvas" );
3000+
openLayer( fileName, true );
3001+
}
3002+
}
3003+
3004+
29733005
void QgisApp::newPrintComposer()
29743006
{
29753007
if ( mMapCanvas && mMapCanvas->isDrawing() )

‎src/app/qgisapp.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -140,22 +140,23 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
140140
//! Remove all layers from the map and legend - reimplements same method from qgisappbase
141141
void removeAllLayers();
142142
/** Open a raster or vector file; ignore other files.
143-
Used to process a commandline argument or OpenDocument AppleEvent.
143+
Used to process a commandline argument, FileOpen or Drop event.
144+
Set interactive to true if it is ok to ask the user for information (mostly for
145+
when a vector layer has sublayers and we want to ask which sublayers to use).
144146
@returns true if the file is successfully opened
145147
*/
146148
bool openLayer( const QString & fileName, bool allowInteractive = false );
147-
/** Open the specified file (project, vector, or raster); prompt to save
148-
previous project if necessary.
149-
Used to process a commandline argument, OpenDocument AppleEvent, or a
150-
file drag/drop event. Set interactive to true if it is ok to ask the
151-
user for information (mostly for when a vector layer has sublayers and
152-
we want to ask which sublayers to use).
149+
/** Open the specified project file; prompt to save previous project if necessary.
150+
Used to process a commandline argument, FileOpen or Drop event.
153151
*/
154152
void openProject( const QString & fileName );
155153
/** opens a qgis project file
156154
@returns false if unable to open the project
157155
*/
158156
bool addProject( QString projectFile );
157+
/** Convenience function to open either a project or a layer file.
158+
*/
159+
void openFile( const QString & fileName );
159160
//!Overloaded version of the private function with same name that takes the imagename as a parameter
160161
void saveMapAsImage( QString, QPixmap * );
161162
/** Get the mapcanvas object from the app */
@@ -431,6 +432,9 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
431432
//! layer selection changed
432433
void legendLayerSelectionChanged( void );
433434

435+
//! Watch for QFileOpenEvent.
436+
virtual bool event( QEvent * event );
437+
434438
protected:
435439

436440
//! Handle state changes (WindowTitleChange)

‎src/core/qgsapplication.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "qgsexception.h"
2121

2222
#include <QDir>
23+
#include <QFileOpenEvent>
2324
#include <QMessageBox>
2425
#include <QPalette>
2526
#include <QSettings>
@@ -34,6 +35,8 @@
3435

3536
#include <ogr_api.h>
3637

38+
QObject * QgsApplication::mFileOpenEventReceiver;
39+
QStringList QgsApplication::mFileOpenEventList;
3740
QString QgsApplication::mPrefixPath;
3841
QString QgsApplication::mPluginPath;
3942
QString QgsApplication::mPkgDataPath;
@@ -79,6 +82,34 @@ QgsApplication::~QgsApplication()
7982
{
8083
}
8184

85+
bool QgsApplication::event( QEvent * event )
86+
{
87+
bool done = false;
88+
if ( event->type() == QEvent::FileOpen )
89+
{
90+
// handle FileOpen event (double clicking a file icon in Mac OS X Finder)
91+
if ( mFileOpenEventReceiver )
92+
{
93+
// Forward event to main window.
94+
done = notify( mFileOpenEventReceiver, event );
95+
}
96+
else
97+
{
98+
// Store filename because receiver has not registered yet.
99+
// If QGIS has been launched by double clicking a file icon, FileOpen will be
100+
// the first event; the main window is not yet ready to handle the event.
101+
mFileOpenEventList.append( static_cast<QFileOpenEvent *>( event )->file() );
102+
done = true;
103+
}
104+
}
105+
else
106+
{
107+
// pass other events to base class
108+
done = QApplication::event( event );
109+
}
110+
return done;
111+
}
112+
82113
bool QgsApplication::notify( QObject * receiver, QEvent * event )
83114
{
84115
// Send event to receiver and catch unhandled exceptions
@@ -102,6 +133,23 @@ bool QgsApplication::notify( QObject * receiver, QEvent * event )
102133
return done;
103134
}
104135

136+
void QgsApplication::setFileOpenEventReceiver( QObject * receiver )
137+
{
138+
// Set receiver for FileOpen events
139+
mFileOpenEventReceiver = receiver;
140+
// Propagate any events collected before the receiver has registered.
141+
if ( mFileOpenEventList.count() > 0 )
142+
{
143+
QStringListIterator i( mFileOpenEventList );
144+
while ( i.hasNext() )
145+
{
146+
QFileOpenEvent foe( i.next() );
147+
QgsApplication::sendEvent( mFileOpenEventReceiver, &foe );
148+
}
149+
mFileOpenEventList.clear();
150+
}
151+
}
152+
105153
void QgsApplication::setPrefixPath( const QString thePrefixPath, bool useDefaultPaths )
106154
{
107155
mPrefixPath = thePrefixPath;

‎src/core/qgsapplication.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define QGSAPPLICATION_H
1818

1919
#include <QApplication>
20+
#include <QEvent>
2021

2122
#include <qgis.h>
2223

@@ -32,9 +33,15 @@ class CORE_EXPORT QgsApplication: public QApplication
3233
QgsApplication( int & argc, char ** argv, bool GUIenabled, QString customConfigPath = QString() );
3334
virtual ~QgsApplication();
3435

36+
//! Watch for QFileOpenEvent.
37+
virtual bool event( QEvent * event );
38+
3539
//! Catch exceptions when sending event to receiver.
3640
virtual bool notify( QObject * receiver, QEvent * event );
3741

42+
//! Set the FileOpen event receiver
43+
static void setFileOpenEventReceiver( QObject * receiver );
44+
3845
/** Set the active theme to the specified theme.
3946
* The theme name should be a single word e.g. 'default','classic'.
4047
* The theme search path usually will be pkgDataPath + "/themes/" + themName + "/"
@@ -195,6 +202,9 @@ class CORE_EXPORT QgsApplication: public QApplication
195202
static QString relativePathToAbsolutePath( QString rpath, QString targetPath );
196203

197204
private:
205+
static QObject* mFileOpenEventReceiver;
206+
static QStringList mFileOpenEventList;
207+
198208
static QString mPrefixPath;
199209
static QString mPluginPath;
200210
static QString mPkgDataPath;

0 commit comments

Comments
 (0)
Please sign in to comment.