diff --git a/src/plugins/qt4projectmanager/profileeditor.cpp b/src/plugins/qt4projectmanager/profileeditor.cpp index d7cf57278afc8714762b483bb2b76a3df5183e5a..21a66776e657498eb42371f62007cde65fe1c19e 100644 --- a/src/plugins/qt4projectmanager/profileeditor.cpp +++ b/src/plugins/qt4projectmanager/profileeditor.cpp @@ -44,6 +44,7 @@ #include <texteditor/texteditorsettings.h> #include <QtCore/QFileInfo> +#include <QtCore/QDir> #include <QtGui/QMenu> using namespace Qt4ProjectManager; @@ -107,6 +108,95 @@ void ProFileEditor::unCommentSelection() Utils::unCommentSelection(this, m_commentDefinition); } +static bool isValidFileNameChar(const QChar &c) +{ + if (c.isLetterOrNumber() + || c == QLatin1Char('.') + || c == QLatin1Char('_') + || c == QLatin1Char('-') + || c == QLatin1Char('/') + || c == QLatin1Char('\\')) + return true; + return false; +} + +ProFileEditor::Link ProFileEditor::findLinkAt(const QTextCursor &cursor, + bool resolveTarget) +{ + Link link; + + int lineNumber = 0, positionInBlock = 0; + convertPosition(cursor.position(), &lineNumber, &positionInBlock); + + const QString block = cursor.block().text(); + + // check if the current position is commented out + const int hashPos = block.indexOf(QLatin1Char('#')); + if (hashPos >= 0 && hashPos < positionInBlock) + return link; + + // find the beginning of a filename + QString buffer; + int beginPos = positionInBlock - 1; + while (beginPos >= 0) { + QChar c = block.at(beginPos); + if (isValidFileNameChar(c)) { + buffer.prepend(c); + beginPos--; + } else { + break; + } + } + + // find the end of a filename + int endPos = positionInBlock; + while (endPos < block.count()) { + QChar c = block.at(endPos); + if (isValidFileNameChar(c)) { + buffer.append(c); + endPos++; + } else { + break; + } + } + + if (buffer.isEmpty()) + return link; + + // remove trailing '\' since it can be line continuation char + if (buffer.at(buffer.size() - 1) == QLatin1Char('\\')) { + buffer.chop(1); + endPos--; + } + + // if the buffer starts with $$PWD accept it + if (buffer.startsWith(QLatin1String("PWD/")) || + buffer.startsWith(QLatin1String("PWD\\"))) { + if (beginPos > 0 && block.mid(beginPos - 1, 2) == QLatin1String("$$")) { + beginPos -=2; + buffer = buffer.mid(4); + } + } + + QDir dir(QFileInfo(file()->fileName()).absolutePath()); + QString fileName = dir.filePath(buffer); + QFileInfo fi(fileName); + if (fi.exists()) { + if (fi.isDir()) { + QDir subDir(fi.absoluteFilePath()); + QString subProject = subDir.filePath(subDir.dirName() + QLatin1String(".pro")); + if (QFileInfo(subProject).exists()) + fileName = subProject; + else + return link; + } + link.fileName = fileName; + link.begin = cursor.position() - positionInBlock + beginPos + 1; + link.end = cursor.position() - positionInBlock + endPos; + } + return link; +} + TextEditor::BaseTextEditorEditable *ProFileEditor::createEditableInterface() { return new ProFileEditorEditable(this); @@ -169,6 +259,11 @@ void ProFileEditor::addLibrary() editable->insert(snippet); } +void ProFileEditor::jumpToFile() +{ + openLink(findLinkAt(textCursor())); +} + // // ProFileDocument // diff --git a/src/plugins/qt4projectmanager/profileeditor.h b/src/plugins/qt4projectmanager/profileeditor.h index 025cd5edabedc2d279ff8332dfcb2512869b62d5..1dc9733e23a0aa70dd77c7c654873fdf2034d919 100644 --- a/src/plugins/qt4projectmanager/profileeditor.h +++ b/src/plugins/qt4projectmanager/profileeditor.h @@ -82,12 +82,14 @@ public: void unCommentSelection(); protected: + virtual Link findLinkAt(const QTextCursor &, bool resolveTarget = true); TextEditor::BaseTextEditorEditable *createEditableInterface(); void contextMenuEvent(QContextMenuEvent *); public slots: virtual void setFontSettings(const TextEditor::FontSettings &); void addLibrary(); + void jumpToFile(); private: ProFileEditorFactory *m_factory; diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h b/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h index db3b1719f89d5406c833be113a15010ef76dba76..7dfb1132ad3e174f18dbe386ee79c69e85b826e3 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h +++ b/src/plugins/qt4projectmanager/qt4projectmanagerconstants.h @@ -65,6 +65,8 @@ const char * const BUILDSUBDIR = "Qt4Builder.BuildSubDir"; const char * const REBUILDSUBDIR = "Qt4Builder.RebuildSubDir"; const char * const CLEANSUBDIR = "Qt4Builder.CleanSubDir"; const char * const ADDLIBRARY = "Qt4.AddLibrary"; +const char * const JUMP_TO_FILE = "Qt4.JumpToFile"; +const char * const SEPARATOR = "Qt4.Separator"; //configurations const char * const CONFIG_DEBUG = "debug"; diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp index 6f926c4fd57b41937b431bb8b211cc69c0bce28b..68919a58d5641ef92834b5371f367aaa3e491eb3 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp +++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.cpp @@ -232,19 +232,31 @@ bool Qt4ProjectManagerPlugin::initialize(const QStringList &arguments, QString * Core::Command *cmd; - cmd = am->command(TextEditor::Constants::UN_COMMENT_SELECTION); - contextMenu->addAction(cmd); - Core::Context proFileEditorContext = Core::Context(Qt4ProjectManager::Constants::PROJECT_ID); + QAction *jumpToFile = new QAction(tr("Jump to File Under Cursor"), this); + cmd = am->registerAction(jumpToFile, + Constants::JUMP_TO_FILE, proFileEditorContext); + cmd->setDefaultKeySequence(QKeySequence(Qt::Key_F2)); + connect(jumpToFile, SIGNAL(triggered()), + this, SLOT(jumpToFile())); + contextMenu->addAction(cmd); + QAction *addLibrary = new QAction(tr("Add Library..."), this); cmd = am->registerAction(addLibrary, Constants::ADDLIBRARY, proFileEditorContext); - //cmd->setDefaultKeySequence(QKeySequence(Qt::Key_F2)); connect(addLibrary, SIGNAL(triggered()), this, SLOT(addLibrary())); contextMenu->addAction(cmd); + QAction *separator = new QAction(this); + separator->setSeparator(true); + contextMenu->addAction(am->registerAction(separator, + Core::Id(Constants::SEPARATOR), proFileEditorContext)); + + cmd = am->command(TextEditor::Constants::UN_COMMENT_SELECTION); + contextMenu->addAction(cmd); + return true; } @@ -306,6 +318,14 @@ void Qt4ProjectManagerPlugin::addLibrary() editor->addLibrary(); } +void Qt4ProjectManagerPlugin::jumpToFile() +{ + Core::EditorManager *em = Core::EditorManager::instance(); + ProFileEditor *editor = qobject_cast<ProFileEditor*>(em->currentEditor()->widget()); + if (editor) + editor->jumpToFile(); +} + #ifdef WITH_TESTS void Qt4ProjectManagerPlugin::testBasicProjectLoading() { diff --git a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h index f05803e11db8a9e1873f2771e4dba5a88549a9d5..f2f8164325c6f1ca99821b38e3d8b94283a2a062 100644 --- a/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h +++ b/src/plugins/qt4projectmanager/qt4projectmanagerplugin.h @@ -75,6 +75,7 @@ private slots: void currentProjectChanged(); void buildStateChanged(ProjectExplorer::Project *pro); void addLibrary(); + void jumpToFile(); #ifdef WITH_TESTS void testBasicProjectLoading(); // Test fails! diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index bd9e67274e53a0d9821ad13380fc0297c689afc2..7259b1b615968e4e82e005fdcf13bb4e91e71254 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -4304,7 +4304,9 @@ bool BaseTextEditor::openLink(const Link &link) return true; } - return openEditorAt(link.fileName, link.line, link.column); + return openEditorAt(link.fileName, link.line, link.column, QString(), + Core::EditorManager::IgnoreNavigationHistory + | Core::EditorManager::ModeSwitch); } void BaseTextEditor::updateLink(QMouseEvent *e)