1 /*
2 * Copyright (C) 2009, 2010 Nicolas Bonnefon and other contributors
3 *
4 * This file is part of glogg.
5 *
6 * glogg is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * glogg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with glogg. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "log.h"
21
22 #include "configuration.h"
23 #include "persistentinfo.h"
24 #include "filterset.h"
25
26 #include "filtersdialog.h"
27
28 static const QString DEFAULT_PATTERN = "New Filter";
29 static const bool DEFAULT_IGNORE_CASE = false;
30 static const QString DEFAULT_FORE_COLOUR = "black";
31 static const QString DEFAULT_BACK_COLOUR = "white";
32
33 // Construct the box, including a copy of the global FilterSet
34 // to handle ok/cancel/apply
FiltersDialog(QWidget * parent)35 FiltersDialog::FiltersDialog( QWidget* parent ) : QDialog( parent )
36 {
37 setupUi( this );
38
39 // Reload the filter list from disk (in case it has been changed
40 // by another glogg instance) and copy it to here.
41 GetPersistentInfo().retrieve( "filterSet" );
42 filterSet = PersistentCopy<FilterSet>( "filterSet" );
43
44 populateColors();
45 populateFilterList();
46
47 // Start with all buttons disabled except 'add'
48 removeFilterButton->setEnabled(false);
49 upFilterButton->setEnabled(false);
50 downFilterButton->setEnabled(false);
51
52 // Default to black on white
53 int index = foreColorBox->findText( DEFAULT_FORE_COLOUR );
54 foreColorBox->setCurrentIndex( index );
55 index = backColorBox->findText( DEFAULT_BACK_COLOUR );
56 backColorBox->setCurrentIndex( index );
57
58 // No filter selected by default
59 selectedRow_ = -1;
60
61 connect( filterListWidget, SIGNAL( itemSelectionChanged() ),
62 this, SLOT( updatePropertyFields() ) );
63 connect( patternEdit, SIGNAL( textEdited( const QString& ) ),
64 this, SLOT( updateFilterProperties() ) );
65 connect( ignoreCaseCheckBox, SIGNAL( clicked( bool ) ),
66 this, SLOT( updateFilterProperties() ) );
67 connect( foreColorBox, SIGNAL( activated( int ) ),
68 this, SLOT( updateFilterProperties() ) );
69 connect( backColorBox, SIGNAL( activated( int ) ),
70 this, SLOT( updateFilterProperties() ) );
71
72 if ( !filterSet->filterList.empty() ) {
73 filterListWidget->setCurrentItem( filterListWidget->item( 0 ) );
74 }
75 }
76
77 //
78 // Slots
79 //
80
on_addFilterButton_clicked()81 void FiltersDialog::on_addFilterButton_clicked()
82 {
83 LOG(logDEBUG) << "on_addFilterButton_clicked()";
84
85 Filter newFilter = Filter( DEFAULT_PATTERN, DEFAULT_IGNORE_CASE,
86 DEFAULT_FORE_COLOUR, DEFAULT_BACK_COLOUR );
87 filterSet->filterList << newFilter;
88
89 // Add and select the newly created filter
90 filterListWidget->addItem( DEFAULT_PATTERN );
91 filterListWidget->setCurrentRow( filterListWidget->count() - 1 );
92 }
93
on_removeFilterButton_clicked()94 void FiltersDialog::on_removeFilterButton_clicked()
95 {
96 int index = filterListWidget->currentRow();
97 LOG(logDEBUG) << "on_removeFilterButton_clicked() index " << index;
98
99 if ( index >= 0 ) {
100 filterSet->filterList.removeAt( index );
101 filterListWidget->setCurrentRow( -1 );
102 delete filterListWidget->takeItem( index );
103
104 int count = filterListWidget->count();
105 if ( index < count ) {
106 // Select the new item at the same index
107 filterListWidget->setCurrentRow( index );
108 }
109 else {
110 // or the previous index if it is at the end
111 filterListWidget->setCurrentRow( count - 1 );
112 }
113 }
114 }
115
on_upFilterButton_clicked()116 void FiltersDialog::on_upFilterButton_clicked()
117 {
118 int index = filterListWidget->currentRow();
119 LOG(logDEBUG) << "on_upFilterButton_clicked() index " << index;
120
121 if ( index > 0 ) {
122 filterSet->filterList.move( index, index - 1 );
123
124 QListWidgetItem* item = filterListWidget->takeItem( index );
125 filterListWidget->insertItem( index - 1, item );
126 filterListWidget->setCurrentRow( index - 1 );
127 }
128 }
129
on_downFilterButton_clicked()130 void FiltersDialog::on_downFilterButton_clicked()
131 {
132 int index = filterListWidget->currentRow();
133 LOG(logDEBUG) << "on_downFilterButton_clicked() index " << index;
134
135 if ( ( index >= 0 ) && ( index < ( filterListWidget->count() - 1 ) ) ) {
136 filterSet->filterList.move( index, index + 1 );
137
138 QListWidgetItem* item = filterListWidget->takeItem( index );
139 filterListWidget->insertItem( index + 1, item );
140 filterListWidget->setCurrentRow( index + 1 );
141 }
142 }
143
on_buttonBox_clicked(QAbstractButton * button)144 void FiltersDialog::on_buttonBox_clicked( QAbstractButton* button )
145 {
146 LOG(logDEBUG) << "on_buttonBox_clicked()";
147
148 QDialogButtonBox::ButtonRole role = buttonBox->buttonRole( button );
149 if ( ( role == QDialogButtonBox::AcceptRole )
150 || ( role == QDialogButtonBox::ApplyRole ) ) {
151 // Copy the filter set and persist it to disk
152 *( Persistent<FilterSet>( "filterSet" ) ) = *filterSet;
153 GetPersistentInfo().save( "filterSet" );
154 emit optionsChanged();
155 }
156
157 if ( role == QDialogButtonBox::AcceptRole )
158 accept();
159 else if ( role == QDialogButtonBox::RejectRole )
160 reject();
161 }
162
updatePropertyFields()163 void FiltersDialog::updatePropertyFields()
164 {
165 if ( filterListWidget->selectedItems().count() >= 1 )
166 selectedRow_ = filterListWidget->row(
167 filterListWidget->selectedItems().at(0) );
168 else
169 selectedRow_ = -1;
170
171 LOG(logDEBUG) << "updatePropertyFields(), row = " << selectedRow_;
172
173 if ( selectedRow_ >= 0 ) {
174 const Filter& currentFilter = filterSet->filterList.at( selectedRow_ );
175
176 patternEdit->setText( currentFilter.pattern() );
177 patternEdit->setEnabled( true );
178
179 ignoreCaseCheckBox->setChecked( currentFilter.ignoreCase() );
180 ignoreCaseCheckBox->setEnabled( true );
181
182 int index = foreColorBox->findText( currentFilter.foreColorName() );
183 if ( index != -1 ) {
184 LOG(logDEBUG) << "fore index = " << index;
185 foreColorBox->setCurrentIndex( index );
186 foreColorBox->setEnabled( true );
187 }
188 index = backColorBox->findText( currentFilter.backColorName() );
189 if ( index != -1 ) {
190 LOG(logDEBUG) << "back index = " << index;
191 backColorBox->setCurrentIndex( index );
192 backColorBox->setEnabled( true );
193 }
194
195 // Enable the buttons if needed
196 removeFilterButton->setEnabled( true );
197 upFilterButton->setEnabled( selectedRow_ > 0 );
198 downFilterButton->setEnabled(
199 selectedRow_ < ( filterListWidget->count() - 1 ) );
200 }
201 else {
202 // Nothing is selected, reset and disable the controls
203 patternEdit->clear();
204 patternEdit->setEnabled( false );
205
206 int index = foreColorBox->findText( DEFAULT_FORE_COLOUR );
207 foreColorBox->setCurrentIndex( index );
208 foreColorBox->setEnabled( false );
209 index = backColorBox->findText( DEFAULT_BACK_COLOUR );
210
211 backColorBox->setCurrentIndex( index );
212 backColorBox->setEnabled( false );
213
214 ignoreCaseCheckBox->setChecked( DEFAULT_IGNORE_CASE );
215 ignoreCaseCheckBox->setEnabled( false );
216 removeFilterButton->setEnabled( false );
217 upFilterButton->setEnabled( false );
218 downFilterButton->setEnabled( false );
219 }
220 }
221
updateFilterProperties()222 void FiltersDialog::updateFilterProperties()
223 {
224 LOG(logDEBUG) << "updateFilterProperties()";
225
226 // If a row is selected
227 if ( selectedRow_ >= 0 ) {
228 Filter& currentFilter = filterSet->filterList[selectedRow_];
229
230 // Update the internal data
231 currentFilter.setPattern( patternEdit->text() );
232 currentFilter.setIgnoreCase( ignoreCaseCheckBox->isChecked() );
233 currentFilter.setForeColor( foreColorBox->currentText() );
234 currentFilter.setBackColor( backColorBox->currentText() );
235
236 // Update the entry in the filterList widget
237 filterListWidget->currentItem()->setText( patternEdit->text() );
238 filterListWidget->currentItem()->setForeground(
239 QBrush( QColor( currentFilter.foreColorName() ) ) );
240 filterListWidget->currentItem()->setBackground(
241 QBrush( QColor( currentFilter.backColorName() ) ) );
242 }
243 }
244
245 //
246 // Private functions
247 //
248
249 // Fills the color selection combo boxes
populateColors()250 void FiltersDialog::populateColors()
251 {
252 const QStringList colorNames = QStringList()
253 // Basic 16 HTML colors (minus greys):
254 << "black"
255 << "white"
256 << "maroon"
257 << "red"
258 << "purple"
259 << "fuchsia"
260 << "green"
261 << "lime"
262 << "olive"
263 << "yellow"
264 << "navy"
265 << "blue"
266 << "teal"
267 << "aqua"
268 // Greys
269 << "gainsboro"
270 << "lightgrey"
271 << "silver"
272 << "darkgrey"
273 << "grey"
274 << "dimgrey"
275 // Reds
276 << "tomato"
277 << "orangered"
278 << "orange"
279 << "crimson"
280 << "darkred"
281 // Greens
282 << "greenyellow"
283 << "lightgreen"
284 << "darkgreen"
285 << "lightseagreen"
286 // Blues
287 << "lightcyan"
288 << "darkturquoise"
289 << "steelblue"
290 << "lightblue"
291 << "royalblue"
292 << "darkblue"
293 << "midnightblue"
294 // Browns
295 << "bisque"
296 << "tan"
297 << "sandybrown"
298 << "chocolate";
299
300 for ( QStringList::const_iterator i = colorNames.constBegin();
301 i != colorNames.constEnd(); ++i ) {
302 QPixmap solidPixmap( 20, 10 );
303 solidPixmap.fill( QColor( *i ) );
304 QIcon solidIcon { solidPixmap };
305
306 foreColorBox->addItem( solidIcon, *i );
307 backColorBox->addItem( solidIcon, *i );
308 }
309 }
310
populateFilterList()311 void FiltersDialog::populateFilterList()
312 {
313 filterListWidget->clear();
314 foreach ( Filter filter, filterSet->filterList ) {
315 QListWidgetItem* new_item = new QListWidgetItem( filter.pattern() );
316 // new_item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled );
317 new_item->setForeground( QBrush( QColor( filter.foreColorName() ) ) );
318 new_item->setBackground( QBrush( QColor( filter.backColorName() ) ) );
319 filterListWidget->addItem( new_item );
320 }
321 }
322