• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDEUI

  • kdeui
  • widgets
kcharselect.cpp
Go to the documentation of this file.
1/* This file is part of the KDE libraries
2
3 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "kcharselect.h"
22
23#include "kcharselect_p.h"
24
25#include <QtGui/QActionEvent>
26#include <QtGui/QDoubleSpinBox>
27#include <QtGui/QHeaderView>
28#include <QtGui/QBoxLayout>
29#include <QtGui/QShortcut>
30#include <QtGui/QSplitter>
31#include <QtGui/QPushButton>
32#include <QtGui/QToolButton>
33
34#include <kcombobox.h>
35#include <kdebug.h>
36#include <kdialog.h>
37#include <klocale.h>
38#include <klineedit.h>
39#include <ktextbrowser.h>
40#include <kfontcombobox.h>
41#include <kactioncollection.h>
42#include <kstandardaction.h>
43
44K_GLOBAL_STATIC(KCharSelectData, s_data)
45
46class KCharSelectTablePrivate
47{
48public:
49 KCharSelectTablePrivate(KCharSelectTable *q): q(q), model(0)
50 {}
51
52 KCharSelectTable *q;
53
54 QFont font;
55 KCharSelectItemModel *model;
56 QList<QChar> chars;
57 QChar chr;
58
59 void _k_resizeCells();
60 void _k_doubleClicked(const QModelIndex & index);
61 void _k_slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected);
62};
63
64class KCharSelect::KCharSelectPrivate
65{
66public:
67 struct HistoryItem
68 {
69 QChar c;
70 bool fromSearch;
71 QString searchString;
72 };
73
74 enum { MaxHistoryItems = 100 };
75
76 KCharSelectPrivate(KCharSelect *q)
77 : q(q)
78 ,searchLine(0)
79 ,searchMode(false)
80 ,historyEnabled(false)
81 ,inHistory(0)
82 ,actions(NULL)
83 {
84 }
85
86 KCharSelect *q;
87
88 QToolButton *backButton;
89 QToolButton *forwardButton;
90 KLineEdit* searchLine;
91 KFontComboBox *fontCombo;
92 QSpinBox *fontSizeSpinBox;
93 QComboBox *sectionCombo;
94 QComboBox *blockCombo;
95 KCharSelectTable *charTable;
96 KTextBrowser *detailBrowser;
97
98 bool searchMode; //a search is active
99 bool historyEnabled;
100 int inHistory; //index of current char in history
101 QList<HistoryItem> history;
102 KActionCollection* actions;
103
104 QString createLinks(QString s);
105 void historyAdd(const QChar &c, bool fromSearch, const QString &searchString);
106 void showFromHistory(int index);
107 void updateBackForwardButtons();
108 void _k_activateSearchLine();
109 void _k_back();
110 void _k_forward();
111 void _k_fontSelected();
112 void _k_updateCurrentChar(const QChar &c);
113 void _k_slotUpdateUnicode(const QChar &c);
114 void _k_sectionSelected(int index);
115 void _k_blockSelected(int index);
116 void _k_searchEditChanged();
117 void _k_search();
118 void _k_linkClicked(QUrl url);
119};
120
121/******************************************************************/
122/* Class: KCharSelectTable */
123/******************************************************************/
124
125KCharSelectTable::KCharSelectTable(QWidget *parent, const QFont &_font)
126 : QTableView(parent), d(new KCharSelectTablePrivate(this))
127{
128 d->font = _font;
129
130 setTabKeyNavigation(false);
131 setSelectionMode(QAbstractItemView::SingleSelection);
132 QPalette _palette;
133 _palette.setColor(backgroundRole(), palette().color(QPalette::Base));
134 setPalette(_palette);
135 verticalHeader()->setVisible(false);
136 verticalHeader()->setResizeMode(QHeaderView::Custom);
137 horizontalHeader()->setVisible(false);
138 horizontalHeader()->setResizeMode(QHeaderView::Custom);
139
140 setFocusPolicy(Qt::StrongFocus);
141 setDragEnabled(true);
142 setAcceptDrops(true);
143 setDropIndicatorShown(false);
144 setDragDropMode(QAbstractItemView::DragDrop);
145
146 connect(this, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_k_doubleClicked(QModelIndex)));
147
148 d->_k_resizeCells();
149}
150
151KCharSelectTable::~KCharSelectTable()
152{
153 delete d;
154}
155
156void KCharSelectTable::setFont(const QFont &_font)
157{
158 QTableView::setFont(_font);
159 d->font = _font;
160 if (d->model) d->model->setFont(_font);
161 d->_k_resizeCells();
162}
163
164QChar KCharSelectTable::chr()
165{
166 return d->chr;
167}
168
169QFont KCharSelectTable::font() const
170{
171 return d->font;
172}
173
174QList<QChar> KCharSelectTable::displayedChars() const
175{
176 return d->chars;
177}
178
179void KCharSelectTable::setChar(const QChar &c)
180{
181 int pos = d->chars.indexOf(c);
182 if (pos != -1) {
183 const int columnCount = model()->columnCount();
184 setCurrentIndex(model()->index(pos / columnCount, pos % columnCount));
185 }
186}
187
188void KCharSelectTable::setContents(QList<QChar> chars)
189{
190 d->chars = chars;
191
192 KCharSelectItemModel *m = d->model;
193 d->model = new KCharSelectItemModel(chars, d->font, this);
194 setModel(d->model);
195 d->_k_resizeCells();
196 QItemSelectionModel *selectionModel = new QItemSelectionModel(d->model);
197 setSelectionModel(selectionModel);
198 setSelectionBehavior(QAbstractItemView::SelectItems);
199 setSelectionMode(QAbstractItemView::SingleSelection);
200 connect(selectionModel, SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(_k_slotSelectionChanged(QItemSelection,QItemSelection)));
201 connect(d->model, SIGNAL(showCharRequested(QChar)), this, SIGNAL(showCharRequested(QChar)));
202 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)
203}
204
205void KCharSelectTable::scrollTo(const QModelIndex & index, ScrollHint hint)
206{
207 // this prevents horizontal scrolling when selecting a character in the last column
208 if (index.isValid() && index.column() != 0) {
209 QTableView::scrollTo(d->model->index(index.row(), 0), hint);
210 } else {
211 QTableView::scrollTo(index, hint);
212 }
213}
214
215void KCharSelectTablePrivate::_k_slotSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected)
216{
217 Q_UNUSED(deselected);
218 if (!model || selected.indexes().isEmpty())
219 return;
220 QVariant temp = model->data(selected.indexes().at(0), KCharSelectItemModel::CharacterRole);
221 if (temp.type() != QVariant::Char)
222 return;
223 QChar c = temp.toChar();
224 chr = c;
225 emit q->focusItemChanged(c);
226}
227
228void KCharSelectTable::resizeEvent(QResizeEvent * e)
229{
230 QTableView::resizeEvent(e);
231 if (e->size().width() != e->oldSize().width()) {
232 d->_k_resizeCells();
233 }
234}
235
236void KCharSelectTablePrivate::_k_resizeCells()
237{
238 KCharSelectItemModel *model = static_cast<KCharSelectItemModel*>(q->model());
239 if (!model) return;
240
241 const int viewportWidth = q->viewport()->size().width();
242
243 QFontMetrics fontMetrics(font);
244
245 // Determine the max width of the displayed characters
246 // fontMetrics.maxWidth() doesn't help because of font fallbacks
247 // (testcase: Malayalam characters)
248 int maxCharWidth = 0;
249 const QList<QChar> chars = model->chars();
250 for (int i = 0 ; i < chars.size(); ++i) {
251 maxCharWidth = qMax(maxCharWidth, fontMetrics.width(chars.at(i)));
252 }
253 // Avoid too narrow cells
254 maxCharWidth = qMax(maxCharWidth, 2 * fontMetrics.xHeight());
255 maxCharWidth = qMax(maxCharWidth, fontMetrics.height());
256 // Add the necessary padding, trying to match the delegate
257 const int textMargin = q->style()->pixelMetric(QStyle::PM_FocusFrameHMargin, 0, q) + 1;
258 maxCharWidth += 2 * textMargin;
259
260 const int columns = qMax(1, viewportWidth / maxCharWidth);
261 model->setColumnCount(columns);
262
263 const QChar oldChar = q->chr();
264
265 const int new_w = viewportWidth / columns;
266 const int rows = model->rowCount();
267 q->setUpdatesEnabled(false);
268 QHeaderView *hHeader = q->horizontalHeader();
269 const int spaceLeft = viewportWidth - new_w * columns;
270 for (int i = 0 ; i <= columns; i++ ) {
271 if (i < spaceLeft) {
272 hHeader->resizeSection(i, new_w + 1);
273 } else {
274 hHeader->resizeSection(i, new_w);
275 }
276 }
277
278 QHeaderView *vHeader = q->verticalHeader();
279#ifdef Q_WS_WIN
280 int new_h = fontMetrics.lineSpacing() + 1;
281#else
282 int new_h = fontMetrics.xHeight() * 3;
283#endif
284 const int fontHeight = fontMetrics.height();
285 if (new_h < 5 || new_h < 4 + fontHeight) {
286 new_h = qMax(5, 4 + fontHeight);
287 }
288 for (int i = 0;i < rows;i++) {
289 vHeader->resizeSection(i, new_h);
290 }
291
292 q->setUpdatesEnabled(true);
293 q->setChar(oldChar);
294}
295
296void KCharSelectTablePrivate::_k_doubleClicked(const QModelIndex & index)
297{
298 QChar c = model->data(index, KCharSelectItemModel::CharacterRole).toChar();
299 if (s_data->isPrint(c)) {
300 emit q->activated(c);
301 }
302}
303
304void KCharSelectTable::keyPressEvent(QKeyEvent *e)
305{
306 if (d->model)
307 switch (e->key()) {
308 case Qt::Key_Space:
309 emit activated(' ');
310 return;
311 break;
312 case Qt::Key_Enter: case Qt::Key_Return: {
313 if (!currentIndex().isValid()) return;
314 QChar c = d->model->data(currentIndex(), KCharSelectItemModel::CharacterRole).toChar();
315 if (s_data->isPrint(c)) {
316 emit activated(c);
317 }
318 }
319 return;
320 break;
321 }
322 QTableView::keyPressEvent(e);
323}
324
325
326/******************************************************************/
327/* Class: KCharSelect */
328/******************************************************************/
329
330#ifndef KDE_NO_DEPRECATED
331KCharSelect::KCharSelect(QWidget *parent, const Controls controls)
332 : QWidget(parent), d(new KCharSelectPrivate(this))
333{
334 init(controls, NULL);
335}
336#endif
337
338KCharSelect::KCharSelect(
339 QWidget *parent
340 ,KActionCollection *collection
341 ,const Controls controls)
342 : QWidget(parent), d(new KCharSelectPrivate(this))
343{
344 init(controls, collection);
345}
346
347void KCharSelect::init(const Controls controls, KActionCollection *collection)
348{
349 if (collection==NULL) {
350 d->actions = new KActionCollection(this);
351 d->actions->addAssociatedWidget(this);
352 } else {
353 d->actions = collection;
354 }
355
356 QVBoxLayout *mainLayout = new QVBoxLayout(this);
357 mainLayout->setMargin(0);
358 if (SearchLine & controls) {
359 QHBoxLayout *searchLayout = new QHBoxLayout();
360 mainLayout->addLayout(searchLayout);
361 d->searchLine = new KLineEdit(this);
362 searchLayout->addWidget(d->searchLine);
363 d->searchLine->setClickMessage(i18n("Enter a search term or character here"));
364 d->searchLine->setClearButtonShown(true);
365 d->searchLine->setToolTip(i18n("Enter a search term or character here"));
366 KStandardAction::find(this, SLOT(_k_activateSearchLine()), d->actions);
367 connect(d->searchLine, SIGNAL(textChanged(QString)), this, SLOT(_k_searchEditChanged()));
368 connect(d->searchLine, SIGNAL(returnPressed()), this, SLOT(_k_search()));
369 }
370
371 if ((SearchLine & controls) && ((FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls))) {
372 QFrame* line = new QFrame(this);
373 line->setFrameShape(QFrame::HLine);
374 line->setFrameShadow(QFrame::Sunken);
375 mainLayout->addWidget(line);
376 }
377
378 QHBoxLayout *comboLayout = new QHBoxLayout();
379
380 d->backButton = new QToolButton(this);
381 comboLayout->addWidget(d->backButton);
382 d->backButton->setEnabled(false);
383 d->backButton->setText(i18nc("Goes to previous character", "Previous in History"));
384 d->backButton->setIcon(KIcon("go-previous"));
385 d->backButton->setToolTip(i18n("Previous Character in History"));
386
387 d->forwardButton = new QToolButton(this);
388 comboLayout->addWidget(d->forwardButton);
389 d->forwardButton->setEnabled(false);
390 d->forwardButton->setText(i18nc("Goes to next character", "Next in History"));
391 d->forwardButton->setIcon(KIcon("go-next"));
392 d->forwardButton->setToolTip(i18n("Next Character in History"));
393
394 KStandardAction::back(d->backButton, SLOT(animateClick()), d->actions);
395 KStandardAction::forward(d->forwardButton, SLOT(animateClick()), d->actions);
396 connect(d->backButton, SIGNAL(clicked()), this, SLOT(_k_back()));
397 connect(d->forwardButton, SIGNAL(clicked()), this, SLOT(_k_forward()));
398
399 d->sectionCombo = new KComboBox(this);
400 d->sectionCombo->setToolTip(i18n("Select a category"));
401 comboLayout->addWidget(d->sectionCombo);
402 d->blockCombo = new KComboBox(this);
403 d->blockCombo->setToolTip(i18n("Select a block to be displayed"));
404 d->blockCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
405 comboLayout->addWidget(d->blockCombo, 1);
406 d->sectionCombo->addItems(s_data->sectionList());
407 d->blockCombo->setMinimumWidth(QFontMetrics(QWidget::font()).averageCharWidth() * 25);
408
409 connect(d->sectionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_sectionSelected(int)));
410 connect(d->blockCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(_k_blockSelected(int)));
411
412 d->fontCombo = new KFontComboBox(this);
413 comboLayout->addWidget(d->fontCombo);
414 d->fontCombo->setEditable(true);
415 d->fontCombo->resize(d->fontCombo->sizeHint());
416 d->fontCombo->setToolTip(i18n("Set font"));
417
418 d->fontSizeSpinBox = new QSpinBox(this);
419 comboLayout->addWidget(d->fontSizeSpinBox);
420 d->fontSizeSpinBox->setValue(QWidget::font().pointSize());
421 d->fontSizeSpinBox->setRange(1, 400);
422 d->fontSizeSpinBox->setSingleStep(1);
423 d->fontSizeSpinBox->setToolTip(i18n("Set font size"));
424
425 connect(d->fontCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(_k_fontSelected()));
426 connect(d->fontSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(_k_fontSelected()));
427
428 if ((HistoryButtons & controls) || (FontCombo & controls) || (FontSize & controls) || (BlockCombos & controls)) {
429 mainLayout->addLayout(comboLayout);
430 }
431 if (!(HistoryButtons & controls)) {
432 d->backButton->hide();
433 d->forwardButton->hide();
434 }
435 if (!(FontCombo & controls)) {
436 d->fontCombo->hide();
437 }
438 if (!(FontSize & controls)) {
439 d->fontSizeSpinBox->hide();
440 }
441 if (!(BlockCombos & controls)) {
442 d->sectionCombo->hide();
443 d->blockCombo->hide();
444 }
445
446 QSplitter *splitter = new QSplitter(this);
447 if ((CharacterTable & controls) || (DetailBrowser & controls)) {
448 mainLayout->addWidget(splitter);
449 } else {
450 splitter->hide();
451 }
452 d->charTable = new KCharSelectTable(this, QFont());
453 if (CharacterTable & controls) {
454 splitter->addWidget(d->charTable);
455 d->charTable->setFocus(Qt::OtherFocusReason);
456 } else {
457 d->charTable->hide();
458 }
459
460 const QSize sz(200, 200);
461 d->charTable->resize(sz);
462 d->charTable->setMinimumSize(sz);
463
464 d->charTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
465
466 setCurrentFont(QFont());
467
468 connect(d->charTable, SIGNAL(focusItemChanged(QChar)), this, SLOT(_k_updateCurrentChar(QChar)));
469 connect(d->charTable, SIGNAL(activated(QChar)), this, SIGNAL(charSelected(QChar)));
470 connect(d->charTable, SIGNAL(focusItemChanged(QChar)),
471 this, SIGNAL(currentCharChanged(QChar)));
472
473 connect(d->charTable, SIGNAL(showCharRequested(QChar)), this, SLOT(setCurrentChar(QChar)));
474
475 d->detailBrowser = new KTextBrowser(this);
476 if (DetailBrowser & controls) {
477 splitter->addWidget(d->detailBrowser);
478 } else {
479 d->detailBrowser->hide();
480 }
481 d->detailBrowser->setOpenLinks(false);
482 connect(d->detailBrowser, SIGNAL(anchorClicked(QUrl)), this, SLOT(_k_linkClicked(QUrl)));
483
484 setFocusPolicy(Qt::StrongFocus);
485 setFocusProxy(d->charTable);
486 d->_k_sectionSelected(0);
487 d->_k_blockSelected(0);
488 setCurrentChar(0x0);
489
490 d->historyEnabled = true;
491}
492
493KCharSelect::~KCharSelect()
494{
495 delete d;
496}
497
498QSize KCharSelect::sizeHint() const
499{
500 return QWidget::sizeHint();
501}
502
503void KCharSelect::setCurrentFont(const QFont &_font)
504{
505 d->fontCombo->setCurrentFont(_font);
506 d->fontSizeSpinBox->setValue(_font.pointSize());
507 d->_k_fontSelected();
508}
509
510QChar KCharSelect::currentChar() const
511{
512 return d->charTable->chr();
513}
514
515QFont KCharSelect::currentFont() const
516{
517 return d->charTable->font();
518}
519
520QList<QChar> KCharSelect::displayedChars() const
521{
522 return d->charTable->displayedChars();
523}
524
525void KCharSelect::setCurrentChar(const QChar &c)
526{
527 bool oldHistoryEnabled = d->historyEnabled;
528 d->historyEnabled = false;
529 int block = s_data->blockIndex(c);
530 int section = s_data->sectionIndex(block);
531 d->sectionCombo->setCurrentIndex(section);
532 int index = d->blockCombo->findData(block);
533 if (index != -1) {
534 d->blockCombo->setCurrentIndex(index);
535 }
536 d->historyEnabled = oldHistoryEnabled;
537 d->charTable->setChar(c);
538}
539
540void KCharSelect::KCharSelectPrivate::historyAdd(const QChar &c, bool fromSearch, const QString &searchString)
541{
542 //kDebug() << "about to add char" << c << "fromSearch" << fromSearch << "searchString" << searchString;
543
544 if (!historyEnabled) {
545 return;
546 }
547
548 if (!history.isEmpty() && c == history.last().c) {
549 //avoid duplicates
550 return;
551 }
552
553 //behave like a web browser, i.e. if user goes back from B to A then clicks C, B is forgotten
554 while (!history.isEmpty() && inHistory != history.count() - 1) {
555 history.removeLast();
556 }
557
558 while (history.size() >= MaxHistoryItems) {
559 history.removeFirst();
560 }
561
562 HistoryItem item;
563 item.c = c;
564 item.fromSearch = fromSearch;
565 item.searchString = searchString;
566 history.append(item);
567
568 inHistory = history.count() - 1;
569 updateBackForwardButtons();
570}
571
572void KCharSelect::KCharSelectPrivate::showFromHistory(int index)
573{
574 Q_ASSERT(index >= 0 && index < history.count());
575 Q_ASSERT(index != inHistory);
576
577 inHistory = index;
578 updateBackForwardButtons();
579
580 const HistoryItem &item = history[index];
581 //kDebug() << "index" << index << "char" << item.c << "fromSearch" << item.fromSearch
582 // << "searchString" << item.searchString;
583
584 //avoid adding an item from history into history again
585 bool oldHistoryEnabled = historyEnabled;
586 historyEnabled = false;
587 if (item.fromSearch) {
588 if (searchLine->text() != item.searchString) {
589 searchLine->setText(item.searchString);
590 _k_search();
591 }
592 charTable->setChar(item.c);
593 } else {
594 searchLine->clear();
595 q->setCurrentChar(item.c);
596 }
597 historyEnabled = oldHistoryEnabled;
598}
599
600void KCharSelect::KCharSelectPrivate::updateBackForwardButtons()
601{
602 backButton->setEnabled(inHistory > 0);
603 forwardButton->setEnabled(inHistory < history.count() - 1);
604}
605
606void KCharSelect::KCharSelectPrivate::_k_activateSearchLine()
607{
608 searchLine->setFocus();
609 searchLine->selectAll();
610}
611
612void KCharSelect::KCharSelectPrivate::_k_back()
613{
614 Q_ASSERT(inHistory > 0);
615 showFromHistory(inHistory - 1);
616}
617
618void KCharSelect::KCharSelectPrivate::_k_forward()
619{
620 Q_ASSERT(inHistory + 1 < history.count());
621 showFromHistory(inHistory + 1);
622}
623
624void KCharSelect::KCharSelectPrivate::_k_fontSelected()
625{
626 QFont font = fontCombo->currentFont();
627 font.setPointSize(fontSizeSpinBox->value());
628 charTable->setFont(font);
629 emit q->currentFontChanged(font);
630}
631
632void KCharSelect::KCharSelectPrivate::_k_updateCurrentChar(const QChar &c)
633{
634 if (searchMode) {
635 //we are in search mode. make the two comboboxes show the section & block for this character.
636 //(when we are not in search mode the current character always belongs to the current section & block.)
637 int block = s_data->blockIndex(c);
638 int section = s_data->sectionIndex(block);
639 sectionCombo->setCurrentIndex(section);
640 int index = blockCombo->findData(block);
641 if (index != -1) {
642 blockCombo->setCurrentIndex(index);
643 }
644 }
645
646 if( searchLine)
647 historyAdd(c, searchMode, searchLine->text());
648
649 _k_slotUpdateUnicode(c);
650}
651
652void KCharSelect::KCharSelectPrivate::_k_slotUpdateUnicode(const QChar &c)
653{
654 QString html = "<p>" + i18n("Character:") + ' ' + s_data->display(c, charTable->font()) + ' ' +
655 s_data->formatCode(c.unicode()) + "<br />";
656
657 QString name = s_data->name(c);
658 if (!name.isEmpty()) {
659 //is name ever empty? </p> should always be there...
660 html += i18n("Name: ") + Qt::escape(name) + "</p>";
661 }
662 QStringList aliases = s_data->aliases(c);
663 QStringList notes = s_data->notes(c);
664 QList<QChar> seeAlso = s_data->seeAlso(c);
665 QStringList equivalents = s_data->equivalents(c);
666 QStringList approxEquivalents = s_data->approximateEquivalents(c);
667 if (!(aliases.isEmpty() && notes.isEmpty() && seeAlso.isEmpty() && equivalents.isEmpty() && approxEquivalents.isEmpty())) {
668 html += "<p><b>" + i18n("Annotations and Cross References") + "</b></p>";
669 }
670
671 if (!aliases.isEmpty()) {
672 html += "<p style=\"margin-bottom: 0px;\">" + i18n("Alias names:") + "</p><ul style=\"margin-top: 0px;\">";
673 foreach(const QString &alias, aliases) {
674 html += "<li>" + Qt::escape(alias) + "</li>";
675 }
676 html += "</ul>";
677 }
678
679 if (!notes.isEmpty()) {
680 html += "<p style=\"margin-bottom: 0px;\">" + i18n("Notes:") + "</p><ul style=\"margin-top: 0px;\">";
681 foreach(const QString &note, notes) {
682 html += "<li>" + createLinks(Qt::escape(note)) + "</li>";
683 }
684 html += "</ul>";
685 }
686
687 if (!seeAlso.isEmpty()) {
688 html += "<p style=\"margin-bottom: 0px;\">" + i18n("See also:") + "</p><ul style=\"margin-top: 0px;\">";
689 foreach(const QChar &c2, seeAlso) {
690 html += "<li><a href=\"" + QString::number(c2.unicode(), 16) + "\">";
691 if (s_data->isPrint(c2)) {
692 html += "&#" + QString::number(c2.unicode()) + "; ";
693 }
694 html += s_data->formatCode(c2.unicode()) + ' ' + Qt::escape(s_data->name(c2)) + "</a></li>";
695 }
696 html += "</ul>";
697 }
698
699 if (!equivalents.isEmpty()) {
700 html += "<p style=\"margin-bottom: 0px;\">" + i18n("Equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
701 foreach(const QString &equivalent, equivalents) {
702 html += "<li>" + createLinks(Qt::escape(equivalent)) + "</li>";
703 }
704 html += "</ul>";
705 }
706
707 if (!approxEquivalents.isEmpty()) {
708 html += "<p style=\"margin-bottom: 0px;\">" + i18n("Approximate equivalents:") + "</p><ul style=\"margin-top: 0px;\">";
709 foreach(const QString &approxEquivalent, approxEquivalents) {
710 html += "<li>" + createLinks(Qt::escape(approxEquivalent)) + "</li>";
711 }
712 html += "</ul>";
713 }
714
715 QStringList unihan = s_data->unihanInfo(c);
716 if (unihan.count() == 7) {
717 html += "<p><b>" + i18n("CJK Ideograph Information") + "</b></p><p>";
718 bool newline = true;
719 if (!unihan[0].isEmpty()) {
720 html += i18n("Definition in English: ") + unihan[0];
721 newline = false;
722 }
723 if (!unihan[2].isEmpty()) {
724 if (!newline) html += "<br>";
725 html += i18n("Mandarin Pronunciation: ") + unihan[2];
726 newline = false;
727 }
728 if (!unihan[1].isEmpty()) {
729 if (!newline) html += "<br>";
730 html += i18n("Cantonese Pronunciation: ") + unihan[1];
731 newline = false;
732 }
733 if (!unihan[6].isEmpty()) {
734 if (!newline) html += "<br>";
735 html += i18n("Japanese On Pronunciation: ") + unihan[6];
736 newline = false;
737 }
738 if (!unihan[5].isEmpty()) {
739 if (!newline) html += "<br>";
740 html += i18n("Japanese Kun Pronunciation: ") + unihan[5];
741 newline = false;
742 }
743 if (!unihan[3].isEmpty()) {
744 if (!newline) html += "<br>";
745 html += i18n("Tang Pronunciation: ") + unihan[3];
746 newline = false;
747 }
748 if (!unihan[4].isEmpty()) {
749 if (!newline) html += "<br>";
750 html += i18n("Korean Pronunciation: ") + unihan[4];
751 newline = false;
752 }
753 html += "</p>";
754 }
755
756 html += "<p><b>" + i18n("General Character Properties") + "</b><br>";
757 html += i18n("Block: ") + s_data->block(c) + "<br>";
758 html += i18n("Unicode category: ") + s_data->categoryText(s_data->category(c)) + "</p>";
759
760 QByteArray utf8 = QString(c).toUtf8();
761
762 html += "<p><b>" + i18n("Various Useful Representations") + "</b><br>";
763 html += i18n("UTF-8:");
764 foreach(unsigned char c, utf8)
765 html += ' ' + s_data->formatCode(c, 2, "0x");
766 html += "<br>" + i18n("UTF-16: ") + s_data->formatCode(c.unicode(), 4, "0x") + "<br>";
767 html += i18n("C octal escaped UTF-8: ");
768 foreach(unsigned char c, utf8)
769 html += s_data->formatCode(c, 3, "\\", 8);
770 html += "<br>" + i18n("XML decimal entity:") + " &amp;#" + QString::number(c.unicode()) + ";</p>";
771
772 detailBrowser->setHtml(html);
773}
774
775QString KCharSelect::KCharSelectPrivate::createLinks(QString s)
776{
777 QRegExp rx("\\b([\\dABCDEF]{4})\\b");
778
779 QStringList chars;
780 int pos = 0;
781
782 while ((pos = rx.indexIn(s, pos)) != -1) {
783 chars << rx.cap(1);
784 pos += rx.matchedLength();
785 }
786
787 QSet<QString> chars2 = QSet<QString>::fromList(chars);
788 foreach(const QString &c, chars2) {
789 int unicode = c.toInt(0, 16);
790 QString link = "<a href=\"" + c + "\">";
791 if (s_data->isPrint(QChar(unicode))) {
792 link += "&#" + QString::number(unicode) + ";&nbsp;";
793 }
794 link += "U+" + c + ' ';
795 link += Qt::escape(s_data->name(QChar(unicode))) + "</a>";
796 s.replace(c, link);
797 }
798 return s;
799}
800
801void KCharSelect::KCharSelectPrivate::_k_sectionSelected(int index)
802{
803 blockCombo->clear();
804 QList<int> blocks = s_data->sectionContents(index);
805 foreach(int block, blocks) {
806 blockCombo->addItem(s_data->blockName(block), QVariant(block));
807 }
808 blockCombo->setCurrentIndex(0);
809}
810
811void KCharSelect::KCharSelectPrivate::_k_blockSelected(int index)
812{
813 if (index == -1) {
814 //the combo box has been cleared and is about to be filled again (because the section has changed)
815 return;
816 }
817 if (searchMode) {
818 //we are in search mode, so don't fill the table with this block.
819 return;
820 }
821
822 int block = blockCombo->itemData(index).toInt();
823 const QList<QChar> contents = s_data->blockContents(block);
824 if(contents.count() <= index) {
825 return;
826 }
827 charTable->setContents(contents);
828 emit q->displayedCharsChanged();
829 charTable->setChar(contents[0]);
830}
831
832void KCharSelect::KCharSelectPrivate::_k_searchEditChanged()
833{
834 if (searchLine->text().isEmpty()) {
835 sectionCombo->setEnabled(true);
836 blockCombo->setEnabled(true);
837
838 //upon leaving search mode, keep the same character selected
839 searchMode = false;
840 QChar c = charTable->chr();
841 bool oldHistoryEnabled = historyEnabled;
842 historyEnabled = false;
843 _k_blockSelected(blockCombo->currentIndex());
844 historyEnabled = oldHistoryEnabled;
845 q->setCurrentChar(c);
846 } else {
847 sectionCombo->setEnabled(false);
848 blockCombo->setEnabled(false);
849
850 int length = searchLine->text().length();
851 if (length >= 3) {
852 _k_search();
853 }
854 }
855}
856
857void KCharSelect::KCharSelectPrivate::_k_search()
858{
859 if (searchLine->text().isEmpty()) {
860 return;
861 }
862 searchMode = true;
863 const QList<QChar> contents = s_data->find(searchLine->text());
864 charTable->setContents(contents);
865 emit q->displayedCharsChanged();
866 if (!contents.isEmpty()) {
867 charTable->setChar(contents[0]);
868 }
869}
870
871void KCharSelect::KCharSelectPrivate::_k_linkClicked(QUrl url)
872{
873 QString hex = url.toString();
874 if (hex.size() > 4) {
875 return;
876 }
877 int unicode = hex.toInt(0, 16);
878 searchLine->clear();
879 q->setCurrentChar(QChar(unicode));
880}
881
883
884QVariant KCharSelectItemModel::data(const QModelIndex &index, int role) const
885{
886 int pos = m_columns * (index.row()) + index.column();
887 if (!index.isValid() || pos < 0 || pos >= m_chars.size()
888 || index.row() < 0 || index.column() < 0) {
889 if (role == Qt::BackgroundColorRole) {
890 return QVariant(qApp->palette().color(QPalette::Button));
891 }
892 return QVariant();
893 }
894
895 QChar c = m_chars[pos];
896 if (role == Qt::ToolTipRole) {
897 QString result = s_data->display(c, m_font) + "<br />" + Qt::escape(s_data->name(c)) + "<br />" +
898 i18n("Unicode code point:") + ' ' + s_data->formatCode(c.unicode()) + "<br />" +
899 i18nc("Character", "In decimal:") + ' ' + QString::number(c.unicode());
900 return QVariant(result);
901 } else if (role == Qt::TextAlignmentRole)
902 return QVariant(Qt::AlignHCenter | Qt::AlignVCenter);
903 else if (role == Qt::DisplayRole) {
904 if (s_data->isPrint(c))
905 return QVariant(c);
906 return QVariant();
907 } else if (role == Qt::BackgroundColorRole) {
908 QFontMetrics fm = QFontMetrics(m_font);
909 if (fm.inFont(c) && s_data->isPrint(c))
910 return QVariant(qApp->palette().color(QPalette::Base));
911 else
912 return QVariant(qApp->palette().color(QPalette::Button));
913 } else if (role == Qt::FontRole)
914 return QVariant(m_font);
915 else if (role == CharacterRole) {
916 return QVariant(c);
917 }
918 return QVariant();
919}
920
921bool KCharSelectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
922{
923 Q_UNUSED(row)
924 Q_UNUSED(parent)
925 if (action == Qt::IgnoreAction) {
926 return true;
927 }
928
929 if (!data->hasText()) {
930 return false;
931 }
932
933 if (column > 0) {
934 return false;
935 }
936 QString text = data->text();
937 if (text.isEmpty()) {
938 return false;
939 }
940 emit showCharRequested(text[0]);
941 return true;
942}
943
944void KCharSelectItemModel::setColumnCount(int columns)
945{
946 emit layoutAboutToBeChanged();
947 m_columns = columns;
948 emit layoutChanged();
949}
950
951QList<QChar> KCharSelectItemModel::chars() const
952{
953 return m_chars;
954}
955
956
957#include "kcharselect.moc"
958#include "kcharselect_p.moc"
KActionCollection
A container for a set of QAction objects.
Definition: kactioncollection.h:57
KCharSelect
Character selection widget.
Definition: kcharselect.h:62
KCharSelect::sizeHint
virtual QSize sizeHint() const
Reimplemented.
Definition: kcharselect.cpp:498
KCharSelect::KCharSelect
KCharSelect(QWidget *parent, KActionCollection *collection, const Controls controls=AllGuiElements)
Constructor.
Definition: kcharselect.cpp:331
KCharSelect::setCurrentChar
void setCurrentChar(const QChar &c)
Highlights the character c.
Definition: kcharselect.cpp:525
KCharSelect::currentCharChanged
void currentCharChanged(const QChar &c)
The current character is changed.
KCharSelect::currentFont
QFont currentFont
Definition: kcharselect.h:64
KCharSelect::~KCharSelect
~KCharSelect()
Definition: kcharselect.cpp:493
KCharSelect::currentChar
QChar currentChar
Definition: kcharselect.h:65
KCharSelect::setCurrentFont
void setCurrentFont(const QFont &font)
Sets the font which is displayed to font.
Definition: kcharselect.cpp:503
KCharSelect::charSelected
void charSelected(const QChar &c)
A character is selected to be inserted somewhere.
KCharSelect::displayedChars
QList< QChar > displayedChars
Definition: kcharselect.h:66
KComboBox
An enhanced combo box.
Definition: kcombobox.h:149
KFontComboBox
A lightweight font selection widget.
Definition: kfontcombobox.h:50
KIcon
A wrapper around QIcon that provides KDE icon features.
Definition: kicon.h:41
KLineEdit
An enhanced QLineEdit widget for inputting text.
Definition: klineedit.h:150
KTextBrowser
Extended QTextBrowser.
Definition: ktextbrowser.h:52
QComboBox
QFrame
QItemSelectionModel
QList
QSet
QToolButton
QUrl
QWidget
K_GLOBAL_STATIC
#define K_GLOBAL_STATIC(TYPE, NAME)
kactioncollection.h
kcharselect.h
kcombobox.h
kdebug.h
kdialog.h
kfontcombobox.h
klineedit.h
klocale.h
i18n
QString i18n(const char *text)
i18nc
QString i18nc(const char *ctxt, const char *text)
kstandardaction.h
ktextbrowser.h
KStandardAction::forward
KAction * forward(const QObject *recvr, const char *slot, QObject *parent)
Move forward (web style menu).
Definition: kstandardaction.cpp:399
KStandardAction::back
KAction * back(const QObject *recvr, const char *slot, QObject *parent)
Move back (web style menu).
Definition: kstandardaction.cpp:394
KStandardAction::name
const char * name(StandardAction id)
This will return the internal name of a given standard action.
Definition: kstandardaction.cpp:223
KStandardAction::find
KAction * find(const QObject *recvr, const char *slot, QObject *parent)
Initiate a 'find' request in the current document.
Definition: kstandardaction.cpp:329
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDEUI

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

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal