~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/app/qgsattributeactiondialog.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
                qgsattributeactiondialog.cpp  -  attribute action dialog
 
3
                             -------------------
 
4
 
 
5
This class creates and manages the Action tab of the Vector Layer
 
6
Properties dialog box. Changes made in the dialog box are propagated
 
7
back to QgsVectorLayer.
 
8
 
 
9
    begin                : October 2004
 
10
    copyright            : (C) 2004 by Gavin Macaulay
 
11
    email                : gavin at macaulay dot co dot nz
 
12
 ***************************************************************************/
 
13
 
 
14
/***************************************************************************
 
15
 *                                                                         *
 
16
 *   This program is free software; you can redistribute it and/or modify  *
 
17
 *   it under the terms of the GNU General Public License as published by  *
 
18
 *   the Free Software Foundation; either version 2 of the License, or     *
 
19
 *   (at your option) any later version.                                   *
 
20
 *                                                                         *
 
21
 ***************************************************************************/
 
22
/* $Id$ */
 
23
 
 
24
#include "qgsattributeactiondialog.h"
 
25
#include "qgsattributeaction.h"
 
26
 
 
27
#include <QFileDialog>
 
28
#include <QHeaderView>
 
29
#include <QMessageBox>
 
30
 
 
31
 
 
32
QgsAttributeActionDialog::QgsAttributeActionDialog( QgsAttributeAction* actions,
 
33
    const QgsFieldMap& fields,
 
34
    QWidget* parent ):
 
35
    QWidget( parent ), mActions( actions )
 
36
{
 
37
  setupUi( this );
 
38
  QHeaderView *header = attributeActionTable->horizontalHeader();
 
39
  header->setHighlightSections( false );
 
40
  header->setStretchLastSection( true );
 
41
  attributeActionTable->setColumnWidth( 0, 100 );
 
42
  attributeActionTable->setColumnWidth( 1, 230 );
 
43
#if QT_VERSION >= 0x040300
 
44
  attributeActionTable->setCornerButtonEnabled( false );
 
45
#endif
 
46
 
 
47
  connect( attributeActionTable, SIGNAL( itemSelectionChanged() ),
 
48
           this, SLOT( itemSelectionChanged() ) );
 
49
  connect( moveUpButton, SIGNAL( clicked() ), this, SLOT( moveUp() ) );
 
50
  connect( moveDownButton, SIGNAL( clicked() ), this, SLOT( moveDown() ) );
 
51
  connect( removeButton, SIGNAL( clicked() ), this, SLOT( remove() ) );
 
52
  connect( browseButton, SIGNAL( clicked() ), this, SLOT( browse() ) );
 
53
  connect( insertButton, SIGNAL( clicked() ), this, SLOT( insert() ) );
 
54
  connect( updateButton, SIGNAL( clicked() ), this, SLOT( update() ) );
 
55
  connect( insertFieldButton, SIGNAL( clicked() ), this, SLOT( insertField() ) );
 
56
 
 
57
  init();
 
58
  // Populate the combo box with the field names. Will the field names
 
59
  // change? If so, they need to be passed into the init() call, or
 
60
  // some access to them retained in this class.
 
61
  for ( QgsFieldMap::const_iterator it = fields.begin(); it != fields.end(); it++ )
 
62
    fieldComboBox->addItem( it->name() );
 
63
}
 
64
 
 
65
void QgsAttributeActionDialog::init()
 
66
{
 
67
  // Start from a fresh slate.
 
68
  attributeActionTable->setRowCount( 0 );
 
69
 
 
70
  // Populate with our actions.
 
71
  for ( int i = 0; i < mActions->size(); i++ )
 
72
  {
 
73
    const QgsAction action = ( *mActions )[i];
 
74
    insertRow( i, action.type(), action.name(), action.action(), action.capture() );
 
75
  }
 
76
}
 
77
 
 
78
void QgsAttributeActionDialog::insertRow( int row, QgsAction::ActionType type, const QString &name, const QString &action, bool capture )
 
79
{
 
80
  QTableWidgetItem* item;
 
81
  attributeActionTable->insertRow( row );
 
82
  item = new QTableWidgetItem( actionType->itemText( type ) );
 
83
  item->setFlags( item->flags() & ~Qt::ItemIsEditable );
 
84
  attributeActionTable->setItem( row, 0, item );
 
85
  attributeActionTable->setItem( row, 1, new QTableWidgetItem( name ) );
 
86
  attributeActionTable->setItem( row, 2, new QTableWidgetItem( action ) );
 
87
  item = new QTableWidgetItem();
 
88
  item->setFlags( item->flags() & ~( Qt::ItemIsEditable | Qt::ItemIsUserCheckable ) );
 
89
  item->setCheckState( capture ? Qt::Checked : Qt::Unchecked );
 
90
  attributeActionTable->setItem( row, 3, item );
 
91
}
 
92
 
 
93
void QgsAttributeActionDialog::moveUp()
 
