void ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, Utils::ProcessLinkCallback &&processLinkCallback, bool /*resolveTarget*/, bool /*inNextSplit*/) { Link link; int line = 0; int column = 0; convertPosition(cursor.position(), &line, &column); const int positionInBlock = column - 1; 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 processLinkCallback(link); // find the beginning of a filename QString buffer; int beginPos = positionInBlock - 1; int endPos = positionInBlock; // Check is cursor is somewhere on $${PWD}: const int chunkStart = std::max(0, positionInBlock - 7); const int chunkLength = 14 + std::min(0, positionInBlock - 7); QString chunk = block.mid(chunkStart, chunkLength); const QString curlyPwd = "$${PWD}"; const QString pwd = "$$PWD"; const int posCurlyPwd = chunk.indexOf(curlyPwd); const int posPwd = chunk.indexOf(pwd); bool doBackwardScan = true; if (posCurlyPwd >= 0) { const int end = chunkStart + posCurlyPwd + curlyPwd.count(); const int start = chunkStart + posCurlyPwd; if (start <= positionInBlock && end >= positionInBlock) { buffer = pwd; beginPos = chunkStart + posCurlyPwd - 1; endPos = end; doBackwardScan = false; } } else if (posPwd >= 0) { const int end = chunkStart + posPwd + pwd.count(); const int start = chunkStart + posPwd; if (start <= positionInBlock && end >= positionInBlock) { buffer = pwd; beginPos = start - 1; endPos = end; doBackwardScan = false; } } while (doBackwardScan && beginPos >= 0) { QChar c = block.at(beginPos); if (isValidFileNameChar(c)) { buffer.prepend(c); beginPos--; } else { break; } } if (doBackwardScan && beginPos > 0 && block.mid(beginPos - 1, pwd.count()) == pwd && (block.at(beginPos + pwd.count() - 1) == '/' || block.at(beginPos + pwd.count() - 1) == '\\')) { buffer.prepend("$$"); beginPos -= 2; } else if (doBackwardScan && beginPos >= curlyPwd.count() - 1 && block.mid(beginPos - curlyPwd.count() + 1, curlyPwd.count()) == curlyPwd) { buffer.prepend(pwd); beginPos -= curlyPwd.count(); } // find the end of a filename while (endPos < block.count()) { QChar c = block.at(endPos); if (isValidFileNameChar(c)) { buffer.append(c); endPos++; } else { break; } } if (buffer.isEmpty()) return processLinkCallback(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("$$PWD/") || buffer.startsWith("$$PWD\\")) buffer = buffer.mid(6); QDir dir(textDocument()->filePath().toFileInfo().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::exists(subProject)) fileName = subProject; else return processLinkCallback(link); } link.targetFileName = QDir::cleanPath(fileName); link.linkTextStart = cursor.position() - positionInBlock + beginPos + 1; link.linkTextEnd = cursor.position() - positionInBlock + endPos; } processLinkCallback(link); }
ProFileEditorWidget::Link ProFileEditorWidget::findLinkAt(const QTextCursor &cursor, bool /*resolveTarget*/, bool /*inNextSplit*/) { 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(textDocument()->filePath()).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::exists(subProject)) fileName = subProject; else return link; } link.targetFileName = QDir::cleanPath(fileName); link.linkTextStart = cursor.position() - positionInBlock + beginPos + 1; link.linkTextEnd = cursor.position() - positionInBlock + endPos; } return link; }
CMakeEditorWidget::Link CMakeEditorWidget::findLinkAt(const QTextCursor &cursor, bool/* resolveTarget*/, bool /*inNextSplit*/) { 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; // TODO: Resolve variables QDir dir(textDocument()->filePath().toFileInfo().absolutePath()); QString fileName = dir.filePath(buffer); QFileInfo fi(fileName); if (fi.exists()) { if (fi.isDir()) { QDir subDir(fi.absoluteFilePath()); QString subProject = subDir.filePath(QLatin1String("CMakeLists.txt")); if (QFileInfo::exists(subProject)) fileName = subProject; else return link; } link.targetFileName = fileName; link.linkTextStart = cursor.position() - positionInBlock + beginPos + 1; link.linkTextEnd = cursor.position() - positionInBlock + endPos; } return link; }