• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • 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 #ifndef KDE_NO_DEPRECATED
00304 KCharSelect::KCharSelect(QWidget *parent, const Controls controls)
00305         : QWidget(parent), d(new KCharSelectPrivate(this))
00306 {
00307     init(controls, NULL);
00308 }
00309 #endif
00310 
00311 KCharSelect::KCharSelect(
00312         QWidget *parent
00313         ,KActionCollection *collection
00314         ,const Controls controls)
00315     : QWidget(parent), d(new KCharSelectPrivate(this))
00316 {
00317     init(controls, collection);
00318 }
00319 
00320 void KCharSelect::init(const Controls controls, KActionCollection *collection)
00321 {
00322     if (collection==NULL) {
00323         d->actions = new KActionCollection(this);
00324         d->actions->addAssociatedWidget(this);
00325     } else {
00326         d->actions = collection;
00327     }
00328 
00329     QVBoxLayout *mainLayout = new QVBoxLayout(this);
00330     mainLayout->setMargin(0);
00331     if (SearchLine & controls) {
00332         QHBoxLayout *searchLayout = new QHBoxLayout();
00333         mainLayout->addLayout(searchLayout);
00334         d->searchLine = new KLineEdit(this);
00335         searchLayout->addWidget(d->searchLine);
00336         d->searchLine->setClickMessage(i18n("Enter a search term or character here"));
00337         d->searchLine->setClearButtonShown(true);
00338         d->searchLine->setToolTip(i18n("Enter a search term or character here"));
00339         KStandardAction::find(this, SLOT(_k_activateSearchLine()), d->actions);
00340         connect(d->searchLine, SIGNAL(textChanged(QString)), this, SLOT(_k_searchEditChanged()));
00341         connect(d->searchLine, SIGNAL(returnPressed()), this, SLOT(_k_search()));
00342     }
00343 
00344     if ((SearchLine & controls) && ((FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls))) {
00345         QFrame* line = new QFrame(this);
00346         line->setFrameShape(QFrame::HLine);
00347         line->setFrameShadow(QFrame::Sunken);
00348         mainLayout->addWidget(line);
00349     }
00350 
00351     QHBoxLayout *comboLayout = new QHBoxLayout();
00352 
00353     d->backButton = new QToolButton(this);
00354     comboLayout->addWidget(d->backButton);
00355     d->backButton->setEnabled(false);
00356     d->backButton->setText(i18nc("Goes to previous character", "Previous in History"));
00357     d->backButton->setIcon(KIcon("go-previous"));
00358     d->backButton->setToolTip(i18n("Previous Character in History"));
00359 
00360     d->forwardButton = new QToolButton(this);
00361     comboLayout->addWidget(d->forwardButton);
00362     d->forwardButton->setEnabled(false);
00363     d->forwardButton->setText(i18nc("Goes to next character", "Next in History"));
00364     d->forwardButton->setIcon(KIcon("go-next"));
00365     d->forwardButton->setToolTip(i18n("Next Character in History"));
00366 
00367     KStandardAction::back(d->backButton, SLOT(animateClick()), d->actions);
00368     KStandardAction::forward(d->forwardButton, SLOT(animateClick()), d->actions);
00369     connect(d->backButton, SIGNAL(clicked()), this, SLOT(_k_back()));
00370     connect(d->forwardButton, SIGNAL(clicked()), this, SLOT(_k_forward()));
00371 
00372     d->sectionCombo = new KComboBox(this);
00373     d->sectionCombo->setToolTip(i18n("Select a category"));
00374     comboLayout->addWidget(d->sectionCombo);
00375     d->blockCombo = new KComboBox(this);
00376     d->blockCombo->setToolTip(i18n("Select a block to be displayed"));
00377     d->blockCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
00378     comboLayout->addWidget(d->blockCombo, 1);
00379     d->sectionCombo->addItems(s_data->sectionList());
00380     d->blockCombo->setMinimumWidth(QFontMetrics(QWidget::font()).averageCharWidth() * 25);
00381 
00382     connect(d->sectionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_sectionSelected(int)));
00383     connect(d->blockCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_blockSelected(int)));
00384 
00385     d->fontCombo = new KFontComboBox(this);
00386     comboLayout->addWidget(d->fontCombo);
00387     d->fontCombo->setEditable(true);
00388     d->fontCombo->resize(d->fontCombo->sizeHint());
00389     d->fontCombo->setToolTip(i18n("Set font"));
00390 
00391     d->fontSizeSpinBox = new QSpinBox(this);
00392     comboLayout->addWidget(d->fontSizeSpinBox);
00393     d->fontSizeSpinBox->setValue(QWidget::font().pointSize());
00394     d->fontSizeSpinBox->setRange(1, 400);
00395     d->fontSizeSpinBox->setSingleStep(1);
00396     d->fontSizeSpinBox->setToolTip(i18n("Set font size"));
00397 
00398     connect(d->fontCombo, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(_k_fontSelected()));
00399     connect(d->fontSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(_k_fontSelected()));
00400 
00401     if ((HistoryButtons & controls) || (FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls)) {
00402         mainLayout->addLayout(comboLayout);
00403     }
00404     if (!(HistoryButtons & controls)) {
00405         d->backButton->hide();
00406         d->forwardButton->hide();
00407     }
00408     if (!(FontCombo & controls)) {
00409         d->fontCombo->hide();
00410     }
00411     if (!(FontSize & controls)) {
00412         d->fontSizeSpinBox->hide();
00413     }
00414     if (!(BlockCombos & controls)) {
00415         d->sectionCombo->hide();
00416         d->blockCombo->hide();
00417     }
00418 
00419     QSplitter *splitter = new QSplitter(this);
00420     if ((CharacterTable & controls) || (DetailBrowser & controls)) {
00421         mainLayout->addWidget(splitter);
00422     } else {
00423         splitter->hide();
00424     }
00425     d->charTable = new KCharSelectTable(this, QFont());
00426     if (CharacterTable & controls) {
00427         splitter->addWidget(d->charTable);
00428         d->charTable->setFocus(Qt::OtherFocusReason);
00429     } else {
00430         d->charTable->hide();
00431     }
00432 
00433     const QSize sz(200, 200);
00434     d->charTable->resize(sz);
00435     d->charTable->setMinimumSize(sz);
00436 
00437     d->charTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00438 
00439     setCurrentFont(QFont());
00440 
00441     connect(d->charTable, SIGNAL(focusItemChanged(const QChar &)), this, SLOT(_k_updateCurrentChar(const QChar &)));
00442     connect(d->charTable, SIGNAL(activated(const QChar &)), this, SIGNAL(charSelected(const QChar &)));
00443     connect(d->charTable, SIGNAL(focusItemChanged(const QChar &)),
00444             this, SIGNAL(currentCharChanged(const QChar &)));
00445 
00446     connect(d->charTable, SIGNAL(showCharRequested(QChar)), this, SLOT(setCurrentChar(QChar)));
00447 
00448     d->detailBrowser = new KTextBrowser(this);
00449     if (DetailBrowser & controls) {
00450         splitter->addWidget(d->detailBrowser);
00451     } else {
00452         d->detailBrowser->hide();
00453     }
00454     d->detailBrowser->setOpenLinks(false);
00455     connect(d->detailBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(_k_linkClicked(QUrl)));
00456 
00457     setFocusPolicy(Qt::StrongFocus);
00458     setFocusProxy(d->charTable);
00459     d->_k_sectionSelected(0);
00460     d->_k_blockSelected(0);
00461     setCurrentChar(0x0);
00462 
00463     d->historyEnabled = true;
00464 }
00465 
00466 KCharSelect::~KCharSelect()
00467 {
00468     delete d;
00469 }
00470 
00471 QSize KCharSelect::sizeHint() const
00472 {
00473     return QWidget::sizeHint();
00474 }
00475 
00476 void KCharSelect::setCurrentFont(const QFont &_font)
00477 {
00478     d->fontCombo->setCurrentFont(_font);
00479     d->fontSizeSpinBox->setValue(_font.pointSize());
00480     d->_k_fontSelected();
00481 }
00482 
00483 QChar KCharSelect::currentChar() const
00484 {
00485     return d->charTable->chr();
00486 }
00487 
00488 QFont KCharSelect::currentFont() const
00489 {
00490     return d->charTable->font();
00491 }
00492 
00493 QList<QChar> KCharSelect::displayedChars() const
00494 {
00495     return d->charTable->displayedChars();
00496 }
00497 
00498 void KCharSelect::setCurrentChar(const QChar &c)
00499 {
00500     bool oldHistoryEnabled = d->historyEnabled;
00501     d->historyEnabled = false;
00502     int block = s_data->blockIndex(c);
00503     int section = s_data->sectionIndex(block);
00504     d->sectionCombo->setCurrentIndex(section);
00505     int index = d->blockCombo->findData(block);
00506     if (index != -1) {
00507         d->blockCombo->setCurrentIndex(index);
00508     }
00509     d->historyEnabled = oldHistoryEnabled;
00510     d->charTable->setChar(c);
00511 }
00512 
00513 void KCharSelect::KCharSelectPrivate::historyAdd(const QChar &c, bool fromSearch, const QString &searchString)
00514 {
00515     //kDebug() << "about to add char" << c << "fromSearch" << fromSearch << "searchString" << searchString;
00516 
00517     if (!historyEnabled) {
00518         return;
00519     }
00520 
00521     if (!history.isEmpty() && c == history.last().c) {
00522         //avoid duplicates
00523         return;
00524     }
00525 
00526     //behave like a web browser, i.e. if user goes back from B to A then clicks C, B is forgotten
00527     while (!history.isEmpty() && inHistory != history.count() - 1) {
00528         history.removeLast();
00529     }
00530 
00531     while (history.size() >= MaxHistoryItems) {
00532         history.removeFirst();
00533     }
00534 
00535     HistoryItem item;
00536     item.c = c;
00537     item.fromSearch = fromSearch;
00538     item.searchString = searchString;
00539     history.append(item);
00540 
00541     inHistory = history.count() - 1;
00542     updateBackForwardButtons();
00543 }
00544 
00545 void KCharSelect::KCharSelectPrivate::showFromHistory(int index)
00546 {
00547     Q_ASSERT(index >= 0 && index < history.count());
00548     Q_ASSERT(index != inHistory);
00549 
00550     inHistory = index;
00551     updateBackForwardButtons();
00552 
00553     const HistoryItem &item = history[index];
00554     //kDebug() << "index" << index << "char" << item.c << "fromSearch" << item.fromSearch
00555     //    << "searchString" << item.searchString;
00556 
00557     //avoid adding an item from history into history again
00558     bool oldHistoryEnabled = historyEnabled;
00559     historyEnabled = false;
00560     if (item.fromSearch) {
00561         if (searchLine->text() != item.searchString) {
00562             searchLine->setText(item.searchString);
00563             _k_search();
00564         }
00565         charTable->setChar(item.c);
00566     } else {
00567         searchLine->clear();
00568         q->setCurrentChar(item.c);
00569     }
00570     historyEnabled = oldHistoryEnabled;
00571 }
00572 
00573 void KCharSelect::KCharSelectPrivate::updateBackForwardButtons()
00574 {
00575     backButton->setEnabled(inHistory > 0);
00576     forwardButton->setEnabled(inHistory < history.count() - 1);
00577 }
00578 
00579 void KCharSelect::KCharSelectPrivate::_k_activateSearchLine()
00580 {
00581     searchLine->setFocus();
00582     searchLine->selectAll();
00583 }
00584 
00585 void KCharSelect::KCharSelectPrivate::_k_back()
00586 {
00587     Q_ASSERT(inHistory > 0);
00588     showFromHistory(inHistory - 1);
00589 }
00590 
00591 void KCharSelect::KCharSelectPrivate::_k_forward()
00592 {
00593     Q_ASSERT(inHistory + 1 < history.count());
00594     showFromHistory(inHistory + 1);
00595 }
00596 
00597 void KCharSelect::KCharSelectPrivate::_k_fontSelected()
00598 {
00599     QFont font = fontCombo->currentFont();
00600     font.setPointSize(fontSizeSpinBox->value());
00601     charTable->setFont(font);
00602     emit q->currentFontChanged(font);
00603 }
00604 
00605 void KCharSelect::KCharSelectPrivate::_k_updateCurrentChar(const QChar &c)
00606 {
00607     if (searchMode) {
00608         //we are in search mode. make the two comboboxes show the section & block for this character.
00609         //(when we are not in search mode the current character always belongs to the current section & block.)
00610         int block = s_data->blockIndex(c);
00611         int section = s_data->sectionIndex(block);
00612         sectionCombo->setCurrentIndex(section);
00613         int index = blockCombo->findData(block);
00614         if (index != -1) {
00615             blockCombo->setCurrentIndex(index);
00616         }
00617     }
00618 
00619     if( searchLine)
00620        historyAdd(c, searchMode, searchLine->text());
00621 
00622     _k_slotUpdateUnicode(c);
00623 }
00624 
00625 void KCharSelect::KCharSelectPrivate::_k_slotUpdateUnicode(const QChar &c)
00626 {
00627     QString html = "<p>" + i18n("Character:") + ' ' + s_data->display(c, charTable->font()) + ' ' +
00628                    s_data->formatCode(c.unicode())  + "<br />";
00629 
00630     QString name = s_data->name(c);
00631     if (!name.isEmpty()) {
00632         //is name ever empty? </p> should always be there...
00633         html += i18n("Name: ") + Qt::escape(name) + "</p>";
00634     }
00635     QStringList aliases = s_data->aliases(c);
00636     QStringList notes = s_data->notes(c);
00637     QList<QChar> seeAlso = s_data->seeAlso(c);
00638     QStringList equivalents = s_data->equivalents(c);
00639     QStringList approxEquivalents = s_data->approximateEquivalents(c);
00640     if (!(aliases.isEmpty() && notes.isEmpty() && seeAlso.isEmpty() && equivalents.isEmpty() && approxEquivalents.isEmpty())) {
00641         html += "<p><b>" + i18n("Annotations and Cross References") + "</b></p>";
00642     }
00643 
00644     if (!aliases.isEmpty()) {
00645         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Alias names:") + "</p><ul style=\"margin-top: 0px;\">";
00646         foreach(const QString &alias, aliases) {
00647             html += "<li>" + Qt::escape(alias) + "</li>";
00648         }
00649         html += "</ul>";
00650     }
00651 
00652     if (!notes.isEmpty()) {
00653         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Notes:") + "</p><ul style=\"margin-top: 0px;\">";
00654         foreach(const QString &note, notes) {
00655             html += "<li>" + createLinks(Qt::escape(note)) + "</li>";
00656         }
00657         html += "</ul>";
00658     }
00659 
00660     if (!seeAlso.isEmpty()) {
00661         html += "<p style=\"margin-bottom: 0px;\">" + i18n("See also:") + "</p><ul style=\"margin-top: 0px;\">";
00662         foreach(const QChar &c2, seeAlso) {
00663             html += "<li><a href=\"" + QString::number(c2.unicode(), 16) + "\">";
00664             if (c2.isPrint()) {
00665                 html += "&#" + QString::number(c2.unicode()) + "; ";
00666             }
00667             html += s_data->formatCode(c2.unicode()) + ' ' + Qt::escape(s_data->name(c2)) + "</a></li>";
00668         }
00669         html += "</ul>";
00670     }
00671 
00672     if (!equivalents.isEmpty()) {
00673         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
00674         foreach(const QString &equivalent, equivalents) {
00675             html += "<li>" + createLinks(Qt::escape(equivalent)) + "</li>";
00676         }
00677         html += "</ul>";
00678     }
00679 
00680     if (!approxEquivalents.isEmpty()) {
00681         html += "<p style=\"margin-bottom: 0px;\">" + i18n("Approximate equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
00682         foreach(const QString &approxEquivalent, approxEquivalents) {
00683             html += "<li>" + createLinks(Qt::escape(approxEquivalent)) + "</li>";
00684         }
00685         html += "</ul>";
00686     }
00687 
00688     QStringList unihan = s_data->unihanInfo(c);
00689     if (unihan.count() == 7) {
00690         html += "<p><b>" + i18n("CJK Ideograph Information") + "</b></p><p>";
00691         bool newline = true;
00692         if (!unihan[0].isEmpty()) {
00693             html += i18n("Definition in English: ") + unihan[0];
00694             newline = false;
00695         }
00696         if (!unihan[2].isEmpty()) {
00697             if (!newline) html += "<br>";
00698             html += i18n("Mandarin Pronunciation: ") + unihan[2];
00699             newline = false;
00700         }
00701         if (!unihan[1].isEmpty()) {
00702             if (!newline) html += "<br>";
00703             html += i18n("Cantonese Pronunciation: ") + unihan[1];
00704             newline = false;
00705         }
00706         if (!unihan[6].isEmpty()) {
00707             if (!newline) html += "<br>";
00708             html += i18n("Japanese On Pronunciation: ") + unihan[6];
00709             newline = false;
00710         }
00711         if (!unihan[5].isEmpty()) {
00712             if (!newline) html += "<br>";
00713             html += i18n("Japanese Kun Pronunciation: ") + unihan[5];
00714             newline = false;
00715         }
00716         if (!unihan[3].isEmpty()) {
00717             if (!newline) html += "<br>";
00718             html += i18n("Tang Pronunciation: ") + unihan[3];
00719             newline = false;
00720         }
00721         if (!unihan[4].isEmpty()) {
00722             if (!newline) html += "<br>";
00723             html += i18n("Korean Pronunciation: ") + unihan[4];
00724             newline = false;
00725         }
00726         html += "</p>";
00727     }
00728 
00729     html += "<p><b>" + i18n("General Character Properties") + "</b><br>";
00730     html += i18n("Block: ") + s_data->block(c) + "<br>";
00731     html += i18n("Unicode category: ") + s_data->categoryText(c.category()) + "</p>";
00732 
00733     QByteArray utf8 = QString(c).toUtf8();
00734 
00735     html += "<p><b>" + i18n("Various Useful Representations") + "</b><br>";
00736     html += i18n("UTF-8:");
00737     foreach(unsigned char c, utf8)
00738     html += ' ' + s_data->formatCode(c, 2, "0x");
00739     html += "<br>" + i18n("UTF-16: ") + s_data->formatCode(c.unicode(), 4, "0x") + "<br>";
00740     html += i18n("C octal escaped UTF-8: ");
00741     foreach(unsigned char c, utf8)
00742     html += s_data->formatCode(c, 3, "\\", 8);
00743     html += "<br>" + i18n("XML decimal entity:") + " &amp;#" + QString::number(c.unicode()) + ";</p>";
00744 
00745     detailBrowser->setHtml(html);
00746 }
00747 
00748 QString KCharSelect::KCharSelectPrivate::createLinks(QString s)
00749 {
00750     QRegExp rx("\\b([\\dABCDEF]{4})\\b");
00751 
00752     QStringList chars;
00753     int pos = 0;
00754 
00755     while ((pos = rx.indexIn(s, pos)) != -1) {
00756         chars << rx.cap(1);
00757         pos += rx.matchedLength();
00758     }
00759 
00760     QSet<QString> chars2 = QSet<QString>::fromList(chars);
00761     foreach(const QString &c, chars2) {
00762         int unicode = c.toInt(0, 16);
00763         QString link = "<a href=\"" + c + "\">";
00764         if (QChar(unicode).isPrint()) {
00765             link += "&#" + QString::number(unicode) + ";&nbsp;";
00766         }
00767         link += "U+" + c + ' ';
00768         link += Qt::escape(s_data->name(QChar(unicode))) + "</a>";
00769         s.replace(c, link);
00770     }
00771     return s;
00772 }
00773 
00774 void KCharSelect::KCharSelectPrivate::_k_sectionSelected(int index)
00775 {
00776     blockCombo->clear();
00777     QList<int> blocks = s_data->sectionContents(index);
00778     foreach(int block, blocks) {
00779         blockCombo->addItem(s_data->blockName(block), QVariant(block));
00780     }
00781     blockCombo->setCurrentIndex(0);
00782 }
00783 
00784 void KCharSelect::KCharSelectPrivate::_k_blockSelected(int index)
00785 {
00786     if (index == -1) {
00787         //the combo box has been cleared and is about to be filled again (because the section has changed)
00788         return;
00789     }
00790     if (searchMode) {
00791         //we are in search mode, so don't fill the table with this block.
00792         return;
00793     }
00794 
00795     int block = blockCombo->itemData(index).toInt();
00796     const QList<QChar> contents = s_data->blockContents(block);
00797     if(contents.count() <= index) {
00798         return;
00799     }
00800     charTable->setContents(contents);
00801     emit q->displayedCharsChanged();
00802     charTable->setChar(contents[0]);
00803 }
00804 
00805 void KCharSelect::KCharSelectPrivate::_k_searchEditChanged()
00806 {
00807     if (searchLine->text().isEmpty()) {
00808         sectionCombo->setEnabled(true);
00809         blockCombo->setEnabled(true);
00810 
00811         //upon leaving search mode, keep the same character selected
00812         searchMode = false;
00813         QChar c = charTable->chr();
00814         bool oldHistoryEnabled = historyEnabled;
00815         historyEnabled = false;
00816         _k_blockSelected(blockCombo->currentIndex());
00817         historyEnabled = oldHistoryEnabled;
00818         q->setCurrentChar(c);
00819     } else {
00820         sectionCombo->setEnabled(false);
00821         blockCombo->setEnabled(false);
00822 
00823         int length = searchLine->text().length();
00824         if (length >= 3) {
00825             _k_search();
00826         }
00827     }
00828 }
00829 
00830 void KCharSelect::KCharSelectPrivate::_k_search()
00831 {
00832     if (searchLine->text().isEmpty()) {
00833         return;
00834     }
00835     searchMode = true;
00836     const QList<QChar> contents = s_data->find(searchLine->text());
00837     charTable->setContents(contents);
00838     emit q->displayedCharsChanged();
00839     if (!contents.isEmpty()) {
00840         charTable->setChar(contents[0]);
00841     }
00842 }
00843 
00844 void  KCharSelect::KCharSelectPrivate::_k_linkClicked(QUrl url)
00845 {
00846     QString hex = url.toString();
00847     if (hex.size() > 4) {
00848         return;
00849     }
00850     int unicode = hex.toInt(0, 16);
00851     searchLine->clear();
00852     q->setCurrentChar(QChar(unicode));
00853 }
00854 
00856 
00857 QVariant KCharSelectItemModel::data(const QModelIndex &index, int role) const
00858 {
00859     int pos = m_columns * (index.row()) + index.column();
00860     if (pos >= m_chars.size() || index.row() < 0 || index.column() < 0) {
00861         if (role == Qt::BackgroundColorRole) {
00862             return QVariant(qApp->palette().color(QPalette::Button));
00863         }
00864         return QVariant();
00865     }
00866 
00867     QChar c = m_chars[pos];
00868     if (!index.isValid())
00869         return QVariant();
00870     else if (role == Qt::ToolTipRole) {
00871         QString result = s_data->display(c, m_font) + "<br />" + Qt::escape(s_data->name(c)) + "<br />" +
00872                          i18n("Unicode code point:") + ' ' + s_data->formatCode(c.unicode()) + "<br />" +
00873                          i18nc("Character", "In decimal:") + ' ' + QString::number(c.unicode());
00874         return QVariant(result);
00875     } else if (role == Qt::TextAlignmentRole)
00876         return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
00877     else if (role == Qt::DisplayRole) {
00878         if (c.isPrint())
00879             return QVariant(c);
00880         return QVariant();
00881     } else if (role == Qt::BackgroundColorRole) {
00882         QFontMetrics fm = QFontMetrics(m_font);
00883         if (fm.inFont(c) && c.isPrint())
00884             return QVariant(qApp->palette().color(QPalette::Base));
00885         else
00886             return QVariant(qApp->palette().color(QPalette::Button));
00887     } else if (role == Qt::FontRole)
00888         return QVariant(m_font);
00889     else if (role == CharacterRole) {
00890         return QVariant(c);
00891     }
00892     return QVariant();
00893 }
00894 
00895 #include "kcharselect.moc"
00896 #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
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
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