directoryfilter.cpp 7.67 KB
Newer Older
hjk's avatar
hjk committed
1
/****************************************************************************
con's avatar
con committed
2
**
3
4
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
con's avatar
con committed
5
**
hjk's avatar
hjk committed
6
** This file is part of Qt Creator.
con's avatar
con committed
7
**
hjk's avatar
hjk committed
8
9
10
11
** 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
12
13
14
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
15
**
16
17
18
19
20
21
22
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
con's avatar
con committed
23
**
hjk's avatar
hjk committed
24
****************************************************************************/
hjk's avatar
hjk committed
25

con's avatar
con committed
26
27
#include "directoryfilter.h"

Eike Ziller's avatar
Eike Ziller committed
28
#include <coreplugin/coreconstants.h>
29
#include <utils/filesearch.h>
30

31
32
33
#include <QFileDialog>
#include <QTimer>

34
35
using namespace Core;
using namespace Core::Internal;
con's avatar
con committed
36

37
DirectoryFilter::DirectoryFilter(Id id)
Montel Laurent's avatar
Montel Laurent committed
38
    : m_dialog(nullptr)
con's avatar
con committed
39
{
40
    setId(id);
con's avatar
con committed
41
    setIncludedByDefault(true);
42
    setDisplayName(tr("Generic Directory Filter"));
hjk's avatar
hjk committed
43
44
45
46
47

    m_filters.append(QLatin1String("*.h"));
    m_filters.append(QLatin1String("*.cpp"));
    m_filters.append(QLatin1String("*.ui"));
    m_filters.append(QLatin1String("*.qrc"));
con's avatar
con committed
48
49
50
51
52
53
54
}

QByteArray DirectoryFilter::saveState() const
{
    QMutexLocker locker(&m_lock);
    QByteArray value;
    QDataStream out(&value, QIODevice::WriteOnly);
55
    out << displayName();
con's avatar
con committed
56
57
58
    out << m_directories;
    out << m_filters;
    out << shortcutString();
59
    out << isIncludedByDefault();
60
    out << m_files;
con's avatar
con committed
61
62
63
64
65
66
67
    return value;
}

bool DirectoryFilter::restoreState(const QByteArray &state)
{
    QMutexLocker locker(&m_lock);

68
    QString name;
con's avatar
con committed
69
70
71
72
    QString shortcut;
    bool defaultFilter;

    QDataStream in(state);
73
    in >> name;
74
    in >> m_directories;
con's avatar
con committed
75
76
77
    in >> m_filters;
    in >> shortcut;
    in >> defaultFilter;
78
    in >> m_files;
con's avatar
con committed
79

80
    setDisplayName(name);
con's avatar
con committed
81
82
83
    setShortcutString(shortcut);
    setIncludedByDefault(defaultFilter);

84
    updateFileIterator();
con's avatar
con committed
85
86
87
88
89
90
91
92
93
    return true;
}

bool DirectoryFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
{
    bool success = false;
    QDialog dialog(parent);
    m_dialog = &dialog;
    m_ui.setupUi(&dialog);
Eike Ziller's avatar
Eike Ziller committed
94
95
96
97
    dialog.setWindowTitle(ILocatorFilter::msgConfigureDialogTitle());
    m_ui.prefixLabel->setText(ILocatorFilter::msgPrefixLabel());
    m_ui.prefixLabel->setToolTip(ILocatorFilter::msgPrefixToolTip());
    m_ui.defaultFlag->setText(ILocatorFilter::msgIncludeByDefault());
98
    m_ui.defaultFlag->setToolTip(ILocatorFilter::msgIncludeByDefaultToolTip());
Montel Laurent's avatar
Montel Laurent committed
99
100
101
102
103
104
105
106
    connect(m_ui.addButton, &QPushButton::clicked,
            this, &DirectoryFilter::addDirectory, Qt::DirectConnection);
    connect(m_ui.editButton, &QPushButton::clicked,
            this, &DirectoryFilter::editDirectory, Qt::DirectConnection);
    connect(m_ui.removeButton, &QPushButton::clicked,
            this, &DirectoryFilter::removeDirectory, Qt::DirectConnection);
    connect(m_ui.directoryList, &QListWidget::itemSelectionChanged,
            this, &DirectoryFilter::updateOptionButtons, Qt::DirectConnection);
107
    m_ui.nameEdit->setText(displayName());
con's avatar
con committed
108
109
110
    m_ui.nameEdit->selectAll();
    m_ui.directoryList->clear();
    m_ui.directoryList->addItems(m_directories);
hjk's avatar
hjk committed
111
    m_ui.fileTypeEdit->setText(m_filters.join(QLatin1Char(',')));
con's avatar
con committed
112
    m_ui.shortcutEdit->setText(shortcutString());
Eike Ziller's avatar
Eike Ziller committed
113
    m_ui.defaultFlag->setChecked(isIncludedByDefault());
con's avatar
con committed
114
115
116
117
118
119
    updateOptionButtons();
    if (dialog.exec() == QDialog::Accepted) {
        QMutexLocker locker(&m_lock);
        bool directoriesChanged = false;
        QStringList oldDirectories = m_directories;
        QStringList oldFilters = m_filters;
120
        setDisplayName(m_ui.nameEdit->text().trimmed());
con's avatar
con committed
121
122
123
124
125
126
127
128
129
130
        m_directories.clear();
        int oldCount = oldDirectories.count();
        int newCount = m_ui.directoryList->count();
        if (oldCount != newCount)
            directoriesChanged = true;
        for (int i = 0; i < newCount; ++i) {
            m_directories.append(m_ui.directoryList->item(i)->text());
            if (!directoriesChanged && m_directories.at(i) != oldDirectories.at(i))
                directoriesChanged = true;
        }
131
        m_filters = m_ui.fileTypeEdit->text().trimmed().split(QLatin1Char(','));
con's avatar
con committed
132
        setShortcutString(m_ui.shortcutEdit->text().trimmed());
Eike Ziller's avatar
Eike Ziller committed
133
        setIncludedByDefault(m_ui.defaultFlag->isChecked());
con's avatar
con committed
134
135
136
137
138
139
140
141
142
        if (directoriesChanged || oldFilters != m_filters)
            needsRefresh = true;
        success = true;
    }
    return success;
}

void DirectoryFilter::addDirectory()
{
143
    QString dir = QFileDialog::getExistingDirectory(m_dialog, tr("Select Directory"));
144
    if (!dir.isEmpty())
con's avatar
con committed
145
146
147
148
149
150
151
152
        m_ui.directoryList->addItem(dir);
}

void DirectoryFilter::editDirectory()
{
    if (m_ui.directoryList->selectedItems().count() < 1)
        return;
    QListWidgetItem *currentItem = m_ui.directoryList->selectedItems().at(0);
153
    QString dir = QFileDialog::getExistingDirectory(m_dialog, tr("Select Directory"),
con's avatar
con committed
154
                                                    currentItem->text());
155
    if (!dir.isEmpty())
con's avatar
con committed
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
        currentItem->setText(dir);
}

void DirectoryFilter::removeDirectory()
{
    if (m_ui.directoryList->selectedItems().count() < 1)
        return;
    QListWidgetItem *currentItem = m_ui.directoryList->selectedItems().at(0);
    delete m_ui.directoryList->takeItem(m_ui.directoryList->row(currentItem));
}

void DirectoryFilter::updateOptionButtons()
{
    bool haveSelectedItem = (m_ui.directoryList->selectedItems().count() > 0);
    m_ui.editButton->setEnabled(haveSelectedItem);
    m_ui.removeButton->setEnabled(haveSelectedItem);
}

174
175
176
177
178
void DirectoryFilter::updateFileIterator()
{
    setFileIterator(new BaseFileFilter::ListIterator(m_files));
}

con's avatar
con committed
179
180
void DirectoryFilter::refresh(QFutureInterface<void> &future)
{
181
182
    QStringList directories;
    {
con's avatar
con committed
183
        QMutexLocker locker(&m_lock);
184
        if (m_directories.count() < 1) {
185
            m_files.clear();
Orgad Shaneh's avatar
Orgad Shaneh committed
186
            QTimer::singleShot(0, this, &DirectoryFilter::updateFileIterator);
187
            future.setProgressRange(0, 1);
188
            future.setProgressValueAndText(1, tr("%1 filter update: 0 files").arg(displayName()));
189
            return;
con's avatar
con committed
190
        }
191
        directories = m_directories;
con's avatar
con committed
192
    }
193
    Utils::SubDirFileIterator subDirIterator(directories, m_filters, {});
194
    future.setProgressRange(0, subDirIterator.maxProgress());
195
    QStringList filesFound;
196
197
198
199
200
    auto end = subDirIterator.end();
    for (auto it = subDirIterator.begin(); it != end; ++it) {
        if (future.isCanceled())
            break;
        filesFound << (*it).filePath;
con's avatar
con committed
201
202
        if (future.isProgressUpdateNeeded()
                || future.progressValue() == 0 /*workaround for regression in Qt*/) {
203
            future.setProgressValueAndText(subDirIterator.currentProgress(),
204
                                           tr("%1 filter update: %n files", 0, filesFound.size()).arg(displayName()));
con's avatar
con committed
205
206
207
208
209
        }
    }

    if (!future.isCanceled()) {
        QMutexLocker locker(&m_lock);
210
        m_files = filesFound;
Orgad Shaneh's avatar
Orgad Shaneh committed
211
        QTimer::singleShot(0, this, &DirectoryFilter::updateFileIterator);
212
        future.setProgressValue(subDirIterator.maxProgress());
con's avatar
con committed
213
    } else {
214
        future.setProgressValueAndText(subDirIterator.currentProgress(), tr("%1 filter update: canceled").arg(displayName()));
con's avatar
con committed
215
216
    }
}