todoitemsprovider.cpp 6.35 KB
Newer Older
Dmitry Savchenko's avatar
Dmitry Savchenko committed
1 2
/**************************************************************************
**
Eike Ziller's avatar
Eike Ziller committed
3 4 5
** Copyright (C) 2015 Dmitry Savchenko
** Copyright (C) 2015 Vasiliy Sorokin
** Contact: http://www.qt.io/licensing
Dmitry Savchenko's avatar
Dmitry Savchenko committed
6
**
hjk's avatar
hjk committed
7
** This file is part of Qt Creator.
Dmitry Savchenko's avatar
Dmitry Savchenko committed
8
**
hjk's avatar
hjk committed
9 10 11 12
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
Eike Ziller's avatar
Eike Ziller committed
13 14
** a written agreement between you and The Qt Company.  For licensing terms and
** conditions see http://www.qt.io/terms-conditions.  For further information
Eike Ziller's avatar
Eike Ziller committed
15
** use the contact form at http://www.qt.io/contact-us.
Dmitry Savchenko's avatar
Dmitry Savchenko committed
16 17
**
** GNU Lesser General Public License Usage
hjk's avatar
hjk committed
18
** Alternatively, this file may be used under the terms of the GNU Lesser
Eike Ziller's avatar
Eike Ziller committed
19 20 21 22 23 24
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file.  Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
hjk's avatar
hjk committed
25
**
Eike Ziller's avatar
Eike Ziller committed
26 27
** In addition, as a special exception, The Qt Company gives you certain additional
** rights.  These rights are described in The Qt Company LGPL Exception
Dmitry Savchenko's avatar
Dmitry Savchenko committed
28 29
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
30
****************************************************************************/
Dmitry Savchenko's avatar
Dmitry Savchenko committed
31 32 33 34 35

#include "todoitemsprovider.h"
#include "constants.h"
#include "cpptodoitemsscanner.h"
#include "qmljstodoitemsscanner.h"
36 37
#include "todoitemsmodel.h"
#include "todoitemsscanner.h"
Dmitry Savchenko's avatar
Dmitry Savchenko committed
38 39 40

#include <projectexplorer/projectexplorer.h>
#include <coreplugin/editormanager/editormanager.h>
41
#include <coreplugin/idocument.h>
Dmitry Savchenko's avatar
Dmitry Savchenko committed
42 43 44 45
#include <projectexplorer/session.h>

#include <QTimer>

hjk's avatar
hjk committed
46 47
using namespace ProjectExplorer;

