28 #include <QTextStream>
29 #include <QScrollArea>
31 #include <QStringList>
32 #include <QProgressDialog>
33 #include <QGridLayout>
34 #include <QPushButton>
36 #include <QStackedWidget>
38 #include <QMessageBox>
40 #include <QApplication>
41 #include <QCloseEvent>
44 #include <QPlastiqueStyle>
46 #include <QDomDocument>
47 #include <QDomElement>
51 #include <ui_klflatexsymbols.h>
64 : symbol(), preamble(), textmode(false), bbexpand(), hidden(false)
69 for (k = 0; k < usepackagelist.
size(); ++k) {
70 QString package = usepackagelist.at(k).toElement().attribute("name");
71 if (package[0] ==
'[' || package[0] ==
'{')
77 for (k = 0; k < preamblelinelist.
size(); ++k) {
78 preamble.append(preamblelinelist.
at(k).toElement().text());
91 if (bblist.
size() > 1) {
92 fprintf(stderr,
"WARNING: Expected at most single <bb expand=\"..\"/> item!\n");
95 sscanf(bblist.
at(0).toElement().attribute(
"expand").toLatin1().constData(),
"%d,%d,%d,%d",
101 if (latexlist.
size() != 1) {
102 fprintf(stderr,
"WARNING: Expected single <latex>...</latex> in symbol entry!\n");
104 if (latexlist.
size() == 0)
106 symbol = latexlist.
at(0).toElement().text();
132 for (k = 0; k < a.
preamble.size(); ++k)
149 struct { qint16 t, r, b, l; } readbbexpand;
150 stream >> s.
symbol >> s.
preamble >> textmode >> readbbexpand.t >> readbbexpand.r
151 >> readbbexpand.b >> readbbexpand.l >>
hidden;
171 if (__rel_cache_file.
isEmpty())
177 KLFLatexSymbolsCache::KLFLatexSymbolsCache()
185 <<
":/data/symbolspixmapcache_base" ;
188 for (k = 0; !ok && k < cachefiles.size(); ++k) {
191 klfDbg(
"trying to load from "<<cachefiles[k]) ;
192 ok = ( loadCacheFrom(cachefiles[k], QDataStream::Qt_4_4)
195 klfDbg(
"trying to load from "<<cachefiles[k]<<
" with default header datastream version") ;
196 ok = ( loadCacheFrom(cachefiles[k], -1)
201 qWarning() <<
KLF_FUNC_NAME <<
": error finding and reading cache file!";
204 flag_modified =
false;
207 int KLFLatexSymbolsCache::loadCacheStream(
QDataStream& stream)
212 &readHeader, &readCompatKLFVersion);
214 klfDbg(
"failed to read symbolscache data header. readHeader="<<readHeader
215 <<
", readcompatklfver="<<readCompatKLFVersion) ;
226 flag_modified =
false;
230 int KLFLatexSymbolsCache::saveCacheStream(
QDataStream& stream)
235 flag_modified =
false;
241 klfDbg(
"sym.symbol="<<sym.
symbol<<
" fromCacheOnly="<<fromcacheonly) ;
243 if (cache.contains(sym)) {
244 klfDbg(
"Found symbol in cache! pixmap is null="<<cache[sym].isNull()<<
"; sym.preamble="<<sym.
preamble.
join(
";"));
250 return QPixmap(
":/pics/badsym.png");
260 while (it != cache.
end()) {
261 klfDbg(
"Testing symbol "<<it.
key().symbol<<
",preamble="<<it.
key().preamble.join(
",")
262 <<
"for being a duplicate of "<<sym.
symbol);
264 klfDbg(
"erasing duplicate.");
265 it = cache.
erase(it);
275 klfDbg(
"symbol is hidden. Assigning NULL pixmap.") ;
280 const float mag = 4.0;
288 in.
dpi = (int)(mag * 150);
290 backendsettings.epstopdfexec =
"";
291 backendsettings.tborderoffset = sym.
bbexpand.
t;
292 backendsettings.rborderoffset = sym.
bbexpand.
r;
293 backendsettings.bborderoffset = sym.
bbexpand.
b;
294 backendsettings.lborderoffset = sym.
bbexpand.
l;
301 <<
QString(
":ERROR: Can't generate preview for symbol %1 : status %2 !\n\tError: %3\n")
303 return QPixmap(
":/pics/badsym.png");
306 flag_modified =
true;
310 Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
314 klfDbg(
"Ran getLatexFormula(), got the pixmap. Returning.") ;
332 pdlg->setWindowModality(Qt::WindowModal);
333 pdlg->setModal(
true);
337 for (
int i = 0; i < list.
size(); ++i) {
340 qApp->processEvents();
341 if (pdlg->wasCanceled()) {
347 getPixmap(list[i],
false);
361 backendsettings = settings;
367 it != cache.end(); ++it) {
368 if (it.key().symbol == symbolCode)
378 it != cache.end(); ++it)
379 l << it.key().symbol;
388 qWarning()<<
KLF_FUNC_NAME<<
": Can't find symbol "<<symbolCode<<
".";
402 int KLFLatexSymbolsCache::loadCacheFrom(
const QString& fname,
int version)
405 if ( ! f.open(QIODevice::ReadOnly) ) {
406 klfDbg(
"Failed to open "<<fname) ;
411 ds.setVersion(version);
412 int r = loadCacheStream(ds);
420 if (staticCache == NULL) {
428 if (staticCache->cacheNeedsSave()) {
431 if ( ! f.
open(QIODevice::WriteOnly) ) {
432 qWarning() <<
KLF_FUNC_NAME<<
"Can't save cache to file "<< s <<
"!";
437 staticCache->saveCacheStream(ds);
438 klfDbg(
"Saved cache to file "<<s);
456 setWidgetResizable(
true);
461 mFrame->setObjectName(
"frmSymbolList");
482 for (k = 0; k < symbols.
size(); ++k)
483 if ( ! symbols[k].hidden )
503 btn->setStyle(myStyle);
504 btn->setPalette(pal);
506 btn->setSizePolicy(
QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
507 btn->setProperty(
"symbol", QVariant::fromValue<int>(i));
508 btn->setProperty(
"gridpos",
QPoint(-1,-1));
509 btn->setProperty(
"gridcolspan", -1);
510 btn->setProperty(
"myWidth", p.
width() + 4);
512 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\""
513 " \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n"
514 "<html><head><meta name=\"qrichtext\" content=\"1\" />"
515 "<style type=\"text/css\">\n"
516 "p { white-space: pre-wrap; padding: 0px; margin: 0px 0px 2px 0px; }\n"
517 "pre { padding: 0px; margin: 0px 0px 2px 0px; }\n"
521 "<p style=\"white-space: pre\">"+tr(
"LaTeX code:")+
" <b><tt>"+
_symbols[i].symbol+
"</tt></b>"+
525 tooltiptext +=
"<p>"+tr(
"Requires:")+
"<b><pre>" +
526 _symbols[i].preamble.join(
"\n")+
"</pre></b></p>";
527 tooltiptext +=
"</body></html>";
528 btn->setToolTip(tooltiptext);
533 mSpacerItem =
new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding);
539 int row = 0, col = 0, colspan;
541 int quantawidth = 55;
545 for (i = 0; i < mSymbols.
size(); ++i) {
546 colspan = 1 + mSymbols[i]->property(
"myWidth").toInt() / quantawidth;
552 if (col + colspan > n) {
556 if (mSymbols[i]->property(
"gridpos") !=
QPoint(row, col) ||
557 mSymbols[i]->property(
"gridcolspan") != colspan) {
559 mSymbols[i]->setProperty(
"gridpos",
QPoint(row, col));
560 mSymbols[i]->setProperty(
"gridcolspan", colspan);
561 mLayout->removeWidget(mSymbols[i]);
562 mLayout->
addWidget(mSymbols[i], row, col, 1, colspan);
571 mLayout->removeItem(mSpacerItem);
572 mLayout->
addItem(mSpacerItem, row+1, 0);
574 setMinimumWidth(mFrame->sizeHint().width() + verticalScrollBar()->width() + 2);
581 int i = s->
property(
"symbol").toInt();
592 if (pos < 0 || pos >= mSymbols.
size())
595 int symIndex = mSymbols[pos]->property(
"symbol").toInt();
597 qWarning()<<
KLF_FUNC_NAME<<
": Inavlid symbol index "<<symIndex;
602 Qt::CaseSensitivity cs = (queryString.
contains(
QRegExp(
"[A-Z]")) ? Qt::CaseSensitive : Qt::CaseInsensitive) ;
606 klfDbg(
"found match at "<<symIndex<<
": "<<
_symbols[symIndex].symbol) ;
614 klfDbg(
"result is "<<result<<
" valid="<<(result<mSymbols.
size())) ;
616 highlightSearchMatches(result);
621 highlightSearchMatches(-1);
625 void KLFLatexSymbolsView::highlightSearchMatches(
int currentMatch)
630 "KLFPixmapButton { background-color: rgb(180,180,255); }",
631 "KLFPixmapButton { background-color: rgb(0,0,255); }"
634 if (currentMatch == -1) {
636 stylesheets[0] = stylesheets[1] = stylesheets[2] =
QString();
639 for (k = 0; k < mSymbols.
size(); ++k) {
641 if (k == currentMatch)
645 mSymbols[k]->setStyleSheet(stylesheets[which]);
647 if (currentMatch >= 0 && currentMatch < mSymbols.
size())
657 #if defined(Q_OS_WIN32)
666 u =
new Ui::KLFLatexSymbols;
677 connect(pSearchBar, SIGNAL(escapePressed()), pSearchBar, SLOT(
hide()));
679 klfDbg(
"prepared search bar.") ;
684 read_symbols_create_ui();
688 QFont f = u->cbxCategory->font();
693 u->cbxCategory->setFont(f);
695 connect(u->cbxCategory, SIGNAL(highlighted(
int)),
this, SLOT(
slotShowCategory(
int)));
696 connect(u->cbxCategory, SIGNAL(activated(
int)),
this, SLOT(
slotShowCategory(
int)));
697 connect(u->btnClose, SIGNAL(clicked()),
this, SLOT(
close()));
703 u->retranslateUi(
this);
711 void KLFLatexSymbols::read_symbols_create_ui()
716 u->cbxCategory->clear();
729 <<
":/conf/latexsymbols.d/";
731 klfDbgT(
"starting to collect XML files from dirs "<<fxmldirs) ;
735 for (k = 0; k < fxmldirs.size(); ++k) {
736 QDir fxmldir(fxmldirs[k]);
738 for (j = 0; j < xmllist.size(); ++j)
739 fxmllist << fxmldir.absoluteFilePath(xmllist[j]);
741 klfDbgT(
"files collected: "<<fxmllist) ;
742 if (fxmllist.isEmpty()) {
756 klfDbgT(
"got xml files, ensured not empty; fxmllist="<<fxmllist) ;
765 for (k = 0; k < fxmllist.size(); ++k) {
767 klfDbg(
"reading XML file="<<fxmllist[k]);
771 if ( ! file.open(QIODevice::ReadOnly) ) {
772 qWarning()<<
KLF_FUNC_NAME<<
": Error: Can't open latex symbols XML file "<<fn<<
": "<<file.errorString()<<
"!";
777 QString errMsg;
int errLine, errCol;
778 bool r = doc.setContent(&file,
false, &errMsg, &errLine, &errCol);
780 qWarning()<<
KLF_FUNC_NAME<<
": Error parsing file "<<fn<<
": "<<errMsg<<
" at line "<<errLine<<
", col "<<errCol;
786 if (root.nodeName() !=
"latexsymbollist") {
787 qWarning(
"%s: Error parsing XML for latex symbols from file `%s': unexpected root tag `%s'.\n", KLF_FUNC_NAME,
788 qPrintable(fn), qPrintable(root.nodeName()));
795 if ( e.isNull() || n.
nodeType() != QDomNode::ElementNode )
797 if ( e.nodeName() !=
"category" ) {
798 qWarning(
"WARNING in parsing XML : ignoring unexpected tag `%s'!\n",
799 qPrintable(e.nodeName()));
814 if ( eesym.nodeName() ==
"category-title" ) {
817 klfDbg(
"<category-title>: lang="<<lang<<
"; hasAttribute(xml:lang)="<<eesym.
hasAttribute(
"xml:lang")
818 <<
"; current category-title="<<categoryTitle<<
",lang="<<curCategoryTitleLang) ;
823 categoryTitle = qApp->translate(
"xmltr_latexsymbols", eesym.
text().toUtf8().constData(),
824 "[[tag: <category-title>]]", QCoreApplication::UnicodeUTF8);
825 curCategoryTitleLang = lang;
833 categoryTitle = eesym.
text();
834 curCategoryTitleLang = lang;
841 qWarning(
"%s: WARNING in parsing XML : ignoring unexpected tag `%s' in category `%s'!\n",
842 KLF_FUNC_NAME, qPrintable(esym.
nodeName()), qPrintable(heading));
853 if (
mViews[j]->category() == heading) {
866 categoryTitle = heading;
867 u->cbxCategory->addItem(categoryTitle, heading);
868 categoryTitleLangs << curCategoryTitleLang;
871 if (!categoryTitle.
isEmpty() &&
872 (categoryTitleLangs[j].isEmpty() || curCategoryTitleLang.
startsWith(categoryTitleLangs[j]))) {
874 u->cbxCategory->setItemText(j, categoryTitle);
889 mViews[i]->buildDisplay();
901 klfDbg(
"current index="<<c) ;
926 if (e->
type() == QEvent::Polish) {
927 u->cbxCategory->setMinimumHeight(u->cbxCategory->sizeHint().height()+5);
929 if (e->
type() == QEvent::KeyPress) {
931 if (ke->
key() == Qt::Key_F7 && ke->modifiers() == 0) {
QDataStream & operator<<(QDataStream &stream, const KLFLatexSymbol &s)
void setSymbolList(const QList< KLFLatexSymbol > &symbols)
fromAscii(const char *str, int size=-1)
elementsByTagName(const QString &tagname)
setPointSize(int pointSize)
void slotShowCategory(int cat)
QString locale
When setting this, don't forget to call QLocale::setDefault().
QDataStream & operator>>(QDataStream &stream, KLFLatexSymbol &s)
QList< KLFLatexSymbol > _symbols
QString searchQueryString() const
setColor(ColorGroup group, ColorRole role, const QColor &color)
static KLFLatexSymbolsCache * theCache()
#define klfDbgT(streamableItems)
arg(const QString &a, int fieldWidth=0, const QChar &fillChar=QLatin1Char( ' ')
void symbolActivated(const KLFLatexSymbol &symb)
void retranslateUi(bool alsoBaseUi=true)
static void saveTheCache()
QStackedWidget * stkViews
QPixmap findSymbolPixmap(const QString &symbolCode)
virtual void searchPerformed(const SearchIterator &result)
QList< KLFLatexSymbolsView * > mViews
#define klfDbg(streamableItems)
KLFLatexSymbolsView(const QString &category, QWidget *parent)
fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
#define KLF_DEBUG_BLOCK(msg)
QStringList symbolCodeList()
join(const QString &separator)
void appendSymbolList(const QList< KLFLatexSymbol > &symbols)
tr(const char *sourceText, const char *comment=0, int n=-1)
virtual void setSearchTarget(KLFSearchable *object)
copy(const QString &newName)
void showEvent(QShowEvent *ev)
void slotSymbolActivated()
int precacheList(const QList< KLFLatexSymbol > &list, bool userfeedback, QWidget *parent=NULL)
property(const char *name)
hasAttribute(const QString &name)
QPixmap getPixmap(const KLFLatexSymbol &sym, bool fromcacheonly=true)
KLFLatexSymbol findSymbol(const QString &symbolCode)
void closeEvent(QCloseEvent *ev)
#define KLF_DEBUG_ASSIGN_REF_INSTANCE(object, ref_instance)
KLFLatexSymbols(QWidget *parent, const KLFBackend::klfSettings &baseSettings)
startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive)
static QString relcachefile()
virtual void searchAbort()
bool event(QEvent *event)
virtual void searchAbort()
virtual void setSearchText(const QString &text)
static QString __rel_cache_file
#define KLF_DEBUG_TIME_BLOCK(msg)
void setShowHideButton(bool showHideButton)
contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive)
#define KLF_DATA_STREAM_APP_VERSION
Current datastream compatibility klatexformula version.
struct KLFLatexSymbol::BBOffset bbexpand
KLF_EXPORT bool operator<(const KLFLatexSymbol &a, const KLFLatexSymbol &b)
virtual bool searchIterMatches(const SearchIterator &pos, const QString &queryString)
scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode=Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode=Qt::FastTransformation)
void setShowOverlayMode(bool showOverlayMode)
addItem(QLayoutItem *item, int row, int column, int rowSpan=1, int columnSpan=1, Qt::Alignment alignment=0)
KLF_EXPORT bool operator==(const KLFLatexSymbol &a, const KLFLatexSymbol &b)
void setBackendSettings(const KLFBackend::klfSettings &settings)
KLF_EXPORT void klfDataStreamWriteHeader(QDataStream &stream, const QString headermagic)
virtual void registerShortcuts(QWidget *parent)
KLF_EXPORT bool klfDataStreamReadHeader(QDataStream &stream, const QStringList possibleHeaders, QString *readHeader, QString *readCompatKLFVersion)
static klfOutput getLatexFormula(const klfInput &in, const klfSettings &settings)
mkpath(const QString &dirPath)
void insertSymbol(const KLFLatexSymbol &symb)
attribute(const QString &name, const QString &defValue=QString()