X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiSymbols.cpp;h=6bd5ba210a4bf1f9fcbed1c4751b482422dd8749;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=8f6088f7ad3ba078c8b3edada30d2594ef7fddac;hpb=ea039d6496f2af366d8cdfdbe3b8c0ff7e391361;p=lyx.git diff --git a/src/frontends/qt4/GuiSymbols.cpp b/src/frontends/qt4/GuiSymbols.cpp index 8f6088f7ad..6bd5ba210a 100644 --- a/src/frontends/qt4/GuiSymbols.cpp +++ b/src/frontends/qt4/GuiSymbols.cpp @@ -3,7 +3,7 @@ * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author Jürgen Spitzmüller + * \author Jürgen Spitzmüller * * Full author contact details are available in file CREDITS. */ @@ -17,13 +17,21 @@ #include "qt_helpers.h" #include "Buffer.h" +#include "BufferParams.h" #include "BufferView.h" +#include "Cursor.h" #include "Encoding.h" +#include "FuncRequest.h" +#include "support/debug.h" #include "support/gettext.h" +#include #include #include +#include + +#include using namespace std; @@ -69,6 +77,7 @@ UnicodeBlocks unicode_blocks[] = { { N_("Tibetan"), 0x0f00, 0x0fbf }, { N_("Georgian"), 0x10a0, 0x10ff }, { N_("Hangul Jamo"), 0x1100, 0x11ff }, + { N_("Phonetic Extensions"), 0x1d00, 0x1d7f }, { N_("Latin Extended Additional"), 0x1e00, 0x1eff }, { N_("Greek Extended"), 0x1f00, 0x1fff }, { N_("General Punctuation"), 0x2000, 0x206f }, @@ -134,17 +143,132 @@ UnicodeBlocks unicode_blocks[] = { { N_("CJK Compatibility Ideographs Supplement"), 0x2f800, 0x2fa1f }, { N_("Tags"), 0xe0000, 0xe007f }, { N_("Variation Selectors Supplement"), 0xe0100, 0xe01ef }, - { N_("Supplementary Private Use Area-A"), 0xf0000, 0xe01ef }, - { N_("Supplementary Private Use Area-B"), 0x100000, 0x10ffff } + { N_("Supplementary Private Use Area-A"), 0xf0000, 0xffffd }, + { N_("Supplementary Private Use Area-B"), 0x100000, 0x10fffd } }; const int no_blocks = sizeof(unicode_blocks) / sizeof(UnicodeBlocks); + +QString getBlock(char_type c) +{ + // store an educated guess for the next search + static int lastBlock = 0; + + // "clever reset" + if (c < 0x7f) + lastBlock = 0; + + // off the end already + if (lastBlock == no_blocks) + return QString(); + + // c falls into a covered area, and we can guess which + if (c >= unicode_blocks[lastBlock].start + && c <= unicode_blocks[lastBlock].end) + return qt_(unicode_blocks[lastBlock].name); + + // c falls into an uncovered area, but we can guess which + if (c > unicode_blocks[lastBlock].end + && c < unicode_blocks[lastBlock + 1].start) + return QString(); + + // guessing was wrong so far. do a real search. + int i = 0; + while (c > unicode_blocks[i].end && i < no_blocks) + ++i; + if (i == no_blocks) + return QString(); + lastBlock = i; + //LYXERR0("fail: " << int(c) << ' ' << lastBlock); + return qt_(unicode_blocks[lastBlock].name); +} + + } // namespace anon +///////////////////////////////////////////////////////////////////// +// +// GuiSymbols::Model +// +///////////////////////////////////////////////////////////////////// + +class GuiSymbols::Model : public QAbstractItemModel +{ +public: + Model(GuiSymbols * parent) + : QAbstractItemModel(parent), parent_(parent) + {} + + QModelIndex index(int row, int column, QModelIndex const &) const + { + return createIndex(row, column); + } + + QModelIndex parent(QModelIndex const &) const + { + return QModelIndex(); + } + + int rowCount(QModelIndex const &) const + { + return symbols_.count(); + } + + int columnCount(QModelIndex const &) const + { + return 1; + } + + QVariant data(QModelIndex const & index, int role) const + { + static QString const strCharacter = qt_("Character: "); + static QString const strCodePoint = qt_("Code Point: "); + + static char codeName[10]; + + char_type c = symbols_.at(index.row()); + + if (role == Qt::TextAlignmentRole) + return QVariant(Qt::AlignCenter); + + if (role == Qt::DisplayRole) + return toqstr(c); + + if (role == Qt::ToolTipRole) { + sprintf(codeName, "0x%04x", c); + return strCharacter + toqstr(c) + '\n' + + strCodePoint + QLatin1String(codeName); + } + + //LYXERR0("role: " << role << " row: " << index.row()); + return QVariant(); + } + + void setSymbols(QList const & symbols) + { + symbols_ = symbols; + QAbstractItemModel::reset(); + } + +private: + friend class GuiSymbols; + GuiSymbols * parent_; + + QList symbols_; +}; + + +///////////////////////////////////////////////////////////////////// +// +// GuiSymbols +// +///////////////////////////////////////////////////////////////////// + GuiSymbols::GuiSymbols(GuiView & lv) - : DialogView(lv, "symbols", qt_("Symbols")), encoding_("ascii") + : DialogView(lv, "symbols", qt_("Symbols")), encoding_("ascii"), + model_(new Model(this)) { setupUi(this); @@ -157,6 +281,7 @@ GuiSymbols::GuiSymbols(GuiView & lv) int size = font.pointSize() + 3; font.setPointSize(size); symbolsLW->setFont(font); + symbolsLW->setModel(model_); } @@ -164,12 +289,19 @@ void GuiSymbols::updateView() { chosenLE->clear(); - string const & new_encoding = bufferview()->cursor().getEncoding()->name(); + string new_encoding = bufferview()->cursor().getEncoding()->name(); + if (buffer().params().inputenc != "auto" && + buffer().params().inputenc != "default") + new_encoding = buffer().params().encoding().name(); if (new_encoding == encoding_) // everything up to date return; if (!new_encoding.empty()) encoding_ = new_encoding; + bool const utf8 = toqstr(encoding_).startsWith("utf8"); + if (utf8) + categoryFilterCB->setChecked(false); + //categoryFilterCB->setEnabled(!utf8); updateSymbolList(); } @@ -201,7 +333,7 @@ void GuiSymbols::on_closePB_clicked() } -void GuiSymbols::on_symbolsLW_itemActivated(QListWidgetItem *) +void GuiSymbols::on_symbolsLW_activated(QModelIndex const &) { on_okPB_clicked(); } @@ -221,88 +353,107 @@ void GuiSymbols::on_chosenLE_returnPressed() } -void GuiSymbols::on_symbolsLW_itemClicked(QListWidgetItem * item) +void GuiSymbols::on_symbolsLW_clicked(QModelIndex const & index) { - QString const text = item->text(); + QString const text = model_->data(index, Qt::DisplayRole).toString(); if (text.isEmpty()) return; if (chosenLE->isEnabled()) chosenLE->insert(text); - QString const category = getBlock(text.data()->unicode()); - categoryCO->setCurrentIndex(categoryCO->findText(category)); + if (categoryFilterCB->isChecked()) { + QString const category = getBlock(text.data()->unicode()); + categoryCO->setCurrentIndex(categoryCO->findText(category)); + } } void GuiSymbols::on_categoryCO_activated(QString const & text) { if (!categoryFilterCB->isChecked()) - updateSymbolList(); - if (used_blocks.find(text) != used_blocks.end()) - symbolsLW->scrollToItem(used_blocks[text], - QAbstractItemView::PositionAtTop); + updateSymbolList(false); + else + scrollToItem(text); } void GuiSymbols::on_categoryFilterCB_toggled(bool on) { - updateSymbolList(); - if (on) { - QString const category = categoryCO->currentText(); - if (used_blocks.find(category) != used_blocks.end()) - symbolsLW->scrollToItem(used_blocks[category], - QAbstractItemView::PositionAtTop); - } + updateSymbolList(on); + if (on) + scrollToItem(categoryCO->currentText()); } -void GuiSymbols::updateSymbolList() +void GuiSymbols::scrollToItem(QString const & category) +{ + if (used_blocks.find(category) == used_blocks.end()) + return; + int row = used_blocks[category]; + QModelIndex index = symbolsLW->model()->index(row, 0, QModelIndex()); + symbolsLW->scrollTo(index, QAbstractItemView::PositionAtTop); +} + + +void GuiSymbols::updateSymbolList(bool update_combo) { QString category = categoryCO->currentText(); bool const nocategory = category.isEmpty(); char_type range_start = 0x0000; char_type range_end = 0x110000; - symbolsLW->clear(); - used_blocks.clear(); - categoryCO->clear(); + QList s; + if (update_combo) { + used_blocks.clear(); + categoryCO->clear(); + } bool const show_all = categoryFilterCB->isChecked(); - typedef set SymbolsList; - Encoding enc = *(encodings.getFromLyXName(encoding_)); - SymbolsList symbols = enc.getSymbolsList(); + if (symbols_.empty() || update_combo) + symbols_ = encodings.fromLyXName(encoding_)->symbolsList(); if (!show_all) { for (int i = 0 ; i < no_blocks; ++i) - if (unicode_blocks[i].name == fromqstr(category)) { + if (qt_(unicode_blocks[i].name) == category) { range_start = unicode_blocks[i].start; range_end = unicode_blocks[i].end; break; } } - SymbolsList::const_iterator const end = symbols.end(); - for (SymbolsList::const_iterator it = symbols.begin(); it != end; ++it) { + SymbolsList::const_iterator const end = symbols_.end(); + int numItem = 0; + for (SymbolsList::const_iterator it = symbols_.begin(); it != end; ++it) { char_type c = *it; - QChar::Category cat = QChar::category((uint) c); + if (!update_combo && !show_all && (c <= range_start || c >= range_end)) + continue; +#if QT_VERSION >= 0x040300 + QChar::Category const cat = QChar::category(uint(c)); +#else + QChar::Category const cat = QChar(uint(c)).category(); +#endif // we do not want control or space characters if (cat == QChar::Other_Control || cat == QChar::Separator_Space) continue; - QListWidgetItem * lwi = new QListWidgetItem( - QString::fromUcs4((uint const *) &c, 1)); - if (show_all || c >= range_start && c <= range_end) { - lwi->setTextAlignment(Qt::AlignCenter); - symbolsLW->addItem(lwi); + ++numItem; + if (show_all || (c >= range_start && c <= range_end)) + s.append(c); + if (update_combo) { + QString block = getBlock(c); + if (category.isEmpty()) + category = block; + if (used_blocks.find(block) == used_blocks.end()) + used_blocks[block] = numItem; } - QString block = getBlock(c); - if (category.isEmpty()) - category = block; - if (used_blocks.find(block) == used_blocks.end()) - used_blocks[block] = lwi; } + model_->setSymbols(s); - // update category combo - for (UsedBlocks::iterator it = used_blocks.begin(); it != used_blocks.end(); ++it) { - categoryCO->addItem(it->first); + if (update_combo) { + // update category combo + for (UsedBlocks::iterator it = used_blocks.begin(); + it != used_blocks.end(); ++it) { + categoryCO->addItem(it->first); + } } + int old = categoryCO->findText(category); if (old != -1) categoryCO->setCurrentIndex(old); @@ -313,17 +464,6 @@ void GuiSymbols::updateSymbolList() } -QString const GuiSymbols::getBlock(char_type c) const -{ - int i = 0; - while (c > unicode_blocks[i].end && i < no_blocks) - ++i; - if (unicode_blocks[i].name) - return toqstr(unicode_blocks[i].name); - return QString(); -} - - void GuiSymbols::dispatchParams() { dispatch(FuncRequest(getLfun(), fromqstr(chosenLE->text()))); @@ -339,4 +479,4 @@ Dialog * createGuiSymbols(GuiView & lv) } // namespace frontend } // namespace lyx -#include "GuiSymbols_moc.cpp" +#include "moc_GuiSymbols.cpp"