Skip to content

Commit 4a34e9d

Browse files
author
marco
committedJul 28, 2011
[FEATURE]: Add point and line pattern symbol layers
2 parents a1cc666 + a5f8a82 commit 4a34e9d

File tree

8 files changed

+929
-71
lines changed

8 files changed

+929
-71
lines changed
 

‎src/core/symbology-ng/qgsfillsymbollayerv2.cpp

Lines changed: 406 additions & 59 deletions
Large diffs are not rendered by default.

‎src/core/symbology-ng/qgsfillsymbollayerv2.h

Lines changed: 98 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,29 @@ class CORE_EXPORT QgsSimpleFillSymbolLayerV2 : public QgsFillSymbolLayerV2
6767
QPointF mOffset;
6868
};
6969

70+
/**Base class for polygon renderers generating texture images*/
71+
class CORE_EXPORT QgsImageFillSymbolLayer: public QgsFillSymbolLayerV2
72+
{
73+
public:
74+
QgsImageFillSymbolLayer();
75+
virtual ~QgsImageFillSymbolLayer();
76+
void renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
77+
78+
virtual QgsSymbolV2* subSymbol() { return mOutline; }
79+
virtual bool setSubSymbol( QgsSymbolV2* symbol );
80+
81+
protected:
82+
QBrush mBrush;
83+
84+
/**Outline width*/
85+
double mOutlineWidth;
86+
/**Custom outline*/
87+
QgsLineSymbolV2* mOutline;
88+
};
89+
7090
/**A class for svg fill patterns. The class automatically scales the pattern to
7191
the appropriate pixel dimensions of the output device*/
72-
class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
92+
class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsImageFillSymbolLayer
7393
{
7494
public:
7595
QgsSVGFillSymbolLayer( const QString& svgFilePath = "", double width = 20, double rotation = 0.0 );
@@ -85,8 +105,6 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
85105
void startRender( QgsSymbolV2RenderContext& context );
86106
void stopRender( QgsSymbolV2RenderContext& context );
87107

88-
void renderPolygon( const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolV2RenderContext& context );
89-
90108
QgsStringMap properties() const;
91109

92110
QgsSymbolLayerV2* clone() const;
@@ -97,9 +115,6 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
97115
void setPatternWidth( double width ) { mPatternWidth = width;}
98116
double patternWidth() const { return mPatternWidth; }
99117

100-
QgsSymbolV2* subSymbol() { return mOutline; }
101-
bool setSubSymbol( QgsSymbolV2* symbol );
102-
103118
protected:
104119
/**Width of the pattern (in QgsSymbolV2 output units)*/
105120
double mPatternWidth;
@@ -109,19 +124,90 @@ class CORE_EXPORT QgsSVGFillSymbolLayer: public QgsFillSymbolLayerV2
109124
QString mSvgFilePath;
110125
/**SVG view box (to keep the aspect ratio */
111126
QRectF mSvgViewBox;
112-
/**Brush that receives rendered pixel image in startRender() method*/
113-
QBrush mBrush;
114-
/**Outline width*/
115-
double mOutlineWidth;
116-
/**Custom outline*/
117-
QgsLineSymbolV2* mOutline;
118127

119128
private:
120129
/**Helper function that gets the view box from the byte array*/
121130
void storeViewBox();
122131
};
123132

133+
class CORE_EXPORT QgsLinePatternFillSymbolLayer: public QgsImageFillSymbolLayer
134+
{
135+
public:
136+
QgsLinePatternFillSymbolLayer();
137+
~QgsLinePatternFillSymbolLayer();
138+
139+
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
140+
141+
QString layerType() const;
142+
143+
void startRender( QgsSymbolV2RenderContext& context );
144+
145+
void stopRender( QgsSymbolV2RenderContext& context );
124146

147+
QgsStringMap properties() const;
148+
149+
QgsSymbolLayerV2* clone() const;
150+
151+
//getters and setters
152+
void setAngle( double a ){ mAngle = a; }
153+
double angle() const { return mAngle; }
154+
void setDistance( double d ){ mDistance = d; }
155+
double distance() const { return mDistance; }
156+
void setLineWidth( double w ){ mLineWidth = w; }
157+
double lineWidth() const { return mLineWidth; }
158+
void setColor( const QColor& c ){ mColor = c; }
159+
QColor color() const{ return mColor; }
160+
161+
protected:
162+
/**Distance (in mm or map units) between lines*/
163+
double mDistance;
164+
/**Line width (in mm or map units)*/
165+
double mLineWidth;
166+
QColor mColor;
167+
//todo: line type
168+
double mAngle;
169+
};
170+
171+
class CORE_EXPORT QgsPointPatternFillSymbolLayer: public QgsImageFillSymbolLayer
172+
{
173+
public:
174+
QgsPointPatternFillSymbolLayer();
175+
~QgsPointPatternFillSymbolLayer();
176+
177+
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
178+
QString layerType() const;
179+
180+
void startRender( QgsSymbolV2RenderContext& context );
181+
182+
void stopRender( QgsSymbolV2RenderContext& context );
183+
184+
QgsStringMap properties() const;
185+
186+
QgsSymbolLayerV2* clone() const;
187+
188+
//getters and setters
189+
double distanceX() const { return mDistanceX; }
190+
void setDistanceX( double d ) { mDistanceX = d; }
191+
192+
double distanceY() const { return mDistanceY; }
193+
void setDistanceY( double d ) { mDistanceY = d; }
194+
195+
double displacementX() const { return mDisplacementX; }
196+
void setDisplacementX( double d ){ mDisplacementX = d; }
197+
198+
double displacementY() const { return mDisplacementY; }
199+
void setDisplacementY( double d ){ mDisplacementY = d; }
200+
201+
bool setSubSymbol( QgsSymbolV2* symbol );
202+
virtual QgsSymbolV2* subSymbol() { return mMarkerSymbol; }
203+
204+
protected:
205+
QgsMarkerSymbolV2* mMarkerSymbol;
206+
double mDistanceX;
207+
double mDistanceY;
208+
double mDisplacementX;
209+
double mDisplacementY;
210+
};
125211

126212
class CORE_EXPORT QgsCentroidFillSymbolLayerV2 : public QgsFillSymbolLayerV2
127213
{

‎src/core/symbology-ng/qgssymbollayerv2registry.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ QgsSymbolLayerV2Registry::QgsSymbolLayerV2Registry()
3333
QgsSVGFillSymbolLayer::create ) );
3434
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "CentroidFill", QObject::tr( "Centroid fill" ), QgsSymbolV2::Fill,
3535
QgsCentroidFillSymbolLayerV2::create ) );
36+
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "LinePatternFill", QObject::tr("Line pattern fill"), QgsSymbolV2::Fill,
37+
QgsLinePatternFillSymbolLayer::create ) );
38+
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "PointPatternFill", QObject::tr("Point pattern fill"), QgsSymbolV2::Fill,
39+
QgsPointPatternFillSymbolLayer::create ) );
3640
}
3741

3842
QgsSymbolLayerV2Registry::~QgsSymbolLayerV2Registry()

‎src/gui/symbology-ng/qgssymbollayerv2widget.cpp

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -910,6 +910,183 @@ void QgsSVGFillSymbolLayerWidget::updateOutlineIcon()
910910

911911
/////////////
912912

