1 // Copyright (C) 2014-2018 Manuel Schneider
2 
3 #include <QFileDialog>
4 #include <QStandardPaths>
5 #include <QStringListModel>
6 #include "configwidget.h"
7 #include "extension.h"
8 #include "mimetypedialog.h"
9 
10 /** ***************************************************************************/
ConfigWidget(Extension * _extension,QWidget * _parent)11 Files::ConfigWidget::ConfigWidget(Extension *_extension, QWidget *_parent)
12     : QWidget(_parent), extension(_extension) {
13     ui.setupUi(this);
14 
15     // Paths
16     QStringListModel *pathsModel = new QStringListModel(this);
17     pathsModel->setStringList(extension->paths());
18     ui.listView_paths->setModel(pathsModel);
19     connect(extension, &Extension::pathsChanged,
20             pathsModel, &QStringListModel::setStringList);
21 
22     // Buttons
23     connect(ui.pushButton_add, &QPushButton::clicked, [=](){
24         QFileInfo fileInfo(QFileDialog::getExistingDirectory(
25                                this,
26                                tr("Choose directory"),
27                                QStandardPaths::writableLocation(QStandardPaths::HomeLocation)));
28         if(fileInfo.exists())
29             extension->setPaths(QStringList(extension->paths()) << fileInfo.absoluteFilePath());
30     });
31 
32     connect(ui.pushButton_remove, &QPushButton::clicked, [this, pathsModel](){
33         if ( !ui.listView_paths->currentIndex().isValid() )
34             return;
35         QStringList paths(extension->paths());
36         paths.removeAll(pathsModel->stringList()[ui.listView_paths->currentIndex().row()]);
37         extension->setPaths(paths);
38     });
39 
40     connect(ui.pushButton_restore, &QPushButton::clicked,
41             extension, &Extension::restorePaths);
42 
43     connect(ui.pushButton_update, &QPushButton::clicked,
44             extension, &Extension::updateIndex);
45 
46     /*
47      * Initialize the indexing options
48      */
49 
50     ui.checkBox_hidden->setChecked(extension->indexHidden());
51     connect(ui.checkBox_hidden, &QCheckBox::toggled, extension, &Extension::setIndexHidden);
52 
53     ui.checkBox_followSymlinks->setChecked(extension->followSymlinks());
54     connect(ui.checkBox_followSymlinks, &QCheckBox::toggled, extension, &Extension::setFollowSymlinks);
55 
56     ui.checkBox_fuzzy->setChecked(extension->fuzzy());
57     connect(ui.checkBox_fuzzy, &QCheckBox::toggled, extension, &Extension::setFuzzy);
58 
59     ui.spinBox_interval->setValue(static_cast<int>(extension->scanInterval()));
60     connect(ui.spinBox_interval, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged),
61             extension, &Extension::setScanInterval);
62 
63     /*
64      * Initialize the mime options
65      */
66 
67     QStringList filters = extension->filters();
68 
69     if (filters.contains("audio/*"))
70         ui.checkBox_audio->setCheckState(Qt::Checked);
71     else if (std::any_of(filters.begin(), filters.end(),
72                         [](const QString & str){ return str.startsWith("audio/"); }))
73         ui.checkBox_audio->setCheckState(Qt::PartiallyChecked);
74     else
75         ui.checkBox_audio->setCheckState(Qt::Unchecked);
76 
77     if (filters.contains("video/*"))
78         ui.checkBox_video->setCheckState(Qt::Checked);
79     else if (std::any_of(filters.begin(), filters.end(),
80                         [](const QString & str){ return str.startsWith("video/"); }))
81         ui.checkBox_video->setCheckState(Qt::PartiallyChecked);
82     else
83         ui.checkBox_video->setCheckState(Qt::Unchecked);
84 
85     if (filters.contains("image/*"))
86         ui.checkBox_image->setCheckState(Qt::Checked);
87     else if (std::any_of(filters.begin(), filters.end(),
88                          [](const QString & str){ return str.startsWith("image/"); }))
89         ui.checkBox_image->setCheckState(Qt::PartiallyChecked);
90     else
91         ui.checkBox_image->setCheckState(Qt::Unchecked);
92 
93     if (filters.contains("application/*"))
94         ui.checkBox_docs->setCheckState(Qt::Checked);
95     else if (std::any_of(filters.begin(), filters.end(),
96                          [](const QString & str){ return str.startsWith("application/"); }))
97         ui.checkBox_docs->setCheckState(Qt::PartiallyChecked);
98     else
99         ui.checkBox_docs->setCheckState(Qt::Unchecked);
100 
101     if (filters.contains("inode/directory"))
102         ui.checkBox_dirs->setCheckState(Qt::Checked);
103     else
104         ui.checkBox_dirs->setCheckState(Qt::Unchecked);
105 
106     /*
107      * Set the actions for checking the mime options
108      */
109 
110     connect(ui.checkBox_audio, &QCheckBox::clicked, extension, [this]() {
111         ui.checkBox_audio->setTristate(false);
112         QStringList filters = extension->filters();
113         filters.erase(std::remove_if(filters.begin(), filters.end(),
114                                      [](const QString &str){ return str.startsWith("audio/"); }),
115                       filters.end());
116         if (ui.checkBox_audio->checkState() == Qt::Checked)
117             filters.push_back("audio/*");
118         extension->setFilters(filters);
119     });
120 
121     connect(ui.checkBox_video, &QCheckBox::clicked, extension, [this]() {
122         ui.checkBox_video->setTristate(false);
123         QStringList filters = extension->filters();
124         filters.erase(std::remove_if(filters.begin(), filters.end(),
125                                      [](const QString &str){ return str.startsWith("video/"); }),
126                       filters.end());
127         if (ui.checkBox_video->checkState() == Qt::Checked)
128             filters.push_back("video/*");
129         extension->setFilters(filters);
130     });
131 
132     connect(ui.checkBox_image, &QCheckBox::clicked, extension, [this]() {
133         ui.checkBox_image->setTristate(false);
134         QStringList filters = extension->filters();
135         filters.erase(std::remove_if(filters.begin(), filters.end(),
136                                      [](const QString &str){ return str.startsWith("image/"); }),
137                       filters.end());
138         if (ui.checkBox_image->checkState() == Qt::Checked)
139             filters.push_back("image/*");
140         extension->setFilters(filters);
141     });
142 
143     connect(ui.checkBox_docs, &QCheckBox::clicked, extension, [this]() {
144         ui.checkBox_docs->setTristate(false);
145         QStringList filters = extension->filters();
146         filters.erase(std::remove_if(filters.begin(), filters.end(),
147                                      [](const QString &str){ return str.startsWith("application/"); }),
148                       filters.end());
149         if (ui.checkBox_docs->checkState() == Qt::Checked)
150             filters.push_back("application/*");
151         extension->setFilters(filters);
152     });
153 
154     connect(ui.checkBox_dirs, &QCheckBox::toggled, extension, [=](bool checked){
155         QStringList filters = extension->filters();
156         filters.removeAll("inode/directory");
157         if (checked)
158             filters.push_back("inode/directory");
159         extension->setFilters(filters);
160     });
161 
162     // The advanced button action
163     connect(ui.pushButton_advanced, &QPushButton::clicked, [=](){
164 
165         MimeTypeDialog dialog(extension->filters(), this);
166         dialog.setWindowModality(Qt::WindowModal);
167         if ( dialog.exec() ) {
168 
169             // If the dialog has been accepted, update extension and checkboxes
170             extension->setFilters(dialog.filters());
171 
172             // Set the shortcuts
173             QStringList filters = extension->filters();
174 
175             if (filters.contains("audio/*"))
176                 ui.checkBox_audio->setCheckState(Qt::Checked);
177             else if (std::any_of(filters.begin(), filters.end(),
178                                  [](const QString & str){ return str.startsWith("audio/"); }))
179                 ui.checkBox_audio->setCheckState(Qt::PartiallyChecked);
180             else
181                 ui.checkBox_audio->setCheckState(Qt::Unchecked);
182 
183             if (filters.contains("video/*"))
184                 ui.checkBox_video->setCheckState(Qt::Checked);
185             else if (std::any_of(filters.begin(), filters.end(),
186                                  [](const QString & str){ return str.startsWith("video/"); }))
187                 ui.checkBox_video->setCheckState(Qt::PartiallyChecked);
188             else
189                 ui.checkBox_video->setCheckState(Qt::Unchecked);
190 
191             if (filters.contains("image/*"))
192                 ui.checkBox_image->setCheckState(Qt::Checked);
193             else if (std::any_of(filters.begin(), filters.end(),
194                                  [](const QString & str){ return str.startsWith("image/"); }))
195                 ui.checkBox_image->setCheckState(Qt::PartiallyChecked);
196             else
197                 ui.checkBox_image->setCheckState(Qt::Unchecked);
198 
199             if (filters.contains("application/*"))
200                 ui.checkBox_docs->setCheckState(Qt::Checked);
201             else if (std::any_of(filters.begin(), filters.end(),
202                                  [](const QString & str){ return str.startsWith("application/"); }))
203                 ui.checkBox_docs->setCheckState(Qt::PartiallyChecked);
204             else
205                 ui.checkBox_docs->setCheckState(Qt::Unchecked);
206 
207             if (filters.contains("inode/directory"))
208                 ui.checkBox_dirs->setCheckState(Qt::Checked);
209             else
210                 ui.checkBox_dirs->setCheckState(Qt::Unchecked);
211         }
212     });
213 
214     // Status bar
215     connect(extension, &Extension::statusInfo, this, [this](const QString& text){
216         QFontMetrics metrics(ui.label_statusbar->font());
217         QString elidedText = metrics.elidedText(text, Qt::ElideMiddle, ui.label_statusbar->width()-5);
218         ui.label_statusbar->setText(elidedText);
219     });
220 }
221 
222 
223 
224 /** ***************************************************************************/
~ConfigWidget()225 Files::ConfigWidget::~ConfigWidget() {
226 
227 }
228