2014-11-13 01:04:59 +02:00
/* This file is part of the KDE libraries
Copyright ( C ) 1999 Reginald Stadlbauer < reggie @ kde . org >
This library is free software ; you can redistribute it and / or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation ; either
version 2 of the License , or ( at your option ) any later version .
This library is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
Library General Public License for more details .
You should have received a copy of the GNU Library General Public License
along with this library ; see the file COPYING . LIB . If not , write to
the Free Software Foundation , Inc . , 51 Franklin Street , Fifth Floor ,
Boston , MA 02110 - 1301 , USA .
*/
# include "kcharselect.h"
# include "kcharselect_p.h"
2015-08-11 05:56:07 +03:00
# include <QtGui/qevent.h>
2014-11-13 01:04:59 +02:00
# include <QtGui/QDoubleSpinBox>
# include <QtGui/QHeaderView>
# include <QtGui/QBoxLayout>
# include <QtGui/QShortcut>
# include <QtGui/QSplitter>
# include <QtGui/QPushButton>
# include <QtGui/QToolButton>
2016-08-20 16:39:59 +00:00
# include <QtGui/QTextBrowser>
2014-11-13 01:04:59 +02:00
# include <kcombobox.h>
# include <kdebug.h>
# include <kdialog.h>
# include <klocale.h>
# include <klineedit.h>
# include <kfontcombobox.h>
# include <kactioncollection.h>
# include <kstandardaction.h>
K_GLOBAL_STATIC ( KCharSelectData , s_data )
class KCharSelectTablePrivate
{
public :
KCharSelectTablePrivate ( KCharSelectTable * q ) : q ( q ) , model ( 0 )
{ }
KCharSelectTable * q ;
QFont font ;
KCharSelectItemModel * model ;
QList < QChar > chars ;
QChar chr ;
void _k_resizeCells ( ) ;
void _k_doubleClicked ( const QModelIndex & index ) ;
void _k_slotSelectionChanged ( const QItemSelection & selected , const QItemSelection & deselected ) ;
} ;
class KCharSelect : : KCharSelectPrivate
{
public :
struct HistoryItem
{
QChar c ;
bool fromSearch ;
QString searchString ;
} ;
enum { MaxHistoryItems = 100 } ;
KCharSelectPrivate ( KCharSelect * q )
: q ( q )
, searchLine ( 0 )
, searchMode ( false )
, historyEnabled ( false )
, inHistory ( 0 )
, actions ( NULL )
{
}
KCharSelect * q ;
QToolButton * backButton ;
QToolButton * forwardButton ;
KLineEdit * searchLine ;
KFontComboBox * fontCombo ;
QSpinBox * fontSizeSpinBox ;
QComboBox * sectionCombo ;
QComboBox * blockCombo ;
KCharSelectTable * charTable ;
2016-08-20 16:39:59 +00:00
QTextBrowser * detailBrowser ;
2014-11-13 01:04:59 +02:00
bool searchMode ; //a search is active
bool historyEnabled ;
int inHistory ; //index of current char in history
QList < HistoryItem > history ;
KActionCollection * actions ;
QString createLinks ( QString s ) ;
void historyAdd ( const QChar & c , bool fromSearch , const QString & searchString ) ;
void showFromHistory ( int index ) ;
void updateBackForwardButtons ( ) ;
void _k_activateSearchLine ( ) ;
void _k_back ( ) ;
void _k_forward ( ) ;
void _k_fontSelected ( ) ;
void _k_updateCurrentChar ( const QChar & c ) ;
void _k_slotUpdateUnicode ( const QChar & c ) ;
void _k_sectionSelected ( int index ) ;
void _k_blockSelected ( int index ) ;
void _k_searchEditChanged ( ) ;
void _k_search ( ) ;
void _k_linkClicked ( QUrl url ) ;
} ;
/******************************************************************/
/* Class: KCharSelectTable */
/******************************************************************/
KCharSelectTable : : KCharSelectTable ( QWidget * parent , const QFont & _font )
: QTableView ( parent ) , d ( new KCharSelectTablePrivate ( this ) )
{
d - > font = _font ;
setTabKeyNavigation ( false ) ;
setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
QPalette _palette ;
_palette . setColor ( backgroundRole ( ) , palette ( ) . color ( QPalette : : Base ) ) ;
setPalette ( _palette ) ;
verticalHeader ( ) - > setVisible ( false ) ;
verticalHeader ( ) - > setResizeMode ( QHeaderView : : Custom ) ;
horizontalHeader ( ) - > setVisible ( false ) ;
horizontalHeader ( ) - > setResizeMode ( QHeaderView : : Custom ) ;
setFocusPolicy ( Qt : : StrongFocus ) ;
setDragEnabled ( true ) ;
setAcceptDrops ( true ) ;
setDropIndicatorShown ( false ) ;
setDragDropMode ( QAbstractItemView : : DragDrop ) ;
connect ( this , SIGNAL ( doubleClicked ( QModelIndex ) ) , this , SLOT ( _k_doubleClicked ( QModelIndex ) ) ) ;
d - > _k_resizeCells ( ) ;
}
KCharSelectTable : : ~ KCharSelectTable ( )
{
delete d ;
}
void KCharSelectTable : : setFont ( const QFont & _font )
{
QTableView : : setFont ( _font ) ;
d - > font = _font ;
if ( d - > model ) d - > model - > setFont ( _font ) ;
d - > _k_resizeCells ( ) ;
}
QChar KCharSelectTable : : chr ( )
{
return d - > chr ;
}
QFont KCharSelectTable : : font ( ) const
{
return d - > font ;
}
QList < QChar > KCharSelectTable : : displayedChars ( ) const
{
return d - > chars ;
}
void KCharSelectTable : : setChar ( const QChar & c )
{
int pos = d - > chars . indexOf ( c ) ;
if ( pos ! = - 1 ) {
setCurrentIndex ( model ( ) - > index ( pos / model ( ) - > columnCount ( ) , pos % model ( ) - > columnCount ( ) ) ) ;
}
}
void KCharSelectTable : : setContents ( QList < QChar > chars )
{
d - > chars = chars ;
KCharSelectItemModel * m = d - > model ;
d - > model = new KCharSelectItemModel ( chars , d - > font , this ) ;
setModel ( d - > model ) ;
d - > _k_resizeCells ( ) ;
QItemSelectionModel * selectionModel = new QItemSelectionModel ( d - > model ) ;
setSelectionModel ( selectionModel ) ;
setSelectionBehavior ( QAbstractItemView : : SelectItems ) ;
setSelectionMode ( QAbstractItemView : : SingleSelection ) ;
connect ( selectionModel , SIGNAL ( selectionChanged ( QItemSelection , QItemSelection ) ) , this , SLOT ( _k_slotSelectionChanged ( QItemSelection , QItemSelection ) ) ) ;
connect ( d - > model , SIGNAL ( showCharRequested ( QChar ) ) , this , SIGNAL ( showCharRequested ( QChar ) ) ) ;
delete m ; // this should hopefully delete aold selection models too, since it is the parent of them (didn't track, if there are setParent calls somewhere. Check that (jowenn)
}
void KCharSelectTable : : scrollTo ( const QModelIndex & index , ScrollHint hint )
{
// this prevents horizontal scrolling when selecting a character in the last column
if ( index . isValid ( ) & & index . column ( ) ! = 0 ) {
QTableView : : scrollTo ( d - > model - > index ( index . row ( ) , 0 ) , hint ) ;
} else {
QTableView : : scrollTo ( index , hint ) ;
}
}
void KCharSelectTablePrivate : : _k_slotSelectionChanged ( const QItemSelection & selected , const QItemSelection & deselected )
{
Q_UNUSED ( deselected ) ;
if ( ! model | | selected . indexes ( ) . isEmpty ( ) )
return ;
QVariant temp = model - > data ( selected . indexes ( ) . at ( 0 ) , KCharSelectItemModel : : CharacterRole ) ;
if ( temp . type ( ) ! = QVariant : : Char )
return ;
QChar c = temp . toChar ( ) ;
chr = c ;
emit q - > focusItemChanged ( c ) ;
}
void KCharSelectTable : : resizeEvent ( QResizeEvent * e )
{
QTableView : : resizeEvent ( e ) ;
if ( e - > size ( ) . width ( ) ! = e - > oldSize ( ) . width ( ) ) {
d - > _k_resizeCells ( ) ;
}
}
void KCharSelectTablePrivate : : _k_resizeCells ( )
{
if ( ! q - > model ( ) ) return ;
static_cast < KCharSelectItemModel * > ( q - > model ( ) ) - > updateColumnCount ( q - > viewport ( ) - > size ( ) . width ( ) ) ;
QChar oldChar = q - > chr ( ) ;
const int new_w = q - > viewport ( ) - > size ( ) . width ( ) / q - > model ( ) - > columnCount ( QModelIndex ( ) ) ;
const int columns = q - > model ( ) - > columnCount ( QModelIndex ( ) ) ;
const int rows = q - > model ( ) - > rowCount ( QModelIndex ( ) ) ;
q - > setUpdatesEnabled ( false ) ;
QHeaderView * hv = q - > horizontalHeader ( ) ;
int spaceLeft = q - > viewport ( ) - > size ( ) . width ( ) % new_w + 1 ;
for ( int i = 0 ; i < = columns ; i + + ) {
if ( i < spaceLeft ) {
hv - > resizeSection ( i , new_w + 1 ) ;
} else {
hv - > resizeSection ( i , new_w ) ;
}
}
hv = q - > verticalHeader ( ) ;
int new_h = QFontMetrics ( font ) . xHeight ( ) * 3 ;
if ( new_h < 5 | | new_h < 4 + QFontMetrics ( font ) . height ( ) ) {
new_h = qMax ( 5 , 4 + QFontMetrics ( font ) . height ( ) ) ;
}
for ( int i = 0 ; i < rows ; i + + ) {
hv - > resizeSection ( i , new_h ) ;
}
q - > setUpdatesEnabled ( true ) ;
q - > setChar ( oldChar ) ;
}
void KCharSelectTablePrivate : : _k_doubleClicked ( const QModelIndex & index )
{
QChar c = model - > data ( index , KCharSelectItemModel : : CharacterRole ) . toChar ( ) ;
if ( s_data - > isPrint ( c ) ) {
emit q - > activated ( c ) ;
}
}
void KCharSelectTable : : keyPressEvent ( QKeyEvent * e )
{
if ( d - > model )
switch ( e - > key ( ) ) {
case Qt : : Key_Space :
emit activated ( ' ' ) ;
return ;
break ;
case Qt : : Key_Enter : case Qt : : Key_Return : {
if ( ! currentIndex ( ) . isValid ( ) ) return ;
QChar c = d - > model - > data ( currentIndex ( ) , KCharSelectItemModel : : CharacterRole ) . toChar ( ) ;
if ( s_data - > isPrint ( c ) ) {
emit activated ( c ) ;
}
}
return ;
break ;
}
QTableView : : keyPressEvent ( e ) ;
}
/******************************************************************/
/* Class: KCharSelect */
/******************************************************************/
KCharSelect : : KCharSelect (
QWidget * parent
, KActionCollection * collection
, const Controls controls )
: QWidget ( parent ) , d ( new KCharSelectPrivate ( this ) )
{
init ( controls , collection ) ;
}
void KCharSelect : : init ( const Controls controls , KActionCollection * collection )
{
if ( collection = = NULL ) {
d - > actions = new KActionCollection ( this ) ;
d - > actions - > addAssociatedWidget ( this ) ;
} else {
d - > actions = collection ;
}
QVBoxLayout * mainLayout = new QVBoxLayout ( this ) ;
mainLayout - > setMargin ( 0 ) ;
if ( SearchLine & controls ) {
QHBoxLayout * searchLayout = new QHBoxLayout ( ) ;
mainLayout - > addLayout ( searchLayout ) ;
d - > searchLine = new KLineEdit ( this ) ;
searchLayout - > addWidget ( d - > searchLine ) ;
d - > searchLine - > setClickMessage ( i18n ( " Enter a search term or character here " ) ) ;
d - > searchLine - > setClearButtonShown ( true ) ;
d - > searchLine - > setToolTip ( i18n ( " Enter a search term or character here " ) ) ;
KStandardAction : : find ( this , SLOT ( _k_activateSearchLine ( ) ) , d - > actions ) ;
connect ( d - > searchLine , SIGNAL ( textChanged ( QString ) ) , this , SLOT ( _k_searchEditChanged ( ) ) ) ;
connect ( d - > searchLine , SIGNAL ( returnPressed ( ) ) , this , SLOT ( _k_search ( ) ) ) ;
}
if ( ( SearchLine & controls ) & & ( ( FontCombo & controls ) | | ( FontSize & controls ) | | ( BlockCombos & controls ) ) ) {
QFrame * line = new QFrame ( this ) ;
line - > setFrameShape ( QFrame : : HLine ) ;
line - > setFrameShadow ( QFrame : : Sunken ) ;
mainLayout - > addWidget ( line ) ;
}
QHBoxLayout * comboLayout = new QHBoxLayout ( ) ;
d - > backButton = new QToolButton ( this ) ;
comboLayout - > addWidget ( d - > backButton ) ;
d - > backButton - > setEnabled ( false ) ;
d - > backButton - > setText ( i18nc ( " Goes to previous character " , " Previous in History " ) ) ;
d - > backButton - > setIcon ( KIcon ( " go-previous " ) ) ;
d - > backButton - > setToolTip ( i18n ( " Previous Character in History " ) ) ;
d - > forwardButton = new QToolButton ( this ) ;
comboLayout - > addWidget ( d - > forwardButton ) ;
d - > forwardButton - > setEnabled ( false ) ;
d - > forwardButton - > setText ( i18nc ( " Goes to next character " , " Next in History " ) ) ;
d - > forwardButton - > setIcon ( KIcon ( " go-next " ) ) ;
d - > forwardButton - > setToolTip ( i18n ( " Next Character in History " ) ) ;
KStandardAction : : back ( d - > backButton , SLOT ( animateClick ( ) ) , d - > actions ) ;
KStandardAction : : forward ( d - > forwardButton , SLOT ( animateClick ( ) ) , d - > actions ) ;
connect ( d - > backButton , SIGNAL ( clicked ( ) ) , this , SLOT ( _k_back ( ) ) ) ;
connect ( d - > forwardButton , SIGNAL ( clicked ( ) ) , this , SLOT ( _k_forward ( ) ) ) ;
d - > sectionCombo = new KComboBox ( this ) ;
d - > sectionCombo - > setToolTip ( i18n ( " Select a category " ) ) ;
comboLayout - > addWidget ( d - > sectionCombo ) ;
d - > blockCombo = new KComboBox ( this ) ;
d - > blockCombo - > setToolTip ( i18n ( " Select a block to be displayed " ) ) ;
d - > blockCombo - > setSizePolicy ( QSizePolicy : : MinimumExpanding , QSizePolicy : : Fixed ) ;
comboLayout - > addWidget ( d - > blockCombo , 1 ) ;
d - > sectionCombo - > addItems ( s_data - > sectionList ( ) ) ;
d - > blockCombo - > setMinimumWidth ( QFontMetrics ( QWidget : : font ( ) ) . averageCharWidth ( ) * 25 ) ;
connect ( d - > sectionCombo , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( _k_sectionSelected ( int ) ) ) ;
connect ( d - > blockCombo , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( _k_blockSelected ( int ) ) ) ;
d - > fontCombo = new KFontComboBox ( this ) ;
comboLayout - > addWidget ( d - > fontCombo ) ;
d - > fontCombo - > setEditable ( true ) ;
d - > fontCombo - > resize ( d - > fontCombo - > sizeHint ( ) ) ;
d - > fontCombo - > setToolTip ( i18n ( " Set font " ) ) ;
d - > fontSizeSpinBox = new QSpinBox ( this ) ;
comboLayout - > addWidget ( d - > fontSizeSpinBox ) ;
d - > fontSizeSpinBox - > setValue ( QWidget : : font ( ) . pointSize ( ) ) ;
d - > fontSizeSpinBox - > setRange ( 1 , 400 ) ;
d - > fontSizeSpinBox - > setSingleStep ( 1 ) ;
d - > fontSizeSpinBox - > setToolTip ( i18n ( " Set font size " ) ) ;
connect ( d - > fontCombo , SIGNAL ( currentIndexChanged ( QString ) ) , this , SLOT ( _k_fontSelected ( ) ) ) ;
connect ( d - > fontSizeSpinBox , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( _k_fontSelected ( ) ) ) ;
if ( ( HistoryButtons & controls ) | | ( FontCombo & controls ) | | ( FontSize & controls ) | | ( BlockCombos & controls ) ) {
mainLayout - > addLayout ( comboLayout ) ;
}
if ( ! ( HistoryButtons & controls ) ) {
d - > backButton - > hide ( ) ;
d - > forwardButton - > hide ( ) ;
}
if ( ! ( FontCombo & controls ) ) {
d - > fontCombo - > hide ( ) ;
}
if ( ! ( FontSize & controls ) ) {
d - > fontSizeSpinBox - > hide ( ) ;
}
if ( ! ( BlockCombos & controls ) ) {
d - > sectionCombo - > hide ( ) ;
d - > blockCombo - > hide ( ) ;
}
QSplitter * splitter = new QSplitter ( this ) ;
if ( ( CharacterTable & controls ) | | ( DetailBrowser & controls ) ) {
mainLayout - > addWidget ( splitter ) ;
} else {
splitter - > hide ( ) ;
}
d - > charTable = new KCharSelectTable ( this , QFont ( ) ) ;
if ( CharacterTable & controls ) {
splitter - > addWidget ( d - > charTable ) ;
d - > charTable - > setFocus ( Qt : : OtherFocusReason ) ;
} else {
d - > charTable - > hide ( ) ;
}
const QSize sz ( 200 , 200 ) ;
d - > charTable - > resize ( sz ) ;
d - > charTable - > setMinimumSize ( sz ) ;
d - > charTable - > setHorizontalScrollBarPolicy ( Qt : : ScrollBarAlwaysOff ) ;
setCurrentFont ( QFont ( ) ) ;
connect ( d - > charTable , SIGNAL ( focusItemChanged ( QChar ) ) , this , SLOT ( _k_updateCurrentChar ( QChar ) ) ) ;
connect ( d - > charTable , SIGNAL ( activated ( QChar ) ) , this , SIGNAL ( charSelected ( QChar ) ) ) ;
connect ( d - > charTable , SIGNAL ( focusItemChanged ( QChar ) ) ,
this , SIGNAL ( currentCharChanged ( QChar ) ) ) ;
connect ( d - > charTable , SIGNAL ( showCharRequested ( QChar ) ) , this , SLOT ( setCurrentChar ( QChar ) ) ) ;
2016-08-20 16:39:59 +00:00
d - > detailBrowser = new QTextBrowser ( this ) ;
2014-11-13 01:04:59 +02:00
if ( DetailBrowser & controls ) {
splitter - > addWidget ( d - > detailBrowser ) ;
} else {
d - > detailBrowser - > hide ( ) ;
}
d - > detailBrowser - > setOpenLinks ( false ) ;
connect ( d - > detailBrowser , SIGNAL ( anchorClicked ( QUrl ) ) , this , SLOT ( _k_linkClicked ( QUrl ) ) ) ;
setFocusPolicy ( Qt : : StrongFocus ) ;
setFocusProxy ( d - > charTable ) ;
d - > _k_sectionSelected ( 0 ) ;
d - > _k_blockSelected ( 0 ) ;
setCurrentChar ( 0x0 ) ;
d - > historyEnabled = true ;
}
KCharSelect : : ~ KCharSelect ( )
{
delete d ;
}
QSize KCharSelect : : sizeHint ( ) const
{
return QWidget : : sizeHint ( ) ;
}
void KCharSelect : : setCurrentFont ( const QFont & _font )
{
d - > fontCombo - > setCurrentFont ( _font ) ;
d - > fontSizeSpinBox - > setValue ( _font . pointSize ( ) ) ;
d - > _k_fontSelected ( ) ;
}
QChar KCharSelect : : currentChar ( ) const
{
return d - > charTable - > chr ( ) ;
}
QFont KCharSelect : : currentFont ( ) const
{
return d - > charTable - > font ( ) ;
}
QList < QChar > KCharSelect : : displayedChars ( ) const
{
return d - > charTable - > displayedChars ( ) ;
}
void KCharSelect : : setCurrentChar ( const QChar & c )
{
bool oldHistoryEnabled = d - > historyEnabled ;
d - > historyEnabled = false ;
int block = s_data - > blockIndex ( c ) ;
int section = s_data - > sectionIndex ( block ) ;
d - > sectionCombo - > setCurrentIndex ( section ) ;
int index = d - > blockCombo - > findData ( block ) ;
if ( index ! = - 1 ) {
d - > blockCombo - > setCurrentIndex ( index ) ;
}
d - > historyEnabled = oldHistoryEnabled ;
d - > charTable - > setChar ( c ) ;
}
void KCharSelect : : KCharSelectPrivate : : historyAdd ( const QChar & c , bool fromSearch , const QString & searchString )
{
//kDebug() << "about to add char" << c << "fromSearch" << fromSearch << "searchString" << searchString;
if ( ! historyEnabled ) {
return ;
}
if ( ! history . isEmpty ( ) & & c = = history . last ( ) . c ) {
//avoid duplicates
return ;
}
//behave like a web browser, i.e. if user goes back from B to A then clicks C, B is forgotten
while ( ! history . isEmpty ( ) & & inHistory ! = history . count ( ) - 1 ) {
history . removeLast ( ) ;
}
while ( history . size ( ) > = MaxHistoryItems ) {
history . removeFirst ( ) ;
}
HistoryItem item ;
item . c = c ;
item . fromSearch = fromSearch ;
item . searchString = searchString ;
history . append ( item ) ;
inHistory = history . count ( ) - 1 ;
updateBackForwardButtons ( ) ;
}
void KCharSelect : : KCharSelectPrivate : : showFromHistory ( int index )
{
Q_ASSERT ( index > = 0 & & index < history . count ( ) ) ;
Q_ASSERT ( index ! = inHistory ) ;
inHistory = index ;
updateBackForwardButtons ( ) ;
const HistoryItem & item = history [ index ] ;
//kDebug() << "index" << index << "char" << item.c << "fromSearch" << item.fromSearch
// << "searchString" << item.searchString;
//avoid adding an item from history into history again
bool oldHistoryEnabled = historyEnabled ;
historyEnabled = false ;
if ( item . fromSearch ) {
if ( searchLine - > text ( ) ! = item . searchString ) {
searchLine - > setText ( item . searchString ) ;
_k_search ( ) ;
}
charTable - > setChar ( item . c ) ;
} else {
searchLine - > clear ( ) ;
q - > setCurrentChar ( item . c ) ;
}
historyEnabled = oldHistoryEnabled ;
}
void KCharSelect : : KCharSelectPrivate : : updateBackForwardButtons ( )
{
backButton - > setEnabled ( inHistory > 0 ) ;
forwardButton - > setEnabled ( inHistory < history . count ( ) - 1 ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_activateSearchLine ( )
{
searchLine - > setFocus ( ) ;
searchLine - > selectAll ( ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_back ( )
{
Q_ASSERT ( inHistory > 0 ) ;
showFromHistory ( inHistory - 1 ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_forward ( )
{
Q_ASSERT ( inHistory + 1 < history . count ( ) ) ;
showFromHistory ( inHistory + 1 ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_fontSelected ( )
{
QFont font = fontCombo - > currentFont ( ) ;
font . setPointSize ( fontSizeSpinBox - > value ( ) ) ;
charTable - > setFont ( font ) ;
emit q - > currentFontChanged ( font ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_updateCurrentChar ( const QChar & c )
{
if ( searchMode ) {
//we are in search mode. make the two comboboxes show the section & block for this character.
//(when we are not in search mode the current character always belongs to the current section & block.)
int block = s_data - > blockIndex ( c ) ;
int section = s_data - > sectionIndex ( block ) ;
sectionCombo - > setCurrentIndex ( section ) ;
int index = blockCombo - > findData ( block ) ;
if ( index ! = - 1 ) {
blockCombo - > setCurrentIndex ( index ) ;
}
}
if ( searchLine )
historyAdd ( c , searchMode , searchLine - > text ( ) ) ;
_k_slotUpdateUnicode ( c ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_slotUpdateUnicode ( const QChar & c )
{
QString html = " <p> " + i18n ( " Character: " ) + ' ' + s_data - > display ( c , charTable - > font ( ) ) + ' ' +
s_data - > formatCode ( c . unicode ( ) ) + " <br /> " ;
QString name = s_data - > name ( c ) ;
if ( ! name . isEmpty ( ) ) {
//is name ever empty? </p> should always be there...
html + = i18n ( " Name: " ) + Qt : : escape ( name ) + " </p> " ;
}
QStringList aliases = s_data - > aliases ( c ) ;
QStringList notes = s_data - > notes ( c ) ;
QList < QChar > seeAlso = s_data - > seeAlso ( c ) ;
QStringList equivalents = s_data - > equivalents ( c ) ;
QStringList approxEquivalents = s_data - > approximateEquivalents ( c ) ;
if ( ! ( aliases . isEmpty ( ) & & notes . isEmpty ( ) & & seeAlso . isEmpty ( ) & & equivalents . isEmpty ( ) & & approxEquivalents . isEmpty ( ) ) ) {
html + = " <p><b> " + i18n ( " Annotations and Cross References " ) + " </b></p> " ;
}
if ( ! aliases . isEmpty ( ) ) {
html + = " <p style= \" margin-bottom: 0px; \" > " + i18n ( " Alias names: " ) + " </p><ul style= \" margin-top: 0px; \" > " ;
foreach ( const QString & alias , aliases ) {
html + = " <li> " + Qt : : escape ( alias ) + " </li> " ;
}
html + = " </ul> " ;
}
if ( ! notes . isEmpty ( ) ) {
html + = " <p style= \" margin-bottom: 0px; \" > " + i18n ( " Notes: " ) + " </p><ul style= \" margin-top: 0px; \" > " ;
foreach ( const QString & note , notes ) {
html + = " <li> " + createLinks ( Qt : : escape ( note ) ) + " </li> " ;
}
html + = " </ul> " ;
}
if ( ! seeAlso . isEmpty ( ) ) {
html + = " <p style= \" margin-bottom: 0px; \" > " + i18n ( " See also: " ) + " </p><ul style= \" margin-top: 0px; \" > " ;
foreach ( const QChar & c2 , seeAlso ) {
html + = " <li><a href= \" " + QString : : number ( c2 . unicode ( ) , 16 ) + " \" > " ;
if ( s_data - > isPrint ( c2 ) ) {
html + = " &# " + QString : : number ( c2 . unicode ( ) ) + " ; " ;
}
html + = s_data - > formatCode ( c2 . unicode ( ) ) + ' ' + Qt : : escape ( s_data - > name ( c2 ) ) + " </a></li> " ;
}
html + = " </ul> " ;
}
if ( ! equivalents . isEmpty ( ) ) {
html + = " <p style= \" margin-bottom: 0px; \" > " + i18n ( " Equivalents: " ) + " </p><ul style= \" margin-top: 0px; \" > " ;
foreach ( const QString & equivalent , equivalents ) {
html + = " <li> " + createLinks ( Qt : : escape ( equivalent ) ) + " </li> " ;
}
html + = " </ul> " ;
}
if ( ! approxEquivalents . isEmpty ( ) ) {
html + = " <p style= \" margin-bottom: 0px; \" > " + i18n ( " Approximate equivalents: " ) + " </p><ul style= \" margin-top: 0px; \" > " ;
foreach ( const QString & approxEquivalent , approxEquivalents ) {
html + = " <li> " + createLinks ( Qt : : escape ( approxEquivalent ) ) + " </li> " ;
}
html + = " </ul> " ;
}
QStringList unihan = s_data - > unihanInfo ( c ) ;
if ( unihan . count ( ) = = 7 ) {
html + = " <p><b> " + i18n ( " CJK Ideograph Information " ) + " </b></p><p> " ;
bool newline = true ;
if ( ! unihan [ 0 ] . isEmpty ( ) ) {
html + = i18n ( " Definition in English: " ) + unihan [ 0 ] ;
newline = false ;
}
if ( ! unihan [ 2 ] . isEmpty ( ) ) {
if ( ! newline ) html + = " <br> " ;
html + = i18n ( " Mandarin Pronunciation: " ) + unihan [ 2 ] ;
newline = false ;
}
if ( ! unihan [ 1 ] . isEmpty ( ) ) {
if ( ! newline ) html + = " <br> " ;
html + = i18n ( " Cantonese Pronunciation: " ) + unihan [ 1 ] ;
newline = false ;
}
if ( ! unihan [ 6 ] . isEmpty ( ) ) {
if ( ! newline ) html + = " <br> " ;
html + = i18n ( " Japanese On Pronunciation: " ) + unihan [ 6 ] ;
newline = false ;
}
if ( ! unihan [ 5 ] . isEmpty ( ) ) {
if ( ! newline ) html + = " <br> " ;
html + = i18n ( " Japanese Kun Pronunciation: " ) + unihan [ 5 ] ;
newline = false ;
}
if ( ! unihan [ 3 ] . isEmpty ( ) ) {
if ( ! newline ) html + = " <br> " ;
html + = i18n ( " Tang Pronunciation: " ) + unihan [ 3 ] ;
newline = false ;
}
if ( ! unihan [ 4 ] . isEmpty ( ) ) {
if ( ! newline ) html + = " <br> " ;
html + = i18n ( " Korean Pronunciation: " ) + unihan [ 4 ] ;
newline = false ;
}
html + = " </p> " ;
}
html + = " <p><b> " + i18n ( " General Character Properties " ) + " </b><br> " ;
html + = i18n ( " Block: " ) + s_data - > block ( c ) + " <br> " ;
html + = i18n ( " Unicode category: " ) + s_data - > categoryText ( s_data - > category ( c ) ) + " </p> " ;
QByteArray utf8 = QString ( c ) . toUtf8 ( ) ;
html + = " <p><b> " + i18n ( " Various Useful Representations " ) + " </b><br> " ;
html + = i18n ( " UTF-8: " ) ;
foreach ( unsigned char c , utf8 )
html + = ' ' + s_data - > formatCode ( c , 2 , " 0x " ) ;
html + = " <br> " + i18n ( " UTF-16: " ) + s_data - > formatCode ( c . unicode ( ) , 4 , " 0x " ) + " <br> " ;
html + = i18n ( " C octal escaped UTF-8: " ) ;
foreach ( unsigned char c , utf8 )
html + = s_data - > formatCode ( c , 3 , " \\ " , 8 ) ;
html + = " <br> " + i18n ( " XML decimal entity: " ) + " &# " + QString : : number ( c . unicode ( ) ) + " ;</p> " ;
detailBrowser - > setHtml ( html ) ;
}
QString KCharSelect : : KCharSelectPrivate : : createLinks ( QString s )
{
QRegExp rx ( " \\ b([ \\ dABCDEF]{4}) \ \ b " ) ;
QStringList chars ;
int pos = 0 ;
while ( ( pos = rx . indexIn ( s , pos ) ) ! = - 1 ) {
chars < < rx . cap ( 1 ) ;
pos + = rx . matchedLength ( ) ;
}
QSet < QString > chars2 = QSet < QString > : : fromList ( chars ) ;
foreach ( const QString & c , chars2 ) {
int unicode = c . toInt ( 0 , 16 ) ;
QString link = " <a href= \" " + c + " \" > " ;
if ( s_data - > isPrint ( QChar ( unicode ) ) ) {
link + = " &# " + QString : : number ( unicode ) + " ; " ;
}
link + = " U+ " + c + ' ' ;
link + = Qt : : escape ( s_data - > name ( QChar ( unicode ) ) ) + " </a> " ;
s . replace ( c , link ) ;
}
return s ;
}
void KCharSelect : : KCharSelectPrivate : : _k_sectionSelected ( int index )
{
blockCombo - > clear ( ) ;
QList < int > blocks = s_data - > sectionContents ( index ) ;
foreach ( int block , blocks ) {
blockCombo - > addItem ( s_data - > blockName ( block ) , QVariant ( block ) ) ;
}
blockCombo - > setCurrentIndex ( 0 ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_blockSelected ( int index )
{
if ( index = = - 1 ) {
//the combo box has been cleared and is about to be filled again (because the section has changed)
return ;
}
if ( searchMode ) {
//we are in search mode, so don't fill the table with this block.
return ;
}
int block = blockCombo - > itemData ( index ) . toInt ( ) ;
const QList < QChar > contents = s_data - > blockContents ( block ) ;
if ( contents . count ( ) < = index ) {
return ;
}
charTable - > setContents ( contents ) ;
emit q - > displayedCharsChanged ( ) ;
charTable - > setChar ( contents [ 0 ] ) ;
}
void KCharSelect : : KCharSelectPrivate : : _k_searchEditChanged ( )
{
if ( searchLine - > text ( ) . isEmpty ( ) ) {
sectionCombo - > setEnabled ( true ) ;
blockCombo - > setEnabled ( true ) ;
//upon leaving search mode, keep the same character selected
searchMode = false ;
QChar c = charTable - > chr ( ) ;
bool oldHistoryEnabled = historyEnabled ;
historyEnabled = false ;
_k_blockSelected ( blockCombo - > currentIndex ( ) ) ;
historyEnabled = oldHistoryEnabled ;
q - > setCurrentChar ( c ) ;
} else {
sectionCombo - > setEnabled ( false ) ;
blockCombo - > setEnabled ( false ) ;
int length = searchLine - > text ( ) . length ( ) ;
if ( length > = 3 ) {
_k_search ( ) ;
}
}
}
void KCharSelect : : KCharSelectPrivate : : _k_search ( )
{
if ( searchLine - > text ( ) . isEmpty ( ) ) {
return ;
}
searchMode = true ;
const QList < QChar > contents = s_data - > find ( searchLine - > text ( ) ) ;
charTable - > setContents ( contents ) ;
emit q - > displayedCharsChanged ( ) ;
if ( ! contents . isEmpty ( ) ) {
charTable - > setChar ( contents [ 0 ] ) ;
}
}
void KCharSelect : : KCharSelectPrivate : : _k_linkClicked ( QUrl url )
{
QString hex = url . toString ( ) ;
if ( hex . size ( ) > 4 ) {
return ;
}
int unicode = hex . toInt ( 0 , 16 ) ;
searchLine - > clear ( ) ;
q - > setCurrentChar ( QChar ( unicode ) ) ;
}
////
QVariant KCharSelectItemModel : : data ( const QModelIndex & index , int role ) const
{
int pos = m_columns * ( index . row ( ) ) + index . column ( ) ;
if ( ! index . isValid ( ) | | pos < 0 | | pos > = m_chars . size ( )
| | index . row ( ) < 0 | | index . column ( ) < 0 ) {
2016-11-06 17:43:18 +00:00
if ( role = = Qt : : BackgroundRole ) {
2014-11-13 01:04:59 +02:00
return QVariant ( qApp - > palette ( ) . color ( QPalette : : Button ) ) ;
}
return QVariant ( ) ;
}
QChar c = m_chars [ pos ] ;
if ( role = = Qt : : ToolTipRole ) {
QString result = s_data - > display ( c , m_font ) + " <br /> " + Qt : : escape ( s_data - > name ( c ) ) + " <br /> " +
i18n ( " Unicode code point: " ) + ' ' + s_data - > formatCode ( c . unicode ( ) ) + " <br /> " +
i18nc ( " Character " , " In decimal: " ) + ' ' + QString : : number ( c . unicode ( ) ) ;
return QVariant ( result ) ;
} else if ( role = = Qt : : TextAlignmentRole )
return QVariant ( Qt : : AlignHCenter | Qt : : AlignVCenter ) ;
else if ( role = = Qt : : DisplayRole ) {
if ( s_data - > isPrint ( c ) )
return QVariant ( c ) ;
return QVariant ( ) ;
2016-11-06 17:43:18 +00:00
} else if ( role = = Qt : : BackgroundRole ) {
2014-11-13 01:04:59 +02:00
QFontMetrics fm = QFontMetrics ( m_font ) ;
if ( fm . inFont ( c ) & & s_data - > isPrint ( c ) )
return QVariant ( qApp - > palette ( ) . color ( QPalette : : Base ) ) ;
else
return QVariant ( qApp - > palette ( ) . color ( QPalette : : Button ) ) ;
} else if ( role = = Qt : : FontRole )
return QVariant ( m_font ) ;
else if ( role = = CharacterRole ) {
return QVariant ( c ) ;
}
return QVariant ( ) ;
}
2015-02-27 07:40:26 +00:00
# include "moc_kcharselect.cpp"
# include "moc_kcharselect_p.cpp"