@@ -57,7 +57,6 @@ QgsRuleBasedRendererV2Widget::QgsRuleBasedRendererV2Widget( QgsVectorLayer* laye
57
57
setupUi ( this );
58
58
59
59
treeRules->setRenderer ( mRenderer );
60
-
61
60
mRefineMenu = new QMenu ( btnRefineRule );
62
61
mRefineMenu ->addAction ( tr ( " Add scales" ), this , SLOT ( refineRuleScales () ) );
63
62
mRefineMenu ->addAction ( tr ( " Add categories" ), this , SLOT ( refineRuleCategories () ) );
@@ -303,6 +302,8 @@ QgsRendererRulePropsDialog::QgsRendererRulePropsDialog( const QgsRuleBasedRender
303
302
setupUi ( this );
304
303
305
304
editFilter->setText ( mRule .filterExpression () );
305
+ editLabel->setText ( mRule .label () );
306
+ editDescription->setText ( mRule .description () );
306
307
307
308
if ( mRule .dependsOnScale () )
308
309
{
@@ -368,6 +369,8 @@ void QgsRendererRulePropsDialog::testFilter()
368
369
void QgsRendererRulePropsDialog::updateRuleFromGui ()
369
370
{
370
371
mRule .setFilterExpression ( editFilter->text () );
372
+ mRule .setLabel ( editLabel->text () );
373
+ mRule .setDescription ( editDescription->text () );
371
374
mRule .setScaleMinDenom ( groupScale->isChecked () ? spinMinScale->value () : 0 );
372
375
mRule .setScaleMaxDenom ( groupScale->isChecked () ? spinMaxScale->value () : 0 );
373
376
}
@@ -377,6 +380,9 @@ void QgsRendererRulePropsDialog::updateRuleFromGui()
377
380
QgsRendererRulesTreeWidget::QgsRendererRulesTreeWidget ( QWidget* parent )
378
381
: QTreeWidget( parent ), mR( NULL ), mGrouping( NoGrouping )
379
382
{
383
+ mLongestMinDenom = 0 ;
384
+ mLongestMaxDenom = 0 ;
385
+
380
386
setSelectionMode ( QAbstractItemView::SingleSelection );
381
387
/*
382
388
setDragEnabled(true);
@@ -401,54 +407,100 @@ void QgsRendererRulesTreeWidget::setGrouping( Grouping g )
401
407
QString QgsRendererRulesTreeWidget::formatScaleRange ( int minDenom, int maxDenom )
402
408
{
403
409
if ( maxDenom != 0 )
404
- return QString ( " <1:%1 , 1:%2 >" ).arg ( minDenom ).arg ( maxDenom );
410
+ return QString ( " <1:%L1 , 1:%L2 >" ).arg ( minDenom ).arg ( maxDenom );
405
411
else
406
- return QString ( " <1:%1, 1:inf>" ).arg ( minDenom );
412
+ return QString ( " <1:%L1, 1:inf>" ).arg ( minDenom );
413
+
407
414
}
408
415
416
+ QString QgsRendererRulesTreeWidget::formatScale ( int denom, int size )
417
+ {
418
+ if ( denom != 0 )
419
+ {
420
+ QString txt = QString ( " 1:%L1" ).arg ( denom );
421
+ if ( size > 0 )
422
+ txt.prepend ( QString ( size - txt.count (), QChar ( ' ' ) ) );
423
+ return txt;
424
+ }
425
+ else
426
+ return QString ();
427
+ }
409
428
429
+ #include " qgslogger.h"
410
430
void QgsRendererRulesTreeWidget::populateRules ()
411
431
{
412
432
if ( !mR ) return ;
413
433
414
434
clear ();
435
+
436
+ mLongestMinDenom = 0 ;
437
+ mLongestMaxDenom = 0 ;
438
+ // find longest scale string for future padding
439
+ // TODO: use a custom model and implement custom sorting
440
+ for ( int i = 0 ; i < mR ->ruleCount (); ++i )
441
+ {
442
+ QgsRuleBasedRendererV2::Rule& rule = mR ->ruleAt ( i );
443
+
444
+ mLongestMinDenom = qMax ( mLongestMinDenom , formatScale ( rule.scaleMinDenom () ).size () );
445
+ mLongestMaxDenom = qMax ( mLongestMaxDenom , formatScale ( rule.scaleMaxDenom () ).size () );
446
+ }
447
+
448
+
449
+
415
450
if ( mGrouping == NoGrouping )
416
451
populateRulesNoGrouping ();
417
452
else if ( mGrouping == GroupingByScale )
418
453
populateRulesGroupByScale ();
419
454
else
420
455
populateRulesGroupByFilter ();
456
+
457
+ setColumnWidth ( 1 , 200 ); // make the column for filter a bit bigger
421
458
}
422
459
423
460
void QgsRendererRulesTreeWidget::populateRulesNoGrouping ()
424
461
{
425
462
QList<QTreeWidgetItem *> lst;
463
+
426
464
for ( int i = 0 ; i < mR ->ruleCount (); ++i )
427
465
{
428
466
QgsRuleBasedRendererV2::Rule& rule = mR ->ruleAt ( i );
429
467
430
468
QTreeWidgetItem* item = new QTreeWidgetItem;
431
- QString txt = rule.filterExpression ();
432
- if ( txt.isEmpty () ) txt = tr ( " (no filter)" );
469
+
470
+ QString txtLabel = rule.label ();
471
+ item->setText ( 0 , txtLabel );
472
+ item->setData ( 0 , Qt::UserRole + 1 , i );
473
+ item->setIcon ( 0 , QgsSymbolLayerV2Utils::symbolPreviewIcon ( rule.symbol (), QSize ( 16 , 16 ) ) );
474
+
475
+ QString txtRule = rule.filterExpression ();
476
+ if ( txtRule.isEmpty () ) txtRule = tr ( " (no filter)" );
477
+ item->setText ( 1 , txtRule );
478
+
433
479
if ( rule.dependsOnScale () )
434
480
{
435
- txt += tr ( " , scale " ) + formatScaleRange ( rule.scaleMinDenom (), rule.scaleMaxDenom () );
481
+ item->setText ( 2 , formatScale ( rule.scaleMinDenom (), mLongestMinDenom ) );
482
+ item->setText ( 3 , formatScale ( rule.scaleMaxDenom (), mLongestMaxDenom ) );
483
+ item->setTextAlignment ( 2 , Qt::AlignRight );
484
+ item->setTextAlignment ( 3 , Qt::AlignRight );
436
485
}
437
486
438
- item->setText ( 0 , txt );
439
- item->setData ( 0 , Qt::UserRole + 1 , i );
440
- item->setIcon ( 0 , QgsSymbolLayerV2Utils::symbolPreviewIcon ( rule.symbol (), QSize ( 16 , 16 ) ) );
487
+ // item->setBackground( 1, Qt::lightGray );
488
+ // item->setBackground( 3, Qt::lightGray );
441
489
442
490
lst << item;
443
491
}
444
492
493
+
445
494
addTopLevelItems ( lst );
446
495
}
447
496
448
497
void QgsRendererRulesTreeWidget::populateRulesGroupByScale ()
449
498
{
450
499
QMap< QPair<int , int >, QTreeWidgetItem*> scale_items;
451
500
501
+ QFont italicFont;
502
+ italicFont.setItalic ( true );
503
+
452
504
for ( int i = 0 ; i < mR ->ruleCount (); ++i )
453
505
{
454
506
QgsRuleBasedRendererV2::Rule& rule = mR ->ruleAt ( i );
@@ -466,15 +518,38 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByScale()
466
518
scale_item->setText ( 0 , txt );
467
519
scale_item->setData ( 0 , Qt::UserRole + 1 , -2 );
468
520
scale_item->setFlags ( scale_item->flags () & ~Qt::ItemIsDragEnabled ); // groups cannot be dragged
521
+ scale_item->setFont ( 0 , italicFont );
469
522
scale_items[scale] = scale_item;
523
+ // need to add the item before setFirstColumnSpanned,
524
+ // see http://qt.nokia.com/developer/task-tracker/index_html?method=entry&id=214686
525
+ addTopLevelItem ( scale_item );
526
+ scale_item->setFirstColumnSpanned ( true );
470
527
}
471
528
472
529
QString filter = rule.filterExpression ();
473
530
474
531
QTreeWidgetItem* item = new QTreeWidgetItem ( scale_items[scale] );
475
- item->setText ( 0 , filter.isEmpty () ? tr ( " (no filter)" ) : filter );
532
+
533
+ QString txtLabel = rule.label ();
534
+ item->setText ( 0 , txtLabel );
476
535
item->setData ( 0 , Qt::UserRole + 1 , i );
477
536
item->setIcon ( 0 , QgsSymbolLayerV2Utils::symbolPreviewIcon ( rule.symbol (), QSize ( 16 , 16 ) ) );
537
+
538
+ QString txtRule = rule.filterExpression ();
539
+ if ( txtRule.isEmpty () ) txtRule = tr ( " (no filter)" );
540
+ item->setText ( 1 , txtRule );
541
+
542
+ if ( rule.dependsOnScale () )
543
+ {
544
+ // 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
545
+ item->setText ( 2 , formatScale ( rule.scaleMinDenom (), mLongestMinDenom ) );
546
+ item->setText ( 3 , formatScale ( rule.scaleMaxDenom (), mLongestMaxDenom ) );
547
+ item->setTextAlignment ( 2 , Qt::AlignRight );
548
+ item->setTextAlignment ( 3 , Qt::AlignRight );
549
+ }
550
+
551
+ // item->setBackground( 1, Qt::lightGray );
552
+ // item->setBackground( 3, Qt::lightGray );
478
553
}
479
554
addTopLevelItems ( scale_items.values () );
480
555
}
@@ -483,6 +558,9 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByFilter()
483
558
{
484
559
QMap<QString, QTreeWidgetItem *> filter_items;
485
560
561
+ QFont italicFont;
562
+ italicFont.setItalic ( true );
563
+
486
564
for ( int i = 0 ; i < mR ->ruleCount (); ++i )
487
565
{
488
566
QgsRuleBasedRendererV2::Rule& rule = mR ->ruleAt ( i );
@@ -494,20 +572,38 @@ void QgsRendererRulesTreeWidget::populateRulesGroupByFilter()
494
572
filter_item->setText ( 0 , filter.isEmpty () ? tr ( " (no filter)" ) : filter );
495
573
filter_item->setData ( 0 , Qt::UserRole + 1 , -1 );
496
574
filter_item->setFlags ( filter_item->flags () & ~Qt::ItemIsDragEnabled ); // groups cannot be dragged
575
+ filter_item->setFont ( 0 , italicFont );
497
576
filter_items[filter] = filter_item;
577
+ // need to add the item before setFirstColumnSpanned,
578
+ // see http://qt.nokia.com/developer/task-tracker/index_html?method=entry&id=214686
579
+ addTopLevelItem ( filter_item );
580
+ filter_item->setFirstColumnSpanned ( true );
498
581
}
499
582
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" ;
505
-
506
583
QTreeWidgetItem* item = new QTreeWidgetItem ( filter_items[filter] );
507
- item->setText ( 0 , txt );
584
+
585
+ QString txtLabel = rule.label ();
586
+ item->setText ( 0 , txtLabel );
508
587
item->setData ( 0 , Qt::UserRole + 1 , i );
509
588
item->setIcon ( 0 , QgsSymbolLayerV2Utils::symbolPreviewIcon ( rule.symbol (), QSize ( 16 , 16 ) ) );
510
589
590
+ // 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
591
+ item->setText ( 1 , filter );
592
+
593
+ // Makes table layout slightly more readable when filters are long strings
594
+ // item->setBackground( 1, Qt::lightGray );
595
+ // item->setBackground( 3, Qt::lightGray );
596
+
597
+ if ( rule.dependsOnScale () )
598
+ {
599
+ item->setText ( 2 , formatScale ( rule.scaleMinDenom (), mLongestMinDenom ) );
600
+ item->setText ( 3 , formatScale ( rule.scaleMaxDenom (), mLongestMaxDenom ) );
601
+ item->setTextAlignment ( 2 , Qt::AlignRight );
602
+ item->setTextAlignment ( 3 , Qt::AlignRight );
603
+ }
511
604
}
605
+
512
606
addTopLevelItems ( filter_items.values () );
607
+
608
+
513
609
}
0 commit comments