Skip to content

Commit

Permalink
Add win32 native implementation, and new openFileExplorerAndSelectFile
Browse files Browse the repository at this point in the history
method to QgsNative

Opens the desktop file explorer at the folder containing path,
and (if possible) scrolls to and pre-selects the file at path itself.

The default implementation just calls the QDesktopServices method to open the folder,
without selecting the specified file.

Use this to automatically select the exported layout file
when clicking the message bar success message in layouts (on Windows)
  • Loading branch information
nyalldawson committed Jul 31, 2018
1 parent 1fea03f commit 762099b
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 12 deletions.
10 changes: 4 additions & 6 deletions src/app/layout/qgslayoutdesignerdialog.cpp
Expand Up @@ -1971,14 +1971,13 @@ void QgsLayoutDesignerDialog::exportToPdf()
// force a refresh, to e.g. update data defined properties, tables, etc // force a refresh, to e.g. update data defined properties, tables, etc
mLayout->refresh(); mLayout->refresh();


QFileInfo fi( outputFileName );
QgsLayoutExporter exporter( mLayout ); QgsLayoutExporter exporter( mLayout );
switch ( exporter.exportToPdf( outputFileName, pdfSettings ) ) switch ( exporter.exportToPdf( outputFileName, pdfSettings ) )
{ {
case QgsLayoutExporter::Success: case QgsLayoutExporter::Success:
{ {
mMessageBar->pushMessage( tr( "Export layout" ), mMessageBar->pushMessage( tr( "Export layout" ),
tr( "Successfully exported layout to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( fi.path() ).toString(), QDir::toNativeSeparators( outputFileName ) ), tr( "Successfully exported layout to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( outputFileName ).toString(), QDir::toNativeSeparators( outputFileName ) ),
Qgis::Success, 0 ); Qgis::Success, 0 );
break; break;
} }
Expand Down Expand Up @@ -2078,14 +2077,13 @@ void QgsLayoutDesignerDialog::exportToSvg()
// force a refresh, to e.g. update data defined properties, tables, etc // force a refresh, to e.g. update data defined properties, tables, etc
mLayout->refresh(); mLayout->refresh();


QFileInfo fi( outputFileName );
QgsLayoutExporter exporter( mLayout ); QgsLayoutExporter exporter( mLayout );
switch ( exporter.exportToSvg( outputFileName, svgSettings ) ) switch ( exporter.exportToSvg( outputFileName, svgSettings ) )
{ {
case QgsLayoutExporter::Success: case QgsLayoutExporter::Success:
{ {
mMessageBar->pushMessage( tr( "Export layout" ), mMessageBar->pushMessage( tr( "Export layout" ),
tr( "Successfully exported layout to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( fi.path() ).toString(), QDir::toNativeSeparators( outputFileName ) ), tr( "Successfully exported layout to <a href=\"%1\">%2</a>" ).arg( outputFileName, QDir::toNativeSeparators( outputFileName ) ),
Qgis::Success, 0 ); Qgis::Success, 0 );
break; break;
} }
Expand Down Expand Up @@ -2892,7 +2890,7 @@ void QgsLayoutDesignerDialog::exportAtlasToPdf()
if ( singleFile ) if ( singleFile )
{ {
mMessageBar->pushMessage( tr( "Export atlas" ), mMessageBar->pushMessage( tr( "Export atlas" ),
tr( "Successfully exported atlas to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( fi.path() ).toString(), QDir::toNativeSeparators( outputFileName ) ), tr( "Successfully exported atlas to <a href=\"%1\">%2</a>" ).arg( outputFileName, QDir::toNativeSeparators( outputFileName ) ),
Qgis::Success, 0 ); Qgis::Success, 0 );
} }
else else
Expand Down Expand Up @@ -3251,7 +3249,7 @@ void QgsLayoutDesignerDialog::exportReportToPdf()
case QgsLayoutExporter::Success: case QgsLayoutExporter::Success:
{ {
mMessageBar->pushMessage( tr( "Export report" ), mMessageBar->pushMessage( tr( "Export report" ),
tr( "Successfully exported report to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( fi.path() ).toString(), QDir::toNativeSeparators( outputFileName ) ), tr( "Successfully exported report to <a href=\"%1\">%2</a>" ).arg( outputFileName, QDir::toNativeSeparators( outputFileName ) ),
Qgis::Success, 0 ); Qgis::Success, 0 );
break; break;
} }
Expand Down
6 changes: 3 additions & 3 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -26,9 +26,11 @@
#include "qgsdatumtransformtablewidget.h" #include "qgsdatumtransformtablewidget.h"
#include "qgslayoutmanager.h" #include "qgslayoutmanager.h"
#include "qgslogger.h" #include "qgslogger.h"
#include "qgsgui.h"
#include "qgsmapcanvas.h" #include "qgsmapcanvas.h"
#include "qgsmaplayer.h" #include "qgsmaplayer.h"
#include "qgsproject.h" #include "qgsproject.h"
#include "qgsnative.h"
#include "qgsprojectlayergroupdialog.h" #include "qgsprojectlayergroupdialog.h"
#include "qgsrasterlayer.h" #include "qgsrasterlayer.h"
#include "qgsvectorlayer.h" #include "qgsvectorlayer.h"
Expand Down Expand Up @@ -246,9 +248,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa


connect( mButtonOpenProjectFolder, &QToolButton::clicked, this, [ = ] connect( mButtonOpenProjectFolder, &QToolButton::clicked, this, [ = ]
{ {
QFileInfo fi( QgsProject::instance()->fileName() ); QgsGui::nativePlatformInterface()->openFileExplorerAndSelectFile( QgsProject::instance()->fileName() );
QString folder = fi.path();
QDesktopServices::openUrl( QUrl::fromLocalFile( folder ) );
} ); } );


// get the manner in which the number of decimal places in the mouse // get the manner in which the number of decimal places in the mouse
Expand Down
3 changes: 3 additions & 0 deletions src/gui/CMakeLists.txt
Expand Up @@ -956,6 +956,9 @@ GENERATE_EXPORT_HEADER(
SET(QGIS_GUI_HDRS ${QGIS_GUI_HDRS} ${CMAKE_CURRENT_BINARY_DIR}/qgis_gui.h) SET(QGIS_GUI_HDRS ${QGIS_GUI_HDRS} ${CMAKE_CURRENT_BINARY_DIR}/qgis_gui.h)


IF(NOT APPLE) IF(NOT APPLE)
IF (WIN32 )
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/native/win)
ENDIF (WIN32)
INSTALL(FILES ${QGIS_GUI_HDRS} ${QGIS_GUI_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR}) INSTALL(FILES ${QGIS_GUI_HDRS} ${QGIS_GUI_MOC_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})
ELSE(NOT APPLE) ELSE(NOT APPLE)
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/native/mac) INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/native/mac)
Expand Down
4 changes: 4 additions & 0 deletions src/gui/qgsgui.cpp
Expand Up @@ -25,6 +25,8 @@
#include "qgslayoutviewrubberband.h" #include "qgslayoutviewrubberband.h"
#ifdef Q_OS_MACX #ifdef Q_OS_MACX
#include "qgsmacnative.h" #include "qgsmacnative.h"
#elif defined (Q_OS_WIN)
#include "qgswinnative.h"
#else #else
#include "qgsnative.h" #include "qgsnative.h"
#endif #endif
Expand Down Expand Up @@ -112,6 +114,8 @@ QgsGui::QgsGui()
{ {
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
mNative = new QgsMacNative(); mNative = new QgsMacNative();
#elif defined (Q_OS_WIN)
mNative = new QgsWinNative();
#else #else
mNative = new QgsNative(); mNative = new QgsNative();
#endif #endif
Expand Down
10 changes: 8 additions & 2 deletions src/gui/qgsmessagebaritem.cpp
Expand Up @@ -18,11 +18,13 @@
#include "qgsapplication.h" #include "qgsapplication.h"
#include "qgsmessagebaritem.h" #include "qgsmessagebaritem.h"
#include "qgsmessagebar.h" #include "qgsmessagebar.h"

#include "qgsgui.h"
#include "qgsnative.h"
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QLabel> #include <QLabel>
#include <QTextBrowser> #include <QTextBrowser>
#include <QDesktopServices> #include <QDesktopServices>
#include <QFile>


QgsMessageBarItem::QgsMessageBarItem( const QString &text, Qgis::MessageLevel level, int duration, QWidget *parent ) QgsMessageBarItem::QgsMessageBarItem( const QString &text, Qgis::MessageLevel level, int duration, QWidget *parent )
: QWidget( parent ) : QWidget( parent )
Expand Down Expand Up @@ -269,5 +271,9 @@ QgsMessageBarItem *QgsMessageBarItem::setDuration( int duration )


void QgsMessageBarItem::urlClicked( const QUrl &url ) void QgsMessageBarItem::urlClicked( const QUrl &url )
{ {
QDesktopServices::openUrl( url ); const bool isFile = QFile::exists( url.toLocalFile() );
if ( isFile )
QgsGui::instance()->nativePlatformInterface()->openFileExplorerAndSelectFile( url.toLocalFile() );
else
QDesktopServices::openUrl( url );
} }
25 changes: 24 additions & 1 deletion src/native/CMakeLists.txt
Expand Up @@ -24,6 +24,7 @@ IF(APPLE)
ENDFOREACH(_lib ${APPLE_LIB_LIST}) ENDFOREACH(_lib ${APPLE_LIB_LIST})
ENDIF(APPLE) ENDIF(APPLE)



############################################################# #############################################################
# sources # sources


Expand All @@ -44,6 +45,15 @@ IF(APPLE)
) )
ENDIF(APPLE) ENDIF(APPLE)


IF(WIN32)
SET(QGIS_APP_WIN32_SRCS
win/qgswinnative.cpp
)
SET(QGIS_NATIVE_SRCS ${QGIS_NATIVE_SRCS}
${QGIS_APP_WIN32_SRCS}
)
ENDIF(WIN32)

SET(QGIS_NATIVE_HDRS SET(QGIS_NATIVE_HDRS
qgsnative.h qgsnative.h
) )
Expand All @@ -57,6 +67,12 @@ IF(APPLE)
) )
ENDIF(APPLE) ENDIF(APPLE)


