Skip to content

Commit

Permalink
[FEATURE] Add native platform interface for opening a terminal window at
Browse files Browse the repository at this point in the history
a specified path

And implement for Linux.

Add a new context menu entry to directories in browser to open a
terminal window at that directory on supported platforms
  • Loading branch information
nyalldawson committed Nov 14, 2018
1 parent 22772ea commit 561d90c
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
11 changes: 11 additions & 0 deletions src/app/browser/qgsinbuiltdataitemproviders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,17 @@ void QgsAppDirectoryItemGuiProvider::populateContextMenu( QgsDataItem *item, QMe
} );
menu->addAction( openFolder );

if ( QgsGui::instance()->nativePlatformInterface()->capabilities() & QgsNative::NativeOpenTerminalAtPath )
{
QAction *openTerminal = new QAction( tr( "Open in Terminal…" ), menu );
connect( openTerminal, &QAction::triggered, this, [ = ]
{
QgsGui::instance()->nativePlatformInterface()->openTerminalAtPath( directoryItem->dirPath() );
} );
menu->addAction( openTerminal );
menu->addSeparator();
}

QAction *propertiesAction = new QAction( tr( "Properties…" ), menu );
connect( propertiesAction, &QAction::triggered, this, [ = ]
{
Expand Down
35 changes: 34 additions & 1 deletion src/native/linux/qgslinuxnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@
#include <QtDBus/QtDBus>
#include <QtDebug>
#include <QImage>
#include <QProcess>

QgsNative::Capabilities QgsLinuxNative::capabilities() const
{
return NativeDesktopNotifications | NativeFilePropertiesDialog;
return NativeDesktopNotifications | NativeFilePropertiesDialog | NativeOpenTerminalAtPath;
}

void QgsLinuxNative::initializeMainWindow( QWindow *,
Expand Down Expand Up @@ -138,6 +139,38 @@ void QgsLinuxNative::setApplicationBadgeCount( int count )
QDBusConnection::sessionBus().send( message );
}

bool QgsLinuxNative::openTerminalAtPath( const QString &path )
{
// logic adapted from https://askubuntu.com/a/227669,
// https://github.com/Microsoft/vscode/blob/fec1775aa52e2124d3f09c7b2ac8f69c57309549/src/vs/workbench/parts/execution/electron-browser/terminal.ts
QString term = QStringLiteral( "xterm" );
const QString desktopSession = qgetenv( "DESKTOP_SESSION" );
const QString currentDesktop = qgetenv( "XDG_CURRENT_DESKTOP" );
const QString gdmSession = qgetenv( "GDMSESSION" );
const bool isDebian = QFile::exists( QStringLiteral( "/etc/debian_version" ) );
if ( isDebian )
{
term = QStringLiteral( "x-terminal-emulator" );
}
else if ( desktopSession.contains( QLatin1String( "gnome" ), Qt::CaseInsensitive ) ||
currentDesktop.contains( QLatin1String( "gnome" ), Qt::CaseInsensitive ) ||
currentDesktop.contains( QLatin1String( "unity" ), Qt::CaseInsensitive ) )
{
term = QStringLiteral( "gnome-terminal" );
}
else if ( desktopSession.contains( QLatin1String( "kde" ), Qt::CaseInsensitive ) ||
currentDesktop.contains( QLatin1String( "kde" ), Qt::CaseInsensitive ) ||
gdmSession.contains( QLatin1String( "kde" ), Qt::CaseInsensitive ) )
{
term = QStringLiteral( "konsole" );
}

QStringList arguments;
arguments << QStringLiteral( "--working-directory" )
<< path;
return QProcess::startDetached( term, QStringList(), path );
}

/**
* Automatic marshaling of a QImage for org.freedesktop.Notifications.Notify
*
Expand Down
1 change: 1 addition & 0 deletions src/native/linux/qgslinuxnative.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class NATIVE_EXPORT QgsLinuxNative : public QgsNative
void setApplicationProgress( double progress ) override;
void hideApplicationProgress() override;
void setApplicationBadgeCount( int count ) override;
bool openTerminalAtPath( const QString &path ) override;
NotificationResult showDesktopNotification( const QString &summary, const QString &body, const NotificationSettings &settings = NotificationSettings() ) override;
private:
QString mDesktopFile;
Expand Down
10 changes: 10 additions & 0 deletions src/native/qgsnative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,16 @@ void QgsNative::setApplicationBadgeCount( int )

}

bool QgsNative::hasDarkTheme()
{
return false;
}

bool QgsNative::openTerminalAtPath( const QString & )
{
return false;
}

QgsNative::NotificationResult QgsNative::showDesktopNotification( const QString &, const QString &, const NotificationSettings & )
{
NotificationResult result;
Expand Down
12 changes: 11 additions & 1 deletion src/native/qgsnative.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class NATIVE_EXPORT QgsNative : public QObject
{
NativeDesktopNotifications = 1 << 1, //!< Native desktop notifications are supported. See showDesktopNotification().
NativeFilePropertiesDialog = 1 << 2, //!< Platform can show a native "file" (or folder) properties dialog.
NativeOpenTerminalAtPath = 1 << 3, //!< Platform can open a terminal (command line) at a specific path
};
Q_DECLARE_FLAGS( Capabilities, Capability )

Expand Down Expand Up @@ -150,7 +151,16 @@ class NATIVE_EXPORT QgsNative : public QObject
* Returns true if the operating system is set to utilize a "dark" theme.
* \since QGIS 3.4
*/
virtual bool hasDarkTheme() {return false;}
virtual bool hasDarkTheme();

/**
* Opens a terminal (command line) window at the given \a path.
*
* This method is only supported when the interface returns the NativeOpenTerminalAtPath flag for capabilities().
*
* Returns true if terminal was successfully opened.
*/
virtual bool openTerminalAtPath( const QString &path );

/**
* Notification settings, for use with showDesktopNotification().
Expand Down

0 comments on commit 561d90c

Please sign in to comment.