Dmitry Savchenko's avatar
Dmitry Savchenko committed
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
namespace Todo {
namespace Internal {

TodoItemsProvider::TodoItemsProvider(Settings settings, QObject *parent) :
    QObject(parent),
    m_settings(settings)
{
    setupItemsModel();
    setupStartupProjectBinding();
    setupCurrentEditorBinding();
    setupUpdateListTimer();
    createScanners();
}

TodoItemsModel *TodoItemsProvider::todoItemsModel()
{
    return m_itemsModel;
}

void TodoItemsProvider::settingsChanged(const Settings &newSettings)
{
69
    if (newSettings.keywords != m_settings.keywords) {
Dmitry Savchenko's avatar
Dmitry Savchenko committed
70
        foreach (TodoItemsScanner *scanner, m_scanners)
71 72
            scanner->setParams(newSettings.keywords);
    }
Dmitry Savchenko's avatar
Dmitry Savchenko committed
73 74 75 76 77 78

    m_settings = newSettings;

    updateList();
}

79 80 81 82 83 84
void TodoItemsProvider::projectSettingsChanged(Project *project)
{
    Q_UNUSED(project);
    updateList();
}

Dmitry Savchenko's avatar
Dmitry Savchenko committed
85 86 87 88 89 90 91
void TodoItemsProvider::updateList()
{
    m_itemsList.clear();

    // Show only items of the current file if any
    if (m_settings.scanningScope == ScanningScopeCurrentFile) {
        if (m_currentEditor)
92
            m_itemsList = m_itemsHash.value(m_currentEditor->document()->filePath().toString());
Dmitry Savchenko's avatar
Dmitry Savchenko committed
93
    // Show only items of the startup project if any
94 95
    } else if (m_startupProject) {
        setItemsListWithinStartupProject();
Dmitry Savchenko's avatar
Dmitry Savchenko committed
96 97 98 99 100 101 102 103 104
    }

    m_itemsModel->todoItemsListUpdated();
}

void TodoItemsProvider::createScanners()
{
    qRegisterMetaType<QList<TodoItem> >("QList<TodoItem>");

105
    if (CppTools::CppModelManager::instance())
Dmitry Savchenko's avatar
Dmitry Savchenko committed
106 107 108 109 110
        m_scanners << new CppTodoItemsScanner(m_settings.keywords, this);

    if (QmlJS::ModelManagerInterface::instance())
        m_scanners << new QmlJsTodoItemsScanner(m_settings.keywords, this);

111
    foreach (TodoItemsScanner *scanner, m_scanners) {
Dmitry Savchenko's avatar
Dmitry Savchenko committed
112 113
        connect(scanner, SIGNAL(itemsFetched(QString,QList<TodoItem>)), this,
            SLOT(itemsFetched(QString,QList<TodoItem>)), Qt::QueuedConnection);
114
    }
Dmitry Savchenko's avatar
Dmitry Savchenko committed
115 116 117 118 119
}

void TodoItemsProvider::setItemsListWithinStartupProject()
{
    QHashIterator<QString, QList<TodoItem> > it(m_itemsHash);
120
    QSet<QString> fileNames = QSet<QString>::fromList(m_startupProject->files(Project::ExcludeGeneratedFiles));
121 122 123

    QVariantMap settings = m_startupProject->namedSettings(QLatin1String(Constants::SETTINGS_NAME_KEY)).toMap();

Dmitry Savchenko's avatar
Dmitry Savchenko committed
124 125
    while (it.hasNext()) {
        it.next();
126 127 128 129 130 131 132 133 134 135 136 137 138
        QString fileName = it.key();
        if (fileNames.contains(fileName)) {
            bool skip = false;
            for (const QVariant &pattern : settings[QLatin1String(Constants::EXCLUDES_LIST_KEY)].toList()) {
                QRegExp re(pattern.toString());
                if (re.indexIn(fileName) != -1) {
                    skip = true;
                    break;
                }
            }
            if (!skip)
                m_itemsList << it.value();
        }
Dmitry Savchenko's avatar
Dmitry Savchenko committed
139 140 141 142 143 144 145 146 147 148 149
    }
}

void TodoItemsProvider::itemsFetched(const QString &fileName, const QList<TodoItem> &items)
{
    // Replace old items with new ones
    m_itemsHash.insert(fileName, items);

    m_shouldUpdateList = true;
}

150
void TodoItemsProvider::startupProjectChanged(Project *project)
Dmitry Savchenko's avatar
Dmitry Savchenko committed
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
{
    m_startupProject = project;
    updateList();
}

void TodoItemsProvider::projectsFilesChanged()
{
    updateList();
}

void TodoItemsProvider::currentEditorChanged(Core::IEditor *editor)
{
    m_currentEditor = editor;
    if (m_settings.scanningScope == ScanningScopeCurrentFile)
        updateList();
}

void TodoItemsProvider::updateListTimeoutElapsed()
{
    if (m_shouldUpdateList) {
        m_shouldUpdateList = false;
        updateList();
    }
}

void TodoItemsProvider::setupStartupProjectBinding()
{
hjk's avatar
hjk committed
178 179
    m_startupProject = SessionManager::startupProject();
    connect(SessionManager::instance(), SIGNAL(startupProjectChanged(ProjectExplorer::Project*)),
Dmitry Savchenko's avatar
Dmitry Savchenko committed
180
        SLOT(startupProjectChanged(ProjectExplorer::Project*)));
hjk's avatar
hjk committed
181
    connect(ProjectExplorerPlugin::instance(), SIGNAL(fileListChanged()), SLOT(projectsFilesChanged()));
Dmitry Savchenko's avatar
Dmitry Savchenko committed
182 183 184 185
}

void TodoItemsProvider::setupCurrentEditorBinding()
{
hjk's avatar
hjk committed
186
    m_currentEditor = Core::EditorManager::currentEditor();
187
    connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)),
Dmitry Savchenko's avatar
Dmitry Savchenko committed
188 189 190 191 192 193 194
        SLOT(currentEditorChanged(Core::IEditor*)));
}

void TodoItemsProvider::setupUpdateListTimer()
{
    m_shouldUpdateList = false;
    QTimer *timer = new QTimer(this);
Montel Laurent's avatar
Montel Laurent committed
195
    connect(timer, &QTimer::timeout, this, &TodoItemsProvider::updateListTimeoutElapsed);
Dmitry Savchenko's avatar
Dmitry Savchenko committed
196 197 198 199 200 201 202 203 204 205 206
    timer->start(Constants::OUTPUT_PANE_UPDATE_INTERVAL);
}

void TodoItemsProvider::setupItemsModel()
{
    m_itemsModel = new TodoItemsModel(this);
    m_itemsModel->setTodoItemsList(&m_itemsList);
}

}
}