work save: cpp parser done
This commit is contained in:
parent
9da351dfda
commit
41b9c53146
|
@ -16,9 +16,7 @@ CppParser::CppParser(QObject *parent) : QObject(parent)
|
|||
mUniqId = 0;
|
||||
mParsing = false;
|
||||
//mStatementList ; // owns the objects
|
||||
mIncludesList = std::make_shared<QHash<QString,PFileIncludes>>();
|
||||
//mFilesToScan;
|
||||
mScannedFiles = std::make_shared<QSet<QString>>();
|
||||
//mIncludePaths;
|
||||
//mProjectIncludePaths;
|
||||
//mProjectFiles;
|
||||
|
@ -115,7 +113,7 @@ PStatement CppParser::findAndScanBlockAt(const QString &filename, int line)
|
|||
QMutexLocker locker(&mMutex);
|
||||
if (mParsing)
|
||||
return PStatement();
|
||||
PFileIncludes fileIncludes = mIncludesList->value(filename);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename);
|
||||
if (!fileIncludes)
|
||||
return PStatement();
|
||||
|
||||
|
@ -127,9 +125,9 @@ PStatement CppParser::findAndScanBlockAt(const QString &filename, int line)
|
|||
PFileIncludes CppParser::findFileIncludes(const QString &filename, bool deleteIt)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
PFileIncludes fileIncludes = mIncludesList->value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
if (deleteIt && fileIncludes)
|
||||
mIncludesList->remove(filename);
|
||||
mPreprocessor.includesList().remove(filename);
|
||||
return fileIncludes;
|
||||
}
|
||||
|
||||
|
@ -163,7 +161,7 @@ QString CppParser::findFirstTemplateParamOf(const QString &fileName, const QStri
|
|||
PStatement CppParser::findFunctionAt(const QString &fileName, int line)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
PFileIncludes fileIncludes = mIncludesList->value(fileName);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName);
|
||||
if (!fileIncludes)
|
||||
return PStatement();
|
||||
for (PStatement statement : fileIncludes->statements) {
|
||||
|
@ -489,7 +487,7 @@ QSet<QString> CppParser::getFileDirectIncludes(const QString &filename)
|
|||
return list;
|
||||
if (filename.isEmpty())
|
||||
return list;
|
||||
PFileIncludes fileIncludes = mIncludesList->value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
|
||||
if (fileIncludes) {
|
||||
QMap<QString, bool>::const_iterator iter = fileIncludes->includeFiles.cbegin();
|
||||
|
@ -511,7 +509,7 @@ QSet<QString> CppParser::getFileIncludes(const QString &filename)
|
|||
if (filename.isEmpty())
|
||||
return list;
|
||||
list.insert(filename);
|
||||
PFileIncludes fileIncludes = mIncludesList->value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
|
||||
if (fileIncludes) {
|
||||
for (QString file: fileIncludes->includeFiles.keys()) {
|
||||
|
@ -528,7 +526,7 @@ QSet<QString> CppParser::getFileUsings(const QString &filename)
|
|||
return QSet<QString>();
|
||||
if (mParsing)
|
||||
return QSet<QString>();
|
||||
PFileIncludes fileIncludes= mIncludesList->value(filename,PFileIncludes());
|
||||
PFileIncludes fileIncludes= mPreprocessor.includesList().value(filename,PFileIncludes());
|
||||
if (fileIncludes) {
|
||||
return fileIncludes->usings;
|
||||
}
|
||||
|
@ -572,6 +570,17 @@ void CppParser::invalidateFile(const QString &fileName)
|
|||
mParsing = false;
|
||||
}
|
||||
|
||||
bool CppParser::isIncludeLine(const QString &line)
|
||||
{
|
||||
QString trimmedLine = line.trimmed();
|
||||
if ((trimmedLine.length() > 0)
|
||||
&& trimmedLine.startsWith('#')) { // it's a preprocessor line
|
||||
if (trimmedLine.mid(1).trimmed().startsWith("include"))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CppParser::isProjectHeaderFile(const QString &fileName)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
|
@ -651,58 +660,154 @@ void CppParser::parseFileList(bool updateView)
|
|||
{
|
||||
if (!mEnabled)
|
||||
return;
|
||||
if not fEnabled then
|
||||
Exit;
|
||||
fCriticalSection.Acquire;
|
||||
try
|
||||
if fParsing or (fLockCount>0) then
|
||||
Exit;
|
||||
UpdateSerialId;
|
||||
fParsing:=True;
|
||||
OnBusy;
|
||||
OnStartParsing;
|
||||
finally
|
||||
fCriticalSection.Release;
|
||||
end;
|
||||
try
|
||||
// Support stopping of parsing when files closes unexpectedly
|
||||
fFilesScannedCount := 0;
|
||||
fFilesToScanCount := fFilesToScan.Count;
|
||||
// parse header files in the first parse
|
||||
for i:=0 to fFilesToScan.Count-1 do begin
|
||||
if IsCFile(fFilesToScan[i]) then
|
||||
continue;
|
||||
Inc(fFilesScannedCount); // progress is mentioned before scanning begins
|
||||
OnProgress(fCurrentFile,fFilesToScanCount,fFilesScannedCount);
|
||||
if FastIndexOf(fScannedFiles,fFilesToScan[i]) = -1 then begin
|
||||
InternalParse(fFilesToScan[i]);
|
||||
end;
|
||||
end;
|
||||
//we only parse CFile in the second parse
|
||||
for i:=0 to fFilesToScan.Count-1 do begin
|
||||
if not IsCFile(fFilesToScan[i]) then
|
||||
continue;
|
||||
Inc(fFilesScannedCount); // progress is mentioned before scanning begins
|
||||
OnProgress(fCurrentFile,fFilesToScanCount,fFilesScannedCount);
|
||||
if FastIndexOf(fScannedFiles,fFilesToScan[i]) = -1 then begin
|
||||
InternalParse(fFilesToScan[i]);
|
||||
end;
|
||||
end;
|
||||
fFilesToScan.Clear;
|
||||
finally
|
||||
fParsing:=False;
|
||||
if UpdateView then
|
||||
OnEndParsing(fFilesScannedCount,1)
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mParsing || mLockCount>0)
|
||||
return;
|
||||
updateSerialId();
|
||||
mParsing = true;
|
||||
if (updateView)
|
||||
emit onBusy();
|
||||
emit onStartParsing();
|
||||
}
|
||||
{
|
||||
auto action = finally([&,this]{
|
||||
mParsing = false;
|
||||
if (updateView)
|
||||
emit onEndParsing(mFilesScannedCount,1);
|
||||
else
|
||||
OnEndParsing(fFilesScannedCount,0);
|
||||
end;
|
||||
emit onEndParsing(mFilesScannedCount,0);
|
||||
});
|
||||
// Support stopping of parsing when files closes unexpectedly
|
||||
mFilesScannedCount = 0;
|
||||
mFilesToScanCount = mFilesToScan.count();
|
||||
// parse header files in the first parse
|
||||
for (QString file:mFilesToScan) {
|
||||
if (isHfile(file)) {
|
||||
mFilesScannedCount++;
|
||||
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
|
||||
if (!mPreprocessor.scannedFiles().contains(file)) {
|
||||
internalParse(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
//we only parse CFile in the second parse
|
||||
for (QString file:mFilesToScan) {
|
||||
if (isCfile(file)) {
|
||||
mFilesScannedCount++;
|
||||
emit onProgress(mCurrentFile,mFilesToScanCount,mFilesScannedCount);
|
||||
if (!mPreprocessor.scannedFiles().contains(file)) {
|
||||
internalParse(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
mFilesToScan.clear();
|
||||
}
|
||||
}
|
||||
|
||||
bool CppParser::parsing()
|
||||
void CppParser::parseHardDefines()
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (mParsing)
|
||||
return;
|
||||
mParsing=true;
|
||||
{
|
||||
auto action = finally([this]{
|
||||
mParsing = false;
|
||||
});
|
||||
for (PDefine define:mPreprocessor.hardDefines()) {
|
||||
QString hintText = "#define";
|
||||
if (define->name != "")
|
||||
hintText += ' ' + define->name;
|
||||
if (define->args != "")
|
||||
hintText += ' ' + define->args;
|
||||
if (define->value != "")
|
||||
hintText += ' ' + define->value;
|
||||
addStatement(
|
||||
PStatement(), // defines don't belong to any scope
|
||||
"",
|
||||
hintText, // override hint
|
||||
"", // define has no type
|
||||
define->name,
|
||||
define->value,
|
||||
define->args,
|
||||
-1,
|
||||
StatementKind::skPreprocessor,
|
||||
StatementScope::ssGlobal,
|
||||
StatementClassScope::scsNone,
|
||||
true,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CppParser::parsing() const
|
||||
{
|
||||
return mParsing;
|
||||
}
|
||||
|
||||
void CppParser::reset()
|
||||
{
|
||||
while (true) {
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
if (!mParsing && mLockCount ==0) {
|
||||
mParsing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QThread::msleep(50);
|
||||
QCoreApplication* app = QApplication::instance();
|
||||
app->processEvents();
|
||||
}
|
||||
{
|
||||
auto action = finally([this]{
|
||||
mParsing = false;
|
||||
});
|
||||
emit onBusy();
|
||||
mPreprocessor.clear();
|
||||
mUniqId = 0;
|
||||
mSkipList.clear();
|
||||
mBlockBeginSkips.clear();
|
||||
mBlockEndSkips.clear();
|
||||
mInlineNamespaceEndSkips.clear();
|
||||
mParseLocalHeaders = true;
|
||||
mParseGlobalHeaders = true;
|
||||
|
||||
mCurrentScope.clear();
|
||||
mCurrentClassScope.clear();
|
||||
mProjectFiles.clear();
|
||||
mFilesToScan.clear();
|
||||
mTokenizer.reset();
|
||||
// Remove all statements
|
||||
mStatementList.clear();
|
||||
|
||||
// We haven't scanned anything anymore
|
||||
mPreprocessor.scannedFiles().clear();
|
||||
|
||||
// We don't include anything anymore
|
||||
mPreprocessor.includesList().clear();
|
||||
|
||||
mNamespaces.clear();
|
||||
|
||||
mPreprocessor.projectIncludePaths().clear();
|
||||
mPreprocessor.includePaths().clear();
|
||||
mProjectFiles.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void CppParser::unFreeze()
|
||||
{
|
||||
QMutexLocker locker(&mMutex);
|
||||
mLockCount--;
|
||||
}
|
||||
|
||||
QString CppParser::prettyPrintStatement(PStatement statement, int line)
|
||||
{
|
||||
//TODO: implement it
|
||||
return "not implemented yet";
|
||||
}
|
||||
|
||||
QString CppParser::getFirstTemplateParam(PStatement statement, const QString& filename, const QString& phrase, PStatement currentScope)
|
||||
{
|
||||
if (!statement)
|
||||
|
@ -813,12 +918,12 @@ PStatement CppParser::addStatement(PStatement parent, const QString &fileName, c
|
|||
if (oldStatement && isDefinition && !oldStatement->hasDefinition) {
|
||||
oldStatement->hasDefinition = true;
|
||||
if (oldStatement->fileName!=fileName) {
|
||||
PFileIncludes fileIncludes1=mIncludesList->value(fileName);
|
||||
PFileIncludes fileIncludes1=mPreprocessor.includesList().value(fileName);
|
||||
if (fileIncludes1) {
|
||||
fileIncludes1->statements.insert(oldStatement->fullName,
|
||||
oldStatement);
|
||||
fileIncludes1->dependingFiles.insert(oldStatement->fileName);
|
||||
PFileIncludes fileIncludes2=mIncludesList->value(oldStatement->fileName);
|
||||
PFileIncludes fileIncludes2=mPreprocessor.includesList().value(oldStatement->fileName);
|
||||
if (fileIncludes2) {
|
||||
fileIncludes2->dependedFiles.insert(fileName);
|
||||
}
|
||||
|
@ -876,7 +981,7 @@ PStatement CppParser::addStatement(PStatement parent, const QString &fileName, c
|
|||
}
|
||||
|
||||
if (result->kind!= StatementKind::skBlock) {
|
||||
PFileIncludes fileIncludes = mIncludesList->value(fileName);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(fileName);
|
||||
if (fileIncludes) {
|
||||
fileIncludes->statements.insert(result->fullName,result);
|
||||
fileIncludes->declaredStatements.insert(result->fullName,result);
|
||||
|
@ -957,7 +1062,7 @@ void CppParser::addSoloScopeLevel(PStatement statement, int line)
|
|||
|
||||
mCurrentScope.append(statement);
|
||||
|
||||
PFileIncludes fileIncludes = mIncludesList->value(mCurrentFile);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
|
||||
|
||||
if (fileIncludes) {
|
||||
fileIncludes->scopes.addScope(line,statement);
|
||||
|
@ -981,7 +1086,7 @@ void CppParser::removeScopeLevel(int line)
|
|||
if (mCurrentScope.isEmpty())
|
||||
return; // TODO: should be an exception
|
||||
PStatement currentScope = mCurrentScope.back();;
|
||||
PFileIncludes fileIncludes = mIncludesList->value(mCurrentFile);
|
||||
PFileIncludes fileIncludes = mPreprocessor.includesList().value(mCurrentFile);
|
||||
if (currentScope && (currentScope->kind == StatementKind::skBlock)) {
|
||||
if (currentScope->children.isEmpty()) {
|
||||
// remove no children block
|
||||
|
@ -1482,6 +1587,7 @@ PStatement CppParser::getTypeDef(PStatement statement, const QString& fileName,
|
|||
PStatement result = findTypeDefinitionOf(fileName,statement->type, statement->parentScope.lock());
|
||||
if (!result) // found end of typedef trail, return result
|
||||
return statement;
|
||||
return result;
|
||||
} else
|
||||
return PStatement();
|
||||
}
|
||||
|
@ -1764,7 +1870,7 @@ void CppParser::handleMethod(const QString &sType, const QString &sName, const Q
|
|||
int startLine = mTokenizer[mIndex]->line;
|
||||
|
||||
// Skip over argument list
|
||||
while ((mIndex < mTokenizer.tokenCount()) and ! (
|
||||
while ((mIndex < mTokenizer.tokenCount()) && ! (
|
||||
isblockChar(mTokenizer[mIndex]->text.front())
|
||||
|| mTokenizer[mIndex]->text.startsWith(':')))
|
||||
mIndex++;
|
||||
|
@ -2574,7 +2680,7 @@ void CppParser::handleUsing()
|
|||
scopeStatement->usingList.insert(fullName);
|
||||
}
|
||||
} else {
|
||||
PFileIncludes fileInfo = mIncludesList->value(mCurrentFile);
|
||||
PFileIncludes fileInfo = mPreprocessor.includesList().value(mCurrentFile);
|
||||
if (!fileInfo)
|
||||
return;
|
||||
if (mNamespaces.contains(usingName)) {
|
||||
|
@ -2715,7 +2821,7 @@ void CppParser::handleVar()
|
|||
getScope(),
|
||||
mClassScope,
|
||||
//True,
|
||||
not isExtern,
|
||||
!isExtern,
|
||||
isStatic); // TODO: not supported to pass list
|
||||
varAdded = true;
|
||||
}
|
||||
|
@ -2807,8 +2913,8 @@ void CppParser::internalParse(const QString &fileName)
|
|||
|
||||
void CppParser::inheritClassStatement(PStatement derived, bool isStruct, PStatement base, StatementClassScope access)
|
||||
{
|
||||
PFileIncludes fileIncludes1=mIncludesList->value(derived->fileName);
|
||||
PFileIncludes fileIncludes2=mIncludesList->value(base->fileName);
|
||||
PFileIncludes fileIncludes1=mPreprocessor.includesList().value(derived->fileName);
|
||||
PFileIncludes fileIncludes2=mPreprocessor.includesList().value(base->fileName);
|
||||
if (fileIncludes1 && fileIncludes2) {
|
||||
//derived class depeneds on base class
|
||||
fileIncludes1->dependingFiles.insert(base->fileName);
|
||||
|
@ -2985,7 +3091,7 @@ void CppParser::internalInvalidateFile(const QString &fileName)
|
|||
}
|
||||
}
|
||||
// delete it from scannedfiles
|
||||
mScannedFiles->remove(fileName);
|
||||
mPreprocessor.scannedFiles().remove(fileName);
|
||||
|
||||
// remove its include files list
|
||||
PFileIncludes p = findFileIncludes(fileName, true);
|
||||
|
@ -3031,7 +3137,7 @@ QSet<QString> CppParser::calculateFilesToBeReparsed(const QString &fileName)
|
|||
while (!queue.isEmpty()) {
|
||||
QString name = queue.dequeue();
|
||||
processed.insert(name);
|
||||
PFileIncludes p=mIncludesList->value(name);
|
||||
PFileIncludes p=mPreprocessor.includesList().value(name);
|
||||
if (!p)
|
||||
continue;
|
||||
for (QString s:p->dependedFiles) {
|
||||
|
@ -3411,6 +3517,11 @@ void CppParser::updateSerialId()
|
|||
mSerialId = QString("%1 %2").arg(mParserId).arg(mSerialCount);
|
||||
}
|
||||
|
||||
int CppParser::parserId() const
|
||||
{
|
||||
return mParserId;
|
||||
}
|
||||
|
||||
void CppParser::setOnGetFileStream(const GetFileStreamCallBack &newOnGetFileStream)
|
||||
{
|
||||
mOnGetFileStream = newOnGetFileStream;
|
||||
|
|
|
@ -66,29 +66,29 @@ public:
|
|||
QString getHeaderFileName(const QString& relativeTo, const QString& line);// both
|
||||
StatementKind getKindOfStatement(PStatement statement);
|
||||
void invalidateFile(const QString& fileName);
|
||||
bool isIncludeLine(const QString &line);
|
||||
bool isProjectHeaderFile(const QString& fileName);
|
||||
bool isSystemHeaderFile(const QString& fileName);
|
||||
void parseFile(const QString& fileName, bool inProject,
|
||||
bool onlyIfNotParsed = false, bool updateView = true);
|
||||
void parseFileList(bool updateView = true);
|
||||
bool parsing();
|
||||
|
||||
void parseHardDefines();
|
||||
void getSourcePair(const QString& fName, QString& CFile, QString& HFile);
|
||||
bool parsing() const;
|
||||
void reset();
|
||||
void unFreeze(); // UnFree/UnLock (reparse while searching)
|
||||
|
||||
int suggestMemberInsertionLine(PStatement parentStatement,
|
||||
StatementClassScope Scope,
|
||||
bool addScopeStr);
|
||||
//void getSourcePair(const QString& fName, QString& CFile, QString& HFile);
|
||||
|
||||
// int suggestMemberInsertionLine(PStatement parentStatement,
|
||||
// StatementClassScope Scope,
|
||||
// bool addScopeStr);
|
||||
// {
|
||||
// function GetSystemHeaderFileName(const FileName: AnsiString): AnsiString; // <file.h>
|
||||
// function GetProjectHeaderFileName(const FileName: AnsiString): AnsiString; // <file.h>
|
||||
// function GetLocalHeaderFileName(const RelativeTo, FileName: AnsiString): AnsiString; // "file.h"
|
||||
// }
|
||||
bool isIncludeLine(const QString &line);
|
||||
void parseFileList(bool updateView = true);
|
||||
QString statementKindStr(StatementKind value);
|
||||
QString statementClassScopeStr(StatementClassScope value);
|
||||
void reset();
|
||||
//QString statementKindStr(StatementKind value);
|
||||
//QString statementClassScopeStr(StatementClassScope value);
|
||||
|
||||
QString prettyPrintStatement(PStatement statement, int line = -1);
|
||||
|
||||
|
@ -97,15 +97,9 @@ public:
|
|||
// StatementKind findKindOfStatementOf(const QString& fileName,
|
||||
// const QString& phrase,
|
||||
// int line);
|
||||
QString getHintFromStatement(const QString& fileName,
|
||||
const QString& phrase,
|
||||
int line);
|
||||
|
||||
|
||||
void unFreeze(); // UnFree/UnLock (reparse while searching)
|
||||
bool getParsing();
|
||||
|
||||
|
||||
// QString getHintFromStatement(const QString& fileName,
|
||||
// const QString& phrase,
|
||||
// int line);
|
||||
bool enabled() const;
|
||||
void setEnabled(bool newEnabled);
|
||||
|
||||
|
@ -114,6 +108,8 @@ public:
|
|||
|
||||
void setOnGetFileStream(const GetFileStreamCallBack &newOnGetFileStream);
|
||||
|
||||
int parserId() const;
|
||||
|
||||
signals:
|
||||
void onProgress(const QString& fileName, int total, int current);
|
||||
void onBusy();
|
||||
|
@ -326,7 +322,6 @@ private:
|
|||
QVector<int> mSkipList; // TList<Integer>
|
||||
StatementClassScope mClassScope;
|
||||
StatementModel mStatementList;
|
||||
std::shared_ptr<QHash<QString,PFileIncludes>> mIncludesList; //List of scaned files and it's infos
|
||||
//It's used in preprocessor, so we can't use fIncludeList instead
|
||||
|
||||
CppTokenizer mTokenizer;
|
||||
|
|
|
@ -1580,6 +1580,11 @@ int CppPreprocessor::evaluateExpression(QString line)
|
|||
return result;
|
||||
}
|
||||
|
||||
const DefineMap &CppPreprocessor::hardDefines() const
|
||||
{
|
||||
return mHardDefines;
|
||||
}
|
||||
|
||||
QSet<QString> &CppPreprocessor::projectIncludePaths()
|
||||
{
|
||||
return mProjectIncludePaths;
|
||||
|
|
|
@ -57,6 +57,8 @@ public:
|
|||
|
||||
QSet<QString> &projectIncludePaths();
|
||||
|
||||
const DefineMap &hardDefines() const;
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
|
|
|
@ -103,8 +103,8 @@ void SynEditTextPainter::paintGutter(const QRect& clip)
|
|||
if (edit->mGutter.useFontStyle()) {
|
||||
painter->setFont(edit->mGutter.font());
|
||||
}
|
||||
if (edit->mGutter->textColor().isValid()) {
|
||||
painter->setPen(edit->mGutter->textColor());
|
||||
if (edit->mGutter.textColor().isValid()) {
|
||||
painter->setPen(edit->mGutter.textColor());
|
||||
} else {
|
||||
painter->setPen(edit->palette().color(QPalette::Text));
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ void SearchResultTreeViewDelegate::paint(QPainter *painter, const QStyleOptionVi
|
|||
|
||||
// Painting item without text (this takes care of painting e.g. the highlighted for selected
|
||||
// or hovered over items in an ItemView)
|
||||
option->text = QString();
|
||||
option.text = QString();
|
||||
style->drawControl(QStyle::CE_ItemViewItem, &option, painter, option.widget);
|
||||
SearchResultTreeItem* item = static_cast<SearchResultTreeItem *>(index.internalPointer());
|
||||
|
||||
|
@ -268,7 +268,7 @@ void SearchResultTreeViewDelegate::paint(QPainter *painter, const QStyleOptionVi
|
|||
.arg(item->text);
|
||||
}
|
||||
// Figure out where to render the text in order to follow the requested alignment
|
||||
option->text = fullText;
|
||||
option.text = fullText;
|
||||
QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &option);
|
||||
|
||||
QFontMetrics metrics = option.fontMetrics;
|
||||
|
|
Loading…
Reference in New Issue