Commit 7ddfd865 authored by Friedemann Kleint's avatar Friedemann Kleint

Foldernavigationwidget: Add "Open Terminal" and "Open Explorer".

Move code to Foldernavigationwidget as static utilities and use
them from there and from the Project explorer. Fix error message box.
Task-number: QTCREATORBUG-62
parent 666724b2
......@@ -225,6 +225,7 @@ const char * const WIZARD_TR_CATEGORY_QT = QT_TRANSLATE_NOOP("Core", "Qt");
const char * const SETTINGS_CATEGORY_CORE = "A.Core";
const char * const SETTINGS_TR_CATEGORY_CORE = QT_TRANSLATE_NOOP("Core", "Environment");
const char * const SETTINGS_ID_ENVIRONMENT = "A.General";
} // namespace Constants
} // namespace Core
......
......@@ -59,7 +59,7 @@ GeneralSettings::GeneralSettings():
QString GeneralSettings::id() const
{
return QLatin1String("A.General");
return QLatin1String(Core::Constants::SETTINGS_ID_ENVIRONMENT);
}
QString GeneralSettings::displayName() const
......
......@@ -30,18 +30,24 @@
#include "foldernavigationwidget.h"
#include "projectexplorer.h"
#include "projectexplorerconstants.h"
#include "environment.h"
#include <coreplugin/icore.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/coreconstants.h>
#include <utils/pathchooser.h>
#include <utils/qtcassert.h>
#include <utils/unixutils.h>
#include <utils/consoleprocess.h>
#include <QtCore/QDebug>
#include <QtCore/QProcess>
#include <QtGui/QFileSystemModel>
#include <QtGui/QVBoxLayout>
#include <QtGui/QToolButton>
#include <QtGui/QPushButton>
#include <QtGui/QLabel>
#include <QtGui/QListView>
#include <QtGui/QSortFilterProxyModel>
......@@ -49,6 +55,7 @@
#include <QtGui/QMenu>
#include <QtGui/QFileDialog>
#include <QtGui/QContextMenuEvent>
#include <QtGui/QMessageBox>
enum { debug = 0 };
......@@ -263,8 +270,14 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev)
QMenu menu;
// Open current item
const QModelIndex current = currentItem();
const bool hasCurrentItem = current.isValid();
QAction *actionOpen = menu.addAction(actionOpenText(m_fileSystemModel, current));
actionOpen->setEnabled(current.isValid());
actionOpen->setEnabled(hasCurrentItem);
// Explorer & teminal
QAction *actionExplorer = menu.addAction(msgGraphicalShellAction());
actionExplorer->setEnabled(hasCurrentItem);
QAction *actionTerminal = menu.addAction(msgTerminalAction());
actionTerminal->setEnabled(hasCurrentItem);
// Open file dialog to choose a path starting from current
QAction *actionChooseFolder = menu.addAction(tr("Choose folder..."));
......@@ -281,7 +294,114 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev)
const QString newPath = QFileDialog::getExistingDirectory(this, tr("Choose folder"), currentDirectory());
if (!newPath.isEmpty())
setCurrentDirectory(newPath);
return;
}
if (action == actionTerminal) {
openTerminal(m_fileSystemModel->filePath(current));
return;
}
if (action == actionExplorer) {
showInGraphicalShell(this, m_fileSystemModel->filePath(current));
return;
}
}
QString FolderNavigationWidget::msgGraphicalShellAction()
{
#if defined(Q_OS_WIN)
return tr("Show in Explorer...");
#elif defined(Q_OS_MAC)
return tr("Show in Finder...");
#else
return tr("Show containing folder...");
#endif
}
QString FolderNavigationWidget::msgTerminalAction()
{
#ifdef Q_OS_WIN
return tr("Open Command Prompt here...");
#else
return tr("Open Terminal here...");
#endif
}
// Show error with option to open settings.
static inline void showGraphicalShellError(QWidget *parent,
const QString &app,
const QString &error)
{
const QString title = FolderNavigationWidget::tr("Launching a file browser failed");
const QString msg = FolderNavigationWidget::tr("Unable to start the file manager:\n\n%1\n\n").arg(app);
QMessageBox mbox(QMessageBox::Warning, title, msg, QMessageBox::Close, parent);
if (!error.isEmpty())
mbox.setDetailedText(FolderNavigationWidget::tr("'%1' returned the following error:\n\n%2").arg(app, error));
QAbstractButton *settingsButton = mbox.addButton(FolderNavigationWidget::tr("Settings..."), QMessageBox::ActionRole);
mbox.exec();
if (mbox.clickedButton() == settingsButton)
Core::ICore::instance()->showOptionsDialog(QLatin1String(Core::Constants::SETTINGS_CATEGORY_CORE),
QLatin1String(Core::Constants::SETTINGS_ID_ENVIRONMENT));
}
void FolderNavigationWidget::showInGraphicalShell(QWidget *parent, const QString &pathIn)
{
Q_UNUSED(parent)
// Mac, Windows support folder or file.
#if defined(Q_OS_WIN)
const QString explorer = Environment::systemEnvironment().searchInPath(QLatin1String("explorer.exe"));
if (explorer.isEmpty()) {
QMessageBox::warning(parent,
tr("Launching Windows Explorer failed"),
tr("Could not find explorer.exe in path to launch Windows Explorer."));
return;
}
QProcess::startDetached(explorer, QStringList(QLatin1String("/select,") + QDir::toNativeSeparators(pathIn)));
#elif defined(Q_OS_MAC)
QStringList scriptArgs;
scriptArgs << QLatin1String("-e")
<< QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"")
.arg(pathIn);
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
scriptArgs.clear();
scriptArgs << QLatin1String("-e")
<< QLatin1String("tell application \"Finder\" to activate");
QProcess::execute("/usr/bin/osascript", scriptArgs);
#else
// we cannot select a file here, because no file browser really supports it...
const QFileInfo fileInfo(pathIn);
const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.absolutePath();
const QString app = Utils::UnixUtils::fileBrowser(Core::ICore::instance()->settings());
QProcess browserProc;
const QString browserArgs = Utils::UnixUtils::substituteFileBrowserParameters(app, folder);
if (debug)
qDebug() << browserArgs;
bool success = browserProc.startDetached(browserArgs);
const QString error = QString::fromLocal8Bit(browserProc.readAllStandardError());
success = success && error.isEmpty();
if (!success)
showGraphicalShellError(parent, app, error);
#endif
}
void FolderNavigationWidget::openTerminal(const QString &path)
{
// Get terminal application
#ifdef Q_OS_WIN
const QString terminalEmulator = QString::fromLocal8Bit(qgetenv("COMSPEC"));
const QStringList args; // none
#else
QStringList args = Utils::ConsoleProcess::terminalEmulator(
Core::ICore::instance()->settings()).split(QLatin1Char(' '));
const QString terminalEmulator = args.takeFirst();
const QString shell = QString::fromLocal8Bit(qgetenv("SHELL"));
args.append(shell);
#endif
// Launch terminal with working directory set.
const QFileInfo fileInfo(path);
const QString pwd = QDir::toNativeSeparators(fileInfo.isDir() ?
fileInfo.absoluteFilePath() :
fileInfo.absolutePath());
QProcess::startDetached(terminalEmulator, args, pwd);
}
// --------------------FolderNavigationWidgetFactory
......
......@@ -60,7 +60,12 @@ public:
bool autoSynchronization() const;
void setAutoSynchronization(bool sync);
QString currentFolder() const;
// Helpers for common directory browser options.
static void showInGraphicalShell(QWidget *parent, const QString &path);
static void openTerminal(const QString &path);
// Platform-dependent action descriptions
static QString msgGraphicalShellAction();
static QString msgTerminalAction();
public slots:
void toggleAutoSynchronization();
......
......@@ -86,7 +86,6 @@
#include <utils/consoleprocess.h>
#include <utils/qtcassert.h>
#include <utils/parameteraction.h>
#include <utils/unixutils.h>
#include <QtCore/QtPlugin>
#include <QtCore/QDateTime>
......@@ -489,24 +488,13 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
globalcontext);
mfilec->addAction(cmd, Constants::G_FILE_OPEN);
#if defined(Q_OS_WIN)
d->m_showInGraphicalShell = new QAction(tr("Show in Explorer..."), this);
#elif defined(Q_OS_MAC)
d->m_showInGraphicalShell = new QAction(tr("Show in Finder..."), this);
#else
d->m_showInGraphicalShell = new QAction(tr("Show containing folder..."), this);
#endif
#ifdef Q_OS_WIN
d->m_openTerminalHere = new QAction(tr("Open Command Prompt here..."), this);
#else
d->m_openTerminalHere = new QAction(tr("Open Terminal here..."), this);
#endif
d->m_showInGraphicalShell = new QAction(FolderNavigationWidget::msgGraphicalShellAction(), this);
cmd = am->registerAction(d->m_showInGraphicalShell, ProjectExplorer::Constants::SHOWINGRAPHICALSHELL,
globalcontext);
mfilec->addAction(cmd, Constants::G_FILE_OPEN);
mfolder->addAction(cmd, Constants::G_FOLDER_FILES);
d->m_openTerminalHere = new QAction(FolderNavigationWidget::msgTerminalAction(), this);
cmd = am->registerAction(d->m_openTerminalHere, ProjectExplorer::Constants::OPENTERMIANLHERE,
globalcontext);
mfilec->addAction(cmd, Constants::G_FILE_OPEN);
......@@ -1895,71 +1883,17 @@ void ProjectExplorerPlugin::openFile()
em->ensureEditorManagerVisible();
}
void ProjectExplorerPlugin::graphicalShellHasError(const QString &app, const QString &error)
{
QWidget *w = Core::ICore::instance()->mainWindow();
QMessageBox mbox(w);
mbox.setIcon(QMessageBox::Warning);
mbox.setWindowTitle(tr("Launching a file browser failed"));
mbox.setText(tr("Unable to start the file manager:\n\n%1\n\n"
"Do you want to change the current file manager?").arg(app));
if (!error.isEmpty()) {
mbox.setDetailedText(tr("'%1' returned the following error:\n\n%2").arg(app, error));
}
if (mbox.exec() == QMessageBox::Accepted)
Core::ICore::instance()->showOptionsDialog("environment", QString(), w);
}
void ProjectExplorerPlugin::showInGraphicalShell()
{
QTC_ASSERT(d->m_currentNode, return)
#if defined(Q_OS_WIN)
const QString explorer = Environment::systemEnvironment().searchInPath("explorer.exe");
if (explorer.isEmpty()) {
QMessageBox::warning(Core::ICore::instance()->mainWindow(),
tr("Launching Windows Explorer failed"),
tr("Could not find explorer.exe in path to launch Windows Explorer."));
return;
}
QProcess::startDetached(explorer, QStringList(QLatin1String("/select,") + QDir::toNativeSeparators(d->m_currentNode->path())));
#elif defined(Q_OS_MAC)
QProcess::execute("/usr/bin/osascript", QStringList()
<< "-e"
<< QString("tell application \"Finder\" to reveal POSIX file \"%1\"")
.arg(d->m_currentNode->path()));
QProcess::execute("/usr/bin/osascript", QStringList()
<< "-e"
<< "tell application \"Finder\" to activate");
#else
// we cannot select a file here, because no file browser really supports it...
const QFileInfo fileInfo(d->m_currentNode->path());
QString app = Utils::UnixUtils::fileBrowser(Core::ICore::instance()->settings());
QProcess browserProc;
bool success = browserProc.startDetached(Utils::UnixUtils::substituteFileBrowserParameters(app, fileInfo.filePath()));
QString error = QString::fromLocal8Bit(browserProc.readAllStandardError());
success = success && error.isEmpty();
if (!success) {
graphicalShellHasError(app, error);
}
#endif
FolderNavigationWidget::showInGraphicalShell(Core::ICore::instance()->mainWindow(),
d->m_currentNode->path());
}
void ProjectExplorerPlugin::openTerminalHere()
{
#ifdef Q_OS_WIN
const QString terminalEmulator = QString::fromLocal8Bit(qgetenv("COMSPEC"));
const QStringList args; // none
#else
QStringList args = Utils::ConsoleProcess::terminalEmulator(
Core::ICore::instance()->settings()).split(QLatin1Char(' '));
const QString terminalEmulator = args.takeFirst();
const QString shell = QString::fromLocal8Bit(qgetenv("SHELL"));
args.append(shell);
#endif
const QFileInfo fileInfo(d->m_currentNode->path());
const QString pwd = QDir::toNativeSeparators(fileInfo.path());
QProcess::startDetached(terminalEmulator, args, pwd);
QTC_ASSERT(d->m_currentNode, return)
FolderNavigationWidget::openTerminal(d->m_currentNode->path());
}
void ProjectExplorerPlugin::removeFile()
......
......@@ -217,7 +217,6 @@ private slots:
void currentModeChanged(Core::IMode *mode);
private:
void graphicalShellHasError(const QString &app, const QString &error);
void runProjectImpl(Project *pro, QString mode);
void executeRunConfiguration(RunConfiguration *, const QString &mode);
bool showBuildConfigDialog();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment