filter.cpp 5.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 * This file is part of KDevelop
 * Copyright 2013 Milian Wolff <mail@milianw.de>
 *
 * 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 2 of
 * the License or (at your option) version 3 or any later version
 * accepted by the membership of KDE e.V. (or its successor approved
 * by the membership of KDE e.V.), which shall act as a proxy
 * defined in Section 14 of version 3 of the license.
 *
 * 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 <http://www.gnu.org/licenses/>.
 */

#include "filter.h"

24
#include <KConfigGroup>
25 26 27 28 29 30 31 32

using namespace KDevelop;

Filter::Filter()
    : targets(Files | Folders)
{
}

33
Filter::Filter(const SerializedFilter& filter)
34
    : pattern(QString(), Qt::CaseSensitive, QRegExp::WildcardUnix)
35 36 37
    , targets(filter.targets)
    , type(filter.type)
{
38
    QString pattern = filter.pattern;
39
    if (!filter.pattern.startsWith(QLatin1Char('/')) && !filter.pattern.startsWith(QLatin1Char('*'))) {
40
        // implicitly match against trailing relative path
41
        pattern.prepend(QLatin1String("*/"));
42
    }
43
    if (pattern.endsWith(QLatin1Char('/')) && targets != Filter::Files) {
44 45 46 47 48
        // implicitly match against folders
        targets = Filter::Folders;
        pattern.chop(1);
    }
    this->pattern.setPattern(pattern);
49 50 51 52
}

SerializedFilter::SerializedFilter()
    : targets(Filter::Files | Filter::Folders)
53

54 55 56 57
{

}

58 59 60 61
SerializedFilter::SerializedFilter(const QString& pattern, Filter::Targets targets, Filter::Type type)
    : pattern(pattern)
    , targets(targets)
    , type(type)
62
{
63

64 65 66 67
}

namespace KDevelop {

68
SerializedFilters defaultFilters()
69
{
70
    SerializedFilters ret;
71
    ret.reserve(20);
72

73
    // filter hidden files
74
    ret << SerializedFilter(QStringLiteral(".*"), Filter::Targets(Filter::Files | Filter::Folders));
75 76
    // but do show some with special meaning
    ret << SerializedFilter(QStringLiteral(".gitignore"), Filter::Files, Filter::Inclusive)
77 78
        << SerializedFilter(QStringLiteral(".gitmodules"), Filter::Files, Filter::Inclusive)
        << SerializedFilter(QStringLiteral(".clang-format"), Filter::Files, Filter::Inclusive);
79 80

    // common vcs folders which we want to hide
Kevin Funk's avatar
Kevin Funk committed
81 82 83 84
    static const QVector<QString> invalidFolders = {
        QStringLiteral(".git"), QStringLiteral("CVS"), QStringLiteral(".svn"), QStringLiteral("_svn"),
        QStringLiteral("SCCS"), QStringLiteral("_darcs"), QStringLiteral(".hg"), QStringLiteral(".bzr"), QStringLiteral("__pycache__")
    };
85
    for (const QString& folder : invalidFolders) {
86
        ret << SerializedFilter(folder, Filter::Folders);
87 88 89
    }

    // common files which we want to hide
Kevin Funk's avatar
Kevin Funk committed
90
    static const QVector<QString> filePatterns = {
91
        // binary files (Unix)
Kevin Funk's avatar
Kevin Funk committed
92
        QStringLiteral("*.o"), QStringLiteral("*.a"), QStringLiteral("*.so"), QStringLiteral("*.so.*"),
93
        // binary files (Windows)
94
        QStringLiteral("*.obj"), QStringLiteral("*.lib"), QStringLiteral("*.dll"), QStringLiteral("*.exp"), QStringLiteral("*.pdb"),
95
        // generated files
96
        QStringLiteral("moc_*.cpp"), QStringLiteral("*.moc"), QStringLiteral("ui_*.h"), QStringLiteral("*.qmlc"), QStringLiteral("qrc_*.cpp"),
97
        // backup files
Kevin Funk's avatar
Kevin Funk committed
98
        QStringLiteral("*~"), QStringLiteral("*.orig"), QStringLiteral(".*.kate-swp"), QStringLiteral(".*.swp"),
99
        // python cache and object files
Kevin Funk's avatar
Kevin Funk committed
100 101
        QStringLiteral("*.pyc"), QStringLiteral("*.pyo")
    };
102
    for (const QString& filePattern : filePatterns) {
103
        ret << SerializedFilter(filePattern, Filter::Files);
104
    }
105 106 107 108

    return ret;
}

109
SerializedFilters readFilters(const KSharedConfigPtr& config)
110 111 112 113 114
{
    if (!config->hasGroup("Filters")) {
        return defaultFilters();
    }
    const KConfigGroup& group = config->group("Filters");
115 116 117 118 119
    const int size = group.readEntry("size", -1);
    if (size == -1) {
        // fallback
        return defaultFilters();
    }
120

121
    SerializedFilters filters;
122 123 124 125 126 127
    filters.reserve(size);
    for (int i = 0; i < size; ++i) {
        const QByteArray subGroup = QByteArray::number(i);
        if (!group.hasGroup(subGroup)) {
            continue;
        }
128 129 130
        const KConfigGroup& subConfig = group.group(subGroup);
        const QString pattern = subConfig.readEntry("pattern", QString());
        Filter::Targets targets(subConfig.readEntry("targets", 0));
131
        Filter::Type type = static_cast<Filter::Type>(subConfig.readEntry("inclusive", 0));
132
        filters << SerializedFilter(pattern, targets, type);
133 134 135 136 137
    }

    return filters;
}

138
void writeFilters(const SerializedFilters& filters, KSharedConfigPtr config)
139 140 141 142 143 144
{
    // clear existing
    config->deleteGroup("Filters");

    // write new
    KConfigGroup group = config->group("Filters");
145
    group.writeEntry("size", filters.size());
146
    int i = 0;
147
    for (const SerializedFilter& filter : filters) {
148
        KConfigGroup subGroup = group.group(QByteArray::number(i++));
149
        subGroup.writeEntry("pattern", filter.pattern);
150
        subGroup.writeEntry("targets", static_cast<int>(filter.targets));
151
        subGroup.writeEntry("inclusive", static_cast<int>(filter.type));
152
    }
153
    config->sync();
154 155
}

156 157 158 159
Filters deserialize(const SerializedFilters& filters)
{
    Filters ret;
    ret.reserve(filters.size());
160
    for (const SerializedFilter& filter : filters) {
161 162 163 164 165
        ret << Filter(filter);
    }
    return ret;
}

166
}