OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / locator / directoryfilter.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "directoryfilter.h"
35
36 #include <QtCore/QDir>
37 #include <QtCore/QStack>
38 #include <QtGui/QCompleter>
39 #include <QtGui/QFileDialog>
40 #include <QtGui/QMessageBox>
41
42 #include <qtconcurrent/QtConcurrentTools>
43 #include <utils/filesearch.h>
44
45 using namespace Locator;
46 using namespace Locator::Internal;
47
48 DirectoryFilter::DirectoryFilter()
49   : m_name(tr("Generic Directory Filter")),
50     m_filters(QStringList() << QLatin1String("*.h") << QLatin1String("*.cpp")
51                             << QLatin1String("*.ui") << QLatin1String("*.qrc")),
52     m_dialog(0)
53 {
54     setIncludedByDefault(true);
55 }
56
57 QByteArray DirectoryFilter::saveState() const
58 {
59     QMutexLocker locker(&m_lock);
60     QByteArray value;
61     QDataStream out(&value, QIODevice::WriteOnly);
62     out << m_name;
63     out << m_directories;
64     out << m_filters;
65     out << shortcutString();
66     out << isIncludedByDefault();
67     out << files();
68     return value;
69 }
70
71 bool DirectoryFilter::restoreState(const QByteArray &state)
72 {
73     QMutexLocker locker(&m_lock);
74
75     QStringList dirEntries;
76     QString shortcut;
77     bool defaultFilter;
78
79     QDataStream in(state);
80     in >> m_name;
81     in >> dirEntries;
82     in >> m_filters;
83     in >> shortcut;
84     in >> defaultFilter;
85     in >> files();
86
87     setShortcutString(shortcut);
88     setIncludedByDefault(defaultFilter);
89
90     // ### TODO throw that out again:
91     // clear the list of directories of empty entries (which might at least happen at a format change)
92     m_directories.clear();
93     foreach (const QString &dir, dirEntries) {
94         if (dir.isEmpty())
95             continue;
96         m_directories.append(dir);
97     }
98
99     generateFileNames();
100     return true;
101 }
102
103 bool DirectoryFilter::openConfigDialog(QWidget *parent, bool &needsRefresh)
104 {
105     bool success = false;
106     QDialog dialog(parent);
107     m_dialog = &dialog;
108     m_ui.setupUi(&dialog);
109     dialog.setWindowTitle(tr("Filter Configuration"));
110     connect(m_ui.addButton, SIGNAL(clicked()),
111             this, SLOT(addDirectory()), Qt::DirectConnection);
112     connect(m_ui.editButton, SIGNAL(clicked()),
113             this, SLOT(editDirectory()), Qt::DirectConnection);
114     connect(m_ui.removeButton, SIGNAL(clicked()),
115             this, SLOT(removeDirectory()), Qt::DirectConnection);
116     connect(m_ui.directoryList, SIGNAL(itemSelectionChanged()),
117             this, SLOT(updateOptionButtons()), Qt::DirectConnection);
118     m_ui.nameEdit->setText(m_name);
119     m_ui.nameEdit->selectAll();
120     m_ui.directoryList->clear();
121     m_ui.directoryList->addItems(m_directories);
122     m_ui.fileTypeEdit->setText(m_filters.join(QString(QLatin1Char(','))));
123     m_ui.shortcutEdit->setText(shortcutString());
124     m_ui.defaultFlag->setChecked(!isIncludedByDefault());
125     updateOptionButtons();
126     if (dialog.exec() == QDialog::Accepted) {
127         QMutexLocker locker(&m_lock);
128         bool directoriesChanged = false;
129         QStringList oldDirectories = m_directories;
130         QStringList oldFilters = m_filters;
131         m_name = m_ui.nameEdit->text().trimmed();
132         m_directories.clear();
133         int oldCount = oldDirectories.count();
134         int newCount = m_ui.directoryList->count();
135         if (oldCount != newCount)
136             directoriesChanged = true;
137         for (int i = 0; i < newCount; ++i) {
138             m_directories.append(m_ui.directoryList->item(i)->text());
139             if (!directoriesChanged && m_directories.at(i) != oldDirectories.at(i))
140                 directoriesChanged = true;
141         }
142         m_filters = m_ui.fileTypeEdit->text().trimmed().split(QLatin1Char(','));
143         setShortcutString(m_ui.shortcutEdit->text().trimmed());
144         setIncludedByDefault(!m_ui.defaultFlag->isChecked());
145         if (directoriesChanged || oldFilters != m_filters)
146             needsRefresh = true;
147         success = true;
148     }
149     return success;
150 }
151
152 void DirectoryFilter::addDirectory()
153 {
154     QString dir = QFileDialog::getExistingDirectory(m_dialog, tr("Select Directory"));
155     if (!dir.isEmpty()) {
156         m_ui.directoryList->addItem(dir);
157     }
158 }
159
160 void DirectoryFilter::editDirectory()
161 {
162     if (m_ui.directoryList->selectedItems().count() < 1)
163         return;
164     QListWidgetItem *currentItem = m_ui.directoryList->selectedItems().at(0);
165     QString dir = QFileDialog::getExistingDirectory(m_dialog, tr("Select Directory"),
166                                                     currentItem->text());
167     if (!dir.isEmpty()) {
168         currentItem->setText(dir);
169     }
170 }
171
172 void DirectoryFilter::removeDirectory()
173 {
174     if (m_ui.directoryList->selectedItems().count() < 1)
175         return;
176     QListWidgetItem *currentItem = m_ui.directoryList->selectedItems().at(0);
177     delete m_ui.directoryList->takeItem(m_ui.directoryList->row(currentItem));
178 }
179
180 void DirectoryFilter::updateOptionButtons()
181 {
182     bool haveSelectedItem = (m_ui.directoryList->selectedItems().count() > 0);
183     m_ui.editButton->setEnabled(haveSelectedItem);
184     m_ui.removeButton->setEnabled(haveSelectedItem);
185 }
186
187 void DirectoryFilter::refresh(QFutureInterface<void> &future)
188 {
189     QStringList directories;
190     {
191         QMutexLocker locker(&m_lock);
192         if (m_directories.count() < 1) {
193             files().clear();
194             generateFileNames();
195             future.setProgressRange(0, 1);
196             future.setProgressValueAndText(1, tr("%1 filter update: 0 files").arg(m_name));
197             return;
198         }
199         directories = m_directories;
200     }
201     Utils::SubDirFileIterator it(directories, m_filters);
202     future.setProgressRange(0, it.maxProgress());
203     QStringList filesFound;
204     while (!future.isCanceled() && it.hasNext()) {
205         filesFound << it.next();
206         if (future.isProgressUpdateNeeded()) {
207             future.setProgressValueAndText(it.currentProgress(),
208                                            tr("%1 filter update: %n files", 0, filesFound.size()).arg(m_name));
209         }
210     }
211
212     if (!future.isCanceled()) {
213         QMutexLocker locker(&m_lock);
214         files() = filesFound;
215         generateFileNames();
216         future.setProgressValue(it.maxProgress());
217     } else {
218         future.setProgressValueAndText(it.currentProgress(), tr("%1 filter update: canceled").arg(m_name));
219     }
220 }