• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KDEUI

kcharselect.cpp

Go to the documentation of this file.
00001 /* This file is part of the KDE libraries
00002 
00003    Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018    Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "kcharselect.h"
00022 
00023 #include "kcharselect_p.h"
00024 
00025 #include <QtGui/QActionEvent>
00026 #include <QtGui/QDoubleSpinBox>
00027 #include <QtGui/QHeaderView>
00028 #include <QtGui/QBoxLayout>
00029 #include <QtGui/QShortcut>
00030 #include <QtGui/QSplitter>
00031 #include <QtGui/QPushButton>
00032 #include <QtGui/QToolButton>
00033 
00034 #include <kcombobox.h>
00035 #include <kdebug.h>
00036 #include <kdialog.h>
00037 #include <klocale.h>
00038 #include <klineedit.h>
00039 #include <ktextbrowser.h>
00040 #include <kfontcombobox.h>
00041 #include <kactioncollection.h>
00042 #include <kstandardaction.h>
00043 
00044 K_GLOBAL_STATIC(KCharSelectData, s_data)
00045 
00046 class KCharSelectTablePrivate
00047 {
00048 public:
00049     KCharSelectTablePrivate(KCharSelectTable *q): q(q), model()
00050         {}
00051 
00052     KCharSelectTable *q;
00053 
00054     QFont font;
00055     KCharSelectItemModel *model;
00056     QList<QChar> chars;
00057     QChar chr;
00058 
00059     void _k_resizeCells();
00060     void _k_doubleClicked(const QModelIndex & index);
00061     void _k_slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous);
00062 };
00063 
00064 class KCharSelect::KCharSelectPrivate
00065 {
00066 public:
00067     struct HistoryItem
00068     {
00069         QChar c;
00070         bool fromSearch;
00071         QString searchString;
00072     };
00073 
00074     enum { MaxHistoryItems = 100 };
00075 
00076     KCharSelectPrivate(KCharSelect *q) 
00077         : q(q)
00078           ,searchLine(0)
00079           ,searchMode(false)
00080           ,historyEnabled(false)
00081           ,inHistory(0)
00082           ,actions(NULL)
00083     {
00084     }
00085 
00086     KCharSelect *q;
00087 
00088     QToolButton *backButton;
00089     QToolButton *forwardButton;
00090     KLineEdit* searchLine;
00091     KFontComboBox *fontCombo;
00092     QSpinBox *fontSizeSpinBox;
00093     QComboBox *sectionCombo;
00094     QComboBox *blockCombo;
00095     KCharSelectTable *charTable;
00096     KTextBrowser *detailBrowser;
00097 
00098     bool searchMode; //a search is active
00099     bool historyEnabled;
00100     int inHistory; //index of current char in history
00101     QList<HistoryItem> history;
00102     KActionCollection* actions;
00103 
00104     QString createLinks(QString s);
00105     void historyAdd(const QChar &c, bool fromSearch, const QString &searchString);
00106     void showFromHistory(int index);
00107     void updateBackForwardButtons();
00108     void _k_activateSearchLine();
00109     void _k_back();
00110     void _k_forward();
00111     void _k_fontSelected();
00112     void _k_updateCurrentChar(const QChar &c);
00113     void _k_slotUpdateUnicode(const QChar &c);
00114     void _k_sectionSelected(int index);
00115     void _k_blockSelected(int index);
00116     void _k_searchEditChanged();
00117     void _k_search();
00118     void _k_linkClicked(QUrl url);
00119 };
00120 
00121 /******************************************************************/
00122 /* Class: KCharSelectTable                                        */
00123 /******************************************************************/
00124 
00125 KCharSelectTable::KCharSelectTable(QWidget *parent, const QFont &_font)
00126         : QTableView(parent), d(new KCharSelectTablePrivate(this))
00127 {
00128     d->font = _font;
00129 
00130     setTabKeyNavigation(false);
00131     setSelectionMode(QAbstractItemView::SingleSelection);
00132     QPalette _palette;
00133     _palette.setColor(backgroundRole(), palette().color(QPalette::Base));
00134     setPalette(_palette);
00135     verticalHeader()->setVisible(false);
00136     verticalHeader()->setResizeMode(QHeaderView::Custom);
00137     horizontalHeader()->setVisible(false);
00138     horizontalHeader()->setResizeMode(QHeaderView::Custom);
00139 
00140     setFocusPolicy(Qt::StrongFocus);
00141     setDragEnabled(true);
00142     setAcceptDrops(true);
00143     setDropIndicatorShown(false);
00144     setDragDropMode(QAbstractItemView::DragDrop);
00145 
00146     connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_k_doubleClicked(QModelIndex)));
00147 
00148     d->_k_resizeCells();
00149 }
00150 
00151 KCharSelectTable::~KCharSelectTable()
00152 {
00153     delete d;
00154 }
00155 
00156 void KCharSelectTable::setFont(const QFont &_font)
00157 {
00158     QTableView::setFont(_font);
00159     d->font = _font;
00160     if (d->model) d->model->setFont(_font);
00161     d->_k_resizeCells();
00162 }
00163 
00164 QChar KCharSelectTable::chr()
00165 {
00166     return d->chr;
00167 }
00168 
00169 QFont KCharSelectTable::font() const
00170 {
00171     return d->font;
00172 }
00173 
00174 QList<QChar> KCharSelectTable::displayedChars() const
00175 {
00176     return d->chars;
00177 }
00178 
00179 void KCharSelectTable::setChar(const QChar &c)
00180 {
00181     int pos = d->chars.indexOf(c);
00182     if (pos != -1) {
00183         setCurrentIndex(model()->index(pos / model()->columnCount(), pos % model()->columnCount()));
00184     }
00185 }
00186 
00187 void KCharSelectTable::setContents(QList<QChar> chars)
00188 {
00189     d->chars = chars;
00190 
00191     KCharSelectItemModel *m = d->model;
00192     d->model = new KCharSelectItemModel(chars, d->font, this);
00193     setModel(d->model);
00194     d->_k_resizeCells();
00195     QItemSelectionModel *selectionModel = new QItemSelectionModel(d->model);
00196     setSelectionModel(selectionModel);
00197     setSelectionBehavior(QAbstractItemView::SelectItems);
00198     setSelectionMode(QAbstractItemView::SingleSelection);
00199     connect(selectionModel, SIGNAL(currentChanged(const QModelIndex & , const QModelIndex &)), this, SLOT(_k_slotCurrentChanged(const QModelIndex &, const QModelIndex &)));
00200     connect(d->model, SIGNAL(showCharRequested(QChar)), this, SIGNAL(showCharRequested(QChar)));
00201     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)
00202 }
00203 
00204 void KCharSelectTable::scrollTo(const QModelIndex & index, ScrollHint hint)
00205 {
00206     // this prevents horizontal scrolling when selecting a character in the last column
00207     if (index.isValid() && index.column() != 0) {
00208         QTableView::scrollTo(d->model->index(index.row(), 0), hint);
00209     } else {
00210         QTableView::scrollTo(index, hint);
00211     }
00212 }
00213 
00214 void KCharSelectTablePrivate::_k_slotCurrentChanged(const QModelIndex & current, const QModelIndex & previous)
00215 {
00216     Q_UNUSED(previous);
00217     if (!model) return;
00218     QVariant temp = model->data(current, KCharSelectItemModel::CharacterRole);
00219     if (temp.type() != QVariant::Char)
00220         return;
00221     QChar c = temp.toChar();
00222     chr = c;
00223     emit q->focusItemChanged(c);
00224 }
00225 
00226 void KCharSelectTable::resizeEvent(QResizeEvent * e)
00227 {
00228     QTableView::resizeEvent(e);
00229     if (e->size().width() != e->oldSize().width()) {
00230         d->_k_resizeCells();
00231     }
00232 }
00233 
00234 void KCharSelectTablePrivate::_k_resizeCells()
00235 {
00236     if (!q->model()) return;
00237     static_cast<KCharSelectItemModel*>(q->model())->updateColumnCount(q->viewport()->size().width());
00238 
00239     QChar oldChar = q->chr();
00240 
00241     const int new_w   = q->viewport()->size().width() / q->model()->columnCount(QModelIndex());
00242     const int columns = q->model()->columnCount(QModelIndex());
00243     const int rows = q->model()->rowCount(QModelIndex());
00244     q->setUpdatesEnabled(false);
00245     QHeaderView* hv = q->horizontalHeader();
00246     int spaceLeft = q->viewport()->size().width() % new_w + 1;
00247     for (int i = 0;i <= columns;i++) {
00248         if (i < spaceLeft) {
00249             hv->resizeSection(i, new_w + 1);
00250         } else {
00251             hv->resizeSection(i, new_w);
00252         }
00253     }
00254 
00255     hv = q->verticalHeader();
00256 #ifdef Q_WS_WIN
00257     const int new_h = QFontMetrics(font).lineSpacing() + 1;
00258 #else
00259     const int new_h = QFontMetrics(font).xHeight() * 3;
00260 #endif
00261     for (int i = 0;i < rows;i++) {
00262         hv->resizeSection(i, new_h);
00263     }
00264 
00265     q->setUpdatesEnabled(true);
00266     q->setChar(oldChar);
00267 }
00268 
00269 void KCharSelectTablePrivate::_k_doubleClicked(const QModelIndex & index)
00270 {
00271     QChar c = model->data(index, KCharSelectItemModel::CharacterRole).toChar();
00272     if (c.isPrint()) {
00273         emit q->activated(c);
00274     }
00275 }
00276 
00277 void KCharSelectTable::keyPressEvent(QKeyEvent *e)
00278 {
00279     if (d->model)
00280         switch (e->key()) {
00281         case Qt::Key_Space:
00282             emit activated(' ');
00283             return;
00284             break;
00285     case Qt::Key_Enter: case Qt::Key_Return: {
00286             if (!currentIndex().isValid()) return;
00287             QChar c = d->model->data(currentIndex(), KCharSelectItemModel::CharacterRole).toChar();
00288             if (c.isPrint()) {
00289                 emit activated(c);
00290             }
00291         }
00292         return;
00293         break;
00294         }
00295     QTableView::keyPressEvent(e);
00296 }
00297 
00298 
00299 /******************************************************************/
00300 /* Class: KCharSelect                                             */
00301 /******************************************************************/
00302 
00303 KCharSelect::KCharSelect(QWidget *parent, const Controls controls)
00304         : QWidget(parent), d(new KCharSelectPrivate(this))
00305 {
00306     init(controls, NULL);
00307 }
00308 
00309 KCharSelect::KCharSelect(
00310         QWidget *parent
00311         ,KActionCollection *collection
00312         ,const Controls controls)
00313     : QWidget(parent), d(new KCharSelectPrivate(this))
00314 {
00315     init(controls, collection);
00316 }
00317 
00318 void KCharSelect::init(const Controls controls, KActionCollection *collection)
00319 {
00320     if (collection==NULL) {
00321         d->actions = new KActionCollection(this);
00322         d->actions->addAssociatedWidget(this);
00323     } else {
00324         d->actions = collection;
00325     }
00326 
00327     QVBoxLayout *mainLayout = new QVBoxLayout(this);
00328     mainLayout->setMargin(0);
00329     if (SearchLine & controls) {
00330         QHBoxLayout *searchLayout = new QHBoxLayout();
00331         mainLayout->addLayout(searchLayout);
00332         d->searchLine = new KLineEdit(this);
00333         searchLayout->addWidget(d->searchLine);
00334         d->searchLine->setClickMessage(i18n("Enter a search term or character here"));
00335         d->searchLine->setClearButtonShown(true);
00336         d->searchLine->setToolTip(i18n("Enter a search term or character here"));
00337         KStandardAction::find(this, SLOT(_k_activateSearchLine()), d->actions);
00338         connect(d->searchLine, SIGNAL(textChanged(QString)), this, SLOT(_k_searchEditChanged()));
00339         connect(d->searchLine, SIGNAL(returnPressed()), this, SLOT(_k_search()));
00340     }
00341 
00342     if ((SearchLine & controls) && ((FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls))) {
00343         QFrame* line = new QFrame(this);
00344         line->setFrameShape(QFrame::HLine);
00345         line->setFrameShadow(QFrame::Sunken);
00346         mainLayout->addWidget(line);
00347     }
00348 
00349     QHBoxLayout *comboLayout = new QHBoxLayout();
00350 
00351     d->backButton = new QToolButton(this);
00352     comboLayout->addWidget(d->backButton);
00353     d->backButton->setEnabled(false);
00354     d->backButton->setText(i18nc("Goes to previous character", "Previous in History"));
00355     d->backButton->setIcon(KIcon("go-previous"));
00356     d->backButton->setToolTip(i18n("Previous Character in History"));
00357 
00358     d->forwardButton = new QToolButton(this);
00359     comboLayout->addWidget(d->forwardButton);
00360     d->forwardButton->setEnabled(false);
00361     d->forwardButton->setText(i18nc("Goes to next character", "Next in History"));
00362     d->forwardButton->setIcon(KIcon("go-next"));
00363     d->forwardButton->setToolTip(i18n("Next Character in History"));
00364 
00365     KStandardAction::back(d->backButton, SLOT(animateClick()), d->actions);
00366     KStandardAction::forward(d->forwardButton, SLOT(animateClick()), d->actions);
00367     connect(d->backButton, SIGNAL(clicked()), this, SLOT(_k_back()));
00368     connect(d->forwardButton, SIGNAL(clicked()), this, SLOT(_k_forward()));
00369 
00370     d->sectionCombo = new KComboBox(this);
00371     d->sectionCombo->setToolTip(i18n("Select a category"));
00372     comboLayout->addWidget(d->sectionCombo);
00373     d->blockCombo = new KComboBox(this);
00374     d->blockCombo->setToolTip(i18n("Select a block to be displayed"));
00375     d->blockCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
00376     comboLayout->addWidget(d->blockCombo, 1);
00377     d->sectionCombo->addItems(s_data->sectionList());
00378     d->blockCombo->setMinimumWidth(QFontMetrics(QWidget::font()).averageCharWidth() * 25);
00379 
00380     connect(d->sectionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_sectionSelected(int)));
00381     connect(d->blockCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_blockSelected(int)));
00382 
00383     d->fontCombo = new KFontComboBox(this);
00384     comboLayout->addWidget(d->fontCombo);
00385     d->fontCombo->setEditable(true);
00386     d->fontCombo->resize(d->fontCombo->sizeHint());
00387     d->fontCombo->setToolTip(i18n("Set font"));
00388 
00389     d->fontSizeSpinBox = new QSpinBox(this);
00390     comboLayout->addWidget(d->fontSizeSpinBox);
00391     d->fontSizeSpinBox->setValue(QWidget::font().pointSize());
00392     d->fontSizeSpinBox->setRange(1, 400);
00393     d->fontSizeSpinBox->setSingleStep(1);
00394     d->fontSizeSpinBox->setToolTip(i18n("Set font size"));
00395 
00396     connect(d->fontCombo, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(_k_fontSelected()));
00397     connect(d->fontSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(_k_fontSelected()));
00398 
00399     if ((HistoryButtons & controls) || (FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls)) {
00400         mainLayout->addLayout(comboLayout);
00401     }
00402     if (!(HistoryButtons & controls)) {
00403         d->backButton->hide();
00404         d->forwardButton->hide();
00405     }
00406     if (!(FontCombo & controls)) {
00407         d->fontCombo->hide();
00408     }
00409     if (!(FontSize & controls)) {
00410         d->fontSizeSpinBox->hide();
00411     }
00412     if (!(BlockCombos & controls)) {
00413         d->sectionCombo->hide();
00414         d->blockCombo->hide();
00415     }
00416 
00417     QSplitter *splitter = new QSplitter(this);
00418     if ((CharacterTable & controls) || (DetailBrowser & controls)) {
00419         mainLayout->addWidget(splitter);
00420     } else {
00421         splitter->hide();
00422     }
00423     d->charTable = new KCharSelectTable(this, QFont());
00424     if (CharacterTable & controls) {
00425         splitter->addWidget(d->charTable);
00426         d->charTable->setFocus(Qt::OtherFocusReason);
00427     } else {
00428         d->charTable->hide();
00429     }
00430 
00431     const QSize sz(200, 200);
00432     d->charTable->resize(sz);
00433     d->charTable->setMinimumSize(sz);
00434 
00435     d->charTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00436 
00437     setCurrentFont(QFont());
00438 
00439     connect(d->charTable, SIGNAL(focusItemChanged(const QChar &)), this, SLOT(_k_updateCurrentChar(const QChar &)));
00440     connect(d->charTable, SIGNAL(activated(const QChar &)), this, SIGNAL(charSelected(const QChar &)));
00441     connect(d->charTable, SIGNAL(focusItemChanged(const QChar &)),
00442             this, SIGNAL(currentCharChanged(const QChar &)));
00443 
00444     connect(d->charTable, SIGNAL(showCharRequested(QChar)), this, SLOT(setCurrentChar(QChar)));
00445 
00446     d->detailBrowser = new KTextBrowser(this);
00447     if (DetailBrowser & controls) {
00448         splitter->addWidget(d->detailBrowser);
00449     } else {
00450         d->detailBrowser->hide();
00451     }
00452     d->detailBrowser->setOpenLinks(false);
00453     connect(d->detailBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(_k_linkClicked(QUrl)));
00454 
00455     setFocusPolicy(Qt::StrongFocus);
00456     setFocusProxy(d->charTable);
00457     d->_k_sectionSelected(0);
00458     d->_k_blockSelected(0);
00459     setCurrentChar(0x0);
00460 
00461     d->historyEnabled = true;
00462 }
00463 
00464 KCharSelect::~KCharSelect()
00465 {
00466     delete d;
00467 }
00468 
00469 QSize KCharSelect::sizeHint() const
00470 {
00471     return QWidget::sizeHint();
00472 }
00473 
00474 void KCharSelect::setCurrentFont(const QFont &_font)
00475 {
00476     d->fontCombo->setCurrentFont(_font);
00477     d->fontSizeSpinBox->setValue(_font.pointSize());
00478     d->_k_fontSelected();
00479 }
00480 
00481 QChar KCharSelect::currentChar() const
00482 {
00483     return d->charTable->chr();
00484 }
00485 
00486 QFont KCharSelect::currentFont() const
00487 {
00488     return d->charTable->font();
00489 }
00490 
00491 QList<QChar> KCharSelect::displayedChars() const
00492 {
00493     return d->charTable->displayedChars();
00494 }
00495 
00496 void KCharSelect::setCurrentChar(const QChar &c)
00497 {
00498     bool oldHistoryEnabled = d->historyEnabled;
00499     d->historyEnabled = false;
00500     int block = s_data->blockIndex(c);
00501     int section = s_data->sectionIndex(block);
00502     d->sectionCombo->setCurrentIndex(section);
00503     int index = d->blockCombo->findData(block);
00504     if (index != -1) {
00505         d->blockCombo->setCurrentIndex(index);
00506     }
00507     d->historyEnabled = oldHistoryEnabled;
00508     d->charTable->setChar(c);
00509 }
00510 
00511 void KCharSelect::KCharSelectPrivate::historyAdd(const QChar &c, bool fromSearch, const QString &searchString)
00512 {
00513     //kDebug() << "about to add char" << c << "fromSearch" << fromSearch << "searchString" << searchString;
00514 
00515     if (!historyEnabled) {
00516         return;
00517     }
00518 
00519     if (!history.isEmpty() && c == history.last().c) {
00520         //avoid duplicates
00521         return;
00522     }
00523 
00524     //behave like a web browser, i.e. if user goes back from B to A then clicks C, B is forgotten
00525     while (!history.isEmpty() && inHistory != history.count() - 1) {
00526         history.removeLast();
00527     }
00528 
00529     while (history.size() >= MaxHistoryItems) {
00530         history.removeFirst();
00531     }
00532 
00533     HistoryItem item;
00534     item.c = c;
00535     item.fromSearch = fromSearch;
00536     item.searchString = searchString;
00537     history.append(item);
00538 
00539     inHistory = history.count() - 1;
00540     updateBackForwardButtons();
00541 }
00542 
00543 void KCharSelect::KCharSelectPrivate::showFromHistory(int index)
00544 {
00545     Q_ASSERT(index >= 0 && index < history.count());
00546     Q_ASSERT(index != inHistory);
00547 
00548     inHistory = index;
00549     updateBackForwardButtons();
00550 
00551     const HistoryItem &item = history[index];
00552     //kDebug() << "index" << index << "char" << item.c << "fromSearch" << item.fromSearch
00553     //    << "searchString" << item.searchString;
00554 
00555     //avoid adding an item from history into history again
00556     bool oldHistoryEnabled = historyEnabled;
00557     historyEnabled = false;
00558     if (item.fromSearch) {
00559         if (searchLine->text() != item.searchString) {
00560             searchLine->setText(item.searchString);
00561             _k_search();
00562         }
00563         charTable->setChar(item.c);
00564     } else {
00565         searchLine->clear();
00566         q->setCurrentChar(item.c);
00567     }
00568     historyEnabled = oldHistoryEnabled;
00569 }
00570 
00571 void KCharSelect::KCharSelectPrivate::updateBackForwardButtons()
00572 {
00573     backButton->setEnabled(inHistory > 0);
00574     forwardButton->setEnabled(inHistory < history.count() - 1);
00575 }
00576 
00577 void KCharSelect::KCharSelectPrivate::_k_activateSearchLine()
00578 {
00579     searchLine->setFocus();
00580     searchLine->selectAll();
00581 }
00582 
00583 void KCharSelect::KCharSelectPrivate::_k_back()
00584 {
00585     Q_ASSERT(inHistory > 0);
00586     showFromHistory(inHistory - 1);
00587 }
00588 
00589 void KCharSelect::KCharSelectPrivate::_k_forward()
00590 {
00591     Q_ASSERT(inHistory + 1 < history.count());
00592     showFromHistory(inHistory + 1);
00593 }
00594 
00595 void KCharSelect::KCharSelectPrivate::_k_fontSelected()
00596 {
00597     QFont font = fontCombo->currentFont();
00598     font.setPointSize(fontSizeSpinBox->value());
00599     charTable->setFont(font);
00600     emit q->currentFontChanged(font);
00601 }
00602 
00603 void KCharSelect::KCharSelectPrivate::_k_updateCurrentChar(const QChar &c)
00604 {
00605     if (searchMode) {
00606         //we are in search mode. make the two comboboxes show the section & block for this character.
00607         //(when we are not in search mode the current character always belongs to the current section & block.)
00608         int block = s_data->blockIndex(c);
00609         int section = s_data->sectionIndex(block);
00610         sectionCombo->setCurrentIndex(section);
00611         int index = blockCombo->findData(block);
00612         if (index != -1) {
00613             blockCombo->setCurrentIndex(index);
00614         }
00615     }
00616 
00617     if( searchLine)
00618        historyAdd(c, searchMode, searchLine->text());
00619 
00620     _k_slotUpdateUnicode(c);
00621 }
00622 
00623 void KCharSelect::KCharSelectPrivate::_k_slotUpdateUnicode(const QChar &c)
00624 {
00625     QString html = "<p>" + i18n("Character:") + ' ' + s_data->display(c, charTable->font()) + ' ' +
00626                    s_data->formatCode(c.unicode())  + "<br />";
00627 
00628     QString name = s_data->name(c);
00629     if (!name.isEmpty()) {
00630         //is name ever empty? </p> should always be there...
00631         html += i18n("Name: ") + Qt::escape(name) + "</p>";
00632     }
00633     QStringList aliases = s_data->aliases(c);
00634     QStringList notes = s_data->notes(c);
00635     QList<QChar> seeAlso = s_data->seeAlso(c);
00636     QStringList equivalents = s_data->equivalents(c);
00637     QStringList approxEquivalents = s_data->approximateEquivalents(c);
00638     if (!(aliases.isEmpty() && notes.isEmpty() && seeAlso.isEmpty() && equivalents.isEmpty() && approxEquivalents.isEmpty())) {
00639         html += "<p><b>" + i18n("Annotations and Cross References") + "</b></p>";
00640     }
00641 
00642     if (!aliases.isEmpty()) {
00643         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Alias names:") + "</p><ul style=\"margin-top: 0px;\">";
00644         foreach(const QString &alias, aliases) {
00645             html += "<li>" + Qt::escape(alias) + "</li>";
00646         }
00647         html += "</ul>";
00648     }
00649 
00650     if (!notes.isEmpty()) {
00651         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Notes:") + "</p><ul style=\"margin-top: 0px;\">";
00652         foreach(const QString &note, notes) {
00653             html += "<li>" + createLinks(Qt::escape(note)) + "</li>";
00654         }
00655         html += "</ul>";
00656     }
00657 
00658     if (!seeAlso.isEmpty()) {
00659         html += "<p style=\"margin-bottom: 0px;\">" + i18n("See also:") + "</p><ul style=\"margin-top: 0px;\">";
00660         foreach(const QChar &c2, seeAlso) {
00661             html += "<li><a href=\"" + QString::number(c2.unicode(), 16) + "\">";
00662             if (c2.isPrint()) {
00663                 html += "&#" + QString::number(c2.unicode()) + "; ";
00664             }
00665             html += s_data->formatCode(c2.unicode()) + ' ' + Qt::escape(s_data->name(c2)) + "</a></li>";
00666         }
00667         html += "</ul>";
00668     }
00669 
00670     if (!equivalents.isEmpty()) {
00671         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
00672         foreach(const QString &equivalent, equivalents) {
00673             html += "<li>" + createLinks(Qt::escape(equivalent)) + "</li>";
00674         }
00675         html += "</ul>";
00676     }
00677 
00678     if (!approxEquivalents.isEmpty()) {
00679         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Approximate equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
00680         foreach(const QString &approxEquivalent, approxEquivalents) {
00681             html += "<li>" + createLinks(Qt::escape(approxEquivalent)) + "</li>";
00682         }
00683         html += "</ul>";
00684     }
00685 
00686     QStringList unihan = s_data->unihanInfo(c);
00687     if (unihan.count() == 7) {
00688         html += "<p><b>" + i18n("CJK Ideograph Information") + "</b></p><p>";
00689         bool newline = true;
00690         if (!unihan[0].isEmpty()) {
00691             html += i18n("Definition in English: ") + unihan[0];
00692             newline = false;
00693         }
00694         if (!unihan[2].isEmpty()) {
00695             if (!newline) html += "<br>";
00696             html += i18n("Mandarin Pronunciation: ") + unihan[2];
00697             newline = false;
00698         }
00699         if (!unihan[1].isEmpty()) {
00700             if (!newline) html += "<br>";
00701             html += i18n("Cantonese Pronunciation: ") + unihan[1];
00702             newline = false;
00703         }
00704         if (!unihan[6].isEmpty()) {
00705             if (!newline) html += "<br>";
00706             html += i18n("Japanese On Pronunciation: ") + unihan[6];
00707             newline = false;
00708         }
00709         if (!unihan[5].isEmpty()) {
00710             if (!newline) html += "<br>";
00711             html += i18n("Japanese Kun Pronunciation: ") + unihan[5];
00712             newline = false;
00713         }
00714         if (!unihan[3].isEmpty()) {
00715             if (!newline) html += "<br>";
00716             html += i18n("Tang Pronunciation: ") + unihan[3];
00717             newline = false;
00718         }
00719         if (!unihan[4].isEmpty()) {
00720             if (!newline) html += "<br>";
00721             html += i18n("Korean Pronunciation: ") + unihan[4];
00722             newline = false;
00723         }
00724         html += "</p>";
00725     }
00726 
00727     html += "<p><b>" + i18n("General Character Properties") + "</b><br>";
00728     html += i18n("Block: ") + s_data->block(c) + "<br>";
00729     html += i18n("Unicode category: ") + s_data->categoryText(c.category()) + "</p>";
00730 
00731     QByteArray utf8 = QString(c).toUtf8();
00732 
00733     html += "<p><b>" + i18n("Various Useful Representations") + "</b><br>";
00734     html += i18n("UTF-8:");
00735     foreach(unsigned char c, utf8)
00736     html += ' ' + s_data->formatCode(c, 2, "0x");
00737     html += "<br>" + i18n("UTF-16: ") + s_data->formatCode(c.unicode(), 4, "0x") + "<br>";
00738     html += i18n("C octal escaped UTF-8: ");
00739     foreach(unsigned char c, utf8)
00740     html += s_data->formatCode(c, 3, "\\", 8);
00741     html += "<br>" + i18n("XML decimal entity:") + " &amp;#" + QString::number(c.unicode()) + ";</p>";
00742 
00743     detailBrowser->setHtml(html);
00744 }
00745 
00746 QString KCharSelect::KCharSelectPrivate::createLinks(QString s)
00747 {
00748     QRegExp rx("\\b([\\dABCDEF]{4})\\b");
00749 
00750     QStringList chars;
00751     int pos = 0;
00752 
00753     while ((pos = rx.indexIn(s, pos)) != -1) {
00754         chars << rx.cap(1);
00755         pos += rx.matchedLength();
00756     }
00757 
00758     QSet<QString> chars2 = QSet<QString>::fromList(chars);
00759     foreach(const QString &c, chars2) {
00760         int unicode = c.toInt(0, 16);
00761         QString link = "<a href=\"" + c + "\">";
00762         if (QChar(unicode).isPrint()) {
00763             link += "&#" + QString::number(unicode) + ";&nbsp;";
00764         }
00765         link += "U+" + c + ' ';
00766         link += Qt::escape(s_data->name(QChar(unicode))) + "</a>";
00767         s.replace(c, link);
00768     }
00769     return s;
00770 }
00771 
00772 void KCharSelect::KCharSelectPrivate::_k_sectionSelected(int index)
00773 {
00774     blockCombo->clear();
00775     QList<int> blocks = s_data->sectionContents(index);
00776     foreach(int block, blocks) {
00777         blockCombo->addItem(s_data->blockName(block), QVariant(block));
00778     }
00779     blockCombo->setCurrentIndex(0);
00780 }
00781 
00782 void KCharSelect::KCharSelectPrivate::_k_blockSelected(int index)
00783 {
00784     if (index == -1) {
00785         //the combo box has been cleared and is about to be filled again (because the section has changed)
00786         return;
00787     }
00788     if (searchMode) {
00789         //we are in search mode, so don't fill the table with this block.
00790         return;
00791     }
00792 
00793     int block = blockCombo->itemData(index).toInt();
00794     const QList<QChar> contents = s_data->blockContents(block);
00795     if(contents.count() <= index) {
00796         return;
00797     }
00798     charTable->setContents(contents);
00799     emit q->displayedCharsChanged();
00800     charTable->setChar(contents[0]);
00801 }
00802 
00803 void KCharSelect::KCharSelectPrivate::_k_searchEditChanged()
00804 {
00805     if (searchLine->text().isEmpty()) {
00806         sectionCombo->setEnabled(true);
00807         blockCombo->setEnabled(true);
00808 
00809         //upon leaving search mode, keep the same character selected
00810         searchMode = false;
00811         QChar c = charTable->chr();
00812         bool oldHistoryEnabled = historyEnabled;
00813         historyEnabled = false;
00814         _k_blockSelected(blockCombo->currentIndex());
00815         historyEnabled = oldHistoryEnabled;
00816         q->setCurrentChar(c);
00817     } else {
00818         sectionCombo->setEnabled(false);
00819         blockCombo->setEnabled(false);
00820 
00821         int length = searchLine->text().length();
00822         if (length >= 3) {
00823             _k_search();
00824         }
00825     }
00826 }
00827 
00828 void KCharSelect::KCharSelectPrivate::_k_search()
00829 {
00830     if (searchLine->text().isEmpty()) {
00831         return;
00832     }
00833     searchMode = true;
00834     const QList<QChar> contents = s_data->find(searchLine->text());
00835     charTable->setContents(contents);
00836     emit q->displayedCharsChanged();
00837     if (!contents.isEmpty()) {
00838         charTable->setChar(contents[0]);
00839     }
00840 }
00841 
00842 void  KCharSelect::KCharSelectPrivate::_k_linkClicked(QUrl url)
00843 {
00844     QString hex = url.toString();
00845     if (hex.size() > 4) {
00846         return;
00847     }
00848     int unicode = hex.toInt(0, 16);
00849     searchLine->clear();
00850     q->setCurrentChar(QChar(unicode));
00851 }
00852 
00854 
00855 QVariant KCharSelectItemModel::data(const QModelIndex &index, int role) const
00856 {
00857     int pos = m_columns * (index.row()) + index.column();
00858     if (pos >= m_chars.size() || index.row() < 0 || index.column() < 0) {
00859         if (role == Qt::BackgroundColorRole) {
00860             return QVariant(qApp->palette().color(QPalette::Button));
00861         }
00862         return QVariant();
00863     }
00864 
00865     QChar c = m_chars[pos];
00866     if (!index.isValid())
00867         return QVariant();
00868     else if (role == Qt::ToolTipRole) {
00869         QString result = s_data->display(c, m_font) + "<br />" + Qt::escape(s_data->name(c)) + "<br />" +
00870                          i18n("Unicode code point:") + ' ' + s_data->formatCode(c.unicode()) + "<br />" +
00871                          i18nc("Character", "In decimal:") + ' ' + QString::number(c.unicode());
00872         return QVariant(result);
00873     } else if (role == Qt::TextAlignmentRole)
00874         return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
00875     else if (role == Qt::DisplayRole) {
00876         if (c.isPrint())
00877             return QVariant(c);
00878         return QVariant();
00879     } else if (role == Qt::BackgroundColorRole) {
00880         QFontMetrics fm = QFontMetrics(m_font);
00881         if (fm.inFont(c) && c.isPrint())
00882             return QVariant(qApp->palette().color(QPalette::Base));
00883         else
00884             return QVariant(qApp->palette().color(QPalette::Button));
00885     } else if (role == Qt::FontRole)
00886         return QVariant(m_font);
00887     else if (role == CharacterRole) {
00888         return QVariant(c);
00889     }
00890     return QVariant();
00891 }
00892 
00893 #include "kcharselect.moc"
00894 #include "kcharselect_p.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal