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 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 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 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 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 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 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 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 ) ? true : false ); 198 downFilterButton->setEnabled( 199 ( selectedRow_ < ( filterListWidget->count() - 1 ) ) ? true : false ); 200 } 201 else { 202 // Nothing is selected, greys the buttons 203 patternEdit->setEnabled( false ); 204 foreColorBox->setEnabled( false ); 205 backColorBox->setEnabled( false ); 206 ignoreCaseCheckBox->setEnabled( false ); 207 } 208 } 209 210 void FiltersDialog::updateFilterProperties() 211 { 212 LOG(logDEBUG) << "updateFilterProperties()"; 213 214 // If a row is selected 215 if ( selectedRow_ >= 0 ) { 216 Filter& currentFilter = filterSet->filterList[selectedRow_]; 217 218 // Update the internal data 219 currentFilter.setPattern( patternEdit->text() ); 220 currentFilter.setIgnoreCase( ignoreCaseCheckBox->isChecked() ); 221 currentFilter.setForeColor( foreColorBox->currentText() ); 222 currentFilter.setBackColor( backColorBox->currentText() ); 223 224 // Update the entry in the filterList widget 225 filterListWidget->currentItem()->setText( patternEdit->text() ); 226 filterListWidget->currentItem()->setForeground( 227 QBrush( QColor( currentFilter.foreColorName() ) ) ); 228 filterListWidget->currentItem()->setBackground( 229 QBrush( QColor( currentFilter.backColorName() ) ) ); 230 } 231 } 232 233 // 234 // Private functions 235 // 236 237 // Fills the color selection combo boxes 238 void FiltersDialog::populateColors() 239 { 240 const QStringList colorNames = QStringList() 241 // Basic 16 HTML colors (minus greys): 242 << "black" 243 << "white" 244 << "maroon" 245 << "red" 246 << "purple" 247 << "fuchsia" 248 << "green" 249 << "lime" 250 << "olive" 251 << "yellow" 252 << "navy" 253 << "blue" 254 << "teal" 255 << "aqua" 256 // Greys 257 << "gainsboro" 258 << "lightgrey" 259 << "silver" 260 << "darkgrey" 261 << "grey" 262 << "dimgrey" 263 // Reds 264 << "tomato" 265 << "orangered" 266 << "orange" 267 << "crimson" 268 << "darkred" 269 // Greens 270 << "greenyellow" 271 << "lightgreen" 272 << "darkgreen" 273 << "lightseagreen" 274 // Blues 275 << "lightcyan" 276 << "darkturquoise" 277 << "steelblue" 278 << "lightblue" 279 << "royalblue" 280 << "darkblue" 281 << "midnightblue" 282 // Browns 283 << "bisque" 284 << "tan" 285 << "sandybrown" 286 << "chocolate"; 287 288 for ( QStringList::const_iterator i = colorNames.constBegin(); 289 i != colorNames.constEnd(); ++i ) { 290 QPixmap solidPixmap( 20, 10 ); 291 solidPixmap.fill( QColor( *i ) ); 292 QIcon solidIcon { solidPixmap }; 293 294 foreColorBox->addItem( solidIcon, *i ); 295 backColorBox->addItem( solidIcon, *i ); 296 } 297 } 298 299 void FiltersDialog::populateFilterList() 300 { 301 filterListWidget->clear(); 302 foreach ( Filter filter, filterSet->filterList ) { 303 QListWidgetItem* new_item = new QListWidgetItem( filter.pattern() ); 304 // new_item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled ); 305 new_item->setForeground( QBrush( QColor( filter.foreColorName() ) ) ); 306 new_item->setBackground( QBrush( QColor( filter.backColorName() ) ) ); 307 filterListWidget->addItem( new_item ); 308 } 309 } 310