1 ////////////////////////////////////////////////////////////////////////////// 2 // oxygenexceptionlistwidget.cpp 3 // ------------------- 4 // 5 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr> 6 // 7 // SPDX-License-Identifier: MIT 8 ////////////////////////////////////////////////////////////////////////////// 9 10 #include "oxygenexceptionlistwidget.h" 11 #include "oxygenexceptiondialog.h" 12 13 #include <KLocalizedString> 14 15 #include <QMessageBox> 16 #include <QPointer> 17 #include <QIcon> 18 19 //__________________________________________________________ 20 namespace Oxygen 21 { 22 23 //__________________________________________________________ ExceptionListWidget(QWidget * parent)24 ExceptionListWidget::ExceptionListWidget( QWidget* parent ): 25 QWidget( parent ) 26 { 27 28 // ui 29 m_ui.setupUi( this ); 30 31 // list 32 m_ui.exceptionListView->setAllColumnsShowFocus( true ); 33 m_ui.exceptionListView->setRootIsDecorated( false ); 34 m_ui.exceptionListView->setSortingEnabled( false ); 35 m_ui.exceptionListView->setModel( &model() ); 36 m_ui.exceptionListView->sortByColumn( ExceptionModel::ColumnType, Qt::AscendingOrder ); 37 m_ui.exceptionListView->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Ignored ) ); 38 39 m_ui.moveUpButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-up" ) ) ); 40 m_ui.moveDownButton->setIcon( QIcon::fromTheme( QStringLiteral( "arrow-down" ) ) ); 41 m_ui.addButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-add" ) ) ); 42 m_ui.removeButton->setIcon( QIcon::fromTheme( QStringLiteral( "list-remove" ) ) ); 43 m_ui.editButton->setIcon( QIcon::fromTheme( QStringLiteral( "edit-rename" ) ) ); 44 45 connect( m_ui.addButton, SIGNAL(clicked()), SLOT(add()) ); 46 connect( m_ui.editButton, SIGNAL(clicked()), SLOT(edit()) ); 47 connect( m_ui.removeButton, SIGNAL(clicked()), SLOT(remove()) ); 48 connect( m_ui.moveUpButton, SIGNAL(clicked()), SLOT(up()) ); 49 connect( m_ui.moveDownButton, SIGNAL(clicked()), SLOT(down()) ); 50 51 connect( m_ui.exceptionListView, SIGNAL(activated(QModelIndex)), SLOT(edit()) ); 52 connect( m_ui.exceptionListView, SIGNAL(clicked(QModelIndex)), SLOT(toggle(QModelIndex)) ); 53 connect( m_ui.exceptionListView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(updateButtons()) ); 54 55 updateButtons(); 56 resizeColumns(); 57 58 59 } 60 61 //__________________________________________________________ setExceptions(const InternalSettingsList & exceptions)62 void ExceptionListWidget::setExceptions( const InternalSettingsList& exceptions ) 63 { 64 model().set( exceptions ); 65 resizeColumns(); 66 setChanged( false ); 67 } 68 69 //__________________________________________________________ exceptions(void)70 InternalSettingsList ExceptionListWidget::exceptions( void ) 71 { 72 return model().get(); 73 setChanged( false ); 74 } 75 76 //__________________________________________________________ updateButtons(void)77 void ExceptionListWidget::updateButtons( void ) 78 { 79 80 bool hasSelection( !m_ui.exceptionListView->selectionModel()->selectedRows().empty() ); 81 m_ui.removeButton->setEnabled( hasSelection ); 82 m_ui.editButton->setEnabled( hasSelection ); 83 84 m_ui.moveUpButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( 0, QModelIndex() ) ); 85 m_ui.moveDownButton->setEnabled( hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected( model().rowCount()-1, QModelIndex() ) ); 86 87 } 88 89 90 //_______________________________________________________ add(void)91 void ExceptionListWidget::add( void ) 92 { 93 94 95 QPointer<ExceptionDialog> dialog = new ExceptionDialog( this ); 96 dialog->setWindowTitle( i18n( "New Exception - Oxygen Settings" ) ); 97 InternalSettingsPtr exception( new InternalSettings() ); 98 99 exception->load(); 100 101 dialog->setException( exception ); 102 103 // run dialog and check existence 104 if( !dialog->exec() ) 105 { 106 delete dialog; 107 return; 108 } 109 110 dialog->save(); 111 delete dialog; 112 113 // check exceptions 114 if( !checkException( exception ) ) return; 115 116 // create new item 117 model().add( exception ); 118 setChanged( true ); 119 120 // make sure item is selected 121 QModelIndex index( model().index( exception ) ); 122 if( index != m_ui.exceptionListView->selectionModel()->currentIndex() ) 123 { 124 m_ui.exceptionListView->selectionModel()->select( index, QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 125 m_ui.exceptionListView->selectionModel()->setCurrentIndex( index, QItemSelectionModel::Current|QItemSelectionModel::Rows ); 126 } 127 128 resizeColumns(); 129 return; 130 131 } 132 133 //_______________________________________________________ edit(void)134 void ExceptionListWidget::edit( void ) 135 { 136 137 // retrieve selection 138 QModelIndex current( m_ui.exceptionListView->selectionModel()->currentIndex() ); 139 if( ! model().contains( current ) ) return; 140 141 InternalSettingsPtr exception( model().get( current ) ); 142 143 // create dialog 144 QPointer<ExceptionDialog> dialog( new ExceptionDialog( this ) ); 145 dialog->setWindowTitle( i18n( "Edit Exception - Oxygen Settings" ) ); 146 dialog->setException( exception ); 147 148 // map dialog 149 if( !dialog->exec() ) 150 { 151 delete dialog; 152 return; 153 } 154 155 // check modifications 156 if( !dialog->isChanged() ) return; 157 158 // retrieve exception 159 dialog->save(); 160 delete dialog; 161 162 // check new exception validity 163 checkException( exception ); 164 resizeColumns(); 165 166 setChanged( true ); 167 168 return; 169 170 } 171 172 //_______________________________________________________ remove(void)173 void ExceptionListWidget::remove( void ) 174 { 175 176 // confirmation dialog 177 { 178 QMessageBox messageBox( QMessageBox::Question, i18n("Question - Oxygen Settings" ), i18n("Remove selected exception?"), QMessageBox::Yes | QMessageBox::Cancel ); 179 messageBox.button( QMessageBox::Yes )->setText( i18n("Remove") ); 180 messageBox.setDefaultButton( QMessageBox::Cancel ); 181 if( messageBox.exec() == QMessageBox::Cancel ) return; 182 } 183 184 // remove 185 model().remove( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 186 resizeColumns(); 187 updateButtons(); 188 189 setChanged( true ); 190 191 return; 192 193 } 194 195 //_______________________________________________________ toggle(const QModelIndex & index)196 void ExceptionListWidget::toggle( const QModelIndex& index ) 197 { 198 199 if( !model().contains( index ) ) return; 200 if( index.column() != ExceptionModel::ColumnEnabled ) return; 201 202 // get matching exception 203 InternalSettingsPtr exception( model().get( index ) ); 204 exception->setEnabled( !exception->enabled() ); 205 setChanged( true ); 206 return; 207 208 } 209 210 //_______________________________________________________ up(void)211 void ExceptionListWidget::up( void ) 212 { 213 214 InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 215 if( selection.empty() ) { return; } 216 217 // retrieve selected indexes in list and store in model 218 QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedRows() ); 219 InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); 220 221 InternalSettingsList currentException( model().get() ); 222 InternalSettingsList newExceptions; 223 224 for( InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter ) 225 { 226 227 // check if new list is not empty, current index is selected and last index is not. 228 // if yes, move. 229 if( 230 !( newExceptions.empty() || 231 selectedIndices.indexOf( model().index( *iter ) ) == -1 || 232 selectedIndices.indexOf( model().index( newExceptions.back() ) ) != -1 233 ) ) 234 { 235 InternalSettingsPtr last( newExceptions.back() ); 236 newExceptions.removeLast(); 237 newExceptions.append( *iter ); 238 newExceptions.append( last ); 239 } else newExceptions.append( *iter ); 240 241 } 242 243 model().set( newExceptions ); 244 245 // restore selection 246 m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 247 for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) 248 { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } 249 250 setChanged( true ); 251 252 return; 253 254 } 255 256 //_______________________________________________________ down(void)257 void ExceptionListWidget::down( void ) 258 { 259 260 InternalSettingsList selection( model().get( m_ui.exceptionListView->selectionModel()->selectedRows() ) ); 261 if( selection.empty() ) 262 { return; } 263 264 // retrieve selected indexes in list and store in model 265 QModelIndexList selectedIndices( m_ui.exceptionListView->selectionModel()->selectedIndexes() ); 266 InternalSettingsList selectedExceptions( model().get( selectedIndices ) ); 267 268 InternalSettingsList currentExceptions( model().get() ); 269 InternalSettingsList newExceptions; 270 271 InternalSettingsListIterator iter( currentExceptions ); 272 iter.toBack(); 273 while( iter.hasPrevious() ) 274 { 275 276 InternalSettingsPtr current( iter.previous() ); 277 278 // check if new list is not empty, current index is selected and last index is not. 279 // if yes, move. 280 if( 281 !( newExceptions.empty() || 282 selectedIndices.indexOf( model().index( current ) ) == -1 || 283 selectedIndices.indexOf( model().index( newExceptions.front() ) ) != -1 284 ) ) 285 { 286 287 InternalSettingsPtr first( newExceptions.front() ); 288 newExceptions.removeFirst(); 289 newExceptions.prepend( current ); 290 newExceptions.prepend( first ); 291 292 } else newExceptions.prepend( current ); 293 } 294 295 model().set( newExceptions ); 296 297 // restore selection 298 m_ui.exceptionListView->selectionModel()->select( model().index( selectedExceptions.front() ), QItemSelectionModel::Clear|QItemSelectionModel::Select|QItemSelectionModel::Rows ); 299 for( InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter ) 300 { m_ui.exceptionListView->selectionModel()->select( model().index( *iter ), QItemSelectionModel::Select|QItemSelectionModel::Rows ); } 301 302 setChanged( true ); 303 304 return; 305 306 } 307 308 //_______________________________________________________ resizeColumns(void) const309 void ExceptionListWidget::resizeColumns( void ) const 310 { 311 m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnEnabled ); 312 m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnType ); 313 m_ui.exceptionListView->resizeColumnToContents( ExceptionModel::ColumnRegExp ); 314 } 315 316 //_______________________________________________________ checkException(InternalSettingsPtr exception)317 bool ExceptionListWidget::checkException( InternalSettingsPtr exception ) 318 { 319 320 while( exception->exceptionPattern().isEmpty() || !QRegularExpression( exception->exceptionPattern() ).isValid() ) 321 { 322 323 QMessageBox::warning( this, i18n( "Warning - Oxygen Settings" ), i18n("Regular Expression syntax is incorrect") ); 324 QPointer<ExceptionDialog> dialog( new ExceptionDialog( this ) ); 325 dialog->setException( exception ); 326 if( dialog->exec() == QDialog::Rejected ) 327 { 328 delete dialog; 329 return false; 330 } 331 332 dialog->save(); 333 delete dialog; 334 } 335 336 return true; 337 } 338 339 } 340