IF(WIN32)
SET (QGIS_NATIVE_HDRS ${QGIS_NATIVE_HDRS}
win/qgswinnative.h
)
ENDIF(WIN32)

INCLUDE_DIRECTORIES( INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
Expand Down Expand Up @@ -100,8 +116,15 @@ IF(NOT ANDROID)
) )
ENDIF(NOT ANDROID) ENDIF(NOT ANDROID)


TARGET_LINK_LIBRARIES(qgis_native "${NATIVE_LINK_LIBS}") TARGET_LINK_LIBRARIES(qgis_native
${Qt5Core_LIBRARIES}
${Qt5Gui_LIBRARIES}
"${NATIVE_LINK_LIBS}"
)


IF (WIN32)
TARGET_LINK_LIBRARIES(qgis_native shell32)
ENDIF (WIN32)
# install # install


INSTALL(TARGETS qgis_native INSTALL(TARGETS qgis_native
Expand Down
11 changes: 11 additions & 0 deletions src/native/qgsnative.cpp
Expand Up @@ -16,7 +16,18 @@
***************************************************************************/ ***************************************************************************/


#include "qgsnative.h" #include "qgsnative.h"
#include <QString>
#include <QDesktopServices>
#include <QUrl>
#include <QFileInfo>


void QgsNative::currentAppActivateIgnoringOtherApps() void QgsNative::currentAppActivateIgnoringOtherApps()
{ {
} }

void QgsNative::openFileExplorerAndSelectFile( const QString &path )
{
QFileInfo fi( path );
QString folder = fi.path();
QDesktopServices::openUrl( QUrl::fromLocalFile( folder ) );
}
13 changes: 13 additions & 0 deletions src/native/qgsnative.h
Expand Up @@ -20,6 +20,8 @@


#include "qgis_native.h" #include "qgis_native.h"


class QString;

/** /**
* \class QgsNative * \class QgsNative
* \ingroup native * \ingroup native
Expand All @@ -37,6 +39,17 @@ class NATIVE_EXPORT QgsNative
* Brings the QGIS app to front. The default implementation does nothing. * Brings the QGIS app to front. The default implementation does nothing.
*/ */
virtual void currentAppActivateIgnoringOtherApps(); virtual void currentAppActivateIgnoringOtherApps();

/**
* Opens the desktop file explorer at the folder containing \a path,
* and (if possible) scrolls to and pre-selects the file at \a path itself.
*
* The default implementation just calls the QDesktopServices method to open the folder,
* without selecting the specified file.
*
* \since QGIS 3.4
*/
virtual void openFileExplorerAndSelectFile( const QString &path );
}; };


