QGIS API Documentation 3.41.0-Master (af5edcb665c)
Loading...
Searching...
No Matches
characterwidget.cpp
Go to the documentation of this file.
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This library/program is free software; you can redistribute it
8** and/or modify it under the terms of the GNU Library General Public
9** License as published by the Free Software Foundation; either
10** version 2 of the License, or ( at your option ) any later version.
11**
12** This file is part of the examples of the Qt Toolkit.
13**
14** $QT_BEGIN_LICENSE:LGPL$
15** Commercial Usage
16** Licensees holding valid Qt Commercial licenses may use this file in
17** accordance with the Qt Commercial License Agreement provided with the
18** Software or, alternatively, in accordance with the terms contained in
19** a written agreement between you and Nokia.
20**
21** GNU Lesser General Public License Usage
22** Alternatively, this file may be used under the terms of the
23** GNU Lesser General Public License version 2.1 as published by the Free Software
24** Foundation and appearing in the file LICENSE.LGPL included in the
25** packaging of this file. Please review the following information to
26** ensure the GNU Lesser General Public License version 2.1 requirements
27** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
28** In addition, as a special exception, Nokia gives you certain additional
29** rights. These rights are described in the Nokia Qt LGPL Exception
30** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
31**
32** GNU General Public License Usage
33** Alternatively, this file may be used under the terms of the GNU
34** General Public License version 3.0 as published by the Free Software
35** Foundation and appearing in the file LICENSE.GPL included in the
36** packaging of this file. Please review the following information to
37** ensure the GNU General Public License version 3.0 requirements will be
38** met: http://www.gnu.org/copyleft/gpl.html.
39**
40** If you have questions regarding the use of this file, please contact
41** Nokia at [email protected].
42** $QT_END_LICENSE$
43**
44****************************************************************************/
45
46#include "characterwidget.h"
47#include "moc_characterwidget.cpp"
48#include "qgsapplication.h"
49#include "qgsfontutils.h"
50
51#include <QFontDatabase>
52#include <QMouseEvent>
53#include <QPaintEvent>
54#include <QPainter>
55#include <QPen>
56#include <QPoint>
57#include <QScrollArea>
58#include <QScrollBar>
59#include <QToolTip>
60
62 : QWidget( parent )
63{
64 setMouseTracking( true );
65 setFocusPolicy( Qt::StrongFocus );
66}
67
68void CharacterWidget::setFont( const QFont &font )
69{
70 QgsFontUtils::setFontFamily( mDisplayFont, font.family() );
71 mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
72 adjustSize();
73 update();
74}
75
76void CharacterWidget::setFontSize( double fontSize )
77{
78 mDisplayFont.setPointSizeF( fontSize );
79 mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
80 adjustSize();
81 update();
82}
83
84void CharacterWidget::setFontStyle( const QString &fontStyle )
85{
86 const QFontDatabase fontDatabase;
87 const QFont::StyleStrategy oldStrategy = mDisplayFont.styleStrategy();
88 mDisplayFont = fontDatabase.font( mDisplayFont.family(), fontStyle, mDisplayFont.pointSize() );
89 mDisplayFont.setStyleStrategy( oldStrategy );
90 mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
91 adjustSize();
92 update();
93}
94
96{
97 if ( enable )
98 mDisplayFont.setStyleStrategy( QFont::PreferDefault );
99 else
100 mDisplayFont.setStyleStrategy( QFont::NoFontMerging );
101 adjustSize();
102 update();
103}
104
106{
107 if ( mColumns == columns || columns < 1 )
108 return;
109 mColumns = columns;
110 adjustSize();
111 update();
112}
113
114void CharacterWidget::setCharacter( QChar character )
115{
116 const bool changed = character.unicode() != mLastKey;
117 mLastKey = character.isNull() ? -1 : character.unicode();
118 QWidget *widget = parentWidget();
119 if ( widget )
120 {
121 QScrollArea *scrollArea = qobject_cast<QScrollArea *>( widget->parent() );
122 if ( scrollArea && mLastKey < 65536 )
123 {
124 scrollArea->ensureVisible( 0, mLastKey / mColumns * mSquareSize );
125 }
126 }
127 if ( changed )
128 emit characterSelected( mLastKey >= 0 ? QChar( mLastKey ) : QChar() );
129
130 update();
131}
132
134{
135 mLastKey = -1;
136 update();
137}
138
140{
141 return QSize( mColumns * mSquareSize, ( 65536 / mColumns ) * mSquareSize );
142}
143
144void CharacterWidget::keyPressEvent( QKeyEvent *event )
145{
146 const QFontMetrics fm( mDisplayFont );
147
148 if ( event->key() == Qt::Key_Right )
149 {
150 int next = std::min( mLastKey + 1, 0xfffc );
151 while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
152 {
153 next++;
154 }
155 setCharacter( QChar( next ) );
156 }
157 else if ( event->key() == Qt::Key_Left )
158 {
159 int next = mLastKey - 1;
160 while ( next > 0 && !fm.inFont( QChar( next ) ) )
161 {
162 next--;
163 }
164 setCharacter( QChar( next ) );
165 }
166 else if ( event->key() == Qt::Key_Down )
167 {
168 int next = std::min( mLastKey + mColumns, 0xfffc );
169 while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
170 {
171 next = std::min( next + mColumns, 0xfffc );
172 }
173 setCharacter( QChar( next ) );
174 }
175 else if ( event->key() == Qt::Key_Up )
176 {
177 int next = std::max( 0, mLastKey - mColumns );
178 while ( next > 0 && !fm.inFont( QChar( next ) ) )
179 {
180 next = std::max( 0, next - mColumns );
181 }
182 setCharacter( QChar( next ) );
183 }
184 else if ( event->key() == Qt::Key_Home )
185 {
186 int next = 0;
187 while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
188 {
189 next++;
190 }
191 setCharacter( QChar( next ) );
192 }
193 else if ( event->key() == Qt::Key_End )
194 {
195 int next = 0xfffc;
196 while ( next > 0 && !fm.inFont( QChar( next ) ) )
197 {
198 next--;
199 }
200 setCharacter( QChar( next ) );
201 }
202 else if ( !event->text().isEmpty() )
203 {
204 QChar chr = event->text().at( 0 );
205 if ( chr.unicode() != mLastKey )
206 {
207 setCharacter( chr );
208 }
209 }
210}
211
212void CharacterWidget::mouseMoveEvent( QMouseEvent *event )
213{
214 const QPoint widgetPosition = mapFromGlobal( event->globalPos() );
215 const uint key = ( widgetPosition.y() / mSquareSize ) * mColumns + widgetPosition.x() / mSquareSize;
216
217 const QString text = QStringLiteral( "<p style=\"text-align: center; font-size: 24pt; font-family: %1\">%2</p><p><table><tr><td>%3</td><td>%2</td></tr><tr><td>%4</td><td>%5</td></tr><tr><td>%6</td><td>0x%7</td></tr></table>" )
218 .arg( mDisplayFont.family() )
219 .arg( QChar( key ) )
220 .arg( tr( "Character" ), tr( "Decimal" ) )
221 .arg( key )
222 .arg( tr( "Hex" ), QString::number( key, 16 ) );
223 QToolTip::showText( event->globalPos(), text, this );
224}
225
226void CharacterWidget::mousePressEvent( QMouseEvent *event )
227{
228 if ( event->button() == Qt::LeftButton )
229 {
230 mLastKey = ( event->y() / mSquareSize ) * mColumns + event->x() / mSquareSize;
231 if ( QChar( mLastKey ).category() != QChar::Other_NotAssigned )
232 emit characterSelected( QChar( mLastKey ) );
233 update();
234 }
235 else
236 QWidget::mousePressEvent( event );
237}
238
239void CharacterWidget::paintEvent( QPaintEvent *event )
240{
241 QPainter painter( this );
242 painter.setFont( mDisplayFont );
243
244 const QFontMetrics fontMetrics( mDisplayFont );
245
246 const QRect redrawRect = event->rect();
247 const int beginRow = redrawRect.top() / mSquareSize;
248 const int endRow = redrawRect.bottom() / mSquareSize;
249 const int beginColumn = redrawRect.left() / mSquareSize;
250 const int endColumn = std::min( mColumns - 1, redrawRect.right() / mSquareSize );
251
252 const QPalette palette = qApp->palette();
253 painter.setPen( QPen( palette.color( QPalette::Mid ) ) );
254 for ( int row = beginRow; row <= endRow; ++row )
255 {
256 for ( int column = beginColumn; column <= endColumn; ++column )
257 {
258 const int key = row * mColumns + column;
259 painter.setBrush( fontMetrics.inFont( QChar( key ) ) ? QBrush( palette.color( QPalette::Base ) ) : Qt::NoBrush );
260 painter.drawRect( column * mSquareSize, row * mSquareSize, mSquareSize, mSquareSize );
261 }
262 }
263
264 for ( int row = beginRow; row <= endRow; ++row )
265 {
266 for ( int column = beginColumn; column <= endColumn; ++column )
267 {
268 const int key = row * mColumns + column;
269 painter.setClipRect( column * mSquareSize, row * mSquareSize, mSquareSize, mSquareSize );
270 painter.setPen( QPen( palette.color( key == mLastKey ? QPalette::HighlightedText : QPalette::WindowText ) ) );
271
272 if ( key == mLastKey )
273 painter.fillRect( column * mSquareSize + 1, row * mSquareSize + 1, mSquareSize, mSquareSize, QBrush( palette.color( QPalette::Highlight ) ) );
274
275 if ( fontMetrics.inFont( QChar( key ) ) )
276 {
277 painter.drawText( column * mSquareSize + ( mSquareSize / 2 ) - fontMetrics.boundingRect( QChar( key ) ).width() / 2, row * mSquareSize + 4 + fontMetrics.ascent(), QString( QChar( key ) ) );
278 }
279 }
280 }
281}
282
283void CharacterWidget::resizeEvent( QResizeEvent *event )
284{
285 mColumns = event->size().width() / mSquareSize;
286 QWidget::resizeEvent( event );
287}
void updateFontMerging(bool enable)
void keyPressEvent(QKeyEvent *event) override
void characterSelected(QChar character)
Emitted when a character is selected in the widget.
void setFontStyle(const QString &fontStyle)
Sets the font style to show in the widget.
void setCharacter(QChar character)
Sets the currently selected character in the widget.
void setFont(const QFont &font)
Sets the font to show in the widget.
void mousePressEvent(QMouseEvent *event) override
QSize sizeHint() const override
void paintEvent(QPaintEvent *event) override
CharacterWidget(QWidget *parent=nullptr)
Constructor for CharacterWidget.
void setFontSize(double fontSize)
Sets the font size (in points) to render in the widget.
void clearCharacter()
Clears the currently selected character in the widget.
void setColumns(int columns)
Sets the number of columns of characters to show in the widget.
void resizeEvent(QResizeEvent *event) override
void mouseMoveEvent(QMouseEvent *event) override
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.