forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.15'
Conflicts: cmake/QtCreatorIDEBranding.cmake qbs/modules/qtc/qtc.qbs qtcreator_ide_branding.pri Change-Id: I309fe2a4ea7afac85481fc6466a9a6e58e340019
This commit is contained in:
@@ -44,6 +44,7 @@
|
||||
#include <QTimer>
|
||||
|
||||
using namespace Core;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace ClassView {
|
||||
@@ -94,7 +95,7 @@ public:
|
||||
ParserTreeItem::ConstPtr m_root;
|
||||
|
||||
QTimer m_timer;
|
||||
QHash<QString, CPlusPlus::Document::Ptr> m_awaitingDocuments;
|
||||
QSet<FilePath> m_awaitingDocuments;
|
||||
|
||||
//! Internal manager state. \sa Manager::state
|
||||
bool state = false;
|
||||
@@ -116,7 +117,15 @@ void ManagerPrivate::cancelScheduledUpdate()
|
||||
void ManagerPrivate::resetParser()
|
||||
{
|
||||
cancelScheduledUpdate();
|
||||
QMetaObject::invokeMethod(m_parser, &Parser::resetDataToCurrentState, Qt::QueuedConnection);
|
||||
|
||||
QHash<FilePath, QPair<QString, FilePaths>> projectData;
|
||||
for (const Project *project : SessionManager::projects()) {
|
||||
projectData.insert(project->projectFilePath(),
|
||||
qMakePair(project->displayName(), project->files(Project::SourceFiles)));
|
||||
}
|
||||
QMetaObject::invokeMethod(m_parser, [this, projectData]() {
|
||||
m_parser->resetData(projectData);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -218,15 +227,26 @@ bool Manager::hasChildren(QStandardItem *item) const
|
||||
|
||||
void Manager::initialize()
|
||||
{
|
||||
using ProjectExplorer::SessionManager;
|
||||
d->m_timer.setSingleShot(true);
|
||||
|
||||
// connections to enable/disable navi widget factory
|
||||
SessionManager *sessionManager = SessionManager::instance();
|
||||
connect(sessionManager, &SessionManager::projectAdded,
|
||||
this, &Manager::onProjectListChanged);
|
||||
this, [this](Project *project) {
|
||||
const FilePath projectPath = project->projectFilePath();
|
||||
const QString projectName = project->displayName();
|
||||
const FilePaths projectFiles = project->files(Project::SourceFiles);
|
||||
QMetaObject::invokeMethod(d->m_parser, [this, projectPath, projectName, projectFiles]() {
|
||||
d->m_parser->addProject(projectPath, projectName, projectFiles);
|
||||
}, Qt::QueuedConnection);
|
||||
});
|
||||
connect(sessionManager, &SessionManager::projectRemoved,
|
||||
this, &Manager::onProjectListChanged);
|
||||
this, [this](Project *project) {
|
||||
const FilePath projectPath = project->projectFilePath();
|
||||
QMetaObject::invokeMethod(d->m_parser, [this, projectPath]() {
|
||||
d->m_parser->removeProject(projectPath);
|
||||
}, Qt::QueuedConnection);
|
||||
});
|
||||
|
||||
// connect to the progress manager for signals about Parsing tasks
|
||||
connect(ProgressManager::instance(), &ProgressManager::taskStarted,
|
||||
@@ -283,12 +303,12 @@ void Manager::initialize()
|
||||
if (doc.data() == nullptr)
|
||||
return;
|
||||
|
||||
d->m_awaitingDocuments.insert(doc->fileName(), doc);
|
||||
d->m_awaitingDocuments.insert(FilePath::fromString(doc->fileName()));
|
||||
d->m_timer.start(400); // Accumulate multiple requests into one, restarts the timer
|
||||
});
|
||||
|
||||
connect(&d->m_timer, &QTimer::timeout, this, [this]() {
|
||||
const QList<CPlusPlus::Document::Ptr> docsToBeUpdated = d->m_awaitingDocuments.values();
|
||||
const QSet<FilePath> docsToBeUpdated = d->m_awaitingDocuments;
|
||||
d->cancelScheduledUpdate();
|
||||
if (!state() || d->disableCodeParser) // enabling any of them will trigger the total update
|
||||
return;
|
||||
@@ -346,20 +366,7 @@ void Manager::onWidgetVisibilityIsChanged(bool visibility)
|
||||
if (!visibility)
|
||||
return;
|
||||
setState(true);
|
||||
onProjectListChanged();
|
||||
}
|
||||
|
||||
/*!
|
||||
Reacts to the project list being changed by updating the navigation pane
|
||||
visibility if necessary.
|
||||
*/
|
||||
|
||||
void Manager::onProjectListChanged()
|
||||
{
|
||||
// do nothing if Manager is disabled
|
||||
if (!state())
|
||||
return;
|
||||
|
||||
// TODO: this one may change into getter (when a new class view widget is being shown)
|
||||
QMetaObject::invokeMethod(d->m_parser, &Parser::requestCurrentState, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,6 @@ signals:
|
||||
void treeDataUpdate(QSharedPointer<QStandardItem> result);
|
||||
|
||||
private:
|
||||
void onProjectListChanged();
|
||||
void initialize();
|
||||
|
||||
inline bool state() const;
|
||||
|
||||
@@ -32,18 +32,13 @@
|
||||
|
||||
// other
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <projectexplorer/project.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QStandardItem>
|
||||
#include <QElapsedTimer>
|
||||
#include <QDebug>
|
||||
#include <QHash>
|
||||
#include <QSet>
|
||||
#include <QElapsedTimer>
|
||||
|
||||
enum { debug = false };
|
||||
|
||||
@@ -67,17 +62,11 @@ namespace Internal {
|
||||
\brief The Parser class parses C++ information. Multithreading is supported.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void Parser::treeDataUpdate(QSharedPointer<QStandardItem> result)
|
||||
|
||||
Emits a signal about a tree data update.
|
||||
*/
|
||||
|
||||
class ParserPrivate
|
||||
{
|
||||
public:
|
||||
//! Get document from documentList
|
||||
CPlusPlus::Document::Ptr document(const QString &fileName) const;
|
||||
CPlusPlus::Document::Ptr document(const Utils::FilePath &fileName) const;
|
||||
|
||||
struct DocumentCache {
|
||||
unsigned treeRevision = 0;
|
||||
@@ -87,23 +76,20 @@ public:
|
||||
struct ProjectCache {
|
||||
unsigned treeRevision = 0;
|
||||
ParserTreeItem::ConstPtr tree;
|
||||
QStringList fileList;
|
||||
QString projectName;
|
||||
QSet<FilePath> fileNames;
|
||||
};
|
||||
|
||||
// Project file path to its cached data
|
||||
QHash<QString, DocumentCache> m_documentCache;
|
||||
QHash<FilePath, DocumentCache> m_documentCache;
|
||||
// Project file path to its cached data
|
||||
QHash<QString, ProjectCache> m_projectCache;
|
||||
|
||||
// other
|
||||
//! List for files which has to be parsed
|
||||
QSet<QString> fileList;
|
||||
QHash<FilePath, ProjectCache> m_projectCache;
|
||||
|
||||
//! Flat mode
|
||||
bool flatMode = false;
|
||||
};
|
||||
|
||||
CPlusPlus::Document::Ptr ParserPrivate::document(const QString &fileName) const
|
||||
CPlusPlus::Document::Ptr ParserPrivate::document(const FilePath &fileName) const
|
||||
{
|
||||
return m_documentCache.value(fileName).document;
|
||||
}
|
||||
@@ -161,16 +147,14 @@ ParserTreeItem::ConstPtr Parser::parse()
|
||||
|
||||
QHash<SymbolInformation, ParserTreeItem::ConstPtr> projectTrees;
|
||||
|
||||
// TODO: move a call to SessionManager::projects() out of this thread
|
||||
for (const Project *prj : SessionManager::projects()) {
|
||||
const QString prjName(prj->displayName());
|
||||
const QString prjType = prj->projectFilePath().toString();
|
||||
const SymbolInformation inf(prjName, prjType);
|
||||
|
||||
ParserTreeItem::ConstPtr item = addFlatTree(prj);
|
||||
for (auto it = d->m_projectCache.cbegin(); it != d->m_projectCache.cend(); ++it) {
|
||||
const ParserPrivate::ProjectCache &projectCache = it.value();
|
||||
const FilePath projectPath = it.key();
|
||||
const SymbolInformation projectInfo = { projectCache.projectName, projectPath.toString() };
|
||||
ParserTreeItem::ConstPtr item = getCachedOrParseProjectTree(projectPath, projectCache.fileNames);
|
||||
if (item.isNull())
|
||||
continue;
|
||||
projectTrees.insert(inf, item);
|
||||
projectTrees.insert(projectInfo, item);
|
||||
}
|
||||
|
||||
ParserTreeItem::ConstPtr rootItem(new ParserTreeItem(projectTrees));
|
||||
@@ -189,16 +173,16 @@ ParserTreeItem::ConstPtr Parser::parse()
|
||||
project.
|
||||
*/
|
||||
|
||||
ParserTreeItem::ConstPtr Parser::getParseProjectTree(const QStringList &fileList,
|
||||
const QString &projectId)
|
||||
ParserTreeItem::ConstPtr Parser::getParseProjectTree(const FilePath &projectPath,
|
||||
const QSet<FilePath> &filesInProject)
|
||||
{
|
||||
//! \todo Way to optimize - for documentUpdate - use old cached project and subtract
|
||||
//! changed files only (old edition), and add curent editions
|
||||
|
||||
QList<ParserTreeItem::ConstPtr> docTrees;
|
||||
unsigned revision = 0;
|
||||
for (const QString &file : fileList) {
|
||||
const CPlusPlus::Document::Ptr &doc = d->document(file);
|
||||
for (const FilePath &fileInProject : filesInProject) {
|
||||
const CPlusPlus::Document::Ptr &doc = d->document(fileInProject);
|
||||
if (doc.isNull())
|
||||
continue;
|
||||
|
||||
@@ -210,11 +194,11 @@ ParserTreeItem::ConstPtr Parser::getParseProjectTree(const QStringList &fileList
|
||||
docTrees.append(docTree);
|
||||
}
|
||||
|
||||
ParserTreeItem::ConstPtr item = ParserTreeItem::mergeTrees(Utils::FilePath::fromString(projectId), docTrees);
|
||||
ParserTreeItem::ConstPtr item = ParserTreeItem::mergeTrees(projectPath, docTrees);
|
||||
|
||||
// update the cache
|
||||
if (!projectId.isEmpty()) {
|
||||
ParserPrivate::ProjectCache &projectCache = d->m_projectCache[projectId];
|
||||
if (!projectPath.isEmpty()) {
|
||||
ParserPrivate::ProjectCache &projectCache = d->m_projectCache[projectPath];
|
||||
projectCache.tree = item;
|
||||
projectCache.treeRevision = revision;
|
||||
}
|
||||
@@ -227,15 +211,15 @@ ParserTreeItem::ConstPtr Parser::getParseProjectTree(const QStringList &fileList
|
||||
Updates the internal cached tree for this project.
|
||||
*/
|
||||
|
||||
ParserTreeItem::ConstPtr Parser::getCachedOrParseProjectTree(const QStringList &fileList,
|
||||
const QString &projectId)
|
||||
ParserTreeItem::ConstPtr Parser::getCachedOrParseProjectTree(const FilePath &projectPath,
|
||||
const QSet<FilePath> &filesInProject)
|
||||
{
|
||||
const auto it = d->m_projectCache.constFind(projectId);
|
||||
const auto it = d->m_projectCache.constFind(projectPath);
|
||||
if (it != d->m_projectCache.constEnd() && !it.value().tree.isNull()) {
|
||||
// calculate project's revision
|
||||
unsigned revision = 0;
|
||||
for (const QString &file : fileList) {
|
||||
const CPlusPlus::Document::Ptr &doc = d->document(file);
|
||||
for (const FilePath &fileInProject : filesInProject) {
|
||||
const CPlusPlus::Document::Ptr &doc = d->document(fileInProject);
|
||||
if (doc.isNull())
|
||||
continue;
|
||||
revision += doc->revision();
|
||||
@@ -246,7 +230,7 @@ ParserTreeItem::ConstPtr Parser::getCachedOrParseProjectTree(const QStringList &
|
||||
return it.value().tree;
|
||||
}
|
||||
|
||||
return getParseProjectTree(fileList, projectId);
|
||||
return getParseProjectTree(projectPath, filesInProject);
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -261,9 +245,7 @@ ParserTreeItem::ConstPtr Parser::getParseDocumentTree(const CPlusPlus::Document:
|
||||
if (doc.isNull())
|
||||
return ParserTreeItem::ConstPtr();
|
||||
|
||||
const QString &fileName = doc->fileName();
|
||||
if (!d->fileList.contains(fileName))
|
||||
return ParserTreeItem::ConstPtr();
|
||||
const FilePath fileName = FilePath::fromString(doc->fileName());
|
||||
|
||||
ParserTreeItem::ConstPtr itemPtr = ParserTreeItem::parseDocument(doc);
|
||||
|
||||
@@ -284,7 +266,7 @@ ParserTreeItem::ConstPtr Parser::getCachedOrParseDocumentTree(const CPlusPlus::D
|
||||
return ParserTreeItem::ConstPtr();
|
||||
|
||||
const QString &fileName = doc->fileName();
|
||||
const auto it = d->m_documentCache.constFind(fileName);
|
||||
const auto it = d->m_documentCache.constFind(FilePath::fromString(fileName));
|
||||
if (it != d->m_documentCache.constEnd() && !it.value().tree.isNull()
|
||||
&& it.value().treeRevision == doc->revision()) {
|
||||
return it.value().tree;
|
||||
@@ -297,13 +279,17 @@ ParserTreeItem::ConstPtr Parser::getCachedOrParseDocumentTree(const CPlusPlus::D
|
||||
the internal storage.
|
||||
*/
|
||||
|
||||
void Parser::updateDocuments(const QList<CPlusPlus::Document::Ptr> &docs)
|
||||
void Parser::updateDocuments(const QSet<FilePath> &documentPaths)
|
||||
{
|
||||
for (const CPlusPlus::Document::Ptr &doc: docs) {
|
||||
const QString &name = doc->fileName();
|
||||
updateDocumentsFromSnapshot(documentPaths, CppTools::CppModelManager::instance()->snapshot());
|
||||
}
|
||||
|
||||
// if it is external file (not in any of our projects)
|
||||
if (!d->fileList.contains(name))
|
||||
void Parser::updateDocumentsFromSnapshot(const QSet<Utils::FilePath> &documentPaths,
|
||||
const CPlusPlus::Snapshot &snapshot)
|
||||
{
|
||||
for (const FilePath &documentPath : documentPaths) {
|
||||
CPlusPlus::Document::Ptr doc = snapshot.document(documentPath);
|
||||
if (doc.isNull())
|
||||
continue;
|
||||
|
||||
getParseDocumentTree(doc);
|
||||
@@ -311,16 +297,6 @@ void Parser::updateDocuments(const QList<CPlusPlus::Document::Ptr> &docs)
|
||||
requestCurrentState();
|
||||
}
|
||||
|
||||
/*!
|
||||
Specifies the files that must be allowed for the parsing as a \a fileList.
|
||||
Files outside of this list will not be in any tree.
|
||||
*/
|
||||
|
||||
void Parser::setFileList(const QStringList &fileList)
|
||||
{
|
||||
d->fileList = Utils::toSet(fileList);
|
||||
}
|
||||
|
||||
/*!
|
||||
Removes the files defined in the \a fileList from the parsing.
|
||||
*/
|
||||
@@ -331,11 +307,11 @@ void Parser::removeFiles(const QStringList &fileList)
|
||||
return;
|
||||
|
||||
for (const QString &name : fileList) {
|
||||
d->fileList.remove(name);
|
||||
d->m_documentCache.remove(name);
|
||||
d->m_projectCache.remove(name);
|
||||
const FilePath filePath = FilePath::fromString(name);
|
||||
d->m_documentCache.remove(filePath);
|
||||
d->m_projectCache.remove(filePath);
|
||||
for (auto it = d->m_projectCache.begin(); it != d->m_projectCache.end(); ++it)
|
||||
it.value().fileList.removeOne(name);
|
||||
it.value().fileNames.remove(filePath);
|
||||
}
|
||||
requestCurrentState();
|
||||
}
|
||||
@@ -343,75 +319,66 @@ void Parser::removeFiles(const QStringList &fileList)
|
||||
/*!
|
||||
Fully resets the internal state of the code parser to \a snapshot.
|
||||
*/
|
||||
void Parser::resetData(const CPlusPlus::Snapshot &snapshot)
|
||||
void Parser::resetData(const QHash<FilePath, QPair<QString, FilePaths>> &projects)
|
||||
{
|
||||
d->m_projectCache.clear();
|
||||
d->m_documentCache.clear();
|
||||
for (auto it = snapshot.begin(); it != snapshot.end(); ++it)
|
||||
d->m_documentCache[it.key().toString()].document = it.value();
|
||||
|
||||
// recalculate file list
|
||||
FilePaths fileList;
|
||||
const CPlusPlus::Snapshot &snapshot = CppTools::CppModelManager::instance()->snapshot();
|
||||
for (auto it = projects.cbegin(); it != projects.cend(); ++it) {
|
||||
const auto projectData = it.value();
|
||||
QSet<FilePath> commonFiles;
|
||||
for (const auto &fileInProject : projectData.second) {
|
||||
CPlusPlus::Document::Ptr doc = snapshot.document(fileInProject);
|
||||
if (doc.isNull())
|
||||
continue;
|
||||
commonFiles.insert(fileInProject);
|
||||
d->m_documentCache[fileInProject].document = doc;
|
||||
}
|
||||
d->m_projectCache.insert(it.key(), { 0, nullptr, projectData.first, commonFiles });
|
||||
}
|
||||
|
||||
// TODO: move a call to SessionManager::projects() out of this thread
|
||||
for (const Project *prj : SessionManager::projects())
|
||||
fileList += prj->files(Project::SourceFiles);
|
||||
setFileList(Utils::transform(fileList, &FilePath::toString));
|
||||
requestCurrentState();
|
||||
}
|
||||
|
||||
void Parser::addProject(const FilePath &projectPath, const QString &projectName,
|
||||
const FilePaths &filesInProject)
|
||||
{
|
||||
const CPlusPlus::Snapshot &snapshot = CppTools::CppModelManager::instance()->snapshot();
|
||||
QSet<FilePath> commonFiles;
|
||||
for (const auto &fileInProject : filesInProject) {
|
||||
CPlusPlus::Document::Ptr doc = snapshot.document(fileInProject);
|
||||
if (doc.isNull())
|
||||
continue;
|
||||
commonFiles.insert(fileInProject);
|
||||
d->m_documentCache[fileInProject].document = doc;
|
||||
}
|
||||
d->m_projectCache.insert(projectPath, { 0, nullptr, projectName, commonFiles });
|
||||
updateDocumentsFromSnapshot(commonFiles, snapshot);
|
||||
}
|
||||
|
||||
void Parser::removeProject(const FilePath &projectPath)
|
||||
{
|
||||
auto it = d->m_projectCache.find(projectPath);
|
||||
if (it == d->m_projectCache.end())
|
||||
return;
|
||||
|
||||
const QSet<FilePath> &filesInProject = it.value().fileNames;
|
||||
for (const FilePath &fileInProject : filesInProject)
|
||||
d->m_documentCache.remove(fileInProject);
|
||||
|
||||
d->m_projectCache.erase(it);
|
||||
|
||||
requestCurrentState();
|
||||
}
|
||||
|
||||
/*!
|
||||
Fully resets the internal state of the code parser to the current state.
|
||||
|
||||
\sa resetData
|
||||
*/
|
||||
|
||||
void Parser::resetDataToCurrentState()
|
||||
{
|
||||
// get latest data
|
||||
resetData(CppTools::CppModelManager::instance()->snapshot());
|
||||
}
|
||||
|
||||
/*!
|
||||
Requests to emit a signal with the current tree state.
|
||||
*/
|
||||
|
||||
void Parser::requestCurrentState()
|
||||
{
|
||||
// TODO: we need to have a fresh SessionManager data here, which we could pass to parse()
|
||||
emit treeRegenerated(parse());
|
||||
}
|
||||
|
||||
// TODO: don't use Project class in this thread
|
||||
QStringList Parser::getAllFiles(const Project *project)
|
||||
{
|
||||
if (!project)
|
||||
return {};
|
||||
|
||||
const QString projectPath = project->projectFilePath().toString();
|
||||
const auto it = d->m_projectCache.constFind(projectPath);
|
||||
if (it != d->m_projectCache.constEnd())
|
||||
return it.value().fileList;
|
||||
|
||||
const QStringList fileList = Utils::transform(project->files(Project::SourceFiles),
|
||||
&FilePath::toString);
|
||||
d->m_projectCache[projectPath].fileList = fileList;
|
||||
return fileList;
|
||||
}
|
||||
|
||||
// TODO: don't use Project class in this thread
|
||||
ParserTreeItem::ConstPtr Parser::addFlatTree(const Project *project)
|
||||
{
|
||||
if (!project)
|
||||
return {};
|
||||
|
||||
const QStringList fileList = getAllFiles(project);
|
||||
if (fileList.isEmpty())
|
||||
return {};
|
||||
|
||||
return getCachedOrParseProjectTree(fileList, project->projectFilePath().toString());
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace ClassView
|
||||
|
||||
@@ -54,28 +54,29 @@ public:
|
||||
|
||||
void requestCurrentState();
|
||||
void removeFiles(const QStringList &fileList);
|
||||
void resetDataToCurrentState();
|
||||
void resetData(const QHash<Utils::FilePath, QPair<QString, Utils::FilePaths>> &projects);
|
||||
void addProject(const Utils::FilePath &projectPath, const QString &projectName,
|
||||
const Utils::FilePaths &filesInProject);
|
||||
void removeProject(const Utils::FilePath &projectPath);
|
||||
void setFlatMode(bool flat);
|
||||
|
||||
void updateDocuments(const QList<CPlusPlus::Document::Ptr> &docs);
|
||||
void updateDocuments(const QSet<Utils::FilePath> &documentPaths);
|
||||
|
||||
signals:
|
||||
void treeRegenerated(const ParserTreeItem::ConstPtr &root);
|
||||
|
||||
private:
|
||||
void setFileList(const QStringList &fileList);
|
||||
void resetData(const CPlusPlus::Snapshot &snapshot);
|
||||
void updateDocumentsFromSnapshot(const QSet<Utils::FilePath> &documentPaths,
|
||||
const CPlusPlus::Snapshot &snapshot);
|
||||
|
||||
ParserTreeItem::ConstPtr getParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
||||
ParserTreeItem::ConstPtr getCachedOrParseDocumentTree(const CPlusPlus::Document::Ptr &doc);
|
||||
ParserTreeItem::ConstPtr getParseProjectTree(const QStringList &fileList, const QString &projectId);
|
||||
ParserTreeItem::ConstPtr getCachedOrParseProjectTree(const QStringList &fileList,
|
||||
const QString &projectId);
|
||||
ParserTreeItem::ConstPtr getParseProjectTree(const Utils::FilePath &projectPath,
|
||||
const QSet<Utils::FilePath> &filesInProject);
|
||||
ParserTreeItem::ConstPtr getCachedOrParseProjectTree(const Utils::FilePath &projectPath,
|
||||
const QSet<Utils::FilePath> &filesInProject);
|
||||
ParserTreeItem::ConstPtr parse();
|
||||
|
||||
QStringList getAllFiles(const ProjectExplorer::Project *project);
|
||||
ParserTreeItem::ConstPtr addFlatTree(const ProjectExplorer::Project *project);
|
||||
|
||||
//! Private class data pointer
|
||||
ParserPrivate *d;
|
||||
};
|
||||
|
||||
@@ -233,7 +233,8 @@ void addFileSystemNodes(ProjectNode *root, const QList<const FileNode *> &allFil
|
||||
|
||||
if (!fileSystemNode->isEmpty()) {
|
||||
// make file system nodes less probable to be selected when syncing with the current document
|
||||
fileSystemNode->forEachGenericNode([](Node *n) { n->setPriority(n->priority() + 10); });
|
||||
fileSystemNode->forEachGenericNode(
|
||||
[](Node *n) { n->setPriority(n->priority() + Node::DefaultProjectFilePriority + 1); });
|
||||
root->addNode(std::move(fileSystemNode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1753,6 +1753,11 @@ bool EditorManagerPrivate::closeEditors(const QList<IEditor*> &editors, CloseFla
|
||||
flags = EditorManager::DoNotSwitchToDesignMode;
|
||||
activateEditorForDocument(view, document, flags);
|
||||
}
|
||||
} else {
|
||||
// no documents left - set current view since view->removeEditor can
|
||||
// trigger a focus change, context change, and updateActions, which
|
||||
// requests the current EditorView
|
||||
setCurrentView(currentView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1766,10 +1771,12 @@ bool EditorManagerPrivate::closeEditors(const QList<IEditor*> &editors, CloseFla
|
||||
foreach (IEditor *editor, acceptedEditors)
|
||||
delete editor;
|
||||
|
||||
if (focusView)
|
||||
if (focusView) {
|
||||
activateView(focusView);
|
||||
else
|
||||
} else {
|
||||
setCurrentView(currentView);
|
||||
setCurrentEditor(currentView->currentEditor());
|
||||
}
|
||||
|
||||
if (!EditorManager::currentEditor()) {
|
||||
emit m_instance->currentEditorChanged(nullptr);
|
||||
|
||||
@@ -142,6 +142,8 @@ Client::~Client()
|
||||
}
|
||||
for (IAssistProcessor *processor : qAsConst(m_runningAssistProcessors))
|
||||
processor->setAsyncProposalAvailable(nullptr);
|
||||
qDeleteAll(m_documentHighlightsTimer);
|
||||
m_documentHighlightsTimer.clear();
|
||||
updateEditorToolBar(m_openedDocument.keys());
|
||||
// do not handle messages while shutting down
|
||||
disconnect(m_clientInterface.data(), &BaseClientInterface::messageReceived,
|
||||
@@ -437,6 +439,64 @@ void Client::updateFunctionHintProvider(TextEditor::TextDocument *document)
|
||||
}
|
||||
}
|
||||
|
||||
void Client::requestDocumentHighlights(TextEditor::TextEditorWidget *widget)
|
||||
{
|
||||
const auto uri = DocumentUri::fromFilePath(widget->textDocument()->filePath());
|
||||
if (m_dynamicCapabilities.isRegistered(DocumentHighlightsRequest::methodName).value_or(false)) {
|
||||
TextDocumentRegistrationOptions option(
|
||||
m_dynamicCapabilities.option(DocumentHighlightsRequest::methodName));
|
||||
if (!option.filterApplies(widget->textDocument()->filePath()))
|
||||
return;
|
||||
} else {
|
||||
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> provider
|
||||
= m_serverCapabilities.documentHighlightProvider();
|
||||
if (!provider.has_value())
|
||||
return;
|
||||
if (Utils::holds_alternative<bool>(*provider) && !Utils::get<bool>(*provider))
|
||||
return;
|
||||
}
|
||||
|
||||
auto runningRequest = m_highlightRequests.find(uri);
|
||||
if (runningRequest != m_highlightRequests.end())
|
||||
cancelRequest(runningRequest.value());
|
||||
|
||||
DocumentHighlightsRequest request(
|
||||
TextDocumentPositionParams(TextDocumentIdentifier(uri), Position(widget->textCursor())));
|
||||
request.setResponseCallback(
|
||||
[widget = QPointer<TextEditor::TextEditorWidget>(widget), this, uri]
|
||||
(const DocumentHighlightsRequest::Response &response)
|
||||
{
|
||||
m_highlightRequests.remove(uri);
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
const Id &id = TextEditor::TextEditorWidget::CodeSemanticsSelection;
|
||||
QList<QTextEdit::ExtraSelection> selections;
|
||||
const Utils::optional<DocumentHighlightsResult> &result = response.result();
|
||||
if (!result.has_value() || holds_alternative<std::nullptr_t>(result.value())) {
|
||||
widget->setExtraSelections(id, selections);
|
||||
return;
|
||||
}
|
||||
|
||||
const QTextCharFormat &format =
|
||||
widget->textDocument()->fontSettings().toTextCharFormat(TextEditor::C_OCCURRENCES);
|
||||
QTextDocument *document = widget->document();
|
||||
for (const auto &highlight : get<QList<DocumentHighlight>>(result.value())) {
|
||||
QTextEdit::ExtraSelection selection{widget->textCursor(), format};
|
||||
const int &start = highlight.range().start().toPositionInDocument(document);
|
||||
const int &end = highlight.range().end().toPositionInDocument(document);
|
||||
if (start < 0 || end < 0)
|
||||
continue;
|
||||
selection.cursor.setPosition(start);
|
||||
selection.cursor.setPosition(end, QTextCursor::KeepAnchor);
|
||||
selections << selection;
|
||||
}
|
||||
widget->setExtraSelections(id, selections);
|
||||
});
|
||||
m_highlightRequests[uri] = request.id();
|
||||
sendContent(request);
|
||||
}
|
||||
|
||||
void Client::activateDocument(TextEditor::TextDocument *document)
|
||||
{
|
||||
auto uri = DocumentUri::fromFilePath(document->filePath());
|
||||
@@ -453,11 +513,11 @@ void Client::activateDocument(TextEditor::TextDocument *document)
|
||||
for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(document)) {
|
||||
updateEditorToolBar(editor);
|
||||
if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor)) {
|
||||
textEditor->editorWidget()->addHoverHandler(&m_hoverHandler);
|
||||
if (symbolSupport().supportsRename(document)) {
|
||||
textEditor->editorWidget()->addOptionalActions(
|
||||
TextEditor::TextEditorActionHandler::RenameSymbol);
|
||||
}
|
||||
TextEditor::TextEditorWidget *widget = textEditor->editorWidget();
|
||||
widget->addHoverHandler(&m_hoverHandler);
|
||||
requestDocumentHighlights(widget);
|
||||
if (symbolSupport().supportsRename(document))
|
||||
widget->addOptionalActions(TextEditor::TextEditorActionHandler::RenameSymbol);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -472,8 +532,11 @@ void Client::deactivateDocument(TextEditor::TextDocument *document)
|
||||
highlighter->clearAllExtraFormats();
|
||||
}
|
||||
for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(document)) {
|
||||
if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor))
|
||||
textEditor->editorWidget()->removeHoverHandler(&m_hoverHandler);
|
||||
if (auto textEditor = qobject_cast<TextEditor::BaseTextEditor *>(editor)) {
|
||||
TextEditor::TextEditorWidget *widget = textEditor->editorWidget();
|
||||
widget->removeHoverHandler(&m_hoverHandler);
|
||||
widget->setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -635,61 +698,38 @@ TextEditor::HighlightingResult createHighlightingResult(const SymbolInformation
|
||||
|
||||
void Client::cursorPositionChanged(TextEditor::TextEditorWidget *widget)
|
||||
{
|
||||
if (m_documentsToUpdate.contains(widget->textDocument()))
|
||||
TextEditor::TextDocument *document = widget->textDocument();
|
||||
if (m_documentsToUpdate.contains(document))
|
||||
return; // we are currently changing this document so postpone the DocumentHighlightsRequest
|
||||
const auto uri = DocumentUri::fromFilePath(widget->textDocument()->filePath());
|
||||
if (m_dynamicCapabilities.isRegistered(DocumentHighlightsRequest::methodName).value_or(false)) {
|
||||
TextDocumentRegistrationOptions option(
|
||||
m_dynamicCapabilities.option(DocumentHighlightsRequest::methodName));
|
||||
if (!option.filterApplies(widget->textDocument()->filePath()))
|
||||
return;
|
||||
} else {
|
||||
Utils::optional<Utils::variant<bool, WorkDoneProgressOptions>> provider
|
||||
= m_serverCapabilities.documentHighlightProvider();
|
||||
if (!provider.has_value())
|
||||
return;
|
||||
if (Utils::holds_alternative<bool>(*provider) && !Utils::get<bool>(*provider))
|
||||
return;
|
||||
QTimer *timer = m_documentHighlightsTimer[widget];
|
||||
if (!timer) {
|
||||
const auto uri = DocumentUri::fromFilePath(widget->textDocument()->filePath());
|
||||
auto runningRequest = m_highlightRequests.find(uri);
|
||||
if (runningRequest != m_highlightRequests.end())
|
||||
cancelRequest(runningRequest.value());
|
||||
timer = new QTimer;
|
||||
timer->setSingleShot(true);
|
||||
m_documentHighlightsTimer.insert(widget, timer);
|
||||
connect(timer, &QTimer::timeout, this, [this, widget]() {
|
||||
requestDocumentHighlights(widget);
|
||||
m_documentHighlightsTimer.take(widget)->deleteLater();
|
||||
});
|
||||
connect(widget, &QWidget::destroyed, this, [widget, this]() {
|
||||
delete m_documentHighlightsTimer.take(widget);
|
||||
});
|
||||
}
|
||||
|
||||
auto runningRequest = m_highlightRequests.find(uri);
|
||||
if (runningRequest != m_highlightRequests.end())
|
||||
cancelRequest(runningRequest.value());
|
||||
|
||||
DocumentHighlightsRequest request(
|
||||
TextDocumentPositionParams(TextDocumentIdentifier(uri), Position(widget->textCursor())));
|
||||
request.setResponseCallback(
|
||||
[widget = QPointer<TextEditor::TextEditorWidget>(widget), this, uri]
|
||||
(DocumentHighlightsRequest::Response response)
|
||||
{
|
||||
m_highlightRequests.remove(uri);
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
QList<QTextEdit::ExtraSelection> selections;
|
||||
const DocumentHighlightsResult result = response.result().value_or(DocumentHighlightsResult());
|
||||
if (!holds_alternative<QList<DocumentHighlight>>(result)) {
|
||||
widget->setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections);
|
||||
return;
|
||||
}
|
||||
|
||||
const QTextCharFormat &format =
|
||||
widget->textDocument()->fontSettings().toTextCharFormat(TextEditor::C_OCCURRENCES);
|
||||
QTextDocument *document = widget->document();
|
||||
for (const auto &highlight : get<QList<DocumentHighlight>>(result)) {
|
||||
QTextEdit::ExtraSelection selection{widget->textCursor(), format};
|
||||
const int &start = highlight.range().start().toPositionInDocument(document);
|
||||
const int &end = highlight.range().end().toPositionInDocument(document);
|
||||
if (start < 0 || end < 0)
|
||||
continue;
|
||||
selection.cursor.setPosition(start);
|
||||
selection.cursor.setPosition(end, QTextCursor::KeepAnchor);
|
||||
selections << selection;
|
||||
}
|
||||
widget->setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, selections);
|
||||
});
|
||||
m_highlightRequests[uri] = request.id();
|
||||
sendContent(request);
|
||||
const Id selectionsId(TextEditor::TextEditorWidget::CodeSemanticsSelection);
|
||||
const QList semanticSelections = widget->extraSelections(selectionsId);
|
||||
if (!semanticSelections.isEmpty()) {
|
||||
auto selectionContainsPos =
|
||||
[pos = widget->position()](const QTextEdit::ExtraSelection &selection) {
|
||||
const QTextCursor cursor = selection.cursor;
|
||||
return cursor.selectionStart() <= pos && cursor.selectionEnd() >= pos;
|
||||
};
|
||||
if (!Utils::anyOf(semanticSelections, selectionContainsPos))
|
||||
widget->setExtraSelections(selectionsId, {});
|
||||
}
|
||||
timer->start(250);
|
||||
}
|
||||
|
||||
SymbolSupport &Client::symbolSupport()
|
||||
@@ -893,6 +933,8 @@ bool Client::reset()
|
||||
for (TextEditor::IAssistProcessor *processor : qAsConst(m_runningAssistProcessors))
|
||||
processor->setAsyncProposalAvailable(nullptr);
|
||||
m_runningAssistProcessors.clear();
|
||||
qDeleteAll(m_documentHighlightsTimer);
|
||||
m_documentHighlightsTimer.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -199,6 +199,7 @@ private:
|
||||
void updateCompletionProvider(TextEditor::TextDocument *document);
|
||||
void updateFunctionHintProvider(TextEditor::TextDocument *document);
|
||||
|
||||
void requestDocumentHighlights(TextEditor::TextEditorWidget *widget);
|
||||
void rehighlight();
|
||||
|
||||
using ContentHandler = std::function<void(const QByteArray &, QTextCodec *, QString &,
|
||||
@@ -216,6 +217,7 @@ private:
|
||||
QMap<TextEditor::TextDocument *,
|
||||
QList<LanguageServerProtocol::DidChangeTextDocumentParams::TextDocumentContentChangeEvent>>
|
||||
m_documentsToUpdate;
|
||||
QMap<TextEditor::TextEditorWidget *, QTimer *> m_documentHighlightsTimer;
|
||||
QTimer m_documentUpdateTimer;
|
||||
Utils::Id m_id;
|
||||
LanguageServerProtocol::ServerCapabilities m_serverCapabilities;
|
||||
|
||||
@@ -435,15 +435,10 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor)
|
||||
if (auto client = clientForDocument(document))
|
||||
client->symbolSupport().renameSymbol(document, cursor);
|
||||
});
|
||||
connect(widget, &TextEditorWidget::cursorPositionChanged, this, [this, widget]() {
|
||||
// TODO This would better be a compressing timer
|
||||
QTimer::singleShot(50, this, [widget = QPointer<TextEditorWidget>(widget)]() {
|
||||
if (!widget)
|
||||
return;
|
||||
if (Client *client = clientForDocument(widget->textDocument()))
|
||||
if (client->reachable())
|
||||
client->cursorPositionChanged(widget);
|
||||
});
|
||||
connect(widget, &TextEditorWidget::cursorPositionChanged, this, [widget]() {
|
||||
if (Client *client = clientForDocument(widget->textDocument()))
|
||||
if (client->reachable())
|
||||
client->cursorPositionChanged(widget);
|
||||
});
|
||||
updateEditorToolBar(editor);
|
||||
if (TextEditor::TextDocument *document = textEditor->textDocument()) {
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
|
||||
#include "annotation.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDir;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
|
||||
@@ -63,9 +63,9 @@ CurveEditorStyle CurveEditorModel::style() const
|
||||
{
|
||||
// Pseudo auto generated. See: CurveEditorStyleDialog
|
||||
CurveEditorStyle out;
|
||||
out.backgroundBrush = QBrush(QColor(21, 21, 21));
|
||||
out.backgroundAlternateBrush = QBrush(QColor(32, 32, 32));
|
||||
out.fontColor = QColor(255, 255, 255);
|
||||
out.backgroundBrush = QmlDesigner::Theme::getColor(QmlDesigner::Theme::DSsectionHeadBackground);
|
||||
out.backgroundAlternateBrush = QmlDesigner::Theme::getColor(QmlDesigner::Theme::DSpanelBackground);
|
||||
out.fontColor = QmlDesigner::Theme::getColor(QmlDesigner::Theme::DStextColor);
|
||||
out.gridColor = QColor(114, 116, 118);
|
||||
out.canvasMargin = 15;
|
||||
out.zoomInWidth = 99;
|
||||
|
||||
@@ -363,7 +363,8 @@ void CurveEditorView::commitKeyframes(TreeItem *item)
|
||||
void CurveEditorView::commitCurrentFrame(int frame)
|
||||
{
|
||||
QmlTimeline timeline = activeTimeline();
|
||||
timeline.modelNode().setAuxiliaryData("currentFrame@NodeInstance", frame);
|
||||
if (timeline.isValid())
|
||||
timeline.modelNode().setAuxiliaryData("currentFrame@NodeInstance", frame);
|
||||
}
|
||||
|
||||
void CurveEditorView::commitStartFrame(int frame)
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#include "treeitem.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <theme.h>
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QResizeEvent>
|
||||
@@ -84,6 +87,11 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
||||
|
||||
applyZoom(m_zoomX, m_zoomY);
|
||||
update();
|
||||
|
||||
const QString css = Theme::replaceCssColors(QString::fromUtf8(
|
||||
Utils::FileReader::fetchQrc(QLatin1String(":/qmldesigner/scrollbar.css"))));
|
||||
horizontalScrollBar()->setStyleSheet(css);
|
||||
verticalScrollBar()->setStyleSheet(css);
|
||||
}
|
||||
|
||||
GraphicsView::~GraphicsView()
|
||||
|
||||
@@ -81,7 +81,17 @@ QTabBar::tab:selected {
|
||||
|
||||
QLineEdit {
|
||||
color: creatorTheme.DStextColor;
|
||||
background-color: creatorTheme.DSdockAreaBackground;
|
||||
background-color: creatorTheme.DScontrolBackground;
|
||||
border: 1px solid creatorTheme.DScontrolOutline;
|
||||
selection-color: creatorTheme.DStextSelectedTextColor;
|
||||
selection-background-color: creatorTheme.DStextSelectionColor;
|
||||
}
|
||||
|
||||
QLineEdit:hover {
|
||||
background-color: creatorTheme.DScontrolBackgroundHover;
|
||||
}
|
||||
|
||||
QLineEdit:focus {
|
||||
background-color: creatorTheme.DScontrolBackgroundInteraction;
|
||||
border-color: creatorTheme.DScontrolOutlineInteraction;
|
||||
}
|
||||
|
||||
@@ -70,15 +70,17 @@ void TextEditItem::setFormEditorItem(FormEditorItem *formEditorItem)
|
||||
setGeometry(rect);
|
||||
|
||||
NodeMetaInfo metaInfo = m_formEditorItem->qmlItemNode().modelNode().metaInfo();
|
||||
auto node = m_formEditorItem->qmlItemNode();
|
||||
auto font = node.instanceValue("font").value<QFont>();
|
||||
if (metaInfo.isValid() &&
|
||||
(metaInfo.isSubclassOf("QtQuick.TextEdit")
|
||||
|| metaInfo.isSubclassOf("QtQuick.Controls.TextArea"))) {
|
||||
QSize maximumSize = rect.size().toSize();
|
||||
textEdit()->setFont(font);
|
||||
activateTextEdit(maximumSize);
|
||||
} else {
|
||||
auto lineEdit = TextEditItemWidget::lineEdit();
|
||||
auto node = m_formEditorItem->qmlItemNode();
|
||||
lineEdit->setFont(node.instanceValue("font").value<QFont>());
|
||||
lineEdit->setFont(font);
|
||||
activateLineEdit();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,11 +55,10 @@ constexpr int spacingg = 5;
|
||||
|
||||
const QColor background = Qt::white;
|
||||
|
||||
const QColor labelBackground = qRgb(0x70, 0x70, 0x70);
|
||||
const QColor canvasBackground = qRgb(0x46, 0x46, 0x46);
|
||||
const QColor curveLine = qRgb(0xe6, 0xe7, 0xe8);
|
||||
|
||||
PresetItemDelegate::PresetItemDelegate() = default;
|
||||
PresetItemDelegate::PresetItemDelegate(const QColor& background)
|
||||
: QStyledItemDelegate()
|
||||
, m_background(background)
|
||||
{}
|
||||
|
||||
void PresetItemDelegate::paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &opt,
|
||||
@@ -80,10 +79,10 @@ void PresetItemDelegate::paint(QPainter *painter,
|
||||
option.font.setPixelSize(Theme::instance()->smallFontPixelSize());
|
||||
|
||||
painter->save();
|
||||
painter->fillRect(option.rect, canvasBackground);
|
||||
painter->fillRect(option.rect, m_background);
|
||||
|
||||
if (option.text.isEmpty())
|
||||
painter->fillRect(textRect, canvasBackground);
|
||||
painter->fillRect(textRect, m_background);
|
||||
else
|
||||
painter->fillRect(textRect, Theme::instance()->qmlDesignerButtonColor());
|
||||
|
||||
@@ -118,23 +117,25 @@ QSize PresetItemDelegate::sizeHint(const QStyleOptionViewItem &opt, const QModel
|
||||
return size;
|
||||
}
|
||||
|
||||
QIcon paintPreview()
|
||||
QIcon paintPreview(const QColor& background)
|
||||
{
|
||||
QPixmap pm(iconWidth, iconHeight);
|
||||
pm.fill(canvasBackground);
|
||||
pm.fill(background);
|
||||
return QIcon(pm);
|
||||
}
|
||||
|
||||
QIcon paintPreview(const EasingCurve &curve)
|
||||
QIcon paintPreview(const EasingCurve &curve, const QColor& background, const QColor& curveColor)
|
||||
{
|
||||
const QColor curveLine = Theme::getColor(Theme::DStextColor);
|
||||
|
||||
QPixmap pm(iconWidth, iconHeight);
|
||||
pm.fill(canvasBackground);
|
||||
pm.fill(background);
|
||||
|
||||
QPainter painter(&pm);
|
||||
painter.setRenderHint(QPainter::Antialiasing, true);
|
||||
|
||||
Canvas canvas(iconWidth, iconHeight, 2, 2, 9, 6, 0, 1);
|
||||
canvas.paintCurve(&painter, curve, curveLine);
|
||||
canvas.paintCurve(&painter, curve, curveColor);
|
||||
|
||||
return QIcon(pm);
|
||||
}
|
||||
@@ -159,6 +160,8 @@ PresetList::PresetList(QSettings::Scope scope, QWidget *parent)
|
||||
, m_scope(scope)
|
||||
, m_index(-1)
|
||||
, m_filename(Internal::settingsFullFilePath(scope))
|
||||
, m_background(Theme::getColor(Theme::DSsectionHeadBackground ))
|
||||
, m_curveColor(Theme::getColor(Theme::DStextColor))
|
||||
{
|
||||
int magic = 4;
|
||||
int scrollBarWidth = this->style()->pixelMetric(QStyle::PM_ScrollBarExtent);
|
||||
@@ -168,7 +171,7 @@ PresetList::PresetList(QSettings::Scope scope, QWidget *parent)
|
||||
|
||||
setModel(new QStandardItemModel);
|
||||
|
||||
setItemDelegate(new PresetItemDelegate);
|
||||
setItemDelegate(new PresetItemDelegate(m_background));
|
||||
|
||||
setSpacing(spacingg);
|
||||
|
||||
@@ -260,6 +263,16 @@ bool PresetList::isEditable(const QModelIndex &index) const
|
||||
return flags.testFlag(Qt::ItemIsEditable);
|
||||
}
|
||||
|
||||
QColor PresetList::backgroundColor() const
|
||||
{
|
||||
return m_background;
|
||||
}
|
||||
|
||||
QColor PresetList::curveColor() const
|
||||
{
|
||||
return m_curveColor;
|
||||
}
|
||||
|
||||
void PresetList::initialize(int index)
|
||||
{
|
||||
m_index = index;
|
||||
@@ -278,7 +291,7 @@ void PresetList::readPresets()
|
||||
for (int i = 0; i < curves.size(); ++i) {
|
||||
QVariant curveData = QVariant::fromValue(curves[i].curve());
|
||||
|
||||
auto *item = new QStandardItem(paintPreview(curves[i].curve()), curves[i].name());
|
||||
auto *item = new QStandardItem(paintPreview(curves[i].curve(), m_background, m_curveColor), curves[i].name());
|
||||
item->setData(curveData, ItemRole_Data);
|
||||
item->setEditable(m_scope == QSettings::UserScope);
|
||||
item->setToolTip(curves[i].name());
|
||||
@@ -320,7 +333,7 @@ void PresetList::revert(const QModelIndex &index)
|
||||
for (const auto &curve : curves) {
|
||||
if (curve.name() == name) {
|
||||
item->setData(false, ItemRole_Dirty);
|
||||
item->setData(paintPreview(curve.curve()), Qt::DecorationRole);
|
||||
item->setData(paintPreview(curve.curve(), m_background, m_curveColor), Qt::DecorationRole);
|
||||
item->setData(QVariant::fromValue(curve.curve()), ItemRole_Data);
|
||||
item->setToolTip(name);
|
||||
return;
|
||||
@@ -334,7 +347,7 @@ void PresetList::updateCurve(const EasingCurve &curve)
|
||||
if (!selectionModel()->hasSelection())
|
||||
return;
|
||||
|
||||
QVariant icon = QVariant::fromValue(paintPreview(curve));
|
||||
QVariant icon = QVariant::fromValue(paintPreview(curve, m_background, m_curveColor));
|
||||
QVariant curveData = QVariant::fromValue(curve);
|
||||
|
||||
for (const auto &index : selectionModel()->selectedIndexes())
|
||||
@@ -382,7 +395,7 @@ void PresetList::createItem()
|
||||
|
||||
void PresetList::createItem(const QString &name, const EasingCurve &curve)
|
||||
{
|
||||
auto *item = new QStandardItem(paintPreview(curve), name);
|
||||
auto *item = new QStandardItem(paintPreview(curve, m_background, m_curveColor), name);
|
||||
item->setData(QVariant::fromValue(curve), ItemRole_Data);
|
||||
item->setToolTip(name);
|
||||
|
||||
@@ -507,7 +520,8 @@ void PresetEditor::update(const EasingCurve &curve)
|
||||
m_presets->selectionModel()->clear();
|
||||
else {
|
||||
if (m_customs->selectionModel()->hasSelection()) {
|
||||
QVariant icon = QVariant::fromValue(paintPreview(curve));
|
||||
QVariant icon = QVariant::fromValue(
|
||||
paintPreview(curve, m_presets->backgroundColor(), m_presets->curveColor()));
|
||||
QVariant curveData = QVariant::fromValue(curve);
|
||||
for (const QModelIndex &index : m_customs->selectionModel()->selectedIndexes())
|
||||
m_customs->setItemData(index, curveData, icon);
|
||||
|
||||
@@ -43,13 +43,16 @@ class PresetItemDelegate : public QStyledItemDelegate
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PresetItemDelegate();
|
||||
PresetItemDelegate(const QColor& background);
|
||||
|
||||
void paint(QPainter *painter,
|
||||
const QStyleOptionViewItem &opt,
|
||||
const QModelIndex &index) const override;
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;
|
||||
|
||||
private:
|
||||
QColor m_background;
|
||||
};
|
||||
|
||||
class PresetList : public QListView
|
||||
@@ -80,6 +83,10 @@ public:
|
||||
|
||||
bool isEditable(const QModelIndex &index) const;
|
||||
|
||||
QColor backgroundColor() const;
|
||||
|
||||
QColor curveColor() const;
|
||||
|
||||
void initialize(int index);
|
||||
|
||||
void readPresets();
|
||||
@@ -118,6 +125,10 @@ private:
|
||||
int m_index;
|
||||
|
||||
QString m_filename;
|
||||
|
||||
QColor m_background;
|
||||
|
||||
QColor m_curveColor;
|
||||
};
|
||||
|
||||
class PresetEditor : public QStackedWidget
|
||||
|
||||
@@ -6010,6 +6010,7 @@ void TextEditorWidgetPrivate::toggleBlockVisible(const QTextBlock &block)
|
||||
void TextEditorWidget::setLanguageSettingsId(Id settingsId)
|
||||
{
|
||||
d->m_tabSettingsId = settingsId;
|
||||
setCodeStyle(TextEditorSettings::codeStyle(settingsId));
|
||||
}
|
||||
|
||||
Id TextEditorWidget::languageSettingsId() const
|
||||
@@ -6019,20 +6020,24 @@ Id TextEditorWidget::languageSettingsId() const
|
||||
|
||||
void TextEditorWidget::setCodeStyle(ICodeStylePreferences *preferences)
|
||||
{
|
||||
textDocument()->indenter()->setCodeStylePreferences(preferences);
|
||||
TextDocument *document = d->m_document.data();
|
||||
// Not fully initialized yet... wait for TextEditorWidgetPrivate::setupDocumentSignals
|
||||
if (!document)
|
||||
return;
|
||||
document->indenter()->setCodeStylePreferences(preferences);
|
||||
if (d->m_codeStylePreferences) {
|
||||
disconnect(d->m_codeStylePreferences, &ICodeStylePreferences::currentTabSettingsChanged,
|
||||
d->m_document.data(), &TextDocument::setTabSettings);
|
||||
document, &TextDocument::setTabSettings);
|
||||
disconnect(d->m_codeStylePreferences, &ICodeStylePreferences::currentValueChanged,
|
||||
this, &TextEditorWidget::slotCodeStyleSettingsChanged);
|
||||
}
|
||||
d->m_codeStylePreferences = preferences;
|
||||
if (d->m_codeStylePreferences) {
|
||||
connect(d->m_codeStylePreferences, &ICodeStylePreferences::currentTabSettingsChanged,
|
||||
d->m_document.data(), &TextDocument::setTabSettings);
|
||||
document, &TextDocument::setTabSettings);
|
||||
connect(d->m_codeStylePreferences, &ICodeStylePreferences::currentValueChanged,
|
||||
this, &TextEditorWidget::slotCodeStyleSettingsChanged);
|
||||
d->m_document->setTabSettings(d->m_codeStylePreferences->currentTabSettings());
|
||||
document->setTabSettings(d->m_codeStylePreferences->currentTabSettings());
|
||||
slotCodeStyleSettingsChanged(d->m_codeStylePreferences->currentValue());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user