* 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.
*/
#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 <QChar>
#include <QListWidgetItem>
#include <QString>
+#include <cstdio>
+
using namespace std;
namespace lyx {
{ 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<char_type> const & symbols)
+ {
+ symbols_ = symbols;
+ QAbstractItemModel::reset();
+ }
+
+private:
+ friend class GuiSymbols;
+ GuiSymbols * parent_;
+
+ QList<char_type> 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);
int size = font.pointSize() + 3;
font.setPointSize(size);
symbolsLW->setFont(font);
+ symbolsLW->setModel(model_);
}
return;
if (!new_encoding.empty())
encoding_ = new_encoding;
+ bool const utf8 = toqstr(encoding_).startsWith("utf8");
+ if (utf8)
+ categoryFilterCB->setChecked(false);
+ //categoryFilterCB->setEnabled(!utf8);
updateSymbolList();
}
}
-void GuiSymbols::on_symbolsLW_itemActivated(QListWidgetItem *)
+void GuiSymbols::on_symbolsLW_activated(QModelIndex const &)
{
on_okPB_clicked();
}
}
-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));
+ }
}
{
if (!categoryFilterCB->isChecked())
updateSymbolList(false);
- 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(false);
- 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::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);
}
bool const nocategory = category.isEmpty();
char_type range_start = 0x0000;
char_type range_end = 0x110000;
- symbolsLW->clear();
+ QList<char_type> s;
if (update_combo) {
used_blocks.clear();
categoryCO->clear();
}
bool const show_all = categoryFilterCB->isChecked();
- typedef set<char_type> 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;
+ 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 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;
- if (!update_combo && !show_all && (c <= range_start || c >= range_end))
- 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
}
-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())));
} // namespace frontend
} // namespace lyx
-#include "GuiSymbols_moc.cpp"
+#include "moc_GuiSymbols.cpp"