913+
QgsLinePatternFillSymbolLayerWidget::QgsLinePatternFillSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent ):
914+
QgsSymbolLayerV2Widget( parent, vl ), mLayer( 0 )
915+
{
916+
setupUi( this );
917+
}
918+
919+
void QgsLinePatternFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer)
920+
{
921+
if( layer->layerType() != "LinePatternFill" )
922+
{
923+
return;
924+
}
925+
926+
QgsLinePatternFillSymbolLayer* patternLayer = static_cast<QgsLinePatternFillSymbolLayer*>( layer );
927+
if( patternLayer )
928+
{
929+
mLayer = patternLayer;
930+
mAngleSpinBox->setValue( mLayer->angle() );
931+
mDistanceSpinBox->setValue( mLayer->distance() );
932+
mLineWidthSpinBox->setValue( mLayer->lineWidth() );
933+
}
934+
}
935+
936+
QgsSymbolLayerV2* QgsLinePatternFillSymbolLayerWidget::symbolLayer()
937+
{
938+
return mLayer;
939+
}
940+
941+
void QgsLinePatternFillSymbolLayerWidget::on_mAngleSpinBox_valueChanged( double d )
942+
{
943+
if( mLayer )
944+
{
945+
mLayer->setAngle( d );
946+
emit changed();
947+
}
948+
}
949+
950+
void QgsLinePatternFillSymbolLayerWidget::on_mDistanceSpinBox_valueChanged( double d )
951+
{
952+
if( mLayer )
953+
{
954+
mLayer->setDistance( d );
955+
emit changed();
956+
}
957+
}
958+
959+
void QgsLinePatternFillSymbolLayerWidget::on_mLineWidthSpinBox_valueChanged( double d )
960+
{
961+
if( mLayer )
962+
{
963+
mLayer->setLineWidth( d );
964+
emit changed();
965+
}
966+
}
967+
968+
void QgsLinePatternFillSymbolLayerWidget::on_mColorPushButton_clicked()
969+
{
970+
if( mLayer )
971+
{
972+
QColor c = QColorDialog::getColor( mLayer->color() );
973+
if( c.isValid() )
974+
{
975+
mLayer->setColor( c );
976+
emit changed();
977+
}
978+
}
979+
}
980+
981+
void QgsLinePatternFillSymbolLayerWidget::on_mOutlinePushButton_clicked()
982+
{
983+
if( mLayer )
984+
{
985+
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
986+
if ( dlg.exec() == QDialog::Rejected )
987+
{
988+
return;
989+
}
990+
991+
//updateOutlineIcon();
992+
emit changed();
993+
}
994+
}
995+
996+
/////////////
997+
998+
QgsPointPatternFillSymbolLayerWidget::QgsPointPatternFillSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent ):
999+
QgsSymbolLayerV2Widget( parent, vl ), mLayer( 0 )
1000+
{
1001+
setupUi( this );
1002+
updateMarkerIcon();
1003+
}
1004+
1005+
1006+
void QgsPointPatternFillSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer)
1007+
{
1008+
if( !layer || layer->layerType() != "PointPatternFill" )
1009+
{
1010+
return;
1011+
}
1012+
1013+
mLayer = static_cast<QgsPointPatternFillSymbolLayer*>( layer );
1014+
mHorizontalDistanceSpinBox->setValue( mLayer->distanceX() );
1015+
mVerticalDistanceSpinBox->setValue( mLayer->distanceY() );
1016+
mHorizontalDisplacementSpinBox->setValue( mLayer->displacementX() );
1017+
mVerticalDisplacementSpinBox->setValue( mLayer->displacementY() );
1018+
updateMarkerIcon();
1019+
}
1020+
1021+
QgsSymbolLayerV2* QgsPointPatternFillSymbolLayerWidget::symbolLayer()
1022+
{
1023+
return mLayer;
1024+
}
1025+
1026+
void QgsPointPatternFillSymbolLayerWidget::updateMarkerIcon()
1027+
{
1028+
if ( mLayer )
1029+
{
1030+
QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon( mLayer->subSymbol(), mChangeMarkerButton->iconSize() );
1031+
mChangeMarkerButton->setIcon( icon );
1032+
}
1033+
}
1034+
1035+
void QgsPointPatternFillSymbolLayerWidget::on_mHorizontalDistanceSpinBox_valueChanged ( double d )
1036+
{
1037+
if( mLayer )
1038+
{
1039+
mLayer->setDistanceX( d );
1040+
emit changed();
1041+
}
1042+
}
1043+
1044+
void QgsPointPatternFillSymbolLayerWidget::on_mVerticalDistanceSpinBox_valueChanged ( double d )
1045+
{
1046+
if( mLayer )
1047+
{
1048+
mLayer->setDistanceY( d );
1049+
emit changed();
1050+
}
1051+
}
1052+
1053+
void QgsPointPatternFillSymbolLayerWidget::on_mHorizontalDisplacementSpinBox_valueChanged ( double d )
1054+
{
1055+
if( mLayer )
1056+
{
1057+
mLayer->setDisplacementX( d );
1058+
emit changed();
1059+
}
1060+
}
1061+
1062+
void QgsPointPatternFillSymbolLayerWidget::on_mVerticalDisplacementSpinBox_valueChanged ( double d )
1063+
{
1064+
if( mLayer )
1065+
{
1066+
mLayer->setDisplacementY( d );
1067+
emit changed();
1068+
}
1069+
}
1070+
1071+
void QgsPointPatternFillSymbolLayerWidget::on_mChangeMarkerButton_clicked()
1072+
{
1073+
if( !mLayer )
1074+
{
1075+
return;
1076+
}
1077+
1078+
QgsSymbolV2PropertiesDialog dlg( mLayer->subSymbol(), mVectorLayer, this );
1079+
if ( dlg.exec() == QDialog::Rejected )
1080+
{
1081+
return;
1082+
}
1083+
1084+
updateMarkerIcon();
1085+
emit changed();
1086+
}
1087+
1088+
/////////////
1089+
9131090
QgsFontMarkerSymbolLayerV2Widget::QgsFontMarkerSymbolLayerV2Widget( const QgsVectorLayer* vl, QWidget* parent )
9141091
: QgsSymbolLayerV2Widget( parent, vl )
9151092
{

‎src/gui/symbology-ng/qgssymbollayerv2widget.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,63 @@ class GUI_EXPORT QgsSVGFillSymbolLayerWidget : public QgsSymbolLayerV2Widget, pr
263263

264264
//////////
265265

266+
#include "ui_widget_linepatternfill.h"
267+
268+
class QgsLinePatternFillSymbolLayer;
269+
270+
class GUI_EXPORT QgsLinePatternFillSymbolLayerWidget : public QgsSymbolLayerV2Widget, private Ui::WidgetLinePatternFill
271+
{
272+
Q_OBJECT
273+
274+
public:
275+
276+
QgsLinePatternFillSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent = NULL );
277+
static QgsSymbolLayerV2Widget* create( const QgsVectorLayer* vl ) { return new QgsLinePatternFillSymbolLayerWidget( vl ); }
278+
279+
virtual void setSymbolLayer( QgsSymbolLayerV2* layer);
280+
virtual QgsSymbolLayerV2* symbolLayer();
281+
282+
protected:
283+
QgsLinePatternFillSymbolLayer* mLayer;
284+
285+
private slots:
286+
void on_mAngleSpinBox_valueChanged( double d );
287+
void on_mDistanceSpinBox_valueChanged( double d );
288+
void on_mLineWidthSpinBox_valueChanged( double d );
289+
void on_mColorPushButton_clicked();
290+
void on_mOutlinePushButton_clicked();
291+
};
292+
293+
//////////
294+
295+
#include "ui_widget_pointpatternfill.h"
296+
297+
class QgsPointPatternFillSymbolLayer;
298+
299+
class GUI_EXPORT QgsPointPatternFillSymbolLayerWidget: public QgsSymbolLayerV2Widget, private Ui::WidgetPointPatternFill
300+
{
301+
Q_OBJECT
302+
303+
public:
304+
QgsPointPatternFillSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent = NULL );
305+
static QgsSymbolLayerV2Widget* create( const QgsVectorLayer* vl ) { return new QgsPointPatternFillSymbolLayerWidget( vl ); }
306+
307+
virtual void setSymbolLayer( QgsSymbolLayerV2* layer);
308+
virtual QgsSymbolLayerV2* symbolLayer();
309+
310+
protected:
311+
QgsPointPatternFillSymbolLayer* mLayer;
312+
void updateMarkerIcon();
313+
314+
private slots:
315+
void on_mHorizontalDistanceSpinBox_valueChanged ( double d );
316+
void on_mVerticalDistanceSpinBox_valueChanged ( double d );
317+
void on_mHorizontalDisplacementSpinBox_valueChanged ( double d );
318+
void on_mVerticalDisplacementSpinBox_valueChanged ( double d );
319+
void on_mChangeMarkerButton_clicked();
320+
};
321+
322+
/////////
266323

