QGIS API Documentation 3.99.0-Master (26c88405ac0)
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
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
61#include "moc_characterwidget.cpp"
62
64 : QWidget( parent )
65{
66 setMouseTracking( true );
67 setFocusPolicy( Qt::StrongFocus );
68}
69
70void CharacterWidget::setFont( const QFont &font )
71{
72 QgsFontUtils::setFontFamily( mDisplayFont, font.family() );
73 mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
74 adjustSize();
75 update();
76}
77
78void CharacterWidget::setFontSize( double fontSize )
79{
80 mDisplayFont.setPointSizeF( fontSize );
81 mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
82 adjustSize();
83 update();
84}
85
86void CharacterWidget::setFontStyle( const QString &fontStyle )
87{
88 const QFontDatabase fontDatabase;
89 const QFont::StyleStrategy oldStrategy = mDisplayFont.styleStrategy();
90 mDisplayFont = fontDatabase.font( mDisplayFont.family(), fontStyle, mDisplayFont.pointSize() );
91 mDisplayFont.setStyleStrategy( oldStrategy );
92 mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
93 adjustSize();
94 update();
95}
96
98{
99 if ( enable )
100 mDisplayFont.setStyleStrategy( QFont::PreferDefault );
101 else
102 mDisplayFont.setStyleStrategy( QFont::NoFontMerging );
103 adjustSize();
104 update();
105}
106
108{
109 if ( mColumns == columns || columns < 1 )
110 return;
111 mColumns = columns;
112 adjustSize();
113 update();
114}
115
117{
118 const bool changed = character.unicode() != mLastKey;
119 mLastKey = character.isNull() ? -1 : character.unicode();
120 QWidget *widget = parentWidget();
121 if ( widget )
122 {
123 QScrollArea *scrollArea = qobject_cast<QScrollArea *>( widget->parent() );
124 if ( scrollArea && mLastKey < 65536 )
125 {
126 scrollArea->ensureVisible( 0, mLastKey / mColumns * mSquareSize );
127 }
128 }
129 if ( changed )
130 emit characterSelected( mLastKey >= 0 ? QChar( mLastKey ) : QChar() );
131
132 update();
133}
134
136{
137 mLastKey = -1;
138 update();
139}
140
142{
143 return QSize( mColumns * mSquareSize, ( 65536 / mColumns ) * mSquareSize );
144}
145
146void CharacterWidget::keyPressEvent( QKeyEvent *event )
147{
148 const QFontMetrics fm( mDisplayFont );
149
150 if ( event->key() == Qt::Key_Right )
151 {
152 int next = std::min( mLastKey + 1, 0xfffc );
153 while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
154 {
155 next++;
156 }
157 setCharacter( QChar( next ) );
158 }
159 else if ( event->key() == Qt::Key_Left )
160 {
161 int next = mLastKey - 1;
162 while ( next > 0 && !fm.inFont( QChar( next ) ) )
163 {
164 next--;
165 }
166 setCharacter( QChar( next ) );
167 }
168 else if ( event->key() == Qt::Key_Down )
169 {
170 int next = std::min( mLastKey + mColumns, 0xfffc );
171 while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
172 {
173 next = std::min( next + mColumns, 0xfffc );
174 }
175 setCharacter( QChar( next ) );
176 }
177 else if ( event->key() == Qt::Key_Up )
178 {
179 int next = std::max( 0, mLastKey - mColumns );
180 while ( next > 0 && !fm.inFont( QChar( next ) ) )
181 {
182 next = std::max( 0, next - mColumns );
183 }
184 setCharacter( QChar( next ) );
185 }
186 else if ( event->key() == Qt::Key_Home )
187 {
188 int next = 0;
189 while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
190 {
191 next++;
192 }
193 setCharacter( QChar( next ) );
194 }
195 else if ( event->key() == Qt::Key_End )
196 {
197 int next = 0xfffc;
198 while ( next > 0 && !fm.inFont( QChar( next ) ) )
199 {
200 next--;
201 }
202 setCharacter( QChar( next ) );
203 }
204 else if ( !event->text().isEmpty() )
205 {
206 QChar chr = event->text().at( 0 );
207 if ( chr.unicode() != mLastKey )
208 {
209 setCharacter( chr );
210 }
211 }
212}
213
214void CharacterWidget::mouseMoveEvent( QMouseEvent *event )
215{
216 const QPoint widgetPosition = mapFromGlobal( event->globalPos() );
217 const uint key = ( widgetPosition.y() / mSquareSize ) * mColumns + widgetPosition.x() / mSquareSize;
218
219 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>" )
220 .arg( mDisplayFont.family() )
221 .arg( QChar( key ) )
222 .arg( tr( "Character" ), tr( "Decimal" ) )
223 .arg( key )
224 .arg( tr( "Hex" ), 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, row * mSquareSize + 4 + fontMetrics.ascent(), QString( QChar( key ) ) );
280 }
281 }
282 }
283}
284
285void CharacterWidget::resizeEvent( QResizeEvent *event )
286{
287 mColumns = event->size().width() / mSquareSize;
288 QWidget::resizeEvent( event );
289}
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.