#endif // QGSNATIVE_H #endif // QGSNATIVE_H
31 changes: 31 additions & 0 deletions src/native/win/qgswinnative.cpp
@@ -0,0 +1,31 @@
/***************************************************************************
qgswinnative.cpp - abstracted interface to native system calls
-------------------
begin : January 2017
copyright : (C) 2017 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgswinnative.h"
#include <QString>
#include <QDir>

void QgsWinNative::openFileExplorerAndSelectFile( const QString &path )
{
const QString nativePath = QDir::toNativeSeparators( path );
ITEMIDLIST *pidl = ILCreateFromPath( nativePath.toUtf8().constData() );
if ( pidl )
{
SHOpenFolderAndSelectItems( pidl, 0, 0, 0 );
ILFree( pidl );
}
}
32 changes: 32 additions & 0 deletions src/native/win/qgswinnative.h
@@ -0,0 +1,32 @@
/***************************************************************************
qgswinnative.h - abstracted interface to native Mac objective-c
-------------------
begin : January 2014
copyright : (C) 2014 by Larry Shaffer
email : larrys at dakotacarto dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSMACNATIVE_H
#define QGSMACNATIVE_H

#include "qgsnative.h"
#include <windows.h>
#include <shlobj.h>
#pragma comment(lib,"Shell32.lib")

class NATIVE_EXPORT QgsWinNative : public QgsNative
{
public:
void openFileExplorerAndSelectFile( const QString &path ) override;
};

#endif // QGSMACNATIVE_H

0 comments on commit 762099b

Please sign in to comment.