Commit 4cac9644 authored by Francois Ferrand's avatar Francois Ferrand Committed by Eike Ziller
Browse files

Allow specifying line number when selecting a file with the locator.



When using the file selections locators (OpenDocumentsFilter, FileSystemFilter,
and those inherited from BaseFileFilter), allow specifying the line where to open
the file: like 'file.cpp:654'.

This syntax works for wildcards/incomplete expression as well: toto:423 will match
'toto', and open resulting file at line 423.

Also, fix line extraction in editormanager, to support a single semicolon (without
number) as well as a line explicitely set to 0.

Change-Id: I80e13b59aa9c972f33963cfee81ec04f277fe526
Reviewed-by: default avatarFriedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: default avatarEike Ziller <eike.ziller@nokia.com>
parent 69552f01
......@@ -1218,7 +1218,7 @@ IEditor *EditorManager::openEditor(const QString &fileName, const Id &editorId,
return m_instance->openEditor(m_instance->currentEditorView(), fileName, editorId, flags, newEditor);
}
int extractLineNumber(QString *fileName)
static int extractLineNumber(QString *fileName)
{
int i = fileName->length() - 1;
for (; i >= 0; --i) {
......@@ -1229,7 +1229,10 @@ int extractLineNumber(QString *fileName)
return -1;
const QChar c = fileName->at(i);
if (c == QLatin1Char(':') || c == QLatin1Char('+')) {
if (const int result = fileName->mid(i + 1).toInt()) {
bool ok;
const QString suffix = fileName->mid(i + 1);
const int result = suffix.toInt(&ok);
if (suffix.isEmpty() || ok) {
fileName->truncate(i);
return result;
}
......@@ -1237,6 +1240,29 @@ int extractLineNumber(QString *fileName)
return -1;
}
// Extract line number suffix. Return the suffix (e.g. ":132") and truncates the filename accordingly.
QString EditorManager::splitLineNumber(QString *fileName)
{
int i = fileName->length() - 1;
for (; i >= 0; --i) {
if (!fileName->at(i).isNumber())
break;
}
if (i == -1)
return QString();
const QChar c = fileName->at(i);
if (c == QLatin1Char(':') || c == QLatin1Char('+')) {
const QString result = fileName->mid(i + 1);
bool ok;
result.toInt(&ok);
if (result.isEmpty() || ok) {
fileName->truncate(i);
return QString(c) + result;
}
}
return QString();
}
static QString autoSaveName(const QString &fileName)
{
return fileName + QLatin1String(".autosave");
......
......@@ -117,6 +117,7 @@ public:
};
Q_DECLARE_FLAGS(OpenEditorFlags, OpenEditorFlag)
static QString splitLineNumber(QString *fileName);
static IEditor *openEditor(const QString &fileName, const Id &editorId = Id(),
OpenEditorFlags flags = 0, bool *newEditor = 0);
static IEditor *openEditorWithContents(const Id &editorId,
......
......@@ -51,6 +51,7 @@ QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEn
QList<FilterEntry> matches;
QList<FilterEntry> badMatches;
QString needle = trimWildcards(origEntry);
const QString lineNoSuffix = EditorManager::splitLineNumber(&needle);
QStringMatcher matcher(needle, Qt::CaseInsensitive);
const QChar asterisk = QLatin1Char('*');
QRegExp regexp(asterisk + needle+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard);
......@@ -81,7 +82,7 @@ QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEn
if ((hasWildcard && regexp.exactMatch(name))
|| (!hasWildcard && matcher.indexIn(name) != -1)) {
QFileInfo fi(path);
FilterEntry entry(this, fi.fileName(), path);
FilterEntry entry(this, fi.fileName(), QString(path + lineNoSuffix));
entry.extraInfo = QDir::toNativeSeparators(fi.path());
entry.resolveFileIcon = true;
if (name.startsWith(needle))
......@@ -99,7 +100,8 @@ QList<FilterEntry> BaseFileFilter::matchesFor(QFutureInterface<Locator::FilterEn
void BaseFileFilter::accept(Locator::FilterEntry selection) const
{
EditorManager::openEditor(selection.internalData.toString(), Id(), EditorManager::ModeSwitch);
EditorManager::openEditor(selection.internalData.toString(), Id(),
EditorManager::ModeSwitch | EditorManager::CanContainLineNumber);
}
void BaseFileFilter::generateFileNames()
......
......@@ -48,9 +48,11 @@ FileSystemFilter::FileSystemFilter(EditorManager *editorManager, LocatorWidget *
setIncludedByDefault(false);
}
QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry_)
{
QList<FilterEntry> value;
QString entry = entry_;
const QString lineNoSuffix = EditorManager::splitLineNumber(&entry);
QFileInfo entryInfo(entry);
QString name = entryInfo.fileName();
QString directory = entryInfo.path();
......@@ -81,7 +83,8 @@ QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::Filter
if (future.isCanceled())
break;
if (dir != QLatin1String(".") && (name.isEmpty() || dir.startsWith(name, Qt::CaseInsensitive))) {
FilterEntry filterEntry(this, dir, dirInfo.filePath(dir));
const QString fullPath = dirInfo.filePath(dir);
FilterEntry filterEntry(this, dir, QString(fullPath + lineNoSuffix));
filterEntry.resolveFileIcon = true;
value.append(filterEntry);
}
......@@ -91,7 +94,7 @@ QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::Filter
break;
if (name.isEmpty() || file.startsWith(name, Qt::CaseInsensitive)) {
const QString fullPath = dirInfo.filePath(file);
FilterEntry filterEntry(this, file, fullPath);
FilterEntry filterEntry(this, file, QString(fullPath + lineNoSuffix));
filterEntry.resolveFileIcon = true;
value.append(filterEntry);
}
......@@ -101,16 +104,20 @@ QList<FilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Locator::Filter
void FileSystemFilter::accept(FilterEntry selection) const
{
QFileInfo info(selection.internalData.toString());
QString file = selection.internalData.toString();
const QString lineNoSuffix = EditorManager::splitLineNumber(&file);
QFileInfo info(file);
if (info.isDir()) {
QString value = shortcutString();
value += QLatin1Char(' ');
value += QDir::toNativeSeparators(info.absoluteFilePath() + QLatin1Char('/'));
value += lineNoSuffix;
m_locatorWidget->show(value, value.length());
return;
}
EditorManager::openEditor(selection.internalData.toString(), Id(),
EditorManager::ModeSwitch);
EditorManager::ModeSwitch | EditorManager::CanContainLineNumber);
}
bool FileSystemFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
......
......@@ -43,6 +43,7 @@
#include <coreplugin/modemanager.h>
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/fileiconprovider.h>
#include <utils/filterlineedit.h>
......@@ -189,8 +190,9 @@ QVariant LocatorModel::data(const QModelIndex &index, int role) const
FilterEntry &entry = mEntries[index.row()];
if (entry.resolveFileIcon && entry.displayIcon.isNull()) {
entry.resolveFileIcon = false;
entry.displayIcon =
Core::FileIconProvider::instance()->icon(QFileInfo(entry.internalData.toString()));
QString path = entry.internalData.toString();
Core::EditorManager::splitLineNumber(&path);
entry.displayIcon = Core::FileIconProvider::instance()->icon(QFileInfo(path));
}
return entry.displayIcon;
} else if (role == Qt::ForegroundRole && index.column() == 1) {
......
......@@ -53,9 +53,11 @@ OpenDocumentsFilter::OpenDocumentsFilter(EditorManager *editorManager) :
setIncludedByDefault(true);
}
QList<FilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry)
QList<FilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry_)
{
QList<FilterEntry> value;
QString entry = entry_;
const QString lineNoSuffix = EditorManager::splitLineNumber(&entry);
const QChar asterisk = QLatin1Char('*');
QString pattern = QString(asterisk);
pattern += entry;
......@@ -71,7 +73,7 @@ QList<FilterEntry> OpenDocumentsFilter::matchesFor(QFutureInterface<Locator::Fil
if (regexp.exactMatch(displayName)) {
if (!fileName.isEmpty()) {
QFileInfo fi(fileName);
FilterEntry fiEntry(this, fi.fileName(), fileName);
FilterEntry fiEntry(this, fi.fileName(), QString(fileName + lineNoSuffix));
fiEntry.extraInfo = QDir::toNativeSeparators(fi.path());
fiEntry.resolveFileIcon = true;
value.append(fiEntry);
......@@ -102,5 +104,6 @@ void OpenDocumentsFilter::refresh(QFutureInterface<void> &future)
void OpenDocumentsFilter::accept(FilterEntry selection) const
{
EditorManager::openEditor(selection.internalData.toString(), Id(), EditorManager::ModeSwitch);
EditorManager::openEditor(selection.internalData.toString(), Id(),
EditorManager::ModeSwitch | EditorManager::CanContainLineNumber);
}
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