49 #include <QFontDatabase> 
   50 #include <QMouseEvent> 
   51 #include <QPaintEvent> 
   55 #include <QScrollArea> 
   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   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 != 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   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   QPoint widgetPosition = mapFromGlobal( event->globalPos() );
 
  213   uint key = ( widgetPosition.y() / mSquareSize ) * mColumns + widgetPosition.x() / mSquareSize;
 
  215   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   QFontMetrics fontMetrics( mDisplayFont );
 
  243   QRect redrawRect = 
event->rect();
 
  244   int beginRow = redrawRect.top() / mSquareSize;
 
  245   int endRow = redrawRect.bottom() / mSquareSize;
 
  246   int beginColumn = redrawRect.left() / mSquareSize;
 
  247   int endColumn = std::min( mColumns - 1, redrawRect.right() / mSquareSize );
 
  249   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       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       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 );