2021-12-26 23:18:28 +08:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2020-2022 Roy Qu (royqh1979@gmail.com)
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
2021-08-29 00:48:23 +08:00
|
|
|
#include "headercompletionpopup.h"
|
2024-03-31 17:23:16 +08:00
|
|
|
#include "codecompletionpopup.h"
|
2021-08-29 00:48:23 +08:00
|
|
|
#include <QCoreApplication>
|
|
|
|
#include <QFileInfo>
|
|
|
|
#include <QVBoxLayout>
|
2022-04-14 22:25:49 +08:00
|
|
|
#include <QDebug>
|
2024-03-31 17:23:16 +08:00
|
|
|
#include "qpainter.h"
|
2023-03-11 19:30:56 +08:00
|
|
|
#include "systemconsts.h"
|
2022-10-24 17:23:37 +08:00
|
|
|
#include "../utils.h"
|
2024-03-31 20:43:37 +08:00
|
|
|
#include "../settings.h"
|
|
|
|
#include "../colorscheme.h"
|
|
|
|
#include <qsynedit/constants.h>
|
2021-08-29 00:48:23 +08:00
|
|
|
|
|
|
|
HeaderCompletionPopup::HeaderCompletionPopup(QWidget* parent):QWidget(parent)
|
|
|
|
{
|
|
|
|
setWindowFlags(Qt::Popup);
|
|
|
|
mListView = new CodeCompletionListView(this);
|
2024-03-31 17:23:16 +08:00
|
|
|
mModel=new HeaderCompletionListModel(&mCompletionList, 0);
|
2022-10-10 18:05:18 +08:00
|
|
|
QItemSelectionModel *m=mListView->selectionModel();
|
2021-08-29 00:48:23 +08:00
|
|
|
mListView->setModel(mModel);
|
2022-10-10 18:05:18 +08:00
|
|
|
delete m;
|
2024-03-31 17:23:16 +08:00
|
|
|
mDelegate = new HeaderCompletionListItemDelegate(mModel,this);
|
|
|
|
mListView->setItemDelegate(mDelegate);
|
2021-08-29 00:48:23 +08:00
|
|
|
setLayout(new QVBoxLayout());
|
|
|
|
layout()->addWidget(mListView);
|
|
|
|
layout()->setMargin(0);
|
|
|
|
|
2023-10-18 22:00:32 +08:00
|
|
|
mListView->setFocus();
|
|
|
|
|
2021-08-29 00:48:23 +08:00
|
|
|
mSearchLocal = false;
|
|
|
|
mCurrentFile = "";
|
|
|
|
mPhrase = "";
|
|
|
|
mIgnoreCase = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
HeaderCompletionPopup::~HeaderCompletionPopup()
|
|
|
|
{
|
|
|
|
delete mModel;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionPopup::prepareSearch(const QString &phrase, const QString &fileName)
|
|
|
|
{
|
|
|
|
QCursor oldCursor = cursor();
|
|
|
|
setCursor(Qt::WaitCursor);
|
|
|
|
mCurrentFile = fileName;
|
|
|
|
mPhrase = phrase;
|
|
|
|
getCompletionFor(phrase);
|
|
|
|
setCursor(oldCursor);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HeaderCompletionPopup::search(const QString &phrase, bool autoHideOnSingleResult)
|
|
|
|
{
|
|
|
|
mPhrase = phrase;
|
|
|
|
if (mPhrase.isEmpty()) {
|
|
|
|
hide();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if(!isEnabled())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
QCursor oldCursor = cursor();
|
|
|
|
setCursor(Qt::WaitCursor);
|
|
|
|
|
|
|
|
int i = mPhrase.lastIndexOf('\\');
|
|
|
|
if (i<0) {
|
|
|
|
i = mPhrase.lastIndexOf('/');
|
|
|
|
}
|
|
|
|
QString symbol = mPhrase;
|
|
|
|
if (i>=0) {
|
|
|
|
symbol = mPhrase.mid(i+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// filter fFullCompletionList to fCompletionList
|
|
|
|
filterList(symbol);
|
|
|
|
mModel->notifyUpdated();
|
|
|
|
setCursor(oldCursor);
|
|
|
|
|
|
|
|
if (!mCompletionList.isEmpty()) {
|
2024-03-31 20:43:37 +08:00
|
|
|
QString schemaName = pSettings->editor().colorScheme();
|
|
|
|
PColorSchemeItem item = pColorManager->getItem(schemaName, COLOR_SCHEME_ACTIVE_LINE);
|
|
|
|
if (item)
|
|
|
|
mDelegate->setCurrentSelectionBackColor(item->background());
|
|
|
|
else
|
|
|
|
mDelegate->setCurrentSelectionBackColor(palette().highlight().color());
|
|
|
|
item = pColorManager->getItem(schemaName, SYNS_AttrReserveWord_Type);
|
|
|
|
if (item)
|
|
|
|
mDelegate->setMatchedColor(item->foreground());
|
|
|
|
else
|
|
|
|
mDelegate->setMatchedColor(palette().color(QPalette::HighlightedText));
|
2021-08-29 10:29:56 +08:00
|
|
|
mListView->setCurrentIndex(mModel->index(0,0));
|
2021-08-29 00:48:23 +08:00
|
|
|
if (mCompletionList.count() == 1) {
|
|
|
|
// if only one suggestion and auto hide , don't show the frame
|
|
|
|
if (autoHideOnSingleResult)
|
|
|
|
return true;
|
|
|
|
// if only one suggestion, and is exactly the symbol to search, hide the frame (the search is over)
|
2022-04-14 22:25:49 +08:00
|
|
|
if (symbol == mCompletionList[0]->filename)
|
2021-08-29 00:48:23 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
hide();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionPopup::setKeypressedCallback(const KeyPressedCallback &newKeypressedCallback)
|
|
|
|
{
|
|
|
|
mListView->setKeypressedCallback(newKeypressedCallback);
|
|
|
|
}
|
|
|
|
|
2022-04-14 22:25:49 +08:00
|
|
|
void HeaderCompletionPopup::setSuggestionColor(const QColor& localColor,
|
|
|
|
const QColor& projectColor,
|
2022-06-20 21:43:42 +08:00
|
|
|
const QColor& systemColor,
|
|
|
|
const QColor& folderColor)
|
2021-08-29 00:48:23 +08:00
|
|
|
{
|
2022-04-14 22:25:49 +08:00
|
|
|
mModel->setLocalColor(localColor);
|
|
|
|
mModel->setProjectColor(projectColor);
|
|
|
|
mModel->setSystemColor(systemColor);
|
2022-06-20 21:43:42 +08:00
|
|
|
mModel->setFolderColor(folderColor);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
|
2022-04-14 22:25:49 +08:00
|
|
|
QString HeaderCompletionPopup::selectedFilename(bool updateUsageCount)
|
2021-08-29 10:14:07 +08:00
|
|
|
{
|
|
|
|
if (!isEnabled())
|
|
|
|
return "";
|
|
|
|
int index = mListView->currentIndex().row();
|
2022-04-14 22:25:49 +08:00
|
|
|
PHeaderCompletionListItem item;
|
2021-08-29 10:14:07 +08:00
|
|
|
if (index>=0 && index<mCompletionList.count())
|
2022-04-14 22:25:49 +08:00
|
|
|
item=mCompletionList[index];
|
2021-08-29 10:29:56 +08:00
|
|
|
else if (mCompletionList.count()>0) {
|
2022-04-14 22:25:49 +08:00
|
|
|
item=mCompletionList.front();
|
2021-08-29 10:29:56 +08:00
|
|
|
}
|
2022-04-14 22:25:49 +08:00
|
|
|
if (item) {
|
|
|
|
if (updateUsageCount) {
|
|
|
|
item->usageCount++;
|
|
|
|
mHeaderUsageCounts.insert(item->fullpath,item->usageCount);
|
|
|
|
}
|
2022-06-20 21:43:42 +08:00
|
|
|
if (item->isFolder)
|
|
|
|
return item->filename+"/";
|
2022-04-14 22:25:49 +08:00
|
|
|
return item->filename;
|
|
|
|
}
|
|
|
|
return "";
|
2021-08-29 10:14:07 +08:00
|
|
|
}
|
|
|
|
|
2024-03-31 20:43:37 +08:00
|
|
|
void HeaderCompletionPopup::setLineHeightFactor(float newLineHeightFactor)
|
|
|
|
{
|
|
|
|
mDelegate->setLineHeightFactor(newLineHeightFactor);
|
|
|
|
}
|
|
|
|
|
2022-04-14 22:25:49 +08:00
|
|
|
static bool sortByUsage(const PHeaderCompletionListItem& item1,const PHeaderCompletionListItem& item2){
|
|
|
|
if (item1->usageCount != item2->usageCount)
|
|
|
|
return item1->usageCount > item2->usageCount;
|
|
|
|
|
|
|
|
if (item1->itemType != item2->itemType)
|
|
|
|
return item1->itemType<item2->itemType;
|
|
|
|
|
2023-03-11 19:30:56 +08:00
|
|
|
int code = QString::compare(item1->noSuffixFilename, item2->noSuffixFilename, PATH_SENSITIVITY);
|
|
|
|
if (code!=0)
|
|
|
|
return code<0;
|
|
|
|
return item1->suffix < item2->suffix;
|
2022-04-14 22:25:49 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-08-29 00:48:23 +08:00
|
|
|
void HeaderCompletionPopup::filterList(const QString &member)
|
|
|
|
{
|
2022-04-14 22:25:49 +08:00
|
|
|
Qt::CaseSensitivity caseSensitivity=mIgnoreCase?Qt::CaseInsensitive:Qt::CaseSensitive;
|
2021-08-29 00:48:23 +08:00
|
|
|
mCompletionList.clear();
|
2024-03-31 17:23:16 +08:00
|
|
|
mModel->setMatched(0);
|
2021-08-29 00:48:23 +08:00
|
|
|
if (member.isEmpty()) {
|
2022-04-14 22:25:49 +08:00
|
|
|
foreach (const PHeaderCompletionListItem& item,mFullCompletionList.values()) {
|
|
|
|
mCompletionList.append(item);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
} else {
|
2022-04-14 22:25:49 +08:00
|
|
|
foreach (const PHeaderCompletionListItem& item,mFullCompletionList.values()) {
|
|
|
|
if (item->filename.startsWith(member, caseSensitivity)) {
|
|
|
|
mCompletionList.append(item);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-04-14 22:25:49 +08:00
|
|
|
std::sort(mCompletionList.begin(),mCompletionList.end(), sortByUsage);
|
2024-03-31 17:23:16 +08:00
|
|
|
mModel->setMatched(member.length());
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
|
2022-04-14 22:25:49 +08:00
|
|
|
|
2021-08-29 00:48:23 +08:00
|
|
|
void HeaderCompletionPopup::getCompletionFor(const QString &phrase)
|
|
|
|
{
|
|
|
|
int idx = phrase.lastIndexOf('\\');
|
|
|
|
if (idx<0) {
|
|
|
|
idx = phrase.lastIndexOf('/');
|
|
|
|
}
|
|
|
|
mFullCompletionList.clear();
|
|
|
|
if (idx < 0) { // dont have basedir
|
|
|
|
if (mSearchLocal) {
|
|
|
|
QFileInfo fileInfo(mCurrentFile);
|
2022-04-14 22:25:49 +08:00
|
|
|
addFilesInPath(fileInfo.absolutePath(), HeaderCompletionListItemType::LocalHeader);
|
2021-08-29 00:48:23 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
for (const QString& path: mParser->includePaths()) {
|
2022-04-14 22:25:49 +08:00
|
|
|
addFilesInPath(path, HeaderCompletionListItemType::ProjectHeader);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const QString& path: mParser->projectIncludePaths()) {
|
2022-04-14 22:25:49 +08:00
|
|
|
addFilesInPath(path, HeaderCompletionListItemType::SystemHeader);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
QString current = phrase.mid(0,idx);
|
|
|
|
if (mSearchLocal) {
|
|
|
|
QFileInfo fileInfo(mCurrentFile);
|
2022-04-14 22:25:49 +08:00
|
|
|
addFilesInSubDir(fileInfo.absolutePath(),current, HeaderCompletionListItemType::LocalHeader);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
for (const QString& path: mParser->includePaths()) {
|
2022-04-14 22:25:49 +08:00
|
|
|
addFilesInSubDir(path,current, HeaderCompletionListItemType::ProjectHeader);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const QString& path: mParser->projectIncludePaths()) {
|
2022-04-14 22:25:49 +08:00
|
|
|
addFilesInSubDir(path,current, HeaderCompletionListItemType::SystemHeader);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-14 22:25:49 +08:00
|
|
|
void HeaderCompletionPopup::addFilesInPath(const QString &path, HeaderCompletionListItemType type)
|
2021-08-29 00:48:23 +08:00
|
|
|
{
|
|
|
|
QDir dir(path);
|
|
|
|
if (!dir.exists())
|
|
|
|
return;
|
|
|
|
foreach (const QFileInfo& fileInfo, dir.entryInfoList()) {
|
2021-08-29 10:14:07 +08:00
|
|
|
if (fileInfo.fileName().startsWith("."))
|
|
|
|
continue;
|
2022-06-20 21:43:42 +08:00
|
|
|
if (fileInfo.isDir()) {
|
|
|
|
addFile(dir, fileInfo, type);
|
|
|
|
continue;
|
|
|
|
}
|
2021-08-29 00:48:23 +08:00
|
|
|
QString suffix = fileInfo.suffix().toLower();
|
2021-08-29 10:14:07 +08:00
|
|
|
if (suffix == "h" || suffix == "hpp" || suffix == "") {
|
2022-06-20 21:43:42 +08:00
|
|
|
addFile(dir, fileInfo, type);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-20 21:43:42 +08:00
|
|
|
void HeaderCompletionPopup::addFile(const QDir& dir, const QFileInfo& fileInfo, HeaderCompletionListItemType type)
|
2021-08-29 00:48:23 +08:00
|
|
|
{
|
2022-06-20 21:43:42 +08:00
|
|
|
QString fileName = fileInfo.fileName();
|
2021-08-29 00:48:23 +08:00
|
|
|
if (fileName.isEmpty())
|
|
|
|
return;
|
|
|
|
if (fileName.startsWith('.'))
|
|
|
|
return;
|
2022-04-14 22:25:49 +08:00
|
|
|
PHeaderCompletionListItem item = std::make_shared<HeaderCompletionListItem>();
|
|
|
|
item->filename = fileName;
|
2023-03-11 19:30:56 +08:00
|
|
|
item->noSuffixFilename = fileInfo.baseName();
|
|
|
|
item->suffix = fileInfo.suffix();
|
2022-04-14 22:25:49 +08:00
|
|
|
item->itemType = type;
|
2022-10-24 17:23:37 +08:00
|
|
|
item->fullpath = cleanPath(dir.absoluteFilePath(fileName));
|
2022-04-14 22:25:49 +08:00
|
|
|
item->usageCount = mHeaderUsageCounts.value(item->fullpath,0);
|
2022-06-20 21:43:42 +08:00
|
|
|
item->isFolder = fileInfo.isDir();
|
2022-04-14 22:25:49 +08:00
|
|
|
mFullCompletionList.insert(fileName,item);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
|
2022-04-14 22:25:49 +08:00
|
|
|
void HeaderCompletionPopup::addFilesInSubDir(const QString &baseDirPath, const QString &subDirName, HeaderCompletionListItemType type)
|
2021-08-29 00:48:23 +08:00
|
|
|
{
|
|
|
|
QDir baseDir(baseDirPath);
|
|
|
|
QString subDirPath = baseDir.filePath(subDirName);
|
2022-04-14 22:25:49 +08:00
|
|
|
addFilesInPath(subDirPath, type);
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
|
2021-08-29 10:14:07 +08:00
|
|
|
bool HeaderCompletionPopup::searchLocal() const
|
|
|
|
{
|
|
|
|
return mSearchLocal;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionPopup::setSearchLocal(bool newSearchLocal)
|
|
|
|
{
|
|
|
|
mSearchLocal = newSearchLocal;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HeaderCompletionPopup::ignoreCase() const
|
|
|
|
{
|
|
|
|
return mIgnoreCase;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionPopup::setIgnoreCase(bool newIgnoreCase)
|
|
|
|
{
|
|
|
|
mIgnoreCase = newIgnoreCase;
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString &HeaderCompletionPopup::phrase() const
|
|
|
|
{
|
|
|
|
return mPhrase;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionPopup::setParser(const PCppParser &newParser)
|
|
|
|
{
|
|
|
|
mParser = newParser;
|
|
|
|
}
|
|
|
|
|
2021-08-29 00:48:23 +08:00
|
|
|
void HeaderCompletionPopup::hideEvent(QHideEvent *)
|
|
|
|
{
|
|
|
|
mCompletionList.clear();
|
2024-03-31 17:23:16 +08:00
|
|
|
mModel->setMatched(0);
|
2021-08-29 00:48:23 +08:00
|
|
|
mFullCompletionList.clear();
|
2021-11-12 02:31:45 +08:00
|
|
|
mParser = nullptr;
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool HeaderCompletionPopup::event(QEvent *event)
|
|
|
|
{
|
|
|
|
bool result = QWidget::event(event);
|
|
|
|
switch (event->type()) {
|
|
|
|
case QEvent::FontChange:
|
|
|
|
mListView->setFont(font());
|
2024-03-31 17:23:16 +08:00
|
|
|
mDelegate->setFont(font());
|
2021-08-29 00:48:23 +08:00
|
|
|
break;
|
2021-11-02 23:47:51 +08:00
|
|
|
default:
|
|
|
|
break;
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-03-31 17:23:16 +08:00
|
|
|
HeaderCompletionListModel::HeaderCompletionListModel(const QList<PHeaderCompletionListItem> *files, int matched, QObject *parent):
|
|
|
|
QAbstractListModel{parent},
|
|
|
|
mFiles{files},
|
|
|
|
mMatched{matched}
|
2021-08-29 00:48:23 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
int HeaderCompletionListModel::rowCount(const QModelIndex &) const
|
|
|
|
{
|
|
|
|
return mFiles->count();
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant HeaderCompletionListModel::data(const QModelIndex &index, int role) const
|
|
|
|
{
|
|
|
|
if (!index.isValid())
|
|
|
|
return QVariant();
|
|
|
|
if (index.row()>=mFiles->count())
|
|
|
|
return QVariant();
|
|
|
|
|
|
|
|
switch(role) {
|
|
|
|
case Qt::DisplayRole: {
|
2022-04-14 22:25:49 +08:00
|
|
|
return mFiles->at(index.row())->filename;
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
2022-06-20 21:43:42 +08:00
|
|
|
case Qt::ForegroundRole: {
|
|
|
|
PHeaderCompletionListItem item=mFiles->at(index.row());
|
|
|
|
if (item->isFolder)
|
|
|
|
return mFolderColor;
|
|
|
|
switch(item->itemType) {
|
2022-04-14 22:25:49 +08:00
|
|
|
case HeaderCompletionListItemType::LocalHeader:
|
|
|
|
return mLocalColor;
|
|
|
|
case HeaderCompletionListItemType::ProjectHeader:
|
|
|
|
return mProjectColor;
|
|
|
|
case HeaderCompletionListItemType::SystemHeader:
|
|
|
|
return mSystemColor;
|
|
|
|
}
|
2022-06-20 21:43:42 +08:00
|
|
|
}
|
2021-08-29 00:48:23 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListModel::notifyUpdated()
|
|
|
|
{
|
|
|
|
beginResetModel();
|
|
|
|
endResetModel();
|
|
|
|
}
|
|
|
|
|
2024-03-31 17:23:16 +08:00
|
|
|
void HeaderCompletionListModel::setLocalColor(const QColor &newColor)
|
|
|
|
{
|
|
|
|
mLocalColor = newColor;
|
|
|
|
}
|
|
|
|
|
2022-04-14 22:25:49 +08:00
|
|
|
void HeaderCompletionListModel::setSystemColor(const QColor &newColor)
|
|
|
|
{
|
|
|
|
mSystemColor = newColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListModel::setProjectColor(const QColor &newColor)
|
|
|
|
{
|
|
|
|
mProjectColor = newColor;
|
|
|
|
}
|
|
|
|
|
2022-06-20 21:43:42 +08:00
|
|
|
void HeaderCompletionListModel::setFolderColor(const QColor &newFolderColor)
|
|
|
|
{
|
|
|
|
mFolderColor = newFolderColor;
|
|
|
|
}
|
|
|
|
|
2024-03-31 17:23:16 +08:00
|
|
|
int HeaderCompletionListModel::matched() const
|
2021-08-29 00:48:23 +08:00
|
|
|
{
|
2024-03-31 17:23:16 +08:00
|
|
|
return mMatched;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListModel::setMatched(int newMatched)
|
|
|
|
{
|
|
|
|
mMatched = newMatched;
|
|
|
|
}
|
|
|
|
|
|
|
|
HeaderCompletionListItemDelegate::HeaderCompletionListItemDelegate(HeaderCompletionListModel *model, QWidget *parent):
|
|
|
|
QStyledItemDelegate{parent},
|
2024-03-31 20:43:37 +08:00
|
|
|
mModel{model},
|
|
|
|
mLineHeightFactor{1.0}
|
2024-03-31 17:23:16 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
|
|
{
|
|
|
|
if (!mModel) {
|
|
|
|
QStyledItemDelegate::paint(painter, option, index);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
QString text = mModel->data(index, Qt::DisplayRole).toString();
|
|
|
|
if (text.isEmpty()) {
|
|
|
|
QStyledItemDelegate::paint(painter, option, index);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
painter->save();
|
|
|
|
QFont normalFont{font()};
|
|
|
|
QFont matchedFont{font()};
|
|
|
|
normalFont.setBold(false);
|
|
|
|
matchedFont.setBold(true);
|
|
|
|
painter->setFont(normalFont);
|
|
|
|
QColor normalColor = mModel->data(index, Qt::ForegroundRole).value<QColor>();
|
|
|
|
if (option.state & QStyle::State_Selected) {
|
2024-03-31 20:43:37 +08:00
|
|
|
painter->fillRect(option.rect, mCurrentSelectionBackColor);
|
2024-03-31 17:23:16 +08:00
|
|
|
}
|
2024-03-31 20:43:37 +08:00
|
|
|
int padding = (option.rect.height()-painter->fontMetrics().height())/2;
|
|
|
|
int y=option.rect.bottom()-painter->fontMetrics().descent()-padding;
|
2024-03-31 17:23:16 +08:00
|
|
|
int x=0;
|
|
|
|
QString t = text.left(mModel->matched());
|
2024-03-31 20:43:37 +08:00
|
|
|
painter->setPen(mMatchedColor);
|
2024-03-31 17:23:16 +08:00
|
|
|
painter->setFont(matchedFont);
|
|
|
|
painter->drawText(x,y,t);
|
|
|
|
x+=painter->fontMetrics().horizontalAdvance(t);
|
|
|
|
t = text.mid(mModel->matched());
|
2024-03-31 20:43:37 +08:00
|
|
|
painter->setPen(normalColor);
|
2024-03-31 17:23:16 +08:00
|
|
|
painter->setFont(normalFont);
|
|
|
|
painter->drawText(x,y,t);
|
|
|
|
painter->restore();
|
|
|
|
}
|
|
|
|
|
2024-03-31 20:43:37 +08:00
|
|
|
QSize HeaderCompletionListItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
|
|
|
{
|
|
|
|
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
2024-04-06 21:45:00 +08:00
|
|
|
size.setHeight(QFontMetrics(mFont).height()*mLineHeightFactor);
|
2024-03-31 20:43:37 +08:00
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2024-03-31 17:23:16 +08:00
|
|
|
const QFont &HeaderCompletionListItemDelegate::font() const
|
|
|
|
{
|
|
|
|
return mFont;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListItemDelegate::setFont(const QFont &newFont)
|
|
|
|
{
|
|
|
|
mFont=newFont;
|
2021-08-29 00:48:23 +08:00
|
|
|
}
|
2024-03-31 20:43:37 +08:00
|
|
|
|
|
|
|
float HeaderCompletionListItemDelegate::lineHeightFactor() const
|
|
|
|
{
|
|
|
|
return mLineHeightFactor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListItemDelegate::setLineHeightFactor(float newLineHeightFactor)
|
|
|
|
{
|
|
|
|
mLineHeightFactor = newLineHeightFactor;
|
|
|
|
}
|
|
|
|
|
|
|
|
QColor HeaderCompletionListItemDelegate::matchedColor() const
|
|
|
|
{
|
|
|
|
return mMatchedColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListItemDelegate::setMatchedColor(const QColor &newMatchedColor)
|
|
|
|
{
|
|
|
|
mMatchedColor = newMatchedColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
QColor HeaderCompletionListItemDelegate::currentSelectionBackColor() const
|
|
|
|
{
|
|
|
|
return mCurrentSelectionBackColor;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HeaderCompletionListItemDelegate::setCurrentSelectionBackColor(const QColor &newCurrentSelectionBackColor)
|
|
|
|
{
|
|
|
|
mCurrentSelectionBackColor = newCurrentSelectionBackColor;
|
|
|
|
}
|