Skip to content
Permalink
Browse files

[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.
  • Loading branch information
nirvn committed Apr 30, 2019
1 parent f70acf2 commit dc7bfc5cd3cbf3606a8e97746d76ba1f8ed6685f
@@ -9,6 +9,8 @@





class CharacterWidget : QWidget
{
%Docstring
@@ -109,6 +111,8 @@ Emitted when a character is selected in the widget.
%End

protected:
virtual void keyPressEvent( QKeyEvent *event );

virtual void mouseMoveEvent( QMouseEvent *event );

virtual void mousePressEvent( QMouseEvent *event );
@@ -695,7 +695,22 @@ Set stroke color.
%End
void setSize( double size );
void setAngle( double angle );

void setCharacter( QChar chr );
%Docstring
Set the font marker character from char.

:param chr: the char
%End

void setCharacterFromText( const QString &text );
%Docstring
Set the font marker character from a text string.

:param text: the text string

.. versionadded:: 3.8
%End

protected:

@@ -52,12 +52,15 @@
#include <QPainter>
#include <QPen>
#include <QPoint>
#include <QScrollArea>
#include <QScrollBar>
#include <QToolTip>

CharacterWidget::CharacterWidget( QWidget *parent )
: QWidget( parent )
{
setMouseTracking( true );
setFocusPolicy( Qt::StrongFocus );
}

void CharacterWidget::setFont( const QFont &font )
@@ -109,6 +112,13 @@ void CharacterWidget::setColumns( int columns )
void CharacterWidget::setCharacter( QChar character )
{
mLastKey = character.unicode();
QWidget *widget = parentWidget();
if ( widget )
{
QScrollArea *scrollArea = qobject_cast< QScrollArea *>( widget->parent() );
if ( scrollArea && mLastKey < 65536 )
scrollArea->verticalScrollBar()->setValue( mLastKey / mColumns * mSquareSize );
}
update();
}

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

void CharacterWidget::keyPressEvent( QKeyEvent *event )
{
if ( !event->text().isEmpty() )
{
QChar chr = event->text().at( 0 );
if ( chr.unicode() != mLastKey )
{
setCharacter( chr );
emit characterSelected( chr );
}
}
}

void CharacterWidget::mouseMoveEvent( QMouseEvent *event )
{
QPoint widgetPosition = mapFromGlobal( event->globalPos() );
uint key = ( widgetPosition.y() / mSquareSize ) * mColumns + widgetPosition.x() / mSquareSize;

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

@@ -47,13 +47,15 @@
#ifndef CHARACTERWIDGET_H
#define CHARACTERWIDGET_H

#include "qgis_sip.h"
#include "qgis_gui.h"

#include <QFont>
#include <QPoint>
#include <QSize>
#include <QString>
#include <QWidget>
#include "qgis_sip.h"
#include "qgis_gui.h"


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

protected:
void keyPressEvent( QKeyEvent *event ) override;
void mouseMoveEvent( QMouseEvent *event ) override;
void mousePressEvent( QMouseEvent *event ) override;
void paintEvent( QPaintEvent *event ) override;
@@ -3251,7 +3251,7 @@ QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *
mOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );

widgetChar = new CharacterWidget;
widgetChar = new CharacterWidget();
scrollArea->setWidget( widgetChar );

btnColor->setAllowOpacity( true );
@@ -3284,6 +3284,8 @@ QgsFontMarkerSymbolLayerWidget::QgsFontMarkerSymbolLayerWidget( QgsVectorLayer *
connect( spinOffsetX, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
connect( spinOffsetY, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsFontMarkerSymbolLayerWidget::setOffset );
connect( widgetChar, &CharacterWidget::characterSelected, this, &QgsFontMarkerSymbolLayerWidget::setCharacter );
connect( mCharLineEdit, &QLineEdit::textChanged, this, &QgsFontMarkerSymbolLayerWidget::setCharacterFromText );

connect( this, &QgsSymbolLayerWidget::changed, this, &QgsFontMarkerSymbolLayerWidget::updateAssistantSymbol );
}

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

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

void QgsFontMarkerSymbolLayerWidget::setCharacterFromText( const QString &text )
{
if ( text.isEmpty() )
return;

// take the last character of a string for a better experience when users cycle through several characters on their keyboard
QChar chr = text.back();
if ( text.contains( QRegularExpression( QStringLiteral( "^0x[0-9a-fA-F]{1,4}$" ) ) ) )
{
bool ok = false;
unsigned int value = text.toUInt( &ok, 0 );
if ( ok )
chr = QChar( value );
}
else if ( text.contains( QRegularExpression( QStringLiteral( "^[0-9]{1,}$" ) ) ) )
{
bool ok = false;
unsigned int value = text.toUInt( &ok, 10 );
if ( ok )
chr = QChar( value );
}

if ( chr != mLayer->character() )
{
mLayer->setCharacter( chr );
whileBlocking( widgetChar )->setCharacter( mLayer->character() );
emit changed();
}
}

void QgsFontMarkerSymbolLayerWidget::setCharacter( QChar chr )
{
mLayer->setCharacter( chr );
whileBlocking( mCharLineEdit )->setText( chr );
emit changed();
}

@@ -932,8 +932,20 @@ class GUI_EXPORT QgsFontMarkerSymbolLayerWidget : public QgsSymbolLayerWidget, p
void setColorStroke( const QColor &color );
void setSize( double size );
void setAngle( double angle );

/**
* Set the font marker character from char.
* \param chr the char
*/
void setCharacter( QChar chr );

/**
* Set the font marker character from a text string.
* \param text the text string
* \since QGIS 3.8
*/
void setCharacterFromText( const QString &text );

protected:
QgsFontMarkerSymbolLayer *mLayer = nullptr;
CharacterWidget *widgetChar = nullptr;
@@ -303,7 +303,21 @@
</property>
</widget>
</item>
<item row="13" column="3">
<item row="14" column="0">
<widget class="QLabel" name="label_12">
<property name="text">
<string>Character</string>
</property>
</widget>
</item>
<item row="14" column="1" colspan="2">
<widget class="QLineEdit" name="mCharLineEdit">
<property name="toolTip">
<string>Type in a character directly, or enter its decimal/hexadecimal value.</string>
</property>
</widget>
</item>
<item row="14" column="3">
<widget class="QgsPropertyOverrideButton" name="mCharDDBtn">
<property name="text">
<string>…</string>
@@ -317,7 +331,7 @@
</property>
</widget>
</item>
<item row="13" column="0" colspan="3">
<item row="13" column="0" colspan="4">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" rowspan="2">
<widget class="QgsScrollArea" name="scrollArea">

0 comments on commit dc7bfc5

Please sign in to comment.
You can’t perform that action at this time.