94
{
 
95
  // Swap the selected row with the one above
 
96
 
 
97
  int row1 = -1, row2 = -1;
 
98
  QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
 
99
  if ( !selection.isEmpty() )
 
100
  {
 
101
    row1 = attributeActionTable->row( selection.first() );
 
102
  }
 
103
 
 
104
  if ( row1 > 0 )
 
105
    row2 = row1 - 1;
 
106
 
 
107
  if ( row1 != -1 && row2 != -1 )
 
108
  {
 
109
    swapRows( row1, row2 );
 
110
    // Move the selection to follow
 
111
    attributeActionTable->selectRow( row2 );
 
112
  }
 
113
}
 
114
 
 
115
void QgsAttributeActionDialog::moveDown()
 
116
{
 
117
  // Swap the selected row with the one below
 
118
  int row1 = -1, row2 = -1;
 
119
  QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
 
120
  if ( !selection.isEmpty() )
 
121
  {
 
122
    row1 = attributeActionTable->row( selection.first() );
 
123
  }
 
124
 
 
125
  if ( row1 < attributeActionTable->rowCount() - 1 )
 
126
    row2 = row1 + 1;
 
127
 
 
128
  if ( row1 != -1 && row2 != -1 )
 
129
  {
 
130
    swapRows( row1, row2 );
 
131
    // Move the selection to follow
 
132
    attributeActionTable->selectRow( row2 );
 
133
  }
 
134
}
 
135
 
 
136
void QgsAttributeActionDialog::swapRows( int row1, int row2 )
 
137
{
 
138
  int colCount = attributeActionTable->columnCount();
 
139
  for ( int col = 0; col < colCount; col++ )
 
140
  {
 
141
    QTableWidgetItem *item = attributeActionTable->takeItem( row1, col );
 
142
    attributeActionTable->setItem( row1, col, attributeActionTable->takeItem( row2, col ) );
 
143
    attributeActionTable->setItem( row2, col, item );
 
144
  }
 
145
}
 
146
 
 
147
void QgsAttributeActionDialog::browse()
 
148
{
 
149
  // Popup a file browser and place the results into the actionName
 
150
  // widget
 
151
 
 
152
  QString action = QFileDialog::getOpenFileName(
 
153
                     this, tr( "Select an action", "File dialog window title" ) );
 
154
 
 
155
  if ( !action.isNull() )
 
156
    actionAction->insert( action );
 
157
}
 
158
 
 
159
void QgsAttributeActionDialog::remove()
 
160
{
 
161
  QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
 
162
  if ( !selection.isEmpty() )
 
163
  {
 
164
    // Remove the selected row.
 
165
    int row = attributeActionTable->row( selection.first() );
 
166
    attributeActionTable->removeRow( row );
 
167
 
 
168
    // And select the row below the one that was selected or the last one.
 
169
    if ( row >= attributeActionTable->rowCount() ) row = attributeActionTable->rowCount() - 1;
 
170
    attributeActionTable->selectRow( row );
 
171
  }
 
172
}
 
173
 
 
174
void QgsAttributeActionDialog::insert()
 
175
{
 
176
  // Add the action details as a new row in the table.
 
177
 
 
178
  int pos = attributeActionTable->rowCount();
 
179
  insert( pos );
 
180
}
 
181
 
 
182
void QgsAttributeActionDialog::insert( int pos )
 
183
{
 
184
  // Check to see if the action name and the action have been specified
 
185
  // before proceeding
 
186
 
 
187
  if ( actionName->text().isEmpty() || actionAction->text().isEmpty() )
 
188
  {
 
189
    QMessageBox::warning( this, tr( "Missing Information" ),
 
190
                          tr( "To create an attribute action, you must provide both a name and the action to perform." ) );
 
191
 
 
192
  }
 
193
  else
 
194
  {
 
195
 
 
196
    // Get the action details and insert into the table at the given
 
197
    // position. Name needs to be unique, so make it so if required.
 
198
 
 
199
    // If the new action name is the same as the action name in the
 
200
    // given pos, don't make the new name unique (because we're
 
201
    // replacing it).
 
202
 
 
203
    int numRows = attributeActionTable->rowCount();
 
204
    QString name;
 
205
    if ( pos < numRows && actionName->text() == attributeActionTable->item( pos, 0 )->text() )
 
206
      name = actionName->text();
 
207
    else
 
208
      name = uniqueName( actionName->text() );
 
209
 
 
210
    if ( pos >= numRows )
 
211
    {
 
212
      // Expand the table to have a row with index pos
 
213
      insertRow( pos, ( QgsAction::ActionType ) actionType->currentIndex(), name, actionAction->text(), captureCB->isChecked() );
 
214
    }
 
215
    else
 
216
    {
 
217
      // Update existing row
 
218
      attributeActionTable->item( pos, 0 )->setText( actionType->currentText() );
 
219
      attributeActionTable->item( pos, 1 )->setText( name );
 
220
      attributeActionTable->item( pos, 2 )->setText( actionAction->text() );
 
221
      attributeActionTable->item( pos, 3 )->setCheckState( captureCB->isChecked() ? Qt::Checked : Qt::Unchecked );
 
222
    }
 
223
  }
 
224
}
 