267324
#include "ui_widget_fontmarker.h"
268325

‎src/gui/symbology-ng/qgssymbolv2propertiesdialog.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ static void _initWidgetFunctions()
9696
_initWidgetFunction( "SimpleFill", QgsSimpleFillSymbolLayerV2Widget::create );
9797
_initWidgetFunction( "SVGFill", QgsSVGFillSymbolLayerWidget::create );
9898
_initWidgetFunction( "CentroidFill", QgsCentroidFillSymbolLayerV2Widget::create );
99+
_initWidgetFunction( "LinePatternFill", QgsLinePatternFillSymbolLayerWidget::create );
100+
_initWidgetFunction( "PointPatternFill", QgsPointPatternFillSymbolLayerWidget::create );
99101

100102
initialized = true;
101103
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>WidgetLinePatternFill</class>
4+
<widget class="QWidget" name="WidgetLinePatternFill">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>236</width>
10+
<height>151</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<layout class="QGridLayout" name="gridLayout">
17+
<item row="0" column="0">
18+
<widget class="QLabel" name="mAngleLabel">
19+
<property name="text">
20+
<string>Angle</string>
21+
</property>
22+
</widget>
23+
</item>
24+
<item row="0" column="1">
25+
<widget class="QDoubleSpinBox" name="mAngleSpinBox">
26+
<property name="maximum">
27+
<double>360.000000000000000</double>
28+
</property>
29+
</widget>
30+
</item>
31+
<item row="1" column="0">
32+
<widget class="QLabel" name="mDistanceLabel">
33+
<property name="text">
34+
<string>Distance</string>
35+
</property>
36+
</widget>
37+
</item>
38+
<item row="1" column="1">
39+
<widget class="QDoubleSpinBox" name="mDistanceSpinBox">
40+
<property name="maximum">
41+
<double>999999999.000000000000000</double>
42+
</property>
43+
</widget>
44+
</item>
45+
<item row="2" column="0">
46+
<widget class="QLabel" name="mLineWidthLabel">
47+
<property name="text">
48+
<string>Line width</string>
49+
</property>
50+
</widget>
51+
</item>
52+
<item row="2" column="1">
53+
<widget class="QDoubleSpinBox" name="mLineWidthSpinBox">
54+
<property name="maximum">
55+
<double>99999999.000000000000000</double>
56+
</property>
57+
</widget>
58+
</item>
59+
<item row="3" column="0">
60+
<widget class="QLabel" name="mColorLabel">
61+
<property name="text">
62+
<string>Color</string>
63+
</property>
64+
</widget>
65+
</item>
66+
<item row="3" column="1">
67+
<widget class="QPushButton" name="mColorPushButton">
68+
<property name="text">
69+
<string>Change</string>
70+
</property>
71+
</widget>
72+
</item>
73+
<item row="4" column="0">
74+
<widget class="QLabel" name="mOutlineLabel">
75+
<property name="text">
76+
<string>Outline</string>
77+
</property>
78+
</widget>
79+
</item>
80+
<item row="4" column="1">
81+
<widget class="QPushButton" name="mOutlinePushButton">
82+
<property name="text">
83+
<string>Change</string>
84+
</property>
85+
</widget>
86+
</item>
87+
</layout>
88+
</widget>
89+
<resources/>
90+
<connections/>
91+
</ui>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<ui version="4.0">
3+
<class>WidgetPointPatternFill</class>
4+
<widget class="QWidget" name="WidgetPointPatternFill">
5+
<property name="geometry">
6+
<rect>
7+
<x>0</x>
8+
<y>0</y>
9+
<width>243</width>
10+
<height>152</height>
11+
</rect>
12+
</property>
13+
<property name="windowTitle">
14+
<string>Form</string>
15+
</property>
16+
<layout class="QGridLayout" name="gridLayout">
17+
<item row="0" column="0">
18+
<widget class="QLabel" name="mMarkerLabel">
19+
<property name="frameShape">
20+
<enum>QFrame::NoFrame</enum>
21+
</property>
22+
<property name="text">
23+
<string>Marker</string>
24+
</property>
25+
</widget>
26+
</item>
27+
<item row="0" column="1">
28+
<widget class="QPushButton" name="mChangeMarkerButton">
29+
<property name="text">
30+
<string>Change</string>
31+
</property>
32+
</widget>
33+
</item>
34+
<item row="1" column="0">
35+
<widget class="QLabel" name="mHorizontalDistanceLabel">
36+
<property name="text">
37+
<string>Horizontal distance</string>
38+
</property>
39+
</widget>
40+
</item>
41+
<item row="1" column="1">
42+
<widget class="QDoubleSpinBox" name="mHorizontalDistanceSpinBox">
43+
<property name="maximum">
44+
<double>99999999.989999994635582</double>
45+
</property>
46+
</widget>
47+
</item>
48+
<item row="2" column="0">
49+
<widget class="QLabel" name="mVerticalDistanceLabel">
50+
<property name="text">
51+
<string>Vertical distance</string>
52+
</property>
53+
</widget>
54+
</item>
55+
<item row="2" column="1">
56+
<widget class="QDoubleSpinBox" name="mVerticalDistanceSpinBox">
57+
<property name="maximum">
58+
<double>999999999.990000009536743</double>
59+
</property>
60+
</widget>
61+
</item>
62+
<item row="3" column="0">
63+
<widget class="QLabel" name="mHorizontalDisplacementLabel">
64+
<property name="text">
65+
<string>Horizontal displacement</string>
66+
</property>
67+
</widget>
68+
</item>
69+
<item row="3" column="1">
70+
<widget class="QDoubleSpinBox" name="mHorizontalDisplacementSpinBox">
71+
<property name="maximum">
72+
<double>9999999.990000000223517</double>
73+
</property>
74+
</widget>
75+
</item>
76+
<item row="4" column="0">
77+
<widget class="QLabel" name="mVerticalDisplacementLabel">
78+
<property name="text">
79+
<string>Vertical displacement</string>
80+
</property>
81+
</widget>
82+
</item>
83+
<item row="4" column="1">
84+
<widget class="QDoubleSpinBox" name="mVerticalDisplacementSpinBox">
85+
<property name="maximum">
86+
<double>999999999.990000009536743</double>
87+
</property>
88+
</widget>
89+
</item>
90+
</layout>
91+
</widget>
92+
<resources/>
93+
<connections/>
94+
</ui>

0 commit comments

Comments
 (0)
Please sign in to comment.