rule_renderer_patch_on_r14936.diff

draft patch (symbolForFeature is buggy) - Mayeul Kauffmann, 2010-12-23 08:09 AM

Download (32.2 KB)

View differences:

/hometb/mk/sig/dev/r14936_patched/qgis//src/core/qgsvectorlayer.cpp 2010-12-21 23:24:59.224417564 +0100
837 837
  for ( int i = 0; i < symbols.count(); i++ )
838 838
  {
839 839
    QgsSymbolV2* sym = symbols[i];
840
    
841
    QgsDebugMsg( "num layers symbols:" +
842
                 QString::number( sym->symbolLayerCount() ) );
840 843
    for ( int j = 0; j < sym->symbolLayerCount(); j++ )
841 844
    {
842 845
      int level = sym->symbolLayer( j )->renderingPass();
843
      if ( level < 0 || level >= 1000 ) // ignore invalid levels
844
        continue;
846
     
847
      QgsDebugMsg( "Level: " + QString::number(level ));
848

  
849
      if ( level < 0 || level >= 1000 ){ // ignore invalid levels
850
           QgsDebugMsg( "invalid levels!" );continue;}
845 851
      QgsSymbolV2LevelItem item( sym, j );
846 852
      while ( level >= levels.count() ) // append new empty levels
847 853
        levels.append( QgsSymbolV2Level() );
......
858 864
      QgsSymbolV2LevelItem& item = level[i];
859 865
      if ( !features.contains( item.symbol() ) )
860 866
      {
861
        QgsDebugMsg( "level item's symbol not found!" );
867
//        QgsDebugMsg( "level item's symbol not found!" );
862 868
        continue;
863 869
      }
870
        QgsDebugMsg( "########## level item's symbol found" );
864 871
      int layer = item.layer();
865 872
      QList<QgsFeature>& lst = features[item.symbol()];
866 873
      QList<QgsFeature>::iterator fit;
/hometb/mk/sig/dev/r14936_patched/qgis//src/core/symbology-ng/qgsrulebasedrendererv2.cpp 2010-12-23 02:12:30.503500191 +0100
14 14
 ***************************************************************************/
15 15

  
16 16
#include "qgsrulebasedrendererv2.h"
17

  
17
#include "qgssymbollayerv2.h"
18 18
#include "qgssearchtreenode.h"
19 19
#include "qgssymbollayerv2utils.h"
20 20
#include "qgsrendercontext.h"
......
28 28

  
29 29

  
30 30

  
31
QgsRuleBasedRendererV2::Rule::Rule( QgsSymbolV2* symbol, int scaleMinDenom, int scaleMaxDenom, QString filterExp )
31
QgsRuleBasedRendererV2::Rule::Rule( QgsSymbolV2* symbol, int scaleMinDenom, int scaleMaxDenom, QString filterExp, QString label, QString description )
32 32
    : mSymbol( symbol ),
33 33
    mScaleMinDenom( scaleMinDenom ), mScaleMaxDenom( scaleMaxDenom ),
34
    mFilterExp( filterExp )
34
    mFilterExp( filterExp ), mLabel( label ), mDescription( description )
35 35
{
36 36
  initFilter();
37 37
}
......
62 62

  
63 63
QString QgsRuleBasedRendererV2::Rule::dump() const
64 64
{
65
  return QString( "RULE - scale [%1,%2] - filter %3 - symbol %4" )
66
         .arg( mScaleMinDenom ).arg( mScaleMaxDenom )
65
  return QString( "RULE %1 - scale [%2,%3] - filter %4 - symbol %5" )
66
         .arg( mLabel ).arg( mScaleMinDenom ).arg( mScaleMaxDenom )
67 67
         .arg( mFilterExp ).arg( mSymbol->dump() );
68 68

  
69 69
}
......
107 107
    mScaleMinDenom = other.mScaleMinDenom;
108 108
    mScaleMaxDenom = other.mScaleMaxDenom;
109 109
    mFilterExp = other.mFilterExp;
110
    mLabel = other.mLabel;
111
    mDescription = other.mDescription;
110 112
    initFilter();
111 113
  }
112 114
  return *this;
......
126 128

  
127 129
QgsSymbolV2* QgsRuleBasedRendererV2::symbolForFeature( QgsFeature& feature )
128 130
{
129
  return mCurrentSymbol;
131
//    return mCurrentSymbol; 
132
//    QgsSymbolV2* mergedSymbols = QgsSymbolV2::defaultSymbol( QGis::Line ); // tmp test
133
   QgsSymbolV2* mergedSymbols; //FIXME is this correct?
134
    int nSym = 0; // Number of symbols for a given feature
135

  
136
  for ( QList<Rule*>::iterator it = mCurrentRules.begin(); it != mCurrentRules.end(); ++it )
137
  {
138
    Rule* rule = *it;
139

  
140
    if ( rule->isFilterOK( mCurrentFields, feature ) )
141
        {
142
             if (nSym == 0){
143
                ++nSym;
144
                QgsDebugMsg( "@@@@@@@@@@@@@@@@@@@@@@@@@@ ");
145
                QgsDebugMsg( "@@ 1st symbol to be merged:" + rule->dump());
146
                mergedSymbols = rule->symbol(); //FIXME is this correct? is it why the symbol in the rule itself get modified?
147
            }
148
            else
149
            {
150
                QgsDebugMsg( "@@ ADDING  ADDITIONAL SYMBOL FOR GIVEN FEATURE");
151
                  QgsSymbolV2* tmpSymbol = rule->symbol();
152
//                tmpSymbol = rule->symbol();
153
                QgsDebugMsg( "num layers tmpSymbol:" + QString::number( tmpSymbol->symbolLayerCount() ) );
154
                QgsDebugMsg( "tmpSymbol Rule:" + rule->dump());
155
                QgsDebugMsg( "tmpSymbol Pass0 :" + QString::number( tmpSymbol->symbolLayer( 0 )->renderingPass() ) );
156

  
157
                // Merge layers of additional matched rule with symbol(s) of previously matched rules
158
                QgsSymbolLayerV2*  sl = tmpSymbol->symbolLayer( 0 );
159

  
160
                QgsDebugMsg( "Highest symbol level : " + QString::number ((mergedSymbols->symbolLayer( (mergedSymbols->symbolLayerCount()) -1  ))->renderingPass()));
161

  
162
                // insert symbol matching additional rule only if its first layer is strictly above the last layer of the already merged symbol:
163
                // this is partly to avoid part of the catastrophic consequences of the bug with insertSymbolLayer a few lines below
164
                // and might be changed when this bug is fixed
165
               if(rule->symbol()->symbolLayer( 0 )->renderingPass() <= ((mergedSymbols->symbolLayer( (mergedSymbols->symbolLayerCount()) -1  ))->renderingPass()) ) {QgsDebugMsg("Break"); break;}
166

  
167
               QgsDebugMsg(   QString::number(rule->symbol()->symbolLayer( 0 )->renderingPass()));
168
                mergedSymbols->insertSymbolLayer( (mergedSymbols->symbolLayerCount()) , sl ); // probably buggy: modifies the symbol styles as well!!
169
//                (mergedSymbols->symbolLayer(1))->setRenderingPass(sl->renderingPass() );
170
                 (mergedSymbols->symbolLayer(1))->setRenderingPass( rule->symbol()->symbolLayer( 0 )->renderingPass() );
171
                QgsDebugMsg( "mergedSymbols layer: " + QString::number(1) + "  Pass: "   +
172
                             QString::number(mergedSymbols->symbolLayer(1)->renderingPass())   );
173

  
174
// For testing, currently only one layer is added. Adding several layers could be done with some code more or less like:
175
//                for( int slid = 0 ; slid < tmpSymbol->symbolLayerCount() ; ++slid ){
176
//                    QgsSymbolLayerV2*  sl = tmpSymbol->symbolLayer( slid );
177
//                    mergedSymbols->insertSymbolLayer( slid, sl );
178
//                    (mergedSymbols->symbolLayer(slid))->setRenderingPass(sl->renderingPass() );
179
//                    QgsDebugMsg( "mergedSymbols layer: " + QString::number(slid) + "  Pass: "   +
180
//                                 QString::number(mergedSymbols->symbolLayer(slid)->renderingPass())   );
181
//                }
182

  
183

  
184
            }
185
    //        return rule->symbol(); //work with levels but takes only first rule
186
         }
187
  }
188
    QgsDebugMsg( "num layers mergedSymbols:" + QString::number( mergedSymbols->symbolLayerCount() ) );
189
    QgsDebugMsg( " mergedSymbols Pass layer0:"+ QString::number(mergedSymbols->symbolLayer( 0 )->renderingPass() ));
190
    QgsDebugMsg( "@ @ @ @ @ @ return mergedSymbols");
191
    return mergedSymbols;
130 192
}
131 193

  
132 194
void QgsRuleBasedRendererV2::renderFeature( QgsFeature& feature,
......
198 260
  QgsSymbolV2* s = mDefaultSymbol->clone();
199 261
  QgsRuleBasedRendererV2* r = new QgsRuleBasedRendererV2( s );
200 262
  r->mRules = mRules;
263
  r->setUsingSymbolLevels( usingSymbolLevels() );
201 264
  return r;
202 265
}
203 266

  
......
217 280
{
218 281
  QDomElement rendererElem = doc.createElement( RENDERER_TAG_NAME );
219 282
  rendererElem.setAttribute( "type", "RuleRenderer" );
283
  rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
220 284

  
221 285
  QDomElement rulesElem = doc.createElement( "rules" );
222 286

  
......
233 297
    ruleElem.setAttribute( "filter", rule.filterExpression() );
234 298
    ruleElem.setAttribute( "scalemindenom", rule.scaleMinDenom() );
235 299
    ruleElem.setAttribute( "scalemaxdenom", rule.scaleMaxDenom() );
300
    ruleElem.setAttribute( "label", rule.label() );
301
    ruleElem.setAttribute( "description", rule.description() );
236 302
    rulesElem.appendChild( ruleElem );
237 303
  }
238 304
  rendererElem.appendChild( rulesElem );
......
250 316
  for ( QList<Rule>::iterator it = mRules.begin(); it != mRules.end(); ++it )
251 317
  {
252 318
    QPixmap pix = QgsSymbolLayerV2Utils::symbolPreviewPixmap( it->symbol(), iconSize );
253
    lst << qMakePair( it->filterExpression(), pix );
319
    lst << qMakePair( it->label(), pix );
254 320
  }
255 321
  return lst;
256 322
}
......
260 326
  QgsLegendSymbolList lst;