225
 
 
226
void QgsAttributeActionDialog::update()
 
227
{
 
228
  // Updates the action that is selected with the
 
229
  // action details.
 
230
  QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
 
231
  if ( !selection.isEmpty() )
 
232
  {
 
233
    int i = attributeActionTable->row( selection.first() );
 
234
    insert( i );
 
235
  }
 
236
}
 
237
 
 
238
void QgsAttributeActionDialog::insertField()
 
239
{
 
240
  // Take the selected field, preprend a % and insert into the action
 
241
  // field at the cursor position
 
242
 
 
243
  if ( !fieldComboBox->currentText().isNull() )
 
244
  {
 
245
    QString field( "%" );
 
246
    field += fieldComboBox->currentText();
 
247
    actionAction->insert( field );
 
248
  }
 
249
}
 
250
 
 
251
void QgsAttributeActionDialog::apply()
 
252
{
 
253
  // Update the contents of mActions from the UI.
 
254
 
 
255
  mActions->clearActions();
 
256
  for ( int i = 0; i < attributeActionTable->rowCount(); ++i )
 
257
  {
 
258
    const QgsAction::ActionType type = ( QgsAction::ActionType ) actionType->findText( attributeActionTable->item( i, 0 )->text() );
 
259
    const QString &name = attributeActionTable->item( i, 1 )->text();
 
260
    const QString &action = attributeActionTable->item( i, 2 )->text();
 
261
    if ( !name.isEmpty() && !action.isEmpty() )
 
262
    {
 
263
      QTableWidgetItem *item = attributeActionTable->item( i, 3 );
 
264
      mActions->addAction( type, name, action, item->checkState() == Qt::Checked );
 
265
    }
 
266
  }
 
267
}
 
268
 
 
269
void QgsAttributeActionDialog::itemSelectionChanged()
 
270
{
 
271
  QList<QTableWidgetItem *> selection = attributeActionTable->selectedItems();
 
272
  if ( !selection.isEmpty() )
 
273
  {
 
274
#if QT_VERSION < 0x040400
 
275
    // Supress multiple selection and select row where mouse release occurs.
 
276
    // Workaround for Qt 4.3 bug which allows multiple rows to be selected if
 
277
    // the user presses the mouse in one row header and releases in another.
 
278
    if ( attributeActionTable->row( selection.first() ) != attributeActionTable->row( selection.last() ) )
 
279
    {
 
280
      attributeActionTable->selectRow( attributeActionTable->currentRow() );
 
281
      selection = attributeActionTable->selectedItems();
 
282
    }
 
283
#endif
 
284
    rowSelected( attributeActionTable->row( selection.first() ) );
 
285
  }
 
286
}
 
287
 
 
288
void QgsAttributeActionDialog::rowSelected( int row )
 
289
{
 
290
  // The user has selected a row. We take the contents of that row and
 
291
  // populate the edit section of the dialog so that they can change
 
292
  // the row if desired.
 
293
 
 
294
  QTableWidgetItem *item = attributeActionTable->item( row, 2 );
 
295
  if ( item )
 
296
  {
 
297
    // Only if a populated row was selected
 
298
    actionType->setCurrentIndex( actionType->findText( attributeActionTable->item( row, 0 )->text() ) );
 
299
    actionName->setText( attributeActionTable->item( row, 1 )->text() );
 
300
    actionAction->setText( attributeActionTable->item( row, 2 )->text() );
 
301
    captureCB->setChecked( item->checkState() == Qt::Checked );
 
302
  }
 
303
}
 
304
 
 
305
QString QgsAttributeActionDialog::uniqueName( QString name )
 
306
{
 
307
  // Make sure that the given name is unique, adding a numerical
 
308
  // suffix if necessary.
 
309
 
 
310
  int pos = attributeActionTable->rowCount();
 
311
  bool unique = true;
 
312
 
 
313
  for ( int i = 0; i < pos; ++i )
 
314
  {
 
315
    if ( attributeActionTable->item( i, 0 )->text() == name )
 
316
      unique = false;
 
317
  }
 
318
 
 
319
  if ( !unique )
 
320
  {
 
321
    int suffix_num = 1;
 
322
    QString new_name;
 
323
    while ( !unique )
 
324
    {
 
325
      QString suffix = QString::number( suffix_num );
 
326
      new_name = name + "_" + suffix;
 
327
      unique = true;
 
328
      for ( int i = 0; i < pos; ++i )
 
329
        if ( attributeActionTable->item( i, 0 )->text() == new_name )
 
330
          unique = false;
 
331
      ++suffix_num;
 
332
    }
 
333
    name = new_name;
 
334
  }
 
335
  return name;
 
336
}