QGIS API Documentation 3.41.0-Master (45a0abf3bec)
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" ),
221 tr( "Decimal" ) )
222 .arg( key )
223 .arg( tr( "Hex" ),
224 QString::number( key, 16 ) );
225 QToolTip::showText( event->globalPos(), text, this );
226}
227
228void CharacterWidget::mousePressEvent( QMouseEvent *event )
229{
230 if ( event->button() == Qt::LeftButton )
231 {
232 mLastKey = ( event->y() / mSquareSize ) * mColumns + event->x() / mSquareSize;
233 if ( QChar( mLastKey ).category() != QChar::Other_NotAssigned )
234 emit characterSelected( QChar( mLastKey ) );
235 update();
236 }
237 else
238 QWidget::mousePressEvent( event );
239}
240
241void CharacterWidget::paintEvent( QPaintEvent *event )
242{
243 QPainter painter( this );
244 painter.setFont( mDisplayFont );
245
246 const QFontMetrics fontMetrics( mDisplayFont );
247
248 const QRect redrawRect = event->rect();
249 const int beginRow = redrawRect.top() / mSquareSize;
250 const int endRow = redrawRect.bottom() / mSquareSize;
251 const int beginColumn = redrawRect.left() / mSquareSize;
252 const int endColumn = std::min( mColumns - 1, redrawRect.right() / mSquareSize );
253
254 const QPalette palette = qApp->palette();
255 painter.setPen( QPen( palette.color( QPalette::Mid ) ) );
256 for ( int row = beginRow; row <= endRow; ++row )
257 {
258 for ( int column = beginColumn; column <= endColumn; ++column )
259 {
260 const int key = row * mColumns + column;
261 painter.setBrush( fontMetrics.inFont( QChar( key ) ) ? QBrush( palette.color( QPalette::Base ) ) : Qt::NoBrush );
262 painter.drawRect( column * mSquareSize, row * mSquareSize, mSquareSize, mSquareSize );
263 }
264 }
265
266 for ( int row = beginRow; row <= endRow; ++row )
267 {
268 for ( int column = beginColumn; column <= endColumn; ++column )
269 {
270 const int key = row * mColumns + column;
271 painter.setClipRect( column * mSquareSize, row * mSquareSize, mSquareSize, mSquareSize );
272 painter.setPen( QPen( palette.color( key == mLastKey ? QPalette::HighlightedText : QPalette::WindowText ) ) );
273
274 if ( key == mLastKey )
275 painter.fillRect( column * mSquareSize + 1, row * mSquareSize + 1, mSquareSize, mSquareSize, QBrush( palette.color( QPalette::Highlight ) ) );
276
277 if ( fontMetrics.inFont( QChar( key ) ) )
278 {
279 painter.drawText( column * mSquareSize + ( mSquareSize / 2 ) - fontMetrics.boundingRect( QChar( key ) ).width() / 2,
280 row * mSquareSize + 4 + fontMetrics.ascent(),
281 QString( QChar( key ) ) );
282 }
283 }
284 }
285}
286
287void CharacterWidget::resizeEvent( QResizeEvent *event )
288{
289 mColumns = event->size().width() / mSquareSize;
290 QWidget::resizeEvent( event );
291}
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.