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 // Select the new item at the same index 105 filterListWidget->setCurrentRow( index ); 106 } 107 } 108 109 void FiltersDialog::on_upFilterButton_clicked() 110 { 111 int index = filterListWidget->currentRow(); 112 LOG(logDEBUG) << "on_upFilterButton_clicked() index " << index; 113 114 if ( index > 0 ) { 115 filterSet->filterList.move( index, index - 1 ); 116 117 QListWidgetItem* item = filterListWidget->takeItem( index ); 118 filterListWidget->insertItem( index - 1, item ); 119 filterListWidget->setCurrentRow( index - 1 ); 120 } 121 } 122 123 void FiltersDialog::on_downFilterButton_clicked() 124 { 125 int index = filterListWidget->currentRow(); 126 LOG(logDEBUG) << "on_downFilterButton_clicked() index " << index; 127 128 if ( ( index >= 0 ) && ( index < ( filterListWidget->count() - 1 ) ) ) { 129 filterSet->filterList.move( index, index + 1 ); 130 131 QListWidgetItem* item = filterListWidget->takeItem( index ); 132 filterListWidget->insertItem( index + 1, item ); 133 filterListWidget->setCurrentRow( index + 1 ); 134 } 135 } 136 137 void FiltersDialog::on_buttonBox_clicked( QAbstractButton* button ) 138 { 139 LOG(logDEBUG) << "on_buttonBox_clicked()"; 140 141 QDialogButtonBox::ButtonRole role = buttonBox->buttonRole( button ); 142 if ( ( role == QDialogButtonBox::AcceptRole ) 143 || ( role == QDialogButtonBox::ApplyRole ) ) { 144 // Copy the filter set and persist it to disk 145 *( Persistent<FilterSet>( "filterSet" ) ) = *filterSet; 146 GetPersistentInfo().save( "filterSet" ); 147 emit optionsChanged(); 148 } 149 150 if ( role == QDialogButtonBox::AcceptRole ) 151 accept(); 152 else if ( role == QDialogButtonBox::RejectRole ) 153 reject(); 154 } 155 156 void FiltersDialog::updatePropertyFields() 157 { 158 if ( filterListWidget->selectedItems().count() >= 1 ) 159 selectedRow_ = filterListWidget->row( 160 filterListWidget->selectedItems().at(0) ); 161 else 162 selectedRow_ = -1; 163 164 LOG(logDEBUG) << "updatePropertyFields(), row = " << selectedRow_; 165 166 if ( selectedRow_ >= 0 ) { 167 const Filter& currentFilter = filterSet->filterList.at( selectedRow_ ); 168 169 patternEdit->setText( currentFilter.pattern() ); 170 patternEdit->setEnabled( true ); 171 172 ignoreCaseCheckBox->setChecked( currentFilter.ignoreCase() ); 173 ignoreCaseCheckBox->setEnabled( true ); 174 175 int index = foreColorBox->findText( currentFilter.foreColorName() ); 176 if ( index != -1 ) { 177 LOG(logDEBUG) << "fore index = " << index; 178 foreColorBox->setCurrentIndex( index ); 179 foreColorBox->setEnabled( true ); 180 } 181 index = backColorBox->findText( currentFilter.backColorName() ); 182 if ( index != -1 ) { 183 LOG(logDEBUG) << "back index = " << index; 184 backColorBox->setCurrentIndex( index ); 185 backColorBox->setEnabled( true ); 186 } 187 188 // Enable the buttons if needed 189 removeFilterButton->setEnabled( true ); 190 upFilterButton->setEnabled( selectedRow_ > 0 ); 191 downFilterButton->setEnabled( 192 selectedRow_ < ( filterListWidget->count() - 1 ) ); 193 } 194 else { 195 // Nothing is selected, reset and disable the controls 196 patternEdit->clear(); 197 patternEdit->setEnabled( false ); 198 199 int index = foreColorBox->findText( DEFAULT_FORE_COLOUR ); 200 foreColorBox->setCurrentIndex( index ); 201 foreColorBox->setEnabled( false ); 202 index = backColorBox->findText( DEFAULT_BACK_COLOUR ); 203 204 backColorBox->setCurrentIndex( index ); 205 backColorBox->setEnabled( false ); 206 207 ignoreCaseCheckBox->setChecked( DEFAULT_IGNORE_CASE ); 208 ignoreCaseCheckBox->setEnabled( false ); 209 removeFilterButton->setEnabled( false ); 210 upFilterButton->setEnabled( false ); 211 downFilterButton->setEnabled( false ); 212 } 213 } 214 215 void FiltersDialog::updateFilterProperties() 216 { 217 LOG(logDEBUG) << "updateFilterProperties()"; 218 219 // If a row is selected 220 if ( selectedRow_ >= 0 ) { 221 Filter& currentFilter = filterSet->filterList[selectedRow_]; 222 223 // Update the internal data 224 currentFilter.setPattern( patternEdit->text() ); 225 currentFilter.setIgnoreCase( ignoreCaseCheckBox->isChecked() ); 226 currentFilter.setForeColor( foreColorBox->currentText() ); 227 currentFilter.setBackColor( backColorBox->currentText() ); 228 229 // Update the entry in the filterList widget 230 filterListWidget->currentItem()->setText( patternEdit->text() ); 231 filterListWidget->currentItem()->setForeground( 232 QBrush( QColor( currentFilter.foreColorName() ) ) ); 233 filterListWidget->currentItem()->setBackground( 234 QBrush( QColor( currentFilter.backColorName() ) ) ); 235 } 236 } 237 238 // 239 // Private functions 240 // 241 242 // Fills the color selection combo boxes 243 void FiltersDialog::populateColors() 244 { 245 const QStringList colorNames = QStringList() 246 // Basic 16 HTML colors (minus greys): 247 << "black" 248 << "white" 249 << "maroon" 250 << "red" 251 << "purple" 252 << "fuchsia" 253 << "green" 254 << "lime" 255 << "olive" 256 << "yellow" 257 << "navy" 258 << "blue" 259 << "teal" 260 << "aqua" 261 // Greys 262 << "gainsboro" 263 << "lightgrey" 264 << "silver" 265 << "darkgrey" 266 << "grey" 267 << "dimgrey" 268 // Reds 269 << "tomato" 270 << "orangered" 271 << "orange" 272 << "crimson" 273 << "darkred" 274 // Greens 275 << "greenyellow" 276 << "lightgreen" 277 << "darkgreen" 278 << "lightseagreen" 279 // Blues 280 << "lightcyan" 281 << "darkturquoise" 282 << "steelblue" 283 << "lightblue" 284 << "royalblue" 285 << "darkblue" 286 << "midnightblue" 287 // Browns 288 << "bisque" 289 << "tan" 290 << "sandybrown" 291 << "chocolate"; 292 293 for ( QStringList::const_iterator i = colorNames.constBegin(); 294 i != colorNames.constEnd(); ++i ) { 295 QPixmap solidPixmap( 20, 10 ); 296 solidPixmap.fill( QColor( *i ) ); 297 QIcon solidIcon { solidPixmap }; 298 299 foreColorBox->addItem( solidIcon, *i ); 300 backColorBox->addItem( solidIcon, *i ); 301 } 302 } 303 304 void FiltersDialog::populateFilterList() 305 { 306 filterListWidget->clear(); 307 foreach ( Filter filter, filterSet->filterList ) { 308 QListWidgetItem* new_item = new QListWidgetItem( filter.pattern() ); 309 // new_item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled ); 310 new_item->setForeground( QBrush( QColor( filter.foreColorName() ) ) ); 311 new_item->setBackground( QBrush( QColor( filter.backColorName() ) ) ); 312 filterListWidget->addItem( new_item ); 313 } 314 } 315