Skip to content

Commit dc7bfc5

Browse files
committed
[FEATURE][ui] Add a line edit to type character for the font marker
The line edit also supports pasting of unicode code in decimal or hexadecimal format (i.e. 123 or 0x2713). In addition, the character widget now grabs the keyboard focus and will change the selected character based on key stroke.
1 parent f70acf2 commit dc7bfc5

File tree

7 files changed

+113
-7
lines changed

7 files changed

+113
-7
lines changed

python/gui/auto_generated/symbology/characterwidget.sip.in

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010

1111

12+
13+
1214
class CharacterWidget : QWidget
1315
{
1416
%Docstring
@@ -109,6 +111,8 @@ Emitted when a character is selected in the widget.
109111
%End
110112

111113
protected:
114+
virtual void keyPressEvent( QKeyEvent *event );
115+
112116
virtual void mouseMoveEvent( QMouseEvent *event );
113117

114118
virtual void mousePressEvent( QMouseEvent *event );

python/gui/auto_generated/symbology/qgssymbollayerwidget.sip.in

+15
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,22 @@ Set stroke color.
695695
%End
696696
void setSize( double size );
697697
void setAngle( double angle );
698+
698699
void setCharacter( QChar chr );
700+
%Docstring
701+
Set the font marker character from char.
702+
703+
:param chr: the char
704+
%End
705+
706+
void setCharacterFromText( const QString &text );
707+
%Docstring
708+
Set the font marker character from a text string.
709+
710+
:param text: the text string
711+
712+
.. versionadded:: 3.8
713+
%End
699714

700715
protected:
701716

src/gui/symbology/characterwidget.cpp

+26-2
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,15 @@
5252
#include <QPainter>
5353
#include <QPen>
5454
#include <QPoint>
55+
#include <QScrollArea>
56+
#include <QScrollBar>
5557
#include <QToolTip>
5658

5759
CharacterWidget::CharacterWidget( QWidget *parent )
5860
: QWidget( parent )
5961
{
6062
setMouseTracking( true );
63+
setFocusPolicy( Qt::StrongFocus );
6164
}
6265

6366
void CharacterWidget::setFont( const QFont &font )
@@ -109,6 +112,13 @@ void CharacterWidget::setColumns( int columns )
109112
void CharacterWidget::setCharacter( QChar character )
110113
{
111114
mLastKey = character.unicode();
115+
QWidget *widget = parentWidget();
116+
if ( widget )
117+
{
118+
QScrollArea *scrollArea = qobject_cast< QScrollArea *>( widget->parent() );
119+
if ( scrollArea && mLastKey < 65536 )
120+
scrollArea->verticalScrollBar()->setValue( mLastKey / mColumns * mSquareSize );
121+
}
112122
update();
113123
}
114124

@@ -117,15 +127,29 @@ QSize CharacterWidget::sizeHint() const
117127
return QSize( mColumns * mSquareSize, ( 65536 / mColumns ) * mSquareSize );
118128
}
119129

130+
void CharacterWidget::keyPressEvent( QKeyEvent *event )
131+
{
132+
if ( !event->text().isEmpty() )
133+
{
134+
QChar chr = event->text().at( 0 );
135+
if ( chr.unicode() != mLastKey )
136+
{
137+
setCharacter( chr );
138+
emit characterSelected( chr );
139+
}
140+
}
141+
}
142+
120143
void CharacterWidget::mouseMoveEvent( QMouseEvent *event )
121144
{
122145
QPoint widgetPosition = mapFromGlobal( event->globalPos() );
123146
uint key = ( widgetPosition.y() / mSquareSize ) * mColumns + widgetPosition.x() / mSquareSize;
124147

125-
QString text = tr( "<p>Character: <span style=\"font-size: 24pt; font-family: %1\">%2</span><p>Value: 0x%3" )
148+
QString text = tr( "<p>Character: <span style=\"font-size: 24pt; font-family: %1\">%2</span><p>Decimal: %3<p>Hex: 0x%4" )
126149
.arg( mDisplayFont.family() )
127150
.arg( QChar( key ) )
128-
.arg( key, 16 );
151+
.arg( key )
152+
.arg( QString::number( key, 16 ) );
129153
QToolTip::showText( event->globalPos(), text, this );
130154
}
131155

src/gui/symbology/characterwidget.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,15 @@
4747
#ifndef CHARACTERWIDGET_H
4848
#define CHARACTERWIDGET_H
4949

50+
#include "qgis_sip.h"
51+
#include "qgis_gui.h"
52+
5053
#include <QFont>
5154
#include <QPoint>
5255
#include <QSize>
5356
#include <QString>
5457
#include <QWidget>
55-
#include "qgis_sip.h"
56-
#include "qgis_gui.h"
58+
5759

5860
class QMouseEvent;
5961
class QPaintEvent;
@@ -148,6 +150,7 @@ class GUI_EXPORT CharacterWidget : public QWidget
148150
void characterSelected( QChar character );
149151