261 327
  for ( QList<Rule>::iterator it = mRules.begin(); it != mRules.end(); ++it )
262 328
  {
263
    lst << qMakePair( it->filterExpression(), it->symbol() );
329
    lst << qMakePair( it->label(), it->symbol() );
264 330
  }
265 331
  return lst;
266 332
}
......
292 358
    if ( symbolMap.contains( symbolIdx ) )
293 359
    {
294 360
      QString filterExp = ruleElem.attribute( "filter" );
361
      QString label = ruleElem.attribute( "label" );
362
      QString description = ruleElem.attribute( "description" );
295 363
      int scaleMinDenom = ruleElem.attribute( "scalemindenom", "0" ).toInt();
296 364
      int scaleMaxDenom = ruleElem.attribute( "scalemaxdenom", "0" ).toInt();
297
      r->mRules.append( Rule( symbolMap.take( symbolIdx ), scaleMinDenom, scaleMaxDenom, filterExp ) );
365
      r->mRules.append( Rule( symbolMap.take( symbolIdx ), scaleMinDenom, scaleMaxDenom, filterExp, label, description ) );
298 366
    }
299 367
    else
300 368
    {
......
350 418
  {
351 419
    QString newfilter = QString( "%1 = '%2'" ).arg( r->classAttribute() ).arg( cat.value().toString() );
352 420
    QString filter = initialRule.filterExpression();
421
    QString label = initialRule.label();
422
    QString description = initialRule.description();
353 423
    if ( filter.isEmpty() )
354 424
      filter = newfilter;
355 425
    else
356 426
      filter = QString( "(%1) AND (%2)" ).arg( filter ).arg( newfilter );
357
    rules.append( Rule( cat.symbol()->clone(), initialRule.scaleMinDenom(), initialRule.scaleMaxDenom(), filter ) );
427
    rules.append( Rule( cat.symbol()->clone(), initialRule.scaleMinDenom(), initialRule.scaleMaxDenom(), filter, initialRule.label(), initialRule.description() ) );
358 428
  }
359 429
  return rules;
360 430
}
......
366 436
  {
367 437
    QString newfilter = QString( "%1 >= '%2' AND %1 <= '%3'" ).arg( r->classAttribute() ).arg( rng.lowerValue() ).arg( rng.upperValue() );
368 438
    QString filter = initialRule.filterExpression();
439
    QString label = initialRule.label();
440
    QString description = initialRule.description();
369 441
    if ( filter.isEmpty() )
370 442
      filter = newfilter;
371 443
    else
372 444
      filter = QString( "(%1) AND (%2)" ).arg( filter ).arg( newfilter );
373
    rules.append( Rule( rng.symbol()->clone(), initialRule.scaleMinDenom(), initialRule.scaleMaxDenom(), filter ) );
445
    rules.append( Rule( rng.symbol()->clone(), initialRule.scaleMinDenom(), initialRule.scaleMaxDenom(), filter, initialRule.label(), initialRule.description() ) );
374 446
  }
