src/app/qgsattributeactiondialog.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002                 qgsattributeactiondialog.cpp  -  attribute action dialog
00003                              -------------------
00004 
00005 This class creates and manages the Action tab of the Vector Layer
00006 Properties dialog box. Changes made in the dialog box are propagated
00007 back to QgsVectorLayer.
00008 
00009     begin                : October 2004
00010     copyright            : (C) 2004 by Gavin Macaulay
00011     email                : gavin at macaulay dot co dot nz
00012  ***************************************************************************/
00013 
00014 /***************************************************************************
00015  *                                                                         *
00016  *   This program is free software; you can redistribute it and/or modify  *
00017  *   it under the terms of the GNU General Public License as published by  *
00018  *   the Free Software Foundation; either version 2 of the License, or     *
00019  *   (at your option) any later version.                                   *
00020  *                                                                         *
00021  ***************************************************************************/
00022 /* $Id: qgsattributeactiondialog.cpp 9138 2008-08-23 21:37:31Z jef $ */
00023 
00024 #include "qgsattributeactiondialog.h"
00025 #include "qgsattributeaction.h"
00026 
00027 #include <QFileDialog>
00028 #include <QHeaderView>
00029 
00030 
00031 QgsAttributeActionDialog::QgsAttributeActionDialog( QgsAttributeAction* actions,
00032     const QgsFieldMap& fields,
00033     QWidget* parent ):
00034     QWidget( parent ), mActions( actions )
00035 {
00036   setupUi( this );
00037   QHeaderView *header = attributeActionTable->horizontalHeader();
00038   header->setHighlightSections( false );
00039   header->setStretchLastSection( true );
00040   attributeActionTable->setColumnWidth( 0, 100 );
00041   attributeActionTable->setColumnWidth( 1, 230 );
00042 #if QT_VERSION >= 0x040300
00043   attributeActionTable->setCornerButtonEnabled( false );
00044 #endif
00045 
00046   connect( attributeActionTable, SIGNAL( itemSelectionChanged() ),
00047            this, SLOT( itemSelectionChanged() ) );
00048   connect( moveUpButton, SIGNAL( clicked() ), this, SLOT( moveUp() ) );
00049   connect( moveDownButton, SIGNAL( clicked() ), this, SLOT( moveDown() ) );
00050   connect( removeButton, SIGNAL( clicked() ), this, SLOT( remove() ) );
00051   connect( browseButton, SIGNAL( clicked() ), this, SLOT( browse() ) );
00052   connect( insertButton, SIGNAL( clicked() ), this, SLOT( insert() ) );
00053   connect( updateButton, SIGNAL( clicked() ), this, SLOT( update() ) );
00054   connect( insertFieldButton, SIGNAL( clicked() ), this, SLOT( insertField() ) );
00055 
00056   init();
00057   // Populate the combo box with the field names. Will the field names
00058   // change? If so, they need to be passed into the init() call, or
00059   // some access to them retained in this class.
00060   for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); it++ )
00061     fieldComboBox->addItem( it->name() );
00062 }
00063 
00064 void QgsAttributeActionDialog::init()
00065 {
00066   // Start from a fresh slate.
00067   attributeActionTable->setRowCount( 0 );
00068 
00069   // Populate with our actions.
00070   QgsAttributeAction::AttributeActions::const_iterator
00071   iter = mActions->begin();
00072   int i = 0;
00073   for ( ; iter != mActions->end(); ++iter, ++i )
00074   {
00075     insertRow( i, iter->name(), iter->action(), iter->capture() );
00076   }
00077 }
00078 
00079 void QgsAttributeActionDialog::insertRow( int row, const QString &name, const QString &action, bool capture )
00080 {
00081   attributeActionTable->insertRow( row );
00082   attributeActionTable->setItem( row, 0, new QTableWidgetItem( name ) );
00083   attributeActionTable->setItem( row, 1, new QTableWidgetItem( action ) );
00084   QTableWidgetItem* item = new QTableWidgetItem();
00085   item->setFlags( item->flags() & ~( Qt::ItemIsEditable | Qt::ItemIsUserCheckable ) );
00086   item->setCheckState( capture ? Qt::Checked : Qt::Unchecked );
00087   attributeActionTable->setItem( row, 2, item );
00088 }
00089 
00090 void QgsAttributeActionDialog::moveUp()
00091 {
00092   // Swap the selected row with the one above
00093 
00094   int row1 = -1, row2 = -1;
00095   QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
00096   if ( !selection.isEmpty() )
00097   {
00098     row1 = attributeActionTable->row( selection.first() );
00099   }
00100 
00101   if ( row1 > 0 )
00102     row2 = row1 - 1;
00103 
00104   if ( row1 != -1 && row2 != -1 )
00105   {
00106     swapRows( row1, row2 );
00107     // Move the selection to follow
00108     attributeActionTable->selectRow( row2 );
00109   }
00110 }
00111 
00112 void QgsAttributeActionDialog::moveDown()
00113 {
00114   // Swap the selected row with the one below
00115   int row1 = -1, row2 = -1;
00116   QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
00117   if ( !selection.isEmpty() )
00118   {
00119     row1 = attributeActionTable->row( selection.first() );
00120   }
00121 
00122   if ( row1 < attributeActionTable->rowCount() - 1 )
00123     row2 = row1 + 1;
00124 
00125   if ( row1 != -1 && row2 != -1 )
00126   {
00127     swapRows( row1, row2 );
00128     // Move the selection to follow
00129     attributeActionTable->selectRow( row2 );
00130   }
00131 }
00132 
00133 void QgsAttributeActionDialog::swapRows( int row1, int row2 )
00134 {
00135   int colCount = attributeActionTable->columnCount();
00136   for ( int col = 0; col < colCount; col++ )
00137   {
00138     QTableWidgetItem *item = attributeActionTable->takeItem( row1, col );
00139     attributeActionTable->setItem( row1, col, attributeActionTable->takeItem( row2, col ) );
00140     attributeActionTable->setItem( row2, col, item );
00141   }
00142 }
00143 
00144 void QgsAttributeActionDialog::browse()
00145 {
00146   // Popup a file browser and place the results into the actionName
00147   // widget
00148 
00149   QString action = QFileDialog::getOpenFileName(
00150                      this, tr( "Select an action", "File dialog window title" ) );
00151 
00152   if ( !action.isNull() )
00153     actionAction->insert( action );
00154 }
00155 
00156 void QgsAttributeActionDialog::remove()
00157 {
00158   QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
00159   if ( !selection.isEmpty() )
00160   {
00161     // Remove the selected row.
00162     int row = attributeActionTable->row( selection.first() );
00163     attributeActionTable->removeRow( row );
00164 
00165     // And select the row below the one that was selected or the last one.
00166     if ( row >= attributeActionTable->rowCount() ) row = attributeActionTable->rowCount() - 1;
00167     attributeActionTable->selectRow( row );
00168   }
00169 }
00170 
00171 void QgsAttributeActionDialog::insert()
00172 {
00173   // Add the action details as a new row in the table.
00174 
00175   int pos = attributeActionTable->rowCount();
00176   insert( pos );
00177 }
00178 
00179 void QgsAttributeActionDialog::insert( int pos )
00180 {
00181   // Get the action details and insert into the table at the given
00182   // position. Name needs to be unique, so make it so if required.
00183 
00184   // If the new action name is the same as the action name in the
00185   // given pos, don't make the new name unique (because we're
00186   // replacing it).
00187 
00188   int numRows = attributeActionTable->rowCount();
00189   QString name;
00190   if ( pos < numRows && actionName->text() == attributeActionTable->item( pos, 0 )->text() )
00191     name = actionName->text();
00192   else
00193     name = uniqueName( actionName->text() );
00194 
00195   if ( pos >= numRows )
00196   {
00197     // Expand the table to have a row with index pos
00198     insertRow( pos, name, actionAction->text(), captureCB->isChecked() );
00199   }
00200   else
00201   {
00202     // Update existing row
00203     attributeActionTable->item( pos, 0 )->setText( name );
00204     attributeActionTable->item( pos, 1 )->setText( actionAction->text() );
00205     attributeActionTable->item( pos, 2 )->setCheckState(
00206       captureCB->isChecked() ? Qt::Checked : Qt::Unchecked );
00207   }
00208 }
00209 
00210 void QgsAttributeActionDialog::update()
00211 {
00212   // Updates the action that is selected with the
00213   // action details.
00214   QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
00215   if ( !selection.isEmpty() )
00216   {
00217     int i = attributeActionTable->row( selection.first() );
00218     insert( i );
00219   }
00220 }
00221 
00222 void QgsAttributeActionDialog::insertField()
00223 {
00224   // Take the selected field, preprend a % and insert into the action
00225   // field at the cursor position
00226 
00227   if ( !fieldComboBox->currentText().isNull() )
00228   {
00229     QString field( "%" );
00230     field += fieldComboBox->currentText();
00231     actionAction->insert( field );
00232   }
00233 }
00234 
00235 void QgsAttributeActionDialog::apply()
00236 {
00237   // Update the contents of mActions from the UI.
00238 
00239   mActions->clearActions();
00240   for ( int i = 0; i < attributeActionTable->rowCount(); ++i )
00241   {
00242     const QString &name = attributeActionTable->item( i, 0 )->text();
00243     const QString &action = attributeActionTable->item( i, 1 )->text();
00244     if ( !name.isEmpty() && !action.isEmpty() )
00245     {
00246       QTableWidgetItem *item = attributeActionTable->item( i, 2 );
00247       mActions->addAction( name, action, item->checkState() == Qt::Checked );
00248     }
00249   }
00250 }
00251 
00252 void QgsAttributeActionDialog::itemSelectionChanged()
00253 {
00254   QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
00255   if ( !selection.isEmpty() )
00256   {
00257 #if QT_VERSION < 0x040400
00258     // Supress multiple selection and select row where mouse release occurs.
00259     // Workaround for Qt 4.3 bug which allows multiple rows to be selected if
00260     // the user presses the mouse in one row header and releases in another.
00261     if ( attributeActionTable->row( selection.first() ) != attributeActionTable->row( selection.last() ) )
00262     {
00263       attributeActionTable->selectRow( attributeActionTable->currentRow() );
00264       selection = attributeActionTable->selectedItems();
00265     }
00266 #endif
00267     rowSelected( attributeActionTable->row( selection.first() ) );
00268   }
00269 }
00270 
00271 void QgsAttributeActionDialog::rowSelected( int row )
00272 {
00273   // The user has selected a row. We take the contents of that row and
00274   // populate the edit section of the dialog so that they can change
00275   // the row if desired.
00276 
00277   QTableWidgetItem *item = attributeActionTable->item( row, 2 );
00278   if ( item )
00279   {
00280     // Only if a populated row was selected
00281     actionName->setText( attributeActionTable->item( row, 0 )->text() );
00282     actionAction->setText( attributeActionTable->item( row, 1 )->text() );
00283     captureCB->setChecked( item->checkState() == Qt::Checked );
00284   }
00285 }
00286 
00287 QString QgsAttributeActionDialog::uniqueName( QString name )
00288 {
00289   // Make sure that the given name is unique, adding a numerical
00290   // suffix if necessary.
00291 
00292   int pos = attributeActionTable->rowCount();
00293   bool unique = true;
00294 
00295   for ( int i = 0; i < pos; ++i )
00296   {
00297     if ( attributeActionTable->item( i, 0 )->text() == name )
00298       unique = false;
00299   }
00300 
00301   if ( !unique )
00302   {
00303     int suffix_num = 1;
00304     QString new_name;
00305     while ( !unique )
00306     {
00307       QString suffix = QString::number( suffix_num );
00308       new_name = name + "_" + suffix;
00309       unique = true;
00310       for ( int i = 0; i < pos; ++i )
00311         if ( attributeActionTable->item( i, 0 )->text() == new_name )
00312           unique = false;
00313       ++suffix_num;
00314     }
00315     name = new_name;
00316   }
00317   return name;
00318 }

Generated on Tue Oct 28 16:51:25 2008 for Quantum GIS API Documentation by  doxygen 1.5.1