150152
protected:
153+
void keyPressEvent( QKeyEvent *event ) override;
151154
void mouseMoveEvent( QMouseEvent *event ) override;
152155
void mousePressEvent( QMouseEvent *event ) override;
153156
void paintEvent( QPaintEvent *event ) override;

src/gui/symbology/qgssymbollayerwidget.cpp

+35-1
Original file line numberDiff line numberDiff line change
@@ -3251,7 +3251,7 @@ QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *
32513251
mOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
32523252
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
32533253

3254-
widgetChar = new CharacterWidget;
3254+
widgetChar = new CharacterWidget();
32553255
scrollArea->setWidget( widgetChar );
32563256

32573257
btnColor->setAllowOpacity( true );
@@ -3284,6 +3284,8 @@ QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *
32843284
connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
32853285
connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
32863286
connect( widgetChar, &CharacterWidget::characterSelected, this, &QgsFontMarkerSymbolLayerWidget::setCharacter );
3287+
connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );
3288+
32873289
connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
32883290
}
32893291

@@ -3308,6 +3310,7 @@ void QgsFontMarkerSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer )
33083310
widgetChar->setFont( layerFont );
33093311
widgetChar->setCharacter( mLayer->character() );
33103312
widgetChar->blockSignals( false );
3313+
whileBlocking( mCharLineEdit )->setText( mLayer->character() );
33113314

33123315
//block
33133316
whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
@@ -3385,9 +3388,40 @@ void QgsFontMarkerSymbolLayerWidget::setAngle( double angle )
33853388
emit changed();
33863389
}
33873390

3391+
void QgsFontMarkerSymbolLayerWidget::setCharacterFromText( const QString &text )
3392+
{
3393+
if ( text.isEmpty() )
3394+
return;
3395+
3396+
// take the last character of a string for a better experience when users cycle through several characters on their keyboard
3397+
QChar chr = text.back();
3398+
if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
3399+
{
3400+
bool ok = false;
3401+
unsigned int value = text.toUInt( &ok, 0 );
3402+
if ( ok )
3403+
chr = QChar( value );
3404+
}
3405+
else if ( text.contains( QRegularExpression( QStringLiteral( "^[0-9]{1,}$" ) ) ) )
3406+
{
3407+
bool ok = false;
3408+
unsigned int value = text.toUInt( &ok, 10 );
3409+
if ( ok )
3410+
chr = QChar( value );
3411+
}
3412+
3413+
if ( chr != mLayer->character() )
3414+
{
3415+
mLayer->setCharacter( chr );
3416+
whileBlocking( widgetChar )->setCharacter( mLayer->character() );
3417+
emit changed();
3418+
}
3419+
}
3420+
33883421
void QgsFontMarkerSymbolLayerWidget::setCharacter( QChar chr )
33893422
{
33903423
mLayer->setCharacter( chr );
3424+
whileBlocking( mCharLineEdit )->setText( chr );
33913425
emit changed();
33923426
}
33933427

src/gui/symbology/qgssymbollayerwidget.h

+12
Original file line numberDiff line numberDiff line change
@@ -932,8 +932,20 @@ class GUI_EXPORT QgsFontMarkerSymbolLayerWidget : public QgsSymbolLayerWidget, p
932932
void setColorStroke( const QColor &color );
933933
void setSize( double size );
934934
void setAngle( double angle );
935+
936+
/**
937+
* Set the font marker character from char.
938+
* \param chr the char
939+
*/
935940
void setCharacter( QChar chr );
936941

942+
/**
943+
* Set the font marker character from a text string.
944+
* \param text the text string
945+
* \since QGIS 3.8
946+
*/
947+
void setCharacterFromText( const QString &text );
948+
937949
protected:
938950
QgsFontMarkerSymbolLayer *mLayer = nullptr;
939951
CharacterWidget *widgetChar = nullptr;

src/ui/symbollayer/widget_fontmarker.ui

+16-2
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,21 @@
303303
</property>
304304
</widget>
305305
</item>
306-
<item row="13" column="3">
306+
<item row="14" column="0">
307+
<widget class="QLabel" name="label_12">
308+
<property name="text">
309+
<string>Character</string>
310+
</property>
311+
</widget>
312+
</item>
313+
<item row="14" column="1" colspan="2">
314+
<widget class="QLineEdit" name="mCharLineEdit">
315+
<property name="toolTip">
316+
<string>Type in a character directly, or enter its decimal/hexadecimal value.</string>
317+
</property>
318+
</widget>
319+
</item>
320+
<item row="14" column="3">
307321
<widget class="QgsPropertyOverrideButton" name="mCharDDBtn">
308322
<property name="text">
309323
<string>…</string>
@@ -317,7 +331,7 @@
317331
</property>
318332
</widget>
319333
</item>
320-
<item row="13" column="0" colspan="3">
334+
<item row="13" column="0" colspan="4">
321335
<layout class="QGridLayout" name="gridLayout">
322336
<item row="0" column="0" rowspan="2">
323337
<widget class="QgsScrollArea" name="scrollArea">

0 commit comments

Comments
 (0)