375 447
  return rules;
376 448
}
......
387 459
      continue; // jump over the first scales out of the interval
388 460
    if ( maxDenom != 0 && maxDenom  <= scale )
389 461
      break; // ignore the latter scales out of the interval
390
    rules.append( Rule( initialRule.symbol()->clone(), oldScale, scale, initialRule.filterExpression() ) );
462
    rules.append( Rule( initialRule.symbol()->clone(), oldScale, scale, initialRule.filterExpression(), initialRule.label(), initialRule.description() ) );
391 463
    oldScale = scale;
392 464
  }
393 465
  // last rule
394
  rules.append( Rule( initialRule.symbol()->clone(), oldScale, maxDenom, initialRule.filterExpression() ) );
466
  rules.append( Rule( initialRule.symbol()->clone(), oldScale, maxDenom, initialRule.filterExpression(), initialRule.label(), initialRule.description() ) );
395 467
  return rules;
396 468
}
/hometb/mk/sig/dev/r14936_patched/qgis//src/core/symbology-ng/qgsrulebasedrendererv2.h 2010-12-22 21:14:52.204050948 +0100
44 44
    {
45 45
      public:
46 46
        //! Constructor takes ownership of the symbol
47
        Rule( QgsSymbolV2* symbol, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString() );
47
        Rule( QgsSymbolV2* symbol, int scaleMinDenom = 0, int scaleMaxDenom = 0, QString filterExp = QString(), QString label = QString(), QString description = QString() );
48 48
        Rule( const Rule& other );
49 49
        ~Rule();
50 50
        QString dump() const;
......
57 57
        int scaleMinDenom() const { return mScaleMinDenom; }
58 58
        int scaleMaxDenom() const { return mScaleMaxDenom; }
59 59
        QString filterExpression() const { return mFilterExp; }
60
        QString label() const { return mLabel; }
61
	QString description() const { return mDescription; }
60 62

  
61 63
        void setScaleMinDenom( int scaleMinDenom ) { mScaleMinDenom = scaleMinDenom; }
62 64
        void setScaleMaxDenom( int scaleMaxDenom ) { mScaleMaxDenom = scaleMaxDenom; }
63 65
        void setFilterExpression( QString filterExp ) { mFilterExp = filterExp; initFilter(); }
64

  
66
        void setLabel( QString label ) { mLabel = label; }
67
        void setDescription( QString description ) { mDescription = description; }
68
        
65 69
        Rule& operator=( const Rule& other );
66 70

  
67 71
      protected:
......
70 74

  
71 75
        QgsSymbolV2* mSymbol;
72 76
        int mScaleMinDenom, mScaleMaxDenom;
73
        QString mFilterExp;
77
        QString mFilterExp, mLabel, mDescription;
74 78

  
75 79
        // temporary
76 80
        QgsSearchString mFilterParsed;
......
81 85

  
82 86
    static QgsFeatureRendererV2* create( QDomElement& element );
83 87

  
84
    //! Constructor. Takes ownership of the defult symbol.
88
    //! Constructor. Takes ownership of the default symbol.
85 89
    QgsRuleBasedRendererV2( QgsSymbolV2* defaultSymbol );
86 90

  
87 91
    //! return symbol for current feature. Should not be used individually: there could be more symbols for a feature
/hometb/mk/sig/dev/r14936_patched/qgis//src/gui/symbology-ng/qgsrulebasedrendererv2widget.cpp 2010-12-20 21:10:57.036149117 +0100
27 27
#include <QTreeWidgetItem>
28 28
#include <QVBoxLayout>
29 29
#include <QMessageBox>
30
#include <sstream>
30 31

  
31 32
QgsRendererV2Widget* QgsRuleBasedRendererV2Widget::create( QgsVectorLayer* layer, QgsStyleV2* style, QgsFeatureRendererV2* renderer )
32 33
{
......
57 58
  setupUi( this );
58 59

  
59 60
  treeRules->setRenderer( mRenderer );
60

  
61
  treeRules->setColumnCount(5); // FIXME: is this necessary for all 3 types of grouping?
61 62
  mRefineMenu = new QMenu( btnRefineRule );
62 63
  mRefineMenu->addAction( tr( "Add scales" ), this, SLOT( refineRuleScales() ) );
63 64
  mRefineMenu->addAction( tr( "Add categories" ), this, SLOT( refineRuleCategories() ) );
......
303 304
  setupUi( this );
304 305

  
305 306
  editFilter->setText( mRule.filterExpression() );
306

  
307
  editLabel->setText( mRule.label() );
308
  editDescription->setText( mRule.description() );
309
  
307 310
  if ( mRule.dependsOnScale() )
308 311
  {
309 312
    groupScale->setChecked( true );
......
368 371
void QgsRendererRulePropsDialog::updateRuleFromGui()
369 372
{
370 373
  mRule.setFilterExpression( editFilter->text() );
374
  mRule.setLabel( editLabel->text() );
375
  mRule.setDescription( editDescription->text() );
371 376
  mRule.setScaleMinDenom( groupScale->isChecked() ? spinMinScale->value() : 0 );
372 377
  mRule.setScaleMaxDenom( groupScale->isChecked() ? spinMaxScale->value() : 0 );
373 378
}
......
400 405

  
401 406
QString QgsRendererRulesTreeWidget::formatScaleRange( int minDenom, int maxDenom )
402 407
{
403
  if ( maxDenom != 0 )
404
    return QString( "<1:%1, 1:%2>" ).arg( minDenom ).arg( maxDenom );
408
//   if ( maxDenom != 0 )
409
//     return QString( "<1:%1, 1:%2>" ).arg( minDenom ).arg( maxDenom );
410
//   else
411
//     return QString( "<1:%1, 1:inf>" ).arg( minDenom );
412
  if ( maxDenom != 0 ){
413
    if ( minDenom != 0 ){
414
      return QString( "<%1, %2>" ).arg( formatScale( minDenom ) ).arg( formatScale( maxDenom ) );
415
    }
416
    else
417
      return QString( "<1:0, %1>" ).arg( formatScale( maxDenom ) );
418
  }
405 419
  else
406
    return QString( "<1:%1, 1:inf>" ).arg( minDenom );
420
    return QString( "<%1, 1:inf>" ).arg( formatScale( minDenom ) );
421
  
407 422
}
408 423

  
424
QString QgsRendererRulesTreeWidget::formatScale( int denom )
425
{
426
  if ( denom != 0 ) {
427
    QString denomString = QString( "%1" ).arg( denom );
428

  
429
    // Add spaces for thousands separators
430
    // FIXME: it's not sure to work for right-to-left languages e.g. launching qgis with ./qgis --lang ar
431
    // Hence it is currently disabled for those languages. Otherwise "1:15 000" is displayed "000 15:1"
432
    // (at least running ./qgis --lang ar on French Kubuntu)
433

  
434
     if ( layoutDirection() == Qt::LeftToRight ){
435
      int nSeps=0;
436
      for ( int i=3; i < denomString.size() + nSeps; i+=3){
437
	denomString.insert(denomString.size() - i - nSeps, " " ); nSeps++; // ISO-31-0 recommands spaces rather than locale, see http://en.wikipedia.org/wiki/ISO_31-0#Numbers
438
      } // TODO: fix minor bug (in some cases, space after ":"
439
     }
440
    return QString( "1:%1" ).arg( denomString );
441
  }
442
  else
443
    return QString( "" );
444
}
445

  
446

  
447
int widthMinDenom = 0; // is it the best place to declare those?
448
int widthMaxDenom = 0;
409 449

  
410 450
void QgsRendererRulesTreeWidget::populateRules()
411 451
{
412 452
  if ( !mR ) return;
413 453

  
414 454
  clear();
455

  
456

  
457
  for ( int i = 0; i < mR->ruleCount(); ++i ) // find longest scale string for future padding. FIXME: code already use above; avoid duplicate
458
  {
459
    QgsRuleBasedRendererV2::Rule& rule = mR->ruleAt( i );
460

  
461
    if( formatScale( rule.scaleMinDenom() ).size() > widthMinDenom )
462
      widthMinDenom = formatScale( rule.scaleMinDenom() ).size() ;
463

  
464
    if( formatScale( rule.scaleMaxDenom() ).size() > widthMaxDenom )
465
      widthMaxDenom = formatScale( rule.scaleMaxDenom() ).size() ;
466
  }
467
  
468
  
469
  
415 470
  if ( mGrouping == NoGrouping )
416 471
    populateRulesNoGrouping();
417 472
  else if ( mGrouping == GroupingByScale )
......
423 478
void QgsRendererRulesTreeWidget::populateRulesNoGrouping()
424 479
{
425 480
  QList<QTreeWidgetItem *> lst;
481

  
426 482
  for ( int i = 0; i < mR->ruleCount(); ++i )
427 483
  {
428 484
    QgsRuleBasedRendererV2::Rule& rule = mR->ruleAt( i );
429 485

  
430 486
    QTreeWidgetItem* item = new QTreeWidgetItem;
431
    QString txt = rule.filterExpression();
432
    if ( txt.isEmpty() ) txt = tr( "(no filter)" );
433
    if ( rule.dependsOnScale() )
434
    {
435
      txt += tr( ", scale " ) + formatScaleRange( rule.scaleMinDenom(), rule.scaleMaxDenom() );
436
    }
437 487

  
438
    item->setText( 0, txt );
488
    QString txtLabel = rule.label();
489
    item->setText( 0, txtLabel );
439 490
    item->setData( 0, Qt::UserRole + 1, i );
440 491
    item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule.symbol(), QSize( 16, 16 ) ) );
441 492

  
493
    QString txtRule = rule.filterExpression();
494
    if ( txtRule.isEmpty() ) txtRule = tr( "(no filter)" );
495
    item->setText( 1, txtRule );
496

  
497
    if ( rule.dependsOnScale() )
498
    {
499
      QString txtMinDenomScale = formatScale( rule.scaleMinDenom() );
500
      QString txtMaxDenomScale = formatScale( rule.scaleMaxDenom() );
501
      while( txtMinDenomScale.size() < widthMinDenom ){ txtMinDenomScale.insert( 0, " " );} // pad to left with spaces (to fix string-based sorting)
502
      while( txtMaxDenomScale.size() < widthMaxDenom ){ txtMaxDenomScale.insert( 0, " " );}
503
      item->setText( 2, txtMinDenomScale );
504
      item->setText( 3, txtMaxDenomScale );
505
      item->setTextAlignment (2, Qt::AlignRight);
506
      item->setTextAlignment (3, Qt::AlignRight);
507
    }
508

  
509
    QBrush brush( QColor( 200, 200, 200, 255 ) );
510
    item->setBackground( 1, brush );
511
    item->setBackground( 3, brush );	
512

  
513
    // Id: add 1 to rule number and convert to string
514
    std::ostringstream ioss;
515
    ioss << i+1;
516
    std::string ruleIdx = ioss.str();
517
    while( ruleIdx.size() < 4 ){ ruleIdx.insert( 0, " " );} // pad to left with spaces (to fix string-based sorting)
518
    item->setText( 4, QString(ruleIdx.c_str()) );// Insert Id in table  TODO: base it on SymbolIdx ? How to access it?
519
    item->setTextAlignment (4, Qt::AlignRight);
442 520
    lst << item;
443 521
  }
444 522

  
523

  
524

  
445 525
  addTopLevelItems( lst );
446 526
}
447 527

  
......
466 546
      scale_item->setText( 0, txt );
467 547
      scale_item->setData( 0, Qt::UserRole + 1, -2 );
468 548
      scale_item->setFlags( scale_item->flags() & ~Qt::ItemIsDragEnabled ); // groups cannot be dragged
549
      QFont italicFont("" , -1 , -1, true );
550
      scale_item->setFont( 0, italicFont );
469 551
      scale_items[scale] = scale_item;
552
      // need to add the item before setFirstColumnSpanned,
553
      // see http://qt.nokia.com/developer/task-tracker/index_html?method=entry&id=214686
554
      addTopLevelItem( scale_item );
555
      scale_item->setFirstColumnSpanned( true );
470 556
    }
471 557

  
472 558
    QString filter = rule.filterExpression();
473 559

  
474 560
    QTreeWidgetItem* item = new QTreeWidgetItem( scale_items[scale] );
475
    item->setText( 0, filter.isEmpty() ? tr( "(no filter)" ) : filter );
561

  
562
    QString txtLabel = rule.label();
563
    item->setText( 0, txtLabel );
476 564
    item->setData( 0, Qt::UserRole + 1, i );
477 565
    item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule.symbol(), QSize( 16, 16 ) ) );
