xref: /glogg/src/filtersdialog.cpp (revision 4b904fec17ab43019d7e09e1e5ef8887cb2a54a6)
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