49#include <QFontDatabase> 
   62  setMouseTracking( 
true );
 
   63  setFocusPolicy( Qt::StrongFocus );
 
   68  mDisplayFont.setFamily( 
font.family() );
 
   69  mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
 
   76  mDisplayFont.setPointSizeF( fontSize );
 
   77  mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
 
   84  const QFontDatabase fontDatabase;
 
   85  const QFont::StyleStrategy oldStrategy = mDisplayFont.styleStrategy();
 
   86  mDisplayFont = fontDatabase.font( mDisplayFont.family(), fontStyle, mDisplayFont.pointSize() );
 
   87  mDisplayFont.setStyleStrategy( oldStrategy );
 
   88  mSquareSize = std::max( 34, QFontMetrics( mDisplayFont ).xHeight() * 3 );
 
   96    mDisplayFont.setStyleStrategy( QFont::PreferDefault );
 
   98    mDisplayFont.setStyleStrategy( QFont::NoFontMerging );
 
  114  const bool changed = 
character.unicode() != mLastKey;
 
  116  QWidget *widget = parentWidget();
 
  119    QScrollArea *scrollArea = qobject_cast< QScrollArea *>( widget->parent() );
 
  120    if ( scrollArea && mLastKey < 65536 )
 
  122      scrollArea->ensureVisible( 0, mLastKey / mColumns * mSquareSize );
 
  139  return QSize( mColumns * mSquareSize, ( 65536 / mColumns ) * mSquareSize );
 
  144  const QFontMetrics fm( mDisplayFont );
 
  146  if ( event->key() == Qt::Key_Right )
 
  148    int next = std::min( mLastKey + 1, 0xfffc );
 
  149    while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
 
  155  else if ( event->key() == Qt::Key_Left )
 
  157    int next = mLastKey - 1;
 
  158    while ( next > 0 && !fm.inFont( QChar( next ) ) )
 
  164  else if ( event->key() == Qt::Key_Down )
 
  166    int next = std::min( mLastKey + mColumns, 0xfffc );
 
  167    while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
 
  169      next = std::min( next + mColumns, 0xfffc );
 
  173  else if ( event->key() == Qt::Key_Up )
 
  175    int next = std::max( 0, mLastKey - mColumns );
 
  176    while ( next > 0 && !fm.inFont( QChar( next ) ) )
 
  178      next = std::max( 0, next - mColumns );
 
  182  else if ( event->key() == Qt::Key_Home )
 
  185    while ( next < 0xfffc && !fm.inFont( QChar( next ) ) )
 
  191  else if ( event->key() == Qt::Key_End )
 
  194    while ( next > 0 && !fm.inFont( QChar( next ) ) )
 
  200  else if ( !event->text().isEmpty() )
 
  202    QChar chr = 
event->text().at( 0 );
 
  203    if ( chr.unicode() != mLastKey )
 
  212  const QPoint widgetPosition = mapFromGlobal( event->globalPos() );
 
  213  const uint key = ( widgetPosition.y() / mSquareSize ) * mColumns + widgetPosition.x() / mSquareSize;
 
  215  const QString text = tr( 
"<p>Character: <span style=\"font-size: 24pt; font-family: %1\">%2</span><p>Decimal: %3<p>Hex: 0x%4" )
 
  216                       .arg( mDisplayFont.family() )
 
  219                       .arg( QString::number( key, 16 ) );
 
  220  QToolTip::showText( event->globalPos(), text, 
this );
 
  225  if ( event->button() == Qt::LeftButton )
 
  227    mLastKey = ( 
event->y() / mSquareSize ) * mColumns + event->x() / mSquareSize;
 
  228    if ( QChar( mLastKey ).category() != QChar::Other_NotAssigned )
 
  233    QWidget::mousePressEvent( event );
 
  238  QPainter painter( 
this );
 
  239  painter.setFont( mDisplayFont );
 
  241  const QFontMetrics fontMetrics( mDisplayFont );
 
  243  const QRect redrawRect = 
event->rect();
 
  244  const int beginRow = redrawRect.top() / mSquareSize;
 
  245  const int endRow = redrawRect.bottom() / mSquareSize;
 
  246  const int beginColumn = redrawRect.left() / mSquareSize;
 
  247  const int endColumn = std::min( mColumns - 1, redrawRect.right() / mSquareSize );
 
  249  const QPalette palette = qApp->palette();
 
  250  painter.setPen( QPen( palette.color( QPalette::Mid ) ) );
 
  251  for ( 
int row = beginRow; row <= endRow; ++row )
 
  253    for ( 
int column = beginColumn; column <= endColumn; ++column )
 
  255      const int key = row * mColumns + column;
 
  256      painter.setBrush( fontMetrics.inFont( QChar( key ) ) ? QBrush( palette.color( QPalette::Base ) ) : Qt::NoBrush );
 
  257      painter.drawRect( column * mSquareSize, row * mSquareSize, mSquareSize, mSquareSize );
 
  261  for ( 
int row = beginRow; row <= endRow; ++row )
 
  263    for ( 
int column = beginColumn; column <= endColumn; ++column )
 
  265      const int key = row * mColumns + column;
 
  266      painter.setClipRect( column * mSquareSize, row * mSquareSize, mSquareSize, mSquareSize );
 
  267      painter.setPen( QPen( palette.color( key == mLastKey ? QPalette::HighlightedText : QPalette::WindowText ) ) );
 
  269      if ( key == mLastKey )
 
  270        painter.fillRect( column * mSquareSize + 1, row * mSquareSize + 1, mSquareSize, mSquareSize, QBrush( palette.color( QPalette::Highlight ) ) );
 
  272      if ( fontMetrics.inFont( QChar( key ) ) )
 
  274        painter.drawText( column * mSquareSize + ( mSquareSize / 2 ) - fontMetrics.boundingRect( QChar( key ) ).width() / 2,
 
  275                          row * mSquareSize + 4 + fontMetrics.ascent(),
 
  276                          QString( QChar( key ) ) );
 
  284  mColumns = 
event->size().width() / mSquareSize;
 
  285  QWidget::resizeEvent( event );