566

  
567
    QString txtRule = rule.filterExpression();
568
    if ( txtRule.isEmpty() ) txtRule = tr( "(no filter)" );
569
    item->setText( 1, txtRule );
570

  
571
    if ( rule.dependsOnScale() )
572
    {
573
      QString txtMinDenomScale = formatScale( rule.scaleMinDenom() );
574
      QString txtMaxDenomScale = formatScale( rule.scaleMaxDenom() );
575
      while( txtMinDenomScale.size() < widthMinDenom ){ txtMinDenomScale.insert( 0, " " );} // pad to left with spaces (to fix string-based sorting)
576
      while( txtMaxDenomScale.size() < widthMaxDenom ){ txtMaxDenomScale.insert( 0, " " );}
577
      // Displaying scales is redundant here, but keeping them allows to keep constant the layout and width of all columns when switching to one of the two other views
578
      item->setText( 2, txtMinDenomScale );
579
      item->setText( 3, txtMaxDenomScale );
580
      item->setTextAlignment (2, Qt::AlignRight);
581
      item->setTextAlignment (3, Qt::AlignRight);
582
    }
583

  
584
    QBrush brush( QColor( 200, 200, 200, 255 ) );
585
    item->setBackground( 1, brush );
586
    item->setBackground( 3, brush );
