X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt4%2FGuiSymbols.cpp;h=6bd5ba210a4bf1f9fcbed1c4751b482422dd8749;hb=425d092204118ea6c24c28e85fdf03fcf2bb51a4;hp=3a47a5de1a60670a5d5781855ca2a97177e5b7c6;hpb=c37588d3741517d2309e64bf95e40cb53760d992;p=lyx.git diff --git a/src/frontends/qt4/GuiSymbols.cpp b/src/frontends/qt4/GuiSymbols.cpp index 3a47a5de1a..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. */ @@ -19,8 +19,11 @@ #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 @@ -28,6 +31,8 @@ #include #include +#include + using namespace std; namespace lyx { @@ -138,27 +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 getCodePoint(char_type c) +QString getBlock(char_type c) { - QString cp = QString::number(c, 16); - while (cp.size() < 4) - cp.prepend('0'); - cp.prepend("0x"); - return cp; + // 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); @@ -171,6 +281,7 @@ GuiSymbols::GuiSymbols(GuiView & lv) int size = font.pointSize() + 3; font.setPointSize(size); symbolsLW->setFont(font); + symbolsLW->setModel(model_); } @@ -190,7 +301,7 @@ void GuiSymbols::updateView() bool const utf8 = toqstr(encoding_).startsWith("utf8"); if (utf8) categoryFilterCB->setChecked(false); - categoryFilterCB->setEnabled(!utf8); + //categoryFilterCB->setEnabled(!utf8); updateSymbolList(); } @@ -222,7 +333,7 @@ void GuiSymbols::on_closePB_clicked() } -void GuiSymbols::on_symbolsLW_itemActivated(QListWidgetItem *) +void GuiSymbols::on_symbolsLW_activated(QModelIndex const &) { on_okPB_clicked(); } @@ -242,9 +353,9 @@ 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()) @@ -260,21 +371,26 @@ void GuiSymbols::on_categoryCO_activated(QString const & text) { if (!categoryFilterCB->isChecked()) updateSymbolList(false); - else if (used_blocks.find(text) != used_blocks.end()) - symbolsLW->scrollToItem(used_blocks[text], - QAbstractItemView::PositionAtTop); + else + scrollToItem(text); } void GuiSymbols::on_categoryFilterCB_toggled(bool on) { updateSymbolList(on); - if (on) { - QString const category = categoryCO->currentText(); - if (used_blocks.find(category) != used_blocks.end()) - symbolsLW->scrollToItem(used_blocks[category], - QAbstractItemView::PositionAtTop); - } + if (on) + scrollToItem(categoryCO->currentText()); +} + + +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); } @@ -284,7 +400,7 @@ void GuiSymbols::updateSymbolList(bool update_combo) bool const nocategory = category.isEmpty(); char_type range_start = 0x0000; char_type range_end = 0x110000; - symbolsLW->clear(); + QList s; if (update_combo) { used_blocks.clear(); categoryCO->clear(); @@ -292,11 +408,11 @@ void GuiSymbols::updateSymbolList(bool update_combo) bool const show_all = categoryFilterCB->isChecked(); if (symbols_.empty() || update_combo) - symbols_ = encodings.getFromLyXName(encoding_)->getSymbolsList(); + 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; @@ -304,6 +420,7 @@ void GuiSymbols::updateSymbolList(bool update_combo) } SymbolsList::const_iterator const end = symbols_.end(); + int numItem = 0; for (SymbolsList::const_iterator it = symbols_.begin(); it != end; ++it) { char_type c = *it; if (!update_combo && !show_all && (c <= range_start || c >= range_end)) @@ -311,29 +428,23 @@ void GuiSymbols::updateSymbolList(bool update_combo) #if QT_VERSION >= 0x040300 QChar::Category const cat = QChar::category(uint(c)); #else - QChar const qc = uint(c); - QChar::Category const cat = qc.category(); + 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(toqstr(c)); - if (show_all || c >= range_start && c <= range_end) { - lwi->setTextAlignment(Qt::AlignCenter); - lwi->setToolTip( - qt_("Character: ") + toqstr(c) + "\n" + - qt_("Code Point: ") + getCodePoint(c) - ); - 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] = lwi; + used_blocks[block] = numItem; } } + model_->setSymbols(s); if (update_combo) { // update category combo @@ -353,17 +464,6 @@ void GuiSymbols::updateSymbolList(bool update_combo) } -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()))); @@ -379,4 +479,4 @@ Dialog * createGuiSymbols(GuiView & lv) } // namespace frontend } // namespace lyx -#include "GuiSymbols_moc.cpp" +#include "moc_GuiSymbols.cpp"