587

  
588
    // Id: add 1 to rule number and convert to string
589
    std::ostringstream ioss;
590
    ioss << i+1;
591
    std::string ruleIdx = ioss.str();
592
    while( ruleIdx.size() < 4 ){ ruleIdx.insert( 0, " " );} // pad to left with spaces (to fix string-based sorting)
593
    item->setText( 4, QString(ruleIdx.c_str()) );// Insert Id in table  TODO: base it on SymbolIdx ? How to access it?
594
    item->setTextAlignment (4, Qt::AlignRight);
595

  
478 596
  }
479 597
  addTopLevelItems( scale_items.values() );
480 598
}
......
494 612
      filter_item->setText( 0, filter.isEmpty() ? tr( "(no filter)" ) : filter );
495 613
      filter_item->setData( 0, Qt::UserRole + 1, -1 );
496 614
      filter_item->setFlags( filter_item->flags() & ~Qt::ItemIsDragEnabled ); // groups cannot be dragged
615
      QFont italicFont("" , -1 , -1, true );
616
      filter_item->setFont( 0, italicFont );
497 617
      filter_items[filter] = filter_item;
618
      // need to add the item before setFirstColumnSpanned,
619
      // see http://qt.nokia.com/developer/task-tracker/index_html?method=entry&id=214686
620
      addTopLevelItem( filter_item );
621
      filter_item->setFirstColumnSpanned( true );
498 622
    }
499 623

  
500
    QString txt;
501
    if ( rule.dependsOnScale() )
502
      txt = QString( "scale <1:%1, 1:%2>" ).arg( rule.scaleMinDenom() ).arg( rule.scaleMaxDenom() );
503
    else
504
      txt = "any scale";
624
// Displaying  scaleMinDenom and scaleMaxDenom separately allows to sort by them in the widget
625
//     QString txt;
626
//     if ( rule.dependsOnScale() )
627
//       txt = QString( "scale <1:%1, 1:%2>" ).arg( rule.scaleMinDenom() ).arg( rule.scaleMaxDenom() );
628
//     else
629
//       txt = "any scale";
505 630

  
506 631
    QTreeWidgetItem* item = new QTreeWidgetItem( filter_items[filter] );
507
    item->setText( 0, txt );
632

  
633
    QString txtLabel = rule.label();
634
    item->setText( 0, txtLabel );
508 635
    item->setData( 0, Qt::UserRole + 1, i );
509 636
    item->setIcon( 0, QgsSymbolLayerV2Utils::symbolPreviewIcon( rule.symbol(), QSize( 16, 16 ) ) );
510 637

  
638
    // Displaying filter is redundant here, but keeping it allows to keep constant the layout and width of all columns when switching to one of the two other views
639
    item->setText( 1, filter );
640

  
641
    QBrush brush( QColor( 200, 200, 200, 255 ) );
642
    item->setBackground( 1, brush ); // Makes table layout slightly more readable when filters are long strings
643
    item->setBackground( 3, brush );
644
    
645
    if ( rule.dependsOnScale() )
646
    {
647
      QString txtMinDenomScale = formatScale( rule.scaleMinDenom() );
648
      QString txtMaxDenomScale = formatScale( rule.scaleMaxDenom() );
649
      while( txtMinDenomScale.size() < widthMinDenom ){ txtMinDenomScale.insert( 0, " " );} // pad to left with spaces (to fix string-based sorting)
650
      while( txtMaxDenomScale.size() < widthMaxDenom ){ txtMaxDenomScale.insert( 0, " " );}
651
      item->setText( 2, txtMinDenomScale );
652
      item->setText( 3, txtMaxDenomScale );
653
      item->setTextAlignment (2, Qt::AlignRight);
654
      item->setTextAlignment (3, Qt::AlignRight);
655
    }
656

  
657
    // Id: add 1 to rule number and convert to string
658
    std::ostringstream ioss;
659
    ioss << i+1;
660
    std::string ruleIdx = ioss.str();
661
    while( ruleIdx.size() < 4 ){ ruleIdx.insert( 0, " " );} // pad to left with spaces (to fix string-based sorting)
662
    item->setText( 4, QString(ruleIdx.c_str()) );// Insert Id in table  TODO: base it on SymbolIdx ? How to access it?
663
    item->setTextAlignment (4, Qt::AlignRight);
511 664
  }
512
  addTopLevelItems( filter_items.values() );
665

  
666
   addTopLevelItems( filter_items.values() );
667

  
668

  
513 669
}
/hometb/mk/sig/dev/r14936_patched/qgis//src/gui/symbology-ng/qgsrulebasedrendererv2widget.h 2010-12-19 15:17:17.099983660 +0100
47 47

  
48 48
    QString formatScaleRange( int minDenom, int maxDenom );
49 49

  
50
    QString formatScale( int denom );
51

  
50 52
    QgsRuleBasedRendererV2* mR;
51 53
    Grouping mGrouping;
52 54
};
/hometb/mk/sig/dev/r14936_patched/qgis//src/ui/qgsrendererrulepropsdialogbase.ui 2010-12-18 02:08:46.182228227 +0100
6 6
   <rect>
7 7
    <x>0</x>
8 8
    <y>0</y>
9
    <width>545</width>
9
    <width>558</width>
10 10
    <height>298</height>
11 11
   </rect>
12 12
  </property>
......
22 22
     <item>
23 23
      <widget class="QLabel" name="label">
24 24
       <property name="text">
25
        <string>Legend label</string>
26
       </property>
27
      </widget>
28
     </item>
29
     <item>
30
      <widget class="QLineEdit" name="editLabel"/>
31
     </item>
32
    </layout>
33
   </item>
34
   <item>
35
    <layout class="QHBoxLayout" name="horizontalLayout">
36
     <property name="rightMargin">
37
      <number>0</number>
38
     </property>
39
     <item>
40
      <widget class="QLabel" name="label">
41
       <property name="text">
25 42
        <string>Filter</string>
26 43
       </property>
27 44
      </widget>
......
51 68
     </item>
52 69
    </layout>
53 70
   </item>
71
   <item>
72
    <layout class="QHBoxLayout" name="horizontalLayout_3">
73
     <item>
74
      <widget class="QLabel" name="label_4">
75
       <property name="text">
76
        <string>Description</string>
77
       </property>
78
      </widget>
79
     </item>
80
     <item>
81
      <widget class="QLineEdit" name="editDescription"/>
82
     </item>
83
    </layout>
84
   </item>
54 85
   <item>
55 86
    <widget class="QGroupBox" name="groupScale">
56 87
     <property name="title">
/hometb/mk/sig/dev/r14936_patched/qgis//src/ui/qgsrulebasedrendererv2widget.ui 2010-12-19 23:32:10.703514200 +0100
6 6
   <rect>
7 7
    <x>0</x>
8 8
    <y>0</y>
9
    <width>460</width>
10
    <height>221</height>
9
    <width>554</width>
10
    <height>256</height>
11 11
   </rect>
12 12
  </property>
13 13
  <property name="windowTitle">
......
26 26
     <property name="rootIsDecorated">
27 27
      <bool>false</bool>
28 28
     </property>
29
     <property name="headerHidden">
29
     <property name="sortingEnabled">
30 30
      <bool>true</bool>
31 31
     </property>
32
     <property name="headerHidden">
33
      <bool>false</bool>
34
     </property>
35
     <column>
36
      <property name="text">
37
       <string>Label</string>
38
      </property>
39
     </column>
32 40
     <column>
33 41
      <property name="text">
34 42
       <string>Rule</string>
35 43
      </property>
44
      <property name="background">
45
       <color>
46
        <red>200</red>
47
        <green>200</green>
48
        <blue>200</blue>
49
       </color>
50
      </property>
51
     </column>
52
     <column>
53
      <property name="text">
54
       <string>Min. scale</string>
55
      </property>
56
      <property name="textAlignment">
57
       <set>AlignHCenter|AlignVCenter|AlignCenter</set>
58
      </property>
59
     </column>
60
     <column>
61
      <property name="text">
62
       <string>Max. scale</string>
63
      </property>
64
      <property name="textAlignment">
65
       <set>AlignHCenter|AlignVCenter|AlignCenter</set>
66
      </property>
67
      <property name="background">
68
       <color>
69
        <red>200</red>
70
        <green>200</green>
71
        <blue>200</blue>
72
       </color>
73
      </property>
74
     </column>
75
     <column>
76
      <property name="text">
77
       <string>Id</string>
78
      </property>
79
      <property name="textAlignment">
80
       <set>AlignHCenter|AlignVCenter|AlignCenter</set>
81
      </property>
36 82
     </column>
37 83
    </widget>
38 84
   </item>