[KLF Application][KLF Tools][KLF Backend][KLF Home]
KLatexFormula Project
klfmainwin.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * file klfmainwin.cpp
3  * This file is part of the KLatexFormula Project.
4  * Copyright (C) 2011 by Philippe Faist
5  * philippe.faist at bluewin.ch
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program; if not, write to the *
19  * Free Software Foundation, Inc., *
20  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  ***************************************************************************/
22 /* $Id: klfmainwin.cpp 603 2011-02-26 23:14:55Z phfaist $ */
23 
24 #include <stdio.h>
25 
26 #include <QtCore>
27 #include <QtGui>
28 
29 #include <klfbackend.h>
30 
31 #include <ui_klfprogerr.h>
32 #include <ui_klfmainwin.h>
33 
34 #include <klflibview.h>
35 #include <klfguiutil.h>
36 
37 #include "klflatexedit.h"
38 #include "klflibbrowser.h"
39 #include "klflatexsymbols.h"
40 #include "klfsettings.h"
41 #include "klfmain.h"
42 #include "klfstylemanager.h"
43 #include "klfmime.h"
44 
45 #include "klfmainwin.h"
46 #include "klfmainwin_p.h"
47 
48 
49 #define DEBUG_GEOM_ARGS(g) (g).topLeft().x(), (g).topLeft().y(), (g).size().width(), (g).size().height()
50 
52 {
53 #if defined(Q_WS_X11)
54  QRect g = w->frameGeometry();
55 #else
56  QRect g = w->geometry();
57 #endif
58  return g;
59 }
60 
62 {
63  if ( ! g.isValid() )
64  return;
65 
66  w->setGeometry(g);
67 }
68 
69 
70 
71 
72 
73 
74 
75 // ------------------------------------------------------------------------
76 
77 KLFProgErr::KLFProgErr(QWidget *parent, QString errtext) : QDialog(parent)
78 {
79  u = new Ui::KLFProgErr;
80  u->setupUi(this);
81  setObjectName("KLFProgErr");
82 
83  u->txtError->setText(errtext);
84 }
85 
87 {
88  delete u;
89 }
90 
91 void KLFProgErr::showError(QWidget *parent, QString errtext)
92 {
93  KLFProgErr dlg(parent, errtext);
94  dlg.exec();
95 }
96 
97 
98 
99 // ----------------------------------------------------------------------------
100 
102  KLFBackend::klfSettings settings, int labelwidth,
103  int labelheight)
104  : QThread(parent), _input(input), _settings(settings), _lwidth(labelwidth), _lheight(labelheight),
105  _hasnewinfo(false), _abort(false)
106 {
107 }
109 {
110  _mutex.lock();
111  _abort = true;
113  _mutex.unlock();
114  wait();
115 }
116 
118 {
119  KLFBackend::klfInput input;
120  KLFBackend::klfSettings settings;
121  KLFBackend::klfOutput output;
122  QImage img;
123  int lwid, lhgt;
124 
125  for (;;) {
126  _mutex.lock();
127  bool abrt = _abort;
128  _mutex.unlock();
129  if (abrt)
130  return;
131 
132  // fetch info
133  _mutex.lock();
134  input = _input;
135  settings = _settings;
136  settings.epstopdfexec = "";
137  lwid = _lwidth;
138  lhgt = _lheight;
139  _hasnewinfo = false;
140  _mutex.unlock();
141  // render equation
142  // no performance improvement noticed with lower DPI:
143  // // force 240 DPI (we're only a preview...)
144  // input.dpi = 240;
145 
146  if ( input.latex.trimmed().isEmpty() ) {
147  emit previewAvailable(QImage(), 0);
148  } else {
149  // and GO!
150  output = KLFBackend::getLatexFormula(input, settings);
151  img = output.result;
152  if (output.status == 0) {
153  if (img.width() > lwid || img.height() > lhgt)
154  img = img.scaled(QSize(lwid, lhgt), Qt::KeepAspectRatio, Qt::SmoothTransformation);
155  } else {
156  img = QImage();
157  }
158  }
159 
160  _mutex.lock();
161  bool abort = _abort;
162  bool hasnewinfo = _hasnewinfo;
163  _mutex.unlock();
164 
165  if (abort)
166  return;
167  if (hasnewinfo)
168  continue;
169 
170  emit previewAvailable(img, output.status != 0);
171 
172  _mutex.lock();
174  _mutex.unlock();
175  }
176 }
178 {
179  QMutexLocker mutexlocker(&_mutex);
180  if (_input == input) {
181  return false;
182  }
183  _input = input;
184  _hasnewinfo = true;
186  return true;
187 }
189  int lwidth, int lheight)
190 {
191  _mutex.lock();
192  _settings = settings;
193  if (lwidth > 0) _lwidth = lwidth;
194  if (lheight > 0) _lheight = lheight;
195  _hasnewinfo = true;
197  _mutex.unlock();
198 }
199 
200 
201 // ----------------------------------------------------------------------------
202 
203 
205  : QWidget(0, Qt::Window)
206 {
207  u = new Ui::KLFMainWin;
208  u->setupUi(this);
209  setObjectName("KLFMainWin");
210  setAttribute(Qt::WA_StyledBackground);
211 
212 #ifdef Q_WS_MAC
213  // watch for QFileOpenEvent s on mac
214  QApplication::instance()->installEventFilter(this);
215 #endif
216 
217  mPopup = NULL;
218 
219  loadSettings();
220 
221  _firstshow = true;
222 
223  _output.status = 0;
225 
226 
227  // load styless
228  loadStyles();
229 
231 
232  u->txtLatex->setFont(klfconfig.UI.latexEditFont);
233  u->txtPreamble->setFont(klfconfig.UI.preambleEditFont);
234 
235  u->frmOutput->setEnabled(false);
236 
237  QMenu *DPIPresets = new QMenu(this);
238  // 1200 DPI
239  connect(u->aDPI1200, SIGNAL(triggered()), this, SLOT(slotPresetDPISender()));
240  u->aDPI1200->setData(1200);
241  DPIPresets->addAction(u->aDPI1200);
242  // 600 DPI
243  connect(u->aDPI600, SIGNAL(triggered()), this, SLOT(slotPresetDPISender()));
244  u->aDPI600->setData(600);
245  DPIPresets->addAction(u->aDPI600);
246  // 300 DPI
247  connect(u->aDPI300, SIGNAL(triggered()), this, SLOT(slotPresetDPISender()));
248  u->aDPI300->setData(300);
249  DPIPresets->addAction(u->aDPI300);
250  // 150 DPI
251  connect(u->aDPI150, SIGNAL(triggered()), this, SLOT(slotPresetDPISender()));
252  u->aDPI150->setData(150);
253  DPIPresets->addAction(u->aDPI150);
254  // set menu to the button
255  u->btnDPIPresets->setMenu(DPIPresets);
256 
257 
258  connect(u->txtLatex->syntaxHighlighter(), SIGNAL(newSymbolTyped(const QString&)),
259  this, SLOT(slotNewSymbolTyped(const QString&)));
260 
261  u->lblOutput->setLabelFixedSize(klfconfig.UI.labelOutputFixedSize);
262  u->lblOutput->setEnableToolTipPreview(klfconfig.UI.enableToolTipPreview);
263  u->lblOutput->setGlowEffect(klfconfig.UI.glowEffect);
264  u->lblOutput->setGlowEffectColor(klfconfig.UI.glowEffectColor);
265  u->lblOutput->setGlowEffectRadius(klfconfig.UI.glowEffectRadius);
266 
267  connect(u->lblOutput, SIGNAL(labelDrag()), this, SLOT(slotDrag()));
268 
269  connect(u->btnShowBigPreview, SIGNAL(clicked()),
270  this, SLOT(slotShowBigPreview()));
271 
272  int h;
273  h = u->btnDrag->sizeHint().height(); u->btnDrag->setFixedHeight(h - 5);
274  h = u->btnCopy->sizeHint().height(); u->btnCopy->setFixedHeight(h - 5);
275  h = u->btnSave->sizeHint().height(); u->btnSave->setFixedHeight(h - 5);
276 
277  QGridLayout *lyt = new QGridLayout(u->lblOutput);
278  lyt->setSpacing(0);
279  lyt->setMargin(0);
280  mExportMsgLabel = new QLabel(u->lblOutput);
281  //mExportMsgLabel = new QLabel(frmOutput);
282  mExportMsgLabel->setObjectName("mExportMsgLabel");
283  QFont smallfont = mExportMsgLabel->font();
284  smallfont.setPointSize(QFontInfo(smallfont).pointSize() - 1);
285  mExportMsgLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
286  mExportMsgLabel->setFont(smallfont);
287  mExportMsgLabel->setMargin(1);
288  mExportMsgLabel->setAlignment(Qt::AlignRight|Qt::AlignBottom);
289  QPalette pal = mExportMsgLabel->palette();
290  pal.setColor(QPalette::Window, QColor(180,180,180,200));
291  pal.setColor(QPalette::WindowText, QColor(0,0,0,255));
292  mExportMsgLabel->setPalette(pal);
293  mExportMsgLabel->setAutoFillBackground(true);
294  mExportMsgLabel->setProperty("defaultPalette", QVariant::fromValue<QPalette>(pal));
295  //u->lyt_frmOutput->addWidget(mExportMsgLabel, 5, 0, 1, 2, Qt::AlignRight|Qt::AlignBottom);
296  lyt->addItem(new QSpacerItem(1, 1, QSizePolicy::Fixed, QSizePolicy::Expanding), 0, 1, 2, 1);
297  // lyt->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed), 1, 0, 1, 1);
298  lyt->addWidget(mExportMsgLabel, 1, 0, 1, 2);
299 
301 
302  mExportMsgLabel->hide();
303 
305 
306  u->frmDetails->hide();
307 
308  u->txtLatex->installEventFilter(this);
309  u->txtLatex->setMainWinDataOpener(this);
310 
312 
313  u->btnEvaluate->installEventFilter(this);
314 
315  // for appropriate tooltips
316  u->btnDrag->installEventFilter(this);
317  u->btnCopy->installEventFilter(this);
318 
319  // Shortcut for quit
320  new QShortcut(QKeySequence(tr("Ctrl+Q")), this, SLOT(quit()), SLOT(quit()),
321  Qt::ApplicationShortcut);
322 
323  // Shortcut for activating editor
324  // QShortcut *editorActivatorShortcut =
325  new QShortcut(QKeySequence(Qt::Key_F4), this, SLOT(slotActivateEditor()),
326  SLOT(slotActivateEditor()), Qt::ApplicationShortcut);
327  // QShortcut *editorActivatorShortcut =
328  new QShortcut(QKeySequence(Qt::Key_F4 | Qt::ShiftModifier), this, SLOT(slotActivateEditorSelectAll()),
329  SLOT(slotActivateEditorSelectAll()), Qt::ApplicationShortcut);
330  // shortcut for big preview
331  new QShortcut(QKeySequence(Qt::Key_F2), this, SLOT(slotShowBigPreview()),
332  SLOT(slotShowBigPreview()), Qt::WindowShortcut);
333 
334  // Create our style manager
335  mStyleManager = new KLFStyleManager(&_styles, this);
336  connect(mStyleManager, SIGNAL(refreshStyles()), this, SLOT(refreshStylePopupMenus()));
337  connect(this, SIGNAL(stylesChanged()), mStyleManager, SLOT(slotRefresh()));
338 
339  connect(this, SIGNAL(stylesChanged()), this, SLOT(saveStyles()));
340  connect(mStyleManager, SIGNAL(refreshStyles()), this, SLOT(saveStyles()));
341 
343 
344  // For systematical syntax highlighting
345  // make sure syntax highlighting is up-to-date at all times
346  QTimer *synthighlighttimer = new QTimer(this);
347  connect(synthighlighttimer, SIGNAL(timeout()), u->txtLatex->syntaxHighlighter(), SLOT(refreshAll()));
348  connect(synthighlighttimer, SIGNAL(timeout()), u->txtPreamble->syntaxHighlighter(), SLOT(refreshAll()));
349  synthighlighttimer->start(250);
350 
351  // initialize the margin unit selector
352  u->cbxMarginsUnit->setCurrentUnitAbbrev("pt");
353 
354  // set custom math modes
355  u->cbxMathMode->addItems(klfconfig.UI.customMathModes);
356 
357  // load library
358  mLibBrowser = new KLFLibBrowser(this);
359 
361 
362  // -- MAJOR SIGNAL/SLOT CONNECTIONS --
363 
364  // connect(u->btnClear, SIGNAL(toggled(bool)), this, SLOT(slotClear()));
365  connect(u->aClearLatex, SIGNAL(triggered()), this, SLOT(slotClearLatex()));
366  connect(u->aClearAll, SIGNAL(triggered()), this, SLOT(slotClearAll()));
367  connect(u->btnEvaluate, SIGNAL(clicked()), this, SLOT(slotEvaluate()));
368  connect(u->btnSymbols, SIGNAL(toggled(bool)), this, SLOT(slotSymbols(bool)));
369  connect(u->btnLibrary, SIGNAL(toggled(bool)), this, SLOT(slotLibrary(bool)));
370  connect(u->btnExpand, SIGNAL(clicked()), this, SLOT(slotExpandOrShrink()));
371  connect(u->btnCopy, SIGNAL(clicked()), this, SLOT(slotCopy()));
372  connect(u->btnDrag, SIGNAL(released()), this, SLOT(slotDrag()));
373  connect(u->btnSave, SIGNAL(clicked()), this, SLOT(slotSave()));
374  connect(u->btnSettings, SIGNAL(clicked()), this, SLOT(slotSettings()));
375  connect(u->btnSaveStyle, SIGNAL(clicked()), this, SLOT(slotSaveStyle()));
376 
377  connect(u->btnQuit, SIGNAL(clicked()), this, SLOT(quit()));
378 
379  connect(mLibBrowser, SIGNAL(requestRestore(const KLFLibEntry&, uint)),
380  this, SLOT(restoreFromLibrary(const KLFLibEntry&, uint)));
381  connect(mLibBrowser, SIGNAL(requestRestoreStyle(const KLFStyle&)),
382  this, SLOT(slotLoadStyle(const KLFStyle&)));
383  connect(mLatexSymbols, SIGNAL(insertSymbol(const KLFLatexSymbol&)),
384  this, SLOT(insertSymbol(const KLFLatexSymbol&)));
385 
386 
387  // our help/about dialog
388  connect(u->btnHelp, SIGNAL(clicked()), this, SLOT(showAbout()));
389 
390  // -- SMALL REAL-TIME PREVIEW GENERATOR THREAD --
391 
395 
396  connect(u->txtLatex, SIGNAL(textChanged()), this,
397  SLOT(updatePreviewBuilderThreadInput()), Qt::QueuedConnection);
398  connect(u->txtLatex, SIGNAL(insertContextMenuActions(const QPoint&, QList<QAction*> *)),
399  this, SLOT(slotEditorContextMenuInsertActions(const QPoint&, QList<QAction*> *)));
400  connect(u->cbxMathMode, SIGNAL(editTextChanged(const QString&)),
401  this, SLOT(updatePreviewBuilderThreadInput()),
402  Qt::QueuedConnection);
403  connect(u->chkMathMode, SIGNAL(stateChanged(int)), this, SLOT(updatePreviewBuilderThreadInput()),
404  Qt::QueuedConnection);
405  connect(u->colFg, SIGNAL(colorChanged(const QColor&)), this, SLOT(updatePreviewBuilderThreadInput()),
406  Qt::QueuedConnection);
407  connect(u->chkBgTransparent, SIGNAL(stateChanged(int)), this, SLOT(updatePreviewBuilderThreadInput()),
408  Qt::QueuedConnection);
409  connect(u->colBg, SIGNAL(colorChanged(const QColor&)), this, SLOT(updatePreviewBuilderThreadInput()),
410  Qt::QueuedConnection);
411 
412  connect(mPreviewBuilderThread, SIGNAL(previewAvailable(const QImage&, bool)),
413  this, SLOT(showRealTimePreview(const QImage&, bool)), Qt::QueuedConnection);
414 
417  }
418 
419  // CREATE SETTINGS DIALOG
420 
421  mSettingsDialog = new KLFSettings(this);
422 
423 
424  // INSTALL SOME EVENT FILTERS... FOR show/hide EVENTS
425 
426  mLibBrowser->installEventFilter(this);
427  mLatexSymbols->installEventFilter(this);
428  mStyleManager->installEventFilter(this);
429  mSettingsDialog->installEventFilter(this);
430 
431 
432  // INTERNAL FLAGS
433 
434  _evaloutput_uptodate = true;
435 
436  retranslateUi(false);
437 
438  connect(this, SIGNAL(applicationLocaleChanged(const QString&)), this, SLOT(retranslateUi()));
439  connect(this, SIGNAL(applicationLocaleChanged(const QString&)), mLibBrowser, SLOT(retranslateUi()));
440  connect(this, SIGNAL(applicationLocaleChanged(const QString&)), mSettingsDialog, SLOT(retranslateUi()));
441  connect(this, SIGNAL(applicationLocaleChanged(const QString&)), mStyleManager, SLOT(retranslateUi()));
442 
443  // About Dialog & What's New dialog
444  mAboutDialog = new KLFAboutDialog(this);
446 
447  connect(mAboutDialog, SIGNAL(linkActivated(const QUrl&)), this, SLOT(helpLinkAction(const QUrl&)));
448  connect(mWhatsNewDialog, SIGNAL(linkActivated(const QUrl&)), this, SLOT(helpLinkAction(const QUrl&)));
449 
450  mHelpLinkActions << HelpLinkAction("/whats_new", this, "showWhatsNew", false);
451  mHelpLinkActions << HelpLinkAction("/about", this, "showAbout", false);
452  mHelpLinkActions << HelpLinkAction("/popup_close", this, "slotPopupClose", false);
453  mHelpLinkActions << HelpLinkAction("/popup", this, "slotPopupAction", true);
454  mHelpLinkActions << HelpLinkAction("/settings", this, "showSettingsHelpLinkAction", true);
455 
457  addWhatsNewText("<p><b><span style=\"color: #a00000\">"+
458  tr("Your executable paths (latex, dvips, gs) seem not to be detected properly. "
459  "Please adjust the settings in the <a href=\"klfaction:/settings?control="
460  "ExecutablePaths\">settings dialog</a>.",
461  "[[additional text in what's-new-dialog in case of bad detected settings. this "
462  "is HTML formatted text.]]")
463  +"</span></b></p>");
464  }
465 
466  klfDbg("Font is "<<font()<<", family is "<<fontInfo().family()) ;
467  if (QFontInfo(klfconfig.UI.applicationFont).family().contains("CMU")) {
468  addWhatsNewText("<p>"+tr("LaTeX' Computer Modern Sans Serif font is used as the <b>default application font</b>."
469  " Don't like it? <a href=\"%1\">Choose your preferred application font</a>.")
470  .arg("klfaction:/settings?control=AppFonts") + "</p>");
471  }
472 
473  // and load the library
474 
475  _loadedlibrary = true;
476  loadLibrary();
477 
480 }
481 
482 void KLFMainWin::retranslateUi(bool alsoBaseUi)
483 {
484  if (alsoBaseUi)
485  u->retranslateUi(this);
486 
487  // version information as tooltip on the welcome widget
488  u->lblPromptMain->setToolTip(tr("KLatexFormula %1").arg(QString::fromUtf8(KLF_VERSION_STRING)));
489 
491 }
492 
493 
495 {
496  klfDbg( "()" ) ;
497 
499  saveSettings();
500  saveStyles();
501 
502  if (mStyleMenu)
503  delete mStyleMenu;
504  if (mLatexSymbols)
505  delete mLatexSymbols;
506  if (mLibBrowser)
507  delete mLibBrowser; // we aren't its parent
508  if (mSettingsDialog)
509  delete mSettingsDialog;
510 
512  delete mPreviewBuilderThread;
513 
514  delete u;
515 }
516 
518 {
519  // if ( ! _loadedlibrary ) {
520  // _loadedlibrary = true;
521  //
522  // // load the library browser's saved state
523  // QMetaObject::invokeMethod(this, "loadLibrary", Qt::QueuedConnection);
524  // }
525 
526 
527  // Export profiles selection list
528 
530  int k;
532  QMenu *menu = new QMenu(u->btnSetExportProfile);
533  QActionGroup *actionGroup = new QActionGroup(menu);
534  actionGroup->setExclusive(true);
535  QSignalMapper *smapper = new QSignalMapper(menu);
536  for (k = 0; k < eplist.size(); ++k) {
537  QAction *action = new QAction(actionGroup);
538  action->setText(eplist[k].description());
539  action->setData(eplist[k].profileName());
540  action->setCheckable(true);
541  action->setChecked( (klfconfig.UI.dragExportProfile==klfconfig.UI.copyExportProfile) &&
542  (klfconfig.UI.dragExportProfile==eplist[k].profileName()) );
543  menu->addAction(action);
544  smapper->setMapping(action, eplist[k].profileName());
545  connect(action, SIGNAL(triggered()), smapper, SLOT(map()));
547  }
548  connect(smapper, SIGNAL(mapped(const QString&)), this, SLOT(slotSetExportProfile(const QString&)));
549 
550  u->btnSetExportProfile->setMenu(menu);
551 }
552 
553 
554 
556 {
557  bool curstate_shown = u->frmDetails->isVisible();
558  u->frmDetails->show();
559  _shrinkedsize = u->frmMain->sizeHint() + QSize(3, 3);
560  _expandedsize.setWidth(u->frmMain->sizeHint().width() + u->frmDetails->sizeHint().width() + 3);
561  _expandedsize.setHeight(u->frmMain->sizeHint().height() + 3);
562  if (curstate_shown) {
564  u->frmDetails->show();
565  } else {
567  u->frmDetails->hide();
568  }
569  updateGeometry();
570 }
571 
573 {
574  bool lo = klfconfig.UI.clearLatexOnly;
575  u->btnClearAll->setVisible(!lo);
576  u->btnClearLatex->setVisible(lo);
577 }
578 
579 
581 {
582  // load style "default" or "Default" (or translation) if one of them exists
583  bool r;
584  r = loadNamedStyle(tr("Default", "[[style name]]"));
585  r = r || loadNamedStyle("Default");
586  r = r || loadNamedStyle("default");
587  return r;
588 }
589 
591 {
592  // find style with name sty (if existant) and set it
593  for (int kl = 0; kl < _styles.size(); ++kl) {
594  if (_styles[kl].name == sty) {
595  slotLoadStyle(kl);
596  return true;
597  }
598  }
599  return false;
600 }
601 
603 {
610 
615 
617 
618  _settings_altered = false;
619 }
620 
622 {
623  if ( ! _settings_altered ) { // don't save altered settings
635  }
636 
640 
642 
645 
646  u->lblOutput->setLabelFixedSize(klfconfig.UI.labelOutputFixedSize);
647  u->lblOutput->setEnableToolTipPreview(klfconfig.UI.enableToolTipPreview);
648 
649  u->lblOutput->setGlowEffect(klfconfig.UI.glowEffect);
650  u->lblOutput->setGlowEffectColor(klfconfig.UI.glowEffectColor);
651  u->lblOutput->setGlowEffectRadius(klfconfig.UI.glowEffectRadius);
652 
653  int k;
655  klfDbg("checking quick menu action item export profile="<<klfconfig.UI.copyExportProfile) ;
656  // check this export profile in the quick export profile menu
657  for (k = 0; k < pExportProfileQuickMenuActionList.size(); ++k) {
658  if (pExportProfileQuickMenuActionList[k]->data().toString() == klfconfig.UI.copyExportProfile) {
659  klfDbg("checking item #"<<k<<": "<<pExportProfileQuickMenuActionList[k]->data()) ;
660  // found the one
661  pExportProfileQuickMenuActionList[k]->setChecked(true);
662  break; // by auto-exclusivity the other ones will be un-checked.
663  }
664  }
665  } else {
666  // uncheck all items (since there is not a unique one set, drag and copy differ)
667  for (k = 0; k < pExportProfileQuickMenuActionList.size(); ++k)
668  pExportProfileQuickMenuActionList[k]->setChecked(false);
669  }
670 
671  u->btnSetExportProfile->setEnabled(klfconfig.UI.menuExportProfileAffectsDrag ||
673 
675  if ( ! mPreviewBuilderThread->isRunning() ) {
676  delete mPreviewBuilderThread;
682  }
683  } else {
684  if ( mPreviewBuilderThread->isRunning() ) {
685  delete mPreviewBuilderThread;
686  // do NOT leave a NULL mPreviewBuilderThread !
691  }
692  }
693 }
694 
695 void KLFMainWin::showExportMsgLabel(const QString& msg, int timeout)
696 {
697  mExportMsgLabel->show();
698  mExportMsgLabel->setPalette(mExportMsgLabel->property("defaultPalette").value<QPalette>());
699 
700  mExportMsgLabel->setProperty("timeTotal", timeout);
701  mExportMsgLabel->setProperty("timeRemaining", timeout);
702  mExportMsgLabel->setProperty("timeInterval", 200);
703 
704  mExportMsgLabel->setText(msg);
705 
706  if (pExportMsgLabelTimerId == -1) {
707  pExportMsgLabelTimerId = startTimer(mExportMsgLabel->property("timeInterval").toInt());
708  }
709 }
710 
712 {
713  if (mStyleMenu == NULL)
714  mStyleMenu = new QMenu(this);
715  mStyleMenu->clear();
716 
717  QAction *a;
718  for (int i = 0; i < _styles.size(); ++i) {
719  a = mStyleMenu->addAction(_styles[i].name);
720  a->setData(i);
721  connect(a, SIGNAL(triggered()), this, SLOT(slotLoadStyleAct()));
722  }
723 
725  mStyleMenu->addAction(QIcon(":/pics/managestyles.png"), tr("Manage Styles"),
726  this, SLOT(slotStyleManager()), 0 /* accel */);
727 
728 }
729 
730 
731 
732 static QString kdelocate(const char *fname)
733 {
734  QString candidate;
735 
737  QStringList kdehome = env.filter(QRegExp("^KDEHOME="));
738  if (kdehome.size() == 0) {
739  candidate = QDir::homePath() + QString("/.kde/share/apps/klatexformula/") + QString::fromLocal8Bit(fname);
740  } else {
741  QString kdehomeval = kdehome[0];
742  kdehomeval.replace(QRegExp("^KDEHOME="), "");
743  candidate = kdehomeval + "/share/apps/klatexformula/" + QString::fromLocal8Bit(fname);
744  }
745  if (QFile::exists(candidate)) {
746  return candidate;
747  }
748  return QString::null;
749 }
750 
752 {
753  if ( ! QFile::exists(styfname) )
754  return false;
755 
756  QFile fsty(styfname);
757  if ( ! fsty.open(QIODevice::ReadOnly) )
758  return false;
759 
760  QDataStream str(&fsty);
761 
762  QString readHeader;
763  QString readCompatKLFVersion;
764  bool r = klfDataStreamReadHeader(str, QStringList()<<QLatin1String("KLATEXFORMULA_STYLE_LIST"),
765  &readHeader, &readCompatKLFVersion);
766  if (!r) {
767  if (readHeader.isEmpty() || readCompatKLFVersion.isEmpty()) {
768  QMessageBox::critical(this, tr("Error"), tr("Error: Style file is incorrect or corrupt!\n"));
769  return false;
770  }
771  // too recent version warning
772  QMessageBox::warning(this, tr("Load Styles"),
773  tr("The style file found was created by a more recent version "
774  "of KLatexFormula.\n"
775  "The process of style loading may fail.")
776  );
777  }
778  // read the header, just need to read data now
779  str >> _styles;
780  return true;
781 }
782 
784 {
785  _styles = KLFStyleList(); // empty list to start with
786 
787  QStringList styfnamecandidates;
788  styfnamecandidates << klfconfig.homeConfigDir + QString("/styles-klf%1").arg(KLF_DATA_STREAM_APP_VERSION)
789  << klfconfig.homeConfigDir + QLatin1String("/styles")
790  << QLatin1String("kde-locate"); // locate in KDE only if necessary in for loop below
791 
792  int k;
793  bool result = false;
794  for (k = 0; k < styfnamecandidates.size(); ++k) {
795  QString fn = styfnamecandidates[k];
796  if (fn == QLatin1String("kde-locate"))
797  fn = kdelocate("styles");
798  // try to load this file
799  if ( (result = try_load_style_list(fn)) == true )
800  break;
801  }
802  // Don't fail if result is false, this is the case on first run (!)
803  // if (!result) {
804  // QMessageBox::critical(this, tr("Error"), tr("Error: Unable to load your style list!"));
805  // }
806 
807  if (_styles.isEmpty()) {
808  // if stylelist is empty, populate with default style
809  KLFStyle s1(tr("Default"), qRgb(0, 0, 0), qRgba(255, 255, 255, 0), "\\[ ... \\]", "", 600);
810  // KLFStyle s2(tr("Inline"), qRgb(0, 0, 0), qRgba(255, 255, 255, 0), "\\[ ... \\]", "", 150);
811  // s2.overrideBBoxExpand = KLFStyle::BBoxExpand(0,0,0,0);
812  _styles.append(s1);
813  // _styles.append(s2);
814  }
815 
816  mStyleMenu = 0;
818 
819  u->btnLoadStyle->setMenu(mStyleMenu);
820 }
821 
823 {
826  QFile f(s);
827  if ( ! f.open(QIODevice::WriteOnly) ) {
828  QMessageBox::critical(this, tr("Error"), tr("Error: Unable to write to styles file!\n%1").arg(s));
829  return;
830  }
831  QDataStream stream(&f);
832 
833  klfDataStreamWriteHeader(stream, "KLATEXFORMULA_STYLE_LIST");
834 
835  stream << _styles;
836 }
837 
839 {
841 
842  // start by loading the saved library browser state.
843  // Inside this function the value of klfconfig.LibraryBrowser.restoreURLs is taken
844  // into account.
846 
847  // Locate a good library/history file.
848 
849  // KLFPleaseWaitPopup pwp(tr("Loading library, please wait..."), this);
850  // pwp.showPleaseWait();
851 
852  // the default library file
853  QString localfname = klfconfig.Core.libraryFileName;
854  if (QFileInfo(localfname).isRelative())
855  localfname.prepend(klfconfig.homeConfigDir + "/");
856 
857  QString importfname;
858  if ( ! QFile::exists(localfname) ) {
859  // if unexistant, try to load:
860  importfname = klfconfig.homeConfigDir + "/library"; // the 3.1 library file
861  if ( ! QFile::exists(importfname) )
862  importfname = kdelocate("library"); // or the KDE KLF 2.1 library file
863  if ( ! QFile::exists(importfname) )
864  importfname = kdelocate("history"); // or the KDE KLF 2.0 history file
865  if ( ! QFile::exists(importfname) ) {
866  // as last resort we load our default library bundled with KLatexFormula
867  importfname = ":/data/defaultlibrary.klf";
868  }
869  }
870 
871  // importfname is non-empty only if the local .klf.db library file is inexistant.
872 
873  QUrl localliburl = QUrl::fromLocalFile(localfname);
875  localliburl.addQueryItem("klfDefaultSubResource", "History");
876 
877  // If the history is already open from library browser saved state, retrieve it
878  // This is possibly NULL
880 
881  if (!QFile::exists(localfname)) {
882  // create local library resource
883  KLFLibEngineFactory *localLibFactory = KLFLibEngineFactory::findFactoryFor(localliburl.scheme());
884  if (localLibFactory == NULL) {
885  qWarning()<<KLF_FUNC_NAME<<": Can't find library resource engine factory for scheme "<<localliburl.scheme()<<"!";
886  qFatal("%s: Can't find library resource engine factory for scheme '%s'!",
887  KLF_FUNC_NAME, qPrintable(localliburl.scheme()));
888  return;
889  }
891  param["Filename"] = localliburl.path();
892  param["klfDefaultSubResource"] = QLatin1String("History");
893  param["klfDefaultSubResourceTitle"] = tr("History", "[[default sub-resource title for history]]");
894  mHistoryLibResource = localLibFactory->createResource(localliburl.scheme(), param, this);
895  if (mHistoryLibResource == NULL) {
896  qWarning()<<KLF_FUNC_NAME<<": Can't create resource engine for library, of scheme "<<localliburl.scheme()<<"! "
897  <<"Create parameters are "<<param;
898  qFatal("%s: Can't create resource engine for library!", KLF_FUNC_NAME);
899  return;
900  }
901  mHistoryLibResource->setTitle(tr("Local Library"));
903  -> createSubResource(QLatin1String("Archive"),
904  tr("Archive", "[[default sub-resource title for archive sub-resource]]"));
908  QLatin1String("default+list"));
911  QLatin1String("default"));
912  } else {
914  }
915  }
916 
917  if (mHistoryLibResource == NULL) {
919  }
920  if (mHistoryLibResource == NULL) {
921  qWarning()<<"KLFMainWin::loadLibrary(): Can't open local history resource!\n\tURL="<<localliburl
922  <<"\n\tNot good! Expect crash!";
923  return;
924  }
925 
926  klfDbg("opened history: resource-ptr="<<mHistoryLibResource<<"\n\tImportFile="<<importfname);
927 
928  if (!importfname.isEmpty()) {
929  // needs an import
930  klfDbg("Importing library from "<<importfname) ;
931 
932  // visual feedback for import
933  KLFProgressDialog pdlg(QString(), this);
934  connect(mHistoryLibResource, SIGNAL(operationStartReportingProgress(KLFProgressReporter *,
935  const QString&)),
936  &pdlg, SLOT(startReportingProgress(KLFProgressReporter *)));
937  pdlg.setAutoClose(false);
938  pdlg.setAutoReset(false);
939 
940  // locate the import file and scheme
941  QUrl importliburl = QUrl::fromLocalFile(importfname);
943  if (scheme.isEmpty()) {
944  // assume .klf if not able to guess
945  scheme = "klf+legacy";
946  }
947  importliburl.setScheme(scheme);
948  importliburl.addQueryItem("klfReadOnly", "true");
949  // import library from an older version library file.
951  if (factory == NULL) {
952  qWarning()<<"KLFMainWin::loadLibrary(): Can't find factory for URL="<<importliburl<<"!";
953  } else {
954  KLFLibResourceEngine *importres = factory->openResource(importliburl, this);
955  // import all sub-resources
956  QStringList subResList = importres->subResourceList();
957  klfDbg( "\tImporting sub-resources: "<<subResList ) ;
958  int j;
959  for (j = 0; j < subResList.size(); ++j) {
960  QString subres = subResList[j];
961  pdlg.setDescriptiveText(tr("Importing Library from previous version of KLatexFormula ... "
962  "%3 (%1/%2)")
963  .arg(j+1).arg(subResList.size()).arg(subResList[j]));
965  = importres->allEntries(subres);
966  klfDbg("Got "<<allentries.size()<<" entries from sub-resource "<<subres);
967  int k;
968  KLFLibEntryList insertentries;
969  for (k = 0; k < allentries.size(); ++k) {
970  insertentries << allentries[k].entry;
971  }
972  if ( ! mHistoryLibResource->hasSubResource(subres) ) {
974  }
975  mHistoryLibResource->insertEntries(subres, insertentries);
976  }
977  }
978  }
979 
980  // Open history sub-resource into library browser
981  bool r;
984  QLatin1String("default+list"));
985  if ( ! r ) {
986  qWarning()<<"KLFMainWin::loadLibrary(): Can't open local history resource!\n\tURL="<<localliburl
987  <<"\n\tExpect Crash!";
988  return;
989  }
990 
991  // open all other sub-resources present in our library
993  int k;
994  for (k = 0; k < subresources.size(); ++k) {
995  // if (subresources[k] == QLatin1String("History")) // already open
996  // continue;
997  // if a URL is already open, it won't open it a second time.
998  QUrl url = localliburl;
999  url.removeAllQueryItems("klfDefaultSubResource");
1000  url.addQueryItem("klfDefaultSubResource", subresources[k]);
1001 
1003  QString sr = subresources[k].toLower();
1004  if (sr == "history" || sr == tr("History").toLower())
1006  if (sr == "archive" || sr == tr("Archive").toLower())
1008 
1009  mLibBrowser->openResource(url, flags);
1010  }
1011 }
1012 
1014 {
1015  QString fname = klfconfig.homeConfigDir + "/libbrowserstate.xml";
1016  if ( ! QFile::exists(fname) ) {
1017  klfDbg("No saved library browser state found ("<<fname<<")");
1018  return;
1019  }
1020 
1021  QFile f(fname);
1022  if ( ! f.open(QIODevice::ReadOnly) ) {
1023  qWarning()<<"Can't open file "<<fname<<" for loading library browser state";
1024  return;
1025  }
1026  QDomDocument doc("klflibbrowserstate");
1027  doc.setContent(&f);
1028  f.close();
1029 
1030  QDomNode rootNode = doc.documentElement();
1031  if (rootNode.nodeName() != "klflibbrowserstate") {
1032  qWarning()<<"Invalid root node in file "<<fname<<" !";
1033  return;
1034  }
1035  QDomNode n;
1036  QVariantMap vstatemap;
1037  for (n = rootNode.firstChild(); ! n.isNull(); n = n.nextSibling()) {
1038  QDomElement e = n.toElement();
1039  if ( e.isNull() || n.nodeType() != QDomNode::ElementNode )
1040  continue;
1041  if ( e.nodeName() == "statemap" ) {
1042  vstatemap = klfLoadVariantMapFromXML(e);
1043  continue;
1044  }
1045 
1046  qWarning("%s: Ignoring unrecognized node `%s' in file %s.", KLF_FUNC_NAME,
1047  qPrintable(e.nodeName()), qPrintable(fname));
1048  }
1049 
1051 }
1052 
1054 {
1055  QString fname = klfconfig.homeConfigDir + "/libbrowserstate.xml";
1056 
1057  QVariantMap statemap = mLibBrowser->saveGuiState();
1058 
1059  QFile f(fname);
1060  if ( ! f.open(QIODevice::WriteOnly) ) {
1061  qWarning()<<"Can't open file "<<fname<<" for saving library browser state";
1062  return;
1063  }
1064 
1065  QDomDocument doc("klflibbrowserstate");
1066  QDomElement rootNode = doc.createElement("klflibbrowserstate");
1067  QDomElement statemapNode = doc.createElement("statemap");
1068 
1069  klfSaveVariantMapToXML(statemap, statemapNode);
1070 
1071  rootNode.appendChild(statemapNode);
1072  doc.appendChild(rootNode);
1073 
1074  f.write(doc.toByteArray(2));
1075 }
1076 
1077 // private
1078 void KLFMainWin::slotOpenHistoryLibraryResource()
1079 {
1081 
1082  bool r;
1084  QLatin1String("default+list"));
1085  if ( ! r )
1086  qWarning()<<KLF_FUNC_NAME<<": Can't open local history resource!";
1087 
1088 }
1089 
1090 
1091 
1092 void KLFMainWin::restoreFromLibrary(const KLFLibEntry& entry, uint restoreFlags)
1093 {
1094  if (restoreFlags & KLFLib::RestoreStyle) {
1095  KLFStyle style = entry.style();
1096  slotLoadStyle(style);
1097  }
1098  // restore latex after style, so that the parser-hint-popup doesn't appear for packages
1099  // that we're going to include anyway
1100  if (restoreFlags & KLFLib::RestoreLatex) {
1101  // to preserve text edit undo history... call this slot instead of brutally doing txt->setPlainText(..)
1103  }
1104 
1105  u->lblOutput->display(entry.preview(), entry.preview(), false);
1106  u->frmOutput->setEnabled(false);
1107  activateWindow();
1108  raise();
1109  u->txtLatex->setFocus();
1110 }
1111 
1113 {
1114  u->btnLibrary->setChecked(on);
1115 }
1116 
1117 
1119 {
1120  // see if we need to insert the xtrapreamble
1121  QStringList cmds = s.preamble;
1122  int k;
1123  QString preambletext = u->txtPreamble->toPlainText();
1124  QString addtext;
1125  for (k = 0; k < cmds.size(); ++k) {
1126  slotEnsurePreambleCmd(cmds[k]);
1127  }
1128 
1129  // only after actually insert the symbol, so as not to interfere with popup package suggestions.
1130 
1131  QTextCursor c1(u->txtLatex->document());
1132  c1.beginEditBlock();
1133  c1.setPosition(u->txtLatex->textCursor().position());
1134  c1.insertText(s.symbol+"\n");
1135  c1.deletePreviousChar(); // small hack for forcing a separate undo command when two symbols are inserted
1136  c1.endEditBlock();
1137 
1138  activateWindow();
1139  raise();
1140  u->txtLatex->setFocus();
1141 }
1142 
1143 void KLFMainWin::insertDelimiter(const QString& delim, int charsBack)
1144 {
1145  u->txtLatex->insertDelimiter(delim, charsBack);
1146 }
1147 
1148 
1149 void KLFMainWin::getMissingCmdsFor(const QString& symbol, QStringList * missingCmds,
1150  QString *guiText, bool wantHtmlText)
1151 {
1152  if (missingCmds == NULL) {
1153  qWarning()<<KLF_FUNC_NAME<<": missingCmds is NULL!";
1154  return;
1155  }
1156  if (guiText == NULL) {
1157  qWarning()<<KLF_FUNC_NAME<<": guiText is NULL!";
1158  return;
1159  }
1160 
1161  missingCmds->clear();
1162  *guiText = QString();
1163 
1164  if (symbol.isEmpty())
1165  return;
1166 
1168  if (!sym.valid())
1169  return;
1170 
1171  QStringList cmds = sym.preamble;
1172  klfDbg("Got symbol for "<<symbol<<"; cmds is "<<cmds);
1173  if (cmds.isEmpty()) {
1174  return; // no need to include anything
1175  }
1176 
1177  QString curpreambletext = u->txtPreamble->toPlainText();
1178  QStringList packages;
1179  bool moreDefinitions = false;
1180  int k;
1181  for (k = 0; k < cmds.size(); ++k) {
1182  if (curpreambletext.indexOf(cmds[k]) >= 0)
1183  continue; // this line is already included
1184 
1185  missingCmds->append(cmds[k]);
1186 
1187  QRegExp rx("\\\\usepackage.*\\{(\\w+)\\}");
1188  klfDbg(" regexp="<<rx.pattern()<<"; cmd for symbol: "<<cmds[k].trimmed());
1189  if (rx.exactMatch(cmds[k].trimmed())) {
1190  packages << rx.cap(1); // the package name
1191  } else {
1192  // not a package inclusion
1193  moreDefinitions = true;
1194  }
1195  }
1196  if (wantHtmlText)
1197  packages.replaceInStrings(QRegExp("^(.*)$"), QString("<b>\\1</b>"));
1198 
1199  QString requiredtext;
1200  if (packages.size()) {
1201  if (packages.size() == 1)
1202  requiredtext += tr("package %1",
1203  "[[part of popup text, if one package only]]").arg(packages[0]);
1204  else
1205  requiredtext += tr("packages %1",
1206  "[[part of popup text, if multiple packages]]").arg(packages.join(", "));
1207  }
1208  if (moreDefinitions)
1209  requiredtext += packages.size()
1210  ? tr(" and <i>some more definitions</i>",
1211  "[[part of hint popup text, when packages also need to be included]]")
1212  : tr("<i>some definitions</i>",
1213  "[[part of hint popup text, when no packages need to be included]]");
1214  if (!wantHtmlText)
1215  requiredtext.replace(QRegExp("<[^>]*>"), "");
1216 
1217  *guiText = requiredtext;
1218 }
1219 
1220 void KLFMainWin::slotNewSymbolTyped(const QString& symbol)
1221 {
1222  if (mPopup == NULL)
1223  mPopup = new KLFMainWinPopup(this);
1224 
1226  return;
1227 
1228  QStringList cmds;
1229  QString requiredtext;
1230 
1231  getMissingCmdsFor(symbol, &cmds, &requiredtext);
1232 
1233  if (cmds.isEmpty()) // nothing to include
1234  return;
1235 
1236  QByteArray cmdsData = klfSaveVariantToText(QVariant(cmds));
1237  QString msgkey = "preambleCmdStringList:"+QString::fromLatin1(cmdsData);
1238  QUrl urlaction;
1239  urlaction.setScheme("klfaction");
1240  urlaction.setPath("/popup");
1241  QUrl urlactionClose = urlaction;
1242  urlaction.addQueryItem("preambleCmdStringList", QString::fromLatin1(cmdsData));
1243  urlactionClose.addQueryItem("removeMessageKey", msgkey);
1244  mPopup->addMessage(msgkey,
1245  //"[<a href=\""+urlactionClose.toEncoded()+"\">"
1246  //"<img border=\"0\" src=\":/pics/smallclose.png\"></a>] - "+
1247  tr("Symbol <tt>%3</tt> may require <a href=\"%1\">%2</a>.")
1248  .arg(urlaction.toEncoded(), requiredtext, symbol) );
1249  mPopup->show();
1250  mPopup->raise();
1251 }
1252 void KLFMainWin::slotPopupClose()
1253 {
1254  if (mPopup != NULL) {
1255  delete mPopup;
1256  mPopup = NULL;
1257  }
1258 }
1259 void KLFMainWin::slotPopupAction(const QUrl& url)
1260 {
1261  klfDbg("url="<<url.toEncoded());
1262  if (url.hasQueryItem("preambleCmdStringList")) {
1263  // include the given package
1264  QByteArray data = url.queryItemValue("preambleCmdStringList").toLatin1();
1265  klfDbg("data="<<data);
1266  QStringList cmds = klfLoadVariantFromText(data, "QStringList").toStringList();
1267  klfDbg("ensuring CMDS="<<cmds);
1268  int k;
1269  for (k = 0; k < cmds.size(); ++k) {
1270  slotEnsurePreambleCmd(cmds[k]);
1271  }
1272  mPopup->removeMessage("preambleCmdStringList:"+QString::fromLatin1(data));
1273  if (!mPopup->hasMessages())
1274  slotPopupClose();
1275  return;
1276  }
1277  if (url.hasQueryItem("acceptAll")) {
1278  slotPopupAcceptAll();
1279  return;
1280  }
1281  if (url.hasQueryItem("removeMessageKey")) {
1282  QString key = url.queryItemValue("removeMessageKey");
1283  mPopup->removeMessage(key);
1284  if (!mPopup->hasMessages())
1285  slotPopupClose();
1286  return;
1287  }
1288  if (url.hasQueryItem("configDontShow")) {
1289  // don't show popups
1290  slotPopupClose();
1291  klfconfig.UI.showHintPopups = false;
1292  saveSettings();
1293  return;
1294  }
1295 }
1296 void KLFMainWin::slotPopupAcceptAll()
1297 {
1298  if (mPopup == NULL)
1299  return;
1300 
1301  // accept all messages, based on their key
1302  QStringList keys = mPopup->messageKeys();
1303  int k;
1304  for (k = 0; k < keys.size(); ++k) {
1305  QString s = keys[k];
1306  if (s.startsWith("preambleCmdStringList:")) {
1307  QByteArray data = s.mid(strlen("preambleCmdStringList:")).toLatin1();
1308  QStringList cmds = klfLoadVariantFromText(data, "QStringList").toStringList();
1309  int k;
1310  for (k = 0; k < cmds.size(); ++k) {
1311  slotEnsurePreambleCmd(cmds[k]);
1312  }
1313  continue;
1314  }
1315  qWarning()<<KLF_FUNC_NAME<<": Unknown message key: "<<s;
1316  }
1317  slotPopupClose();
1318 }
1319 
1320 void KLFMainWin::slotEditorContextMenuInsertActions(const QPoint& pos, QList<QAction*> *actionList)
1321 {
1322  KLFLatexEdit *latexEdit = qobject_cast<KLFLatexEdit*>(sender());
1323  KLF_ASSERT_NOT_NULL( latexEdit, "KLFLatexEdit sender is NULL!", return ) ;
1324 
1325  // try to determine if we clicked on a symbol, and suggest to include the corresponding package
1326 
1327  QTextCursor cur = latexEdit->cursorForPosition(pos);
1328  QString text = latexEdit->toPlainText();
1329  int curpos = cur.position();
1330 
1331  QRegExp rxSym("\\\\(\\w+|.)");
1332  int i = text.lastIndexOf(rxSym, curpos); // search backwards from curpos
1333  if (i >= 0) {
1334  // matched somewhere before in text. See if we clicked on it
1335  int len = rxSym.matchedLength();
1336  QString symbol = text.mid(i, len);
1337  QStringList cmds;
1338  QString guitext;
1339  getMissingCmdsFor(symbol, &cmds, &guitext, false);
1340  if (cmds.size()) {
1341  QAction * aInsCmds = new QAction(latexEdit);
1342  aInsCmds->setText(tr("Include missing definitions for %1").arg(symbol));
1343  aInsCmds->setData(QVariant(cmds));
1344  connect(aInsCmds, SIGNAL(triggered()), this, SLOT(slotInsertMissingPackagesFromActionSender()));
1345  *actionList << aInsCmds;
1346  }
1347  }
1348 
1349  QAction *insertSymbolAction = new QAction(QIcon(":/pics/symbols.png"),
1350  tr("Insert Symbol ...", "[[context menu entry]]"), latexEdit);
1351  connect(insertSymbolAction, SIGNAL(triggered()), this, SLOT(slotSymbols()));
1352  *actionList << insertSymbolAction;
1353 }
1354 
1355 
1356 void KLFMainWin::slotInsertMissingPackagesFromActionSender()
1357 {
1358  QAction * a = qobject_cast<QAction*>(sender());
1359  if (a == NULL) {
1360  qWarning()<<KLF_FUNC_NAME<<": NULL QAction sender!";
1361  return;
1362  }
1363  QVariant data = a->data();
1364  QStringList cmds = data.toStringList();
1365  int k;
1366  for (k = 0; k < cmds.size(); ++k) {
1367  slotEnsurePreambleCmd(cmds[k]);
1368  }
1369 }
1370 
1371 
1372 
1374 {
1375  u->btnSymbols->setChecked(on);
1376 }
1377 
1379 {
1380  mAboutDialog->show();
1381 }
1382 
1384 {
1385  // center the widget on the desktop
1386  QSize desktopSize = QApplication::desktop()->screenGeometry(this).size();
1387  QSize wS = mWhatsNewDialog->sizeHint();
1388  mWhatsNewDialog->move(desktopSize.width()/2 - wS.width()/2,
1389  desktopSize.height()/2 - wS.height()/2);
1390  mWhatsNewDialog->show();
1391 }
1392 
1394 {
1395  klfDbg( ": link="<<link ) ;
1396  mSettingsDialog->show();
1397  mSettingsDialog->showControl(link.queryItemValue("control"));
1398 }
1399 
1401 {
1402  klfDbg( ": Link is "<<link<<"; scheme="<<link.scheme()<<"; path="<<link.path()
1403  <<"; queryItems="<<link.queryItems() ) ;
1404 
1405  if (link.scheme() == "http") {
1406  // web link
1408  return;
1409  }
1410  if (link.scheme() == "klfaction") {
1411  // find the help link action(s) that is (are) associated with this link
1412  bool calledOne = false;
1413  int k;
1414  for (k = 0; k < mHelpLinkActions.size(); ++k) {
1415  if (mHelpLinkActions[k].path == link.path()) {
1416  // got one
1417  if (mHelpLinkActions[k].wantParam)
1419  mHelpLinkActions[k].memberFunc.constData(),
1420  Qt::QueuedConnection, Q_ARG(QUrl, link));
1421  else
1423  mHelpLinkActions[k].memberFunc.constData(),
1424  Qt::QueuedConnection);
1425 
1426  calledOne = true;
1427  }
1428  }
1429  if (!calledOne) {
1430  qWarning()<<KLF_FUNC_NAME<<": no action found for link="<<link;
1431  }
1432  return;
1433  }
1434  qWarning()<<KLF_FUNC_NAME<<"("<<link<<"): Unrecognized link scheme!";
1435 }
1436 
1437 void KLFMainWin::addWhatsNewText(const QString& htmlSnipplet)
1438 {
1439  mWhatsNewDialog->addExtraText(htmlSnipplet);
1440 }
1441 
1442 
1443 void KLFMainWin::registerHelpLinkAction(const QString& path, QObject *object, const char * member,
1444  bool wantUrlParam)
1445 {
1446  mHelpLinkActions << HelpLinkAction(path, object, member, wantUrlParam);
1447 }
1448 
1449 
1451 {
1452  KLF_ASSERT_NOT_NULL( outputsaver, "Refusing to register NULL Output Saver object!", return ) ;
1453 
1454  pOutputSavers.append(outputsaver);
1455 }
1456 
1458 {
1459  pOutputSavers.removeAll(outputsaver);
1460 }
1461 
1463 {
1464  KLF_ASSERT_NOT_NULL( dataopener, "Refusing to register NULL Data Opener object!", return ) ;
1465 
1466  pDataOpeners.append(dataopener);
1467 }
1469 {
1470  pDataOpeners.removeAll(dataopener);
1471 }
1472 
1473 
1475 {
1476  // qDebug("setWidgetStyle(\"%s\")", qPrintable(qtstyle));
1477  if (_widgetstyle == qtstyle) {
1478  // qDebug("This style is already applied.");
1479  return;
1480  }
1481  if (qtstyle.isNull()) {
1482  // setting a null style resets internal widgetstyle name...
1483  _widgetstyle = QString::null;
1484  return;
1485  }
1486  QStringList stylelist = QStyleFactory::keys();
1487  if (stylelist.indexOf(qtstyle) == -1) {
1488  qWarning("Bad Style: %s. List of possible styles are:", qPrintable(qtstyle));
1489  int k;
1490  for (k = 0; k < stylelist.size(); ++k)
1491  qWarning("\t%s", qPrintable(stylelist[k]));
1492  return;
1493  }
1494  // qDebug("Setting the style %s. are we visible?=%d", qPrintable(qtstyle), (int)QWidget::isVisible());
1495  QStyle *s = QStyleFactory::create(qtstyle);
1496  // qDebug("Got style ptr=%p", (void*)s);
1497  if ( ! s ) {
1498  qWarning("Can't instantiate style %s!", qPrintable(qtstyle));
1499  return;
1500  }
1501  _widgetstyle = qtstyle;
1502  qApp->setStyle( s );
1503 }
1504 
1505 void KLFMainWin::setQuitOnClose(bool quitOnClose)
1506 {
1507  _ignore_close_event = ! quitOnClose;
1508 }
1509 
1510 
1512 {
1514 
1515  hide();
1516 
1517  if (mLibBrowser)
1518  mLibBrowser->hide();
1519  if (mLatexSymbols)
1520  mLatexSymbols->hide();
1521  if (mStyleManager)
1522  mStyleManager->hide();
1523  if (mSettingsDialog)
1524  mSettingsDialog->hide();
1525  qApp->quit();
1526 }
1527 
1529 {
1530  klfDbg("e->type() == "<<e->type());
1531 
1532  if (e->type() == QEvent::ApplicationFontChange) {
1533  klfDbg("Application font change.") ;
1535  klfconfig.UI.applicationFont = QApplication::font(); // refresh the font setting...
1536  }
1537 
1538  return QWidget::event(e);
1539 }
1540 
1542 {
1543  QObject *child = e->child();
1544  if (e->type() == QEvent::ChildAdded && child->isWidgetType()) {
1545  QWidget *w = qobject_cast<QWidget*>(child);
1546  if (w->windowFlags() & Qt::Window) {
1547  // note that all Qt::Tool, Qt::SplashScreen etc. all have the Qt::Window bit set, but
1548  // not Qt::Widget (!)
1549  pWindowList.append(w);
1550  klfDbg( ": Added child "<<w<<" ("<<w->objectName()<<")" ) ;
1551  }
1552  } else if (e->type() == QEvent::ChildRemoved && child->isWidgetType()) {
1553  QWidget *w = qobject_cast<QWidget*>(child);
1554  int k;
1555  if ((k = pWindowList.indexOf(w)) >= 0) {
1556  klfDbg( ": Removing child "<<w<<" ("<<w->objectName()<<")"
1557  <<" at position k="<<k ) ;
1558  pWindowList.removeAt(k);
1559  }
1560  }
1561 
1562  QWidget::childEvent(e);
1563 }
1564 
1566 {
1567 
1568  // even with QShortcuts, we still need this event handler (why?)
1569  if (obj == u->txtLatex) {
1570  if (e->type() == QEvent::KeyPress) {
1571  QKeyEvent *ke = (QKeyEvent*) e;
1572  if (ke->key() == Qt::Key_Return &&
1573  (QApplication::keyboardModifiers() == Qt::ShiftModifier ||
1574  QApplication::keyboardModifiers() == Qt::ControlModifier)) {
1575  slotEvaluate();
1576  return true;
1577  }
1578  if (mPopup != NULL && ke->key() == Qt::Key_Return &&
1579  QApplication::keyboardModifiers() == Qt::AltModifier) {
1580  slotPopupAcceptAll();
1581  return true;
1582  }
1583  if (mPopup != NULL && ke->key() == Qt::Key_Escape) {
1584  slotPopupClose();
1585  return true;
1586  }
1587  if (ke->key() == Qt::Key_F9) {
1588  slotExpand(true);
1589  u->tabsOptions->setCurrentWidget(u->tabLatexImage);
1590  u->txtPreamble->setFocus();
1591  return true;
1592  }
1593  }
1594  }
1595  if (obj == u->txtLatex || obj == u->btnEvaluate) {
1596  if (e->type() == QEvent::KeyPress) {
1597  QKeyEvent *ke = (QKeyEvent*) e;
1598  QKeySequence seq = QKeySequence(ke->key() | ke->modifiers());
1599  if (seq.matches(QKeySequence::Copy)) {
1600  // copy key shortcut. Check if editor received the event, and if there is a selection
1601  // in the editor. If there is a selection, let the editor copy it to clipboard. Otherwise
1602  // we will copy our output
1603  if (/*obj == u->txtLatex &&*/ u->txtLatex->textCursor().hasSelection()) {
1604  u->txtLatex->copy();
1605  return true;
1606  } else {
1607  slotCopy();
1608  return true;
1609  }
1610  }
1611  }
1612  }
1613 
1614  // ----
1615  if ( obj->isWidgetType() && (e->type() == QEvent::Hide || e->type() == QEvent::Show) ) {
1616  // shown/hidden windows: save/restore geometry
1617  int k = pWindowList.indexOf(qobject_cast<QWidget*>(obj));
1618  if (k >= 0) {
1619  QWidget *w = qobject_cast<QWidget*>(obj);
1620  // this widget is one of our monitored top-level children.
1621  if (e->type() == QEvent::Hide && !((QHideEvent*)e)->spontaneous()) {
1622  if (pLastWindowShownStatus[w])
1624  pLastWindowShownStatus[w] = false;
1625  } else if (e->type() == QEvent::Show && !((QShowEvent*)e)->spontaneous()) {
1626  pLastWindowShownStatus[w] = true;
1628  }
1629  }
1630  }
1631  // ----
1632  if ( obj == mLibBrowser && (e->type() == QEvent::Hide || e->type() == QEvent::Show) ) {
1634  }
1635  if ( obj == mLatexSymbols && (e->type() == QEvent::Hide || e->type() == QEvent::Show) ) {
1637  }
1638 
1639  // ----
1640  if ( obj == QApplication::instance() && e->type() == QEvent::FileOpen ) {
1641  // open a file
1642  openFile(((QFileOpenEvent*)e)->file());
1643  return true;
1644  }
1645 
1646  // ----
1647  if ( (obj == u->btnCopy || obj == u->btnDrag) && e->type() == QEvent::ToolTip ) {
1648  QString tooltipText;
1649  if (obj == u->btnCopy) {
1650  tooltipText = tr("Copy the formula to the clipboard. Current export profile: %1")
1652  } else if (obj == u->btnDrag) {
1653  tooltipText = tr("Click and keep mouse button pressed to drag your formula to another application. "
1654  "Current export profile: %1")
1656  }
1657  QToolTip::showText(((QHelpEvent*)e)->globalPos(), tooltipText, qobject_cast<QWidget*>(obj));
1658  return true;
1659  }
1660 
1661  return QWidget::eventFilter(obj, e);
1662 }
1663 
1664 
1666 {
1667  int k;
1668  for (k = 0; k < pWindowList.size(); ++k)
1669  pWindowList[k]->setStyleSheet(pWindowList[k]->styleSheet());
1670  // me too!
1671  setStyleSheet(styleSheet());
1672 }
1673 
1674 
1676 {
1677  QHash<QWidget*,bool> status;
1678  if (mainWindowToo)
1679  status[this] = isVisible();
1680  int k;
1681  for (k = 0; k < pWindowList.size(); ++k)
1682  status[pWindowList[k]] = pWindowList[k]->isVisible();
1683  return status;
1684 }
1685 QHash<QWidget*,bool> KLFMainWin::prepareAllWindowShownStatus(bool visibleStatus, bool mainWindowToo)
1686 {
1687  QHash<QWidget*,bool> status;
1688  if (mainWindowToo)
1689  status[this] = visibleStatus;
1690  int k;
1691  for (k = 0; k < pWindowList.size(); ++k)
1692  status[pWindowList[k]] = visibleStatus;
1693  return status;
1694 }
1695 
1697 {
1698  for (QHash<QWidget*,bool>::const_iterator it = shownStatus.begin(); it != shownStatus.end(); ++it)
1699  QMetaObject::invokeMethod(it.key(), "setVisible", Qt::QueuedConnection, Q_ARG(bool, it.value()));
1700 }
1701 
1702 
1704 {
1705  if ( ! e->spontaneous() ) {
1708  setWindowShownStatus(prepareAllWindowShownStatus(false, false)); // hide all windows
1709  }
1710 
1711  QWidget::hideEvent(e);
1712 }
1713 
1715 {
1716  if ( _firstshow ) {
1717  _firstshow = false;
1718  // if it's the first time we're run,
1719  // show the what's new if needed.
1721  QMetaObject::invokeMethod(this, "showWhatsNew", Qt::QueuedConnection);
1722  }
1723  }
1724 
1725  if ( ! e->spontaneous() ) {
1726  // restore shown windows ...
1727  if (pLastWindowGeometries.contains(this))
1730  }
1731 
1732  QWidget::showEvent(e);
1733 }
1734 
1735 
1737 {
1738  if (e->timerId() == pExportMsgLabelTimerId) {
1739  int total = mExportMsgLabel->property("timeTotal").toInt();
1740  int remaining = mExportMsgLabel->property("timeRemaining").toInt();
1741  int interval = mExportMsgLabel->property("timeInterval").toInt();
1742 
1743  int fadepercent = (100 * remaining / total) * 3; // 0 ... 300
1744  if (fadepercent < 100 && fadepercent >= 0) {
1745  QPalette pal = mExportMsgLabel->property("defaultPalette").value<QPalette>();
1746  QColor c = pal.color(QPalette::Window);
1747  c.setAlpha(c.alpha() * fadepercent / 100);
1748  pal.setColor(QPalette::Window, c);
1749  QColor c2 = pal.color(QPalette::WindowText);
1750  c2.setAlpha(c2.alpha() * fadepercent / 100);
1751  pal.setColor(QPalette::WindowText, c2);
1752  mExportMsgLabel->setPalette(pal);
1753  }
1754 
1755  remaining -= interval;
1756  if (remaining < 0) {
1757  mExportMsgLabel->hide();
1758  killTimer(pExportMsgLabelTimerId);
1760  } else {
1761  mExportMsgLabel->setProperty("timeRemaining", QVariant(remaining));
1762  }
1763  }
1764 }
1765 
1766 
1767 
1769 {
1770  _settings_altered = true;
1771  switch (which) {
1773  _settings.lborderoffset = ivalue; break;
1775  _settings.tborderoffset = ivalue; break;
1777  _settings.rborderoffset = ivalue; break;
1779  _settings.bborderoffset = ivalue; break;
1781  _settings.outlineFonts = (bool)ivalue; break;
1782  default:
1783  break;
1784  }
1785 }
1787 {
1788  _settings_altered = true;
1789  switch (which) {
1790  case altersetting_TempDir:
1791  _settings.tempdir = svalue; break;
1792  case altersetting_Latex:
1793  _settings.latexexec = svalue; break;
1794  case altersetting_Dvips:
1795  _settings.dvipsexec = svalue; break;
1796  case altersetting_Gs:
1797  _settings.gsexec = svalue; break;
1798  case altersetting_Epstopdf:
1799  _settings.epstopdfexec = svalue; break;
1800  default:
1801  break;
1802  }
1803 }
1804 
1805 
1807 {
1808  return u->txtLatex;
1809 }
1811 {
1812  return u->txtLatex->syntaxHighlighter();
1813 }
1815 {
1816  return u->txtPreamble->syntaxHighlighter();
1817 }
1818 
1819 
1820 
1821 
1822 
1824 {
1825  _settings = s;
1826  _settings_altered = false;
1827 }
1828 
1830 {
1831  QMessageBox::critical(this, tr("Error"), error);
1832 }
1833 
1834 
1836 {
1837  bool reallyinputchanged = mPreviewBuilderThread->inputChanged(collectInput(false));
1838  if (reallyinputchanged) {
1839  _evaloutput_uptodate = false;
1840  }
1841 }
1842 
1844 {
1845  u->txtLatex->setFont(f);
1846 }
1848 {
1849  u->txtPreamble->setFont(f);
1850 }
1851 
1852 void KLFMainWin::showRealTimePreview(const QImage& preview, bool latexerror)
1853 {
1854  klfDbg("preview.size=" << preview.size()<< " latexerror=" << latexerror);
1856  return;
1857 
1858  if (latexerror)
1859  u->lblOutput->displayError(/*labelenabled:*/false);
1860  else
1861  u->lblOutput->display(preview, preview, false);
1862 
1863 }
1864 
1866 {
1867  // KLFBackend input
1868  KLFBackend::klfInput input;
1869 
1870  input.latex = u->txtLatex->toPlainText();
1871  if (u->chkMathMode->isChecked()) {
1872  input.mathmode = u->cbxMathMode->currentText();
1873  if (final && u->cbxMathMode->findText(input.mathmode) == -1) {
1874  u->cbxMathMode->addItem(input.mathmode);
1875  klfconfig.UI.customMathModes.append(input.mathmode);
1876  }
1877  } else {
1878  input.mathmode = "...";
1879  }
1880  input.preamble = u->txtPreamble->toPlainText();
1881  input.fg_color = u->colFg->color().rgb();
1882  if (u->chkBgTransparent->isChecked() == false)
1883  input.bg_color = u->colBg->color().rgb();
1884  else
1885  input.bg_color = qRgba(255, 255, 255, 0);
1886 
1887  input.dpi = u->spnDPI->value();
1888 
1889  return input;
1890 }
1891 
1893 {
1894  // KLFBackend input
1895  KLFBackend::klfInput input;
1896 
1897  u->btnEvaluate->setEnabled(false); // don't allow user to click us while we're not done, and
1898  // additionally this gives visual feedback to the user
1899 
1900  input = collectInput(true);
1901 
1903  // see if we need to override settings
1904  if (u->gbxOverrideMargins->isChecked()) {
1905  settings.tborderoffset = u->spnMarginTop->valueInRefUnit();
1906  settings.rborderoffset = u->spnMarginRight->valueInRefUnit();
1907  settings.bborderoffset = u->spnMarginBottom->valueInRefUnit();
1908  settings.lborderoffset = u->spnMarginLeft->valueInRefUnit();
1909  }
1910 
1911  // and GO !
1912  _output = KLFBackend::getLatexFormula(input, settings);
1913 
1914  if (_output.status < 0) {
1915  QString comment = "";
1916  bool showSettingsPaths = false;
1921  comment = "\n"+tr("Are you sure you configured your system paths correctly in the settings dialog ?");
1922  showSettingsPaths = true;
1923  }
1924  QMessageBox::critical(this, tr("Error"), _output.errorstr+comment);
1925  u->lblOutput->displayClear();
1926  u->frmOutput->setEnabled(false);
1927  if (showSettingsPaths) {
1928  mSettingsDialog->show();
1930  }
1931  }
1932  if (_output.status > 0) {
1934  u->frmOutput->setEnabled(false);
1935  }
1936  if (_output.status == 0) {
1937  // ALL OK
1938  _evaloutput_uptodate = true;
1939 
1940  QPixmap sc;
1941  // scale to view size (klfconfig.UI.labelOutputFixedSize)
1943  if (_output.result.width() > fsize.width() || _output.result.height() > fsize.height())
1944  sc = QPixmap::fromImage(_output.result.scaled(fsize, Qt::KeepAspectRatio, Qt::SmoothTransformation));
1945  else
1947 
1948  QSize goodsize = _output.result.size();
1949  QImage tooltipimg = _output.result;
1950  if ( klfconfig.UI.previewTooltipMaxSize != QSize(0, 0) && // QSize(0,0) meaning no resize
1951  ( tooltipimg.width() > klfconfig.UI.previewTooltipMaxSize.width() ||
1952  tooltipimg.height() > klfconfig.UI.previewTooltipMaxSize.height() ) ) {
1953  tooltipimg =
1954  _output.result.scaled(klfconfig.UI.previewTooltipMaxSize, Qt::KeepAspectRatio,
1955  Qt::SmoothTransformation);
1956  }
1957  emit evaluateFinished(_output);
1958  u->lblOutput->display(sc.toImage(), tooltipimg, true);
1959  u->frmOutput->setEnabled(true);
1960 
1962  currentStyle());
1963  // check that this is not already the last entry. Perform a query to check this.
1964  bool needInsertThisEntry = true;
1967  query.skip = 0;
1968  query.limit = 1;
1970  query.orderDirection = Qt::DescendingOrder;
1971  query.wantedEntryProperties =
1974  int num = mHistoryLibResource->query(mHistoryLibResource->defaultSubResource(), query, &queryResult);
1975  if (num >= 1) {
1976  KLFLibEntry e = queryResult.rawEntryList[0];
1977  if (e.latex() == newentry.latex() &&
1978  e.category() == newentry.category() &&
1979  e.tags() == newentry.tags() &&
1980  e.style() == newentry.style())
1981  needInsertThisEntry = false;
1982  }
1983 
1984  if (needInsertThisEntry) {
1985  int eid = mHistoryLibResource->insertEntry(newentry);
1986  bool result = (eid >= 0);
1987  if ( ! result && mHistoryLibResource->locked() ) {
1988  int r = QMessageBox::warning(this, tr("Warning"),
1989  tr("Can't add the item to history library because the history "
1990  "resource is locked. Do you want to unlock it?"),
1991  QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
1992  if (r == QMessageBox::Yes) {
1994  result = mHistoryLibResource->insertEntry(newentry); // retry inserting entry
1995  }
1996  }
1998  if ( ! result && (fl & KLFLibResourceEngine::FeatureSubResources) &&
2002  int r = QMessageBox::warning(this, tr("Warning"),
2003  tr("Can't add the item to history library because the history "
2004  "sub-resource is locked. Do you want to unlock it?"),
2005  QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes);
2006  if (r == QMessageBox::Yes) {
2009  result = mHistoryLibResource->insertEntry(newentry); // retry inserting entry
2010  }
2011  }
2012  if ( ! result && mHistoryLibResource->isReadOnly() ) {
2013  qWarning("KLFMainWin::slotEvaluate: History resource is READ-ONLY !! Should NOT!");
2014  QMessageBox::critical(this, tr("Error"),
2015  tr("Can't add the item to history library because the history "
2016  "resource is opened in read-only mode. This should not happen! "
2017  "You will need to manually copy and paste your Latex code somewhere "
2018  "else to save it."),
2019  QMessageBox::Ok, QMessageBox::Ok);
2020  }
2021  if ( ! result ) {
2022  qWarning("KLFMainWin::slotEvaluate: History resource couldn't be written!");
2023  QMessageBox::critical(this, tr("Error"),
2024  tr("An error occurred when trying to write the new entry into the "
2025  "history resource!"
2026  "You will need to manually copy and paste your Latex code somewhere "
2027  "else to save it."),
2028  QMessageBox::Ok, QMessageBox::Ok);
2029  }
2030  }
2031  }
2032 
2033  u->btnEvaluate->setEnabled(true); // re-enable our button
2034  u->btnEvaluate->setFocus();
2035 }
2036 
2038 {
2039  u->txtLatex->clearLatex();
2040 }
2042 {
2043  slotClearLatex();
2044  loadDefaultStyle();
2045 }
2046 
2047 
2048 void KLFMainWin::slotLibrary(bool showlib)
2049 {
2050  klfDbg("showlib="<<showlib) ;
2051  mLibBrowser->setShown(showlib);
2052  if (showlib) {
2053  // already shown, raise the window
2055  mLibBrowser->raise();
2056  }
2057 }
2058 
2059 void KLFMainWin::slotSymbols(bool showsymbs)
2060 {
2061  mLatexSymbols->setShown(showsymbs);
2062  slotSymbolsButtonRefreshState(showsymbs);
2064  mLatexSymbols->raise();
2065 }
2066 
2068 {
2069  if (u->frmDetails->isVisible()) {
2070  u->frmDetails->hide();
2072  // adjustSize();
2073  u->btnExpand->setIcon(QIcon(":/pics/switchexpanded.png"));
2074  } else {
2076  u->frmDetails->show();
2077  // adjustSize();
2078  u->btnExpand->setIcon(QIcon(":/pics/switchshrinked.png"));
2079  }
2080 }
2081 void KLFMainWin::slotExpand(bool expanded)
2082 {
2083  if (u->frmDetails->isVisible() == expanded)
2084  return; // nothing to change
2085  // change
2087 }
2088 
2089 
2091 {
2092  u->txtLatex->setLatex(latex);
2093 }
2094 
2096 {
2097  u->chkMathMode->setChecked(mathmode.simplified() != "...");
2098  if (mathmode.simplified() != "...")
2099  u->cbxMathMode->setEditText(mathmode);
2100 }
2101 
2103 {
2104  u->txtPreamble->setLatex(preamble);
2105 }
2106 
2108 {
2109  QTextCursor c = u->txtPreamble->textCursor();
2110  // qDebug("Begin preamble edit: preamble text is %s", qPrintable(u->txtPreamble->toPlainText()));
2111  c.beginEditBlock();
2112  c.movePosition(QTextCursor::End);
2113 
2114  QString preambletext = u->txtPreamble->toPlainText();
2115  if (preambletext.indexOf(line) == -1) {
2116  QString addtext = "";
2117  if (preambletext.length() > 0 &&
2118  preambletext[preambletext.length()-1] != '\n')
2119  addtext = "\n";
2120  addtext += line;
2121  c.insertText(addtext);
2122  preambletext += addtext;
2123  }
2124 
2125  c.endEditBlock();
2126 }
2127 
2129 {
2130  u->spnDPI->setValue(DPI);
2131 }
2132 
2134 {
2135  u->colFg->setColor(fg);
2136 }
2138 {
2139  QColor fgcolor;
2140  fgcolor.setNamedColor(s);
2141  slotSetFgColor(fgcolor);
2142 }
2144 {
2145  u->colBg->setColor(bg);
2146 }
2148 {
2149  QColor bgcolor;
2150  if (s == "-")
2151  bgcolor.setRgb(255, 255, 255, 0); // white transparent
2152  else
2153  bgcolor.setNamedColor(s);
2154  slotSetBgColor(bgcolor);
2155 }
2156 
2157 void KLFMainWin::slotEvaluateAndSave(const QString& output, const QString& format)
2158 {
2159  if ( u->txtLatex->toPlainText().isEmpty() )
2160  return;
2161 
2162  slotEvaluate();
2163 
2164  if ( ! output.isEmpty() ) {
2165  if ( _output.result.isNull() ) {
2166  QMessageBox::critical(this, tr("Error"), tr("There is no image to save."));
2167  } else {
2168  KLFBackend::saveOutputToFile(_output, output, format.trimmed().toUpper());
2169  }
2170  }
2171 
2172 }
2173 
2174 
2175 
2176 
2178 {
2179  // returns the first element in a that is also in b, or a null QString() if there are no
2180  // common elements.
2181  int i, j;
2182  for (i = 0; i < a.size(); ++i)
2183  for (j = 0; j < b.size(); ++j)
2184  if (a[i] == b[j])
2185  return a[i];
2186  return QString();
2187 }
2188 
2189 bool KLFMainWin::canOpenFile(const QString& fileName)
2190 {
2192  klfDbg("file name="<<fileName) ;
2193  int k;
2194  for (k = 0; k < pDataOpeners.size(); ++k)
2195  if (pDataOpeners[k]->canOpenFile(fileName))
2196  return true;
2197  klfDbg("cannot open file.") ;
2198  return false;
2199 }
2201 {
2203  klfDbg("data. length="<<data.size()) ;
2204  int k;
2205  for (k = 0; k < pDataOpeners.size(); ++k)
2206  if (pDataOpeners[k]->canOpenData(data))
2207  return true;
2208  klfDbg("cannot open data.") ;
2209  return false;
2210 }
2211 bool KLFMainWin::canOpenData(const QMimeData *mimeData)
2212 {
2214  QStringList formats = mimeData->formats();
2215  klfDbg("mime data. formats="<<formats) ;
2216 
2217  QString mimetype;
2218  int k;
2219  for (k = 0; k < pDataOpeners.size(); ++k) {
2220  mimetype = find_list_agreement(formats, pDataOpeners[k]->supportedMimeTypes());
2221  if (!mimetype.isEmpty())
2222  return true; // this opener can open the data
2223  }
2224  klfDbg("cannot open data: no appropriate opener found.") ;
2225  return false;
2226 }
2227 
2228 
2230 {
2232  klfDbg("file="<<file) ;
2233  int k;
2234  for (k = 0; k < pDataOpeners.size(); ++k)
2235  if (pDataOpeners[k]->openFile(file))
2236  return true;
2237 
2238  QMessageBox::critical(this, tr("Error"), tr("Failed to load file %1.").arg(file));
2239 
2240  return false;
2241 }
2242 
2243 bool KLFMainWin::openFiles(const QStringList& fileList)
2244 {
2246  klfDbg("file list="<<fileList) ;
2247  int k;
2248  bool result = true;
2249  for (k = 0; k < fileList.size(); ++k) {
2250  result = result && openFile(fileList[k]);
2251  klfDbg("Opened file "<<fileList[k]<<": result="<<result) ;
2252  }
2253  return result;
2254 }
2255 
2256 bool KLFMainWin::openData(const QMimeData *mimeData, bool *openerFound)
2257 {
2259  klfDbg("mime data, formats="<<mimeData->formats()) ;
2260  int k;
2261  QString mimetype;
2262  QStringList fmts = mimeData->formats();
2263  if (openerFound != NULL)
2264  *openerFound = false;
2265  for (k = 0; k < pDataOpeners.size(); ++k) {
2266  mimetype = find_list_agreement(fmts, pDataOpeners[k]->supportedMimeTypes());
2267  if (!mimetype.isEmpty()) {
2268  if (openerFound != NULL)
2269  *openerFound = true;
2270  // mime types intersect.
2271  klfDbg("Opening mimetype "<<mimetype) ;
2272  QByteArray data = mimeData->data(mimetype);
2273  if (pDataOpeners[k]->openData(data, mimetype))
2274  return true;
2275  }
2276  }
2277 
2278  return false;
2279 }
2281 {
2283  klfDbg("data, len="<<data.length()) ;
2284  int k;
2285  for (k = 0; k < pDataOpeners.size(); ++k)
2286  if (pDataOpeners[k]->openData(data, QString()))
2287  return true;
2288 
2289  return false;
2290 }
2291 
2292 
2293 bool KLFMainWin::openLibFiles(const QStringList& files, bool showLibrary)
2294 {
2296  int k;
2297  bool imported = false;
2298  for (k = 0; k < files.size(); ++k) {
2299  bool ok = openLibFile(files[k], false);
2300  imported = imported || ok;
2301  klfDbg("imported file "<<files[k]<<": imported status is now "<<imported) ;
2302  }
2303  if (showLibrary && imported)
2304  slotLibrary(true);
2305  return imported;
2306 }
2307 
2308 bool KLFMainWin::openLibFile(const QString& fname, bool showLibrary)
2309 {
2311  klfDbg("fname="<<fname<<"; showLibrary="<<showLibrary) ;
2312  QUrl url = QUrl::fromLocalFile(fname);
2314  if (scheme.isEmpty()) {
2315  klfDbg("Can't guess scheme for file "<<fname) ;
2316  return false;
2317  }
2318  url.setScheme(scheme);
2319  klfDbg("url to open is "<<url) ;
2321  if ( subreslist.isEmpty() ) {
2322  klfDbg("no sub-resources...") ;
2323  // error reading sub-resources, or sub-resources not supported
2324  return mLibBrowser->openResource(url);
2325  }
2326  klfDbg("subreslist is "<<subreslist);
2327  bool loaded = false;
2328  int k;
2329  for (k = 0; k < subreslist.size(); ++k) {
2330  QUrl url2 = url;
2331  url2.addQueryItem("klfDefaultSubResource", subreslist[k]);
2332  bool thisloaded = mLibBrowser->openResource(url2);
2333  loaded = loaded || thisloaded;
2334  }
2335  if (showLibrary && loaded)
2336  slotLibrary(true);
2337  return loaded;
2338 }
2339 
2340 
2342 {
2343  klf_reload_translations(qApp, locale);
2344 
2345  emit applicationLocaleChanged(locale);
2346 }
2347 
2348 void KLFMainWin::slotSetExportProfile(const QString& exportProfile)
2349 {
2351  klfconfig.UI.copyExportProfile = exportProfile;
2353  klfconfig.UI.dragExportProfile = exportProfile;
2354  saveSettings();
2355 }
2356 
2357 /*
2358 QMimeData * KLFMainWin::resultToMimeData(const QString& exportProfileName)
2359 {
2360  klfDbg("export profile: "<<exportProfileName);
2361  if ( _output.result.isNull() )
2362  return NULL;
2363 
2364  KLFMimeExportProfile p = KLFMimeExportProfile::findExportProfile(exportProfileName);
2365  QStringList mimetypes = p.mimeTypes();
2366 
2367  QMimeData *mimedata = new QMimeData;
2368  int k;
2369  for (k = 0; k < mimetypes.size(); ++k) {
2370  klfDbg("exporting "<<mimetypes[k]<<" ...");
2371  QString mimetype = mimetypes[k];
2372  KLFMimeExporter *exporter = KLFMimeExporter::mimeExporterLookup(mimetype);
2373  if (exporter == NULL) {
2374  qWarning()<<KLF_FUNC_NAME<<": Can't find an exporter for mime-type "<<mimetype<<".";
2375  continue;
2376  }
2377  QByteArray data = exporter->data(mimetype, _output);
2378  mimedata->setData(mimetype, data);
2379  klfDbg("exporting mimetype done");
2380  }
2381 
2382  klfDbg("got mime data.");
2383  return mimedata;
2384 }
2385 */
2386 
2387 
2389 {
2390  if ( _output.result.isNull() )
2391  return;
2392 
2393  QDrag *drag = new QDrag(this);
2395 
2396  // / ** \bug .... Temporary solution for mac os X ... * /
2397  //#ifdef Q_WS_MAC
2398  // mime->setImageData(_output.result);
2399  //#endif
2400 
2401  drag->setMimeData(mime);
2402 
2403  QSize sz = QSize(200, 100);
2404  QImage img = _output.result;
2405  if (img.width() > sz.width() || img.height() > sz.height())
2406  img = img.scaled(sz, Qt::KeepAspectRatio, Qt::SmoothTransformation);
2407  // imprint the export type on the drag pixmap
2409  { QPainter painter(&img);
2410  QFont smallfont = QFont("Helvetica", 8);
2411  smallfont.setPixelSize(12);
2412  painter.setFont(smallfont);
2413  painter.setRenderHint(QPainter::TextAntialiasing, false);
2414  QRect rall = QRect(QPoint(0,0), img.size());
2415  QRect bb = painter.boundingRect(rall, Qt::AlignBottom|Qt::AlignRight, exportProfileText);
2416  klfDbg("BB is "<<bb) ;
2417  painter.setPen(QPen(QColor(255,255,255,0), 0, Qt::NoPen));
2418  painter.fillRect(bb, QColor(150,150,150,128));
2419  painter.setPen(QPen(QColor(0,0,0), 1, Qt::SolidLine));
2420  painter.drawText(rall, Qt::AlignBottom|Qt::AlignRight, exportProfileText);
2421  /*
2422  QRect bb = painter.fontMetrics().boundingRect(exportProfileText);
2423  QPoint translate = QPoint(img.width(), img.height()) - bb.bottomRight();
2424  painter.setPen(QPen(QColor(255,255,255,0), 0, Qt::NoPen));
2425  painter.fillRect(translate.x(), translate.y(), bb.width(), bb.height(), QColor(128,128,128,128));
2426  painter.setPen(QPen(QColor(0,0,0), 1, Qt::SolidLine));
2427  painter.drawText(translate, exportProfileText);*/
2428  }
2429  QPixmap p = QPixmap::fromImage(img);
2430  drag->setPixmap(p);
2431  drag->setDragCursor(p, Qt::MoveAction);
2432  drag->setHotSpot(QPoint(p.width()/2, p.height()));
2433  drag->exec(Qt::CopyAction);
2434 }
2435 
2437 {
2438 #ifdef Q_WS_WIN
2439  extern void klfWinClipboardCopy(HWND h, const QStringList& wintypes,
2440  const QList<QByteArray>& datalist);
2441 
2442  QString profilename = klfconfig.UI.copyExportProfile;
2444 
2445  QStringList mimetypes = p.mimeTypes();
2446  QStringList wintypes;
2447  QList<QByteArray> datalist;
2448 
2449  int k;
2450  for (k = 0; k < mimetypes.size(); ++k) {
2451  QString mimetype = mimetypes[k];
2452  QString wintype = p.respectiveWinType(k); // queries the exporter if needed
2453  if (wintype.isEmpty())
2454  wintype = mimetype;
2456  if (exporter == NULL) {
2457  qWarning()<<KLF_FUNC_NAME<<": Can't find exporter for type "<<mimetype
2458  <<", winformat="<<wintype<<".";
2459  continue;
2460  }
2461  QByteArray data = exporter->data(mimetype, _output);
2462  wintypes << wintype;
2463  datalist << data;
2464  }
2465 
2466  klfWinClipboardCopy(winId(), wintypes, datalist);
2467 
2468 #else
2470  QApplication::clipboard()->setMimeData(mimedata, QClipboard::Clipboard);
2471 #endif
2472 
2474  showExportMsgLabel(tr("Copied as <b>%1</b>").arg(profile.description()));
2475 }
2476 
2477 void KLFMainWin::slotSave(const QString& suggestfname)
2478 {
2479  // application-long persistent selectedfilter
2480  static QString selectedfilter;
2481 
2482  QStringList formatlist, filterformatlist;
2483  QMap<QString,QString> formatsByFilterName;
2485 
2486  for (QList<QByteArray>::iterator it = formats.begin(); it != formats.end(); ++it) {
2487  QString f = (*it).toLower();
2488  if (f == "jpg" || f == "jpeg" || f == "png" || f == "pdf" || f == "eps")
2489  continue;
2490  QString s = tr("%1 Image (*.%2)").arg(f).arg(f);
2491  filterformatlist << s;
2492  formatlist.push_back(f);
2493  formatsByFilterName[s] = f;
2494  }
2495 
2496  QMap<QString,QString> externFormatsByFilterName;
2497  QMap<QString,KLFAbstractOutputSaver*> externSaverByKey;
2498  int k, j;
2499  for (k = 0; k < pOutputSavers.size(); ++k) {
2500  QStringList xoformats = pOutputSavers[k]->supportedMimeFormats();
2501  for (j = 0; j < xoformats.size(); ++j) {
2502  QString f = QString("%1 (%2)").arg(pOutputSavers[k]->formatTitle(xoformats[j]),
2503  pOutputSavers[k]->formatFilePatterns(xoformats[j]).join(" "));
2504  filterformatlist << f;
2505  externFormatsByFilterName[f] = xoformats[j];
2506  externSaverByKey[xoformats[j]] = pOutputSavers[k];
2507  }
2508  }
2509 
2510  QString s;
2511  s = tr("EPS PostScript (*.eps)");
2512  filterformatlist.push_front(s);
2513  formatlist.push_front("eps");
2514  formatsByFilterName[s] = "eps";
2515  s = tr("PDF Portable Document Format (*.pdf)");
2516  filterformatlist.push_front(s);
2517  formatlist.push_front("pdf");
2518  formatsByFilterName[s] = "pdf";
2519  s = tr("Standard JPEG Image (*.jpg *.jpeg)");
2520  filterformatlist.push_front(s);
2521  formatlist.push_front("jpeg");
2522  formatlist.push_front("jpg");
2523  formatsByFilterName[s] = "jpeg";
2524  selectedfilter = s = tr("Standard PNG Image (*.png)");
2525  filterformatlist.push_front(s);
2526  formatlist.push_front("png");
2527  formatsByFilterName[s] = "png";
2528 
2529  QString filterformat = filterformatlist.join(";;");
2530  QString fname, format;
2531 
2532  QString suggestion = suggestfname;
2533  if (suggestion.isEmpty())
2534  suggestion = klfconfig.UI.lastSaveDir;
2535  if (suggestion.isEmpty())
2536  suggestion = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
2537 
2538  fname = QFileDialog::getSaveFileName(this, tr("Save Image Formula"), suggestion, filterformat,
2539  &selectedfilter);
2540 
2541  if (fname.isEmpty())
2542  return;
2543 
2544  // first test if it's an extern-format
2545  if ( externFormatsByFilterName.contains(selectedfilter) ) {
2546  // use an external output-saver
2547  QString key = externFormatsByFilterName[selectedfilter];
2548  if ( ! externSaverByKey.contains(key) ) {
2549  qWarning()<<KLF_FUNC_NAME<<": Internal error: externSaverByKey() does not contain key="<<key
2550  <<": "<<externSaverByKey;
2551  return;
2552  }
2553  KLFAbstractOutputSaver *saver = externSaverByKey[key];
2554  if (saver == NULL) {
2555  qWarning()<<KLF_FUNC_NAME<<": Internal error: saver is NULL!";
2556  return;
2557  }
2558  bool result = saver->saveToFile(key, fname, _output);
2559  if (!result)
2560  qWarning()<<KLF_FUNC_NAME<<": saver failed to save format "<<key<<".";
2561  return;
2562  }
2563 
2564  QFileInfo fi(fname);
2566  if ( fi.suffix().length() == 0 ) {
2567  // get format and suffix from selected filter
2568  if ( ! formatsByFilterName.contains(selectedfilter) && ! externFormatsByFilterName.contains(selectedfilter) ) {
2569  qWarning("%s: ERROR: Unknown format filter selected: `%s'! Assuming PNG!\n", KLF_FUNC_NAME,
2570  qPrintable(selectedfilter));
2571  format = "png";
2572  } else {
2573  format = formatsByFilterName[selectedfilter];
2574  }
2575  fname += "."+format;
2576  // !! : fname has changed, potentially the file could exist, user would not have been warned.
2577  if (QFile::exists(fname)) {
2578  int r = QMessageBox::warning(this, tr("File Exists"),
2579  tr("The file <b>%1</b> already exists.\nOverwrite?").arg(fname),
2580  QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::No);
2581  if (r == QMessageBox::Yes) {
2582  // will continue in this function.
2583  } else if (r == QMessageBox::No) {
2584  // re-prompt for file name & save (by recursion), and return
2585  slotSave(fname);
2586  return;
2587  } else {
2588  // cancel
2589  return;
2590  }
2591  }
2592  }
2593  fi.setFile(fname);
2594  int index = formatlist.indexOf(fi.suffix().toLower());
2595  if ( index < 0 ) {
2596  // select PNG by default if suffix is not recognized
2597  QMessageBox msgbox(this);
2598  msgbox.setIcon(QMessageBox::Warning);
2599  msgbox.setWindowTitle(tr("Extension not recognized"));
2600  msgbox.setText(tr("Extension <b>%1</b> not recognized.").arg(fi.suffix().toUpper()));
2601  msgbox.setInformativeText(tr("Press \"Change\" to change the file name, or \"Use PNG\" to save as PNG."));
2602  QPushButton *png = new QPushButton(tr("Use PNG"), &msgbox);
2603  msgbox.addButton(png, QMessageBox::AcceptRole);
2604  QPushButton *chg = new QPushButton(tr("Change ..."), &msgbox);
2605  msgbox.addButton(chg, QMessageBox::ActionRole);
2606  QPushButton *cancel = new QPushButton(tr("Cancel"), &msgbox);
2607  msgbox.addButton(cancel, QMessageBox::RejectRole);
2608  msgbox.setDefaultButton(chg);
2609  msgbox.setEscapeButton(cancel);
2610  msgbox.exec();
2611  if (msgbox.clickedButton() == png) {
2612  format = "png";
2613  } else if (msgbox.clickedButton() == cancel) {
2614  return;
2615  } else {
2616  // re-prompt for file name & save (by recursion), and return
2617  slotSave(fname);
2618  return;
2619  }
2620  } else {
2621  format = formatlist[index];
2622  }
2623 
2624  // The Qt dialog, or us, already asked user to confirm overwriting existing files
2625 
2626  QString error;
2627  bool res = KLFBackend::saveOutputToFile(_output, fname, format, &error);
2628  if ( ! res ) {
2629  QMessageBox::critical(this, tr("Error"), error);
2630  }
2631 }
2632 
2633 
2635 {
2636  raise();
2637  activateWindow();
2638  u->txtLatex->setFocus();
2639 }
2640 
2642 {
2644  u->txtLatex->selectAll();
2645 }
2646 
2648 {
2649  if ( ! u->btnShowBigPreview->isEnabled() )
2650  return;
2651 
2652  QString text =
2653  tr("<p>%1</p><p align=\"right\" style=\"font-size: %2pt; font-style: italic;\">"
2654  "This preview can be opened with the <strong>F2</strong> key. Hit "
2655  "<strong>Esc</strong> to close.</p>")
2656  .arg(u->lblOutput->bigPreviewText())
2657  .arg(QFontInfo(qApp->font()).pointSize()-1);
2658  QWhatsThis::showText(u->btnEvaluate->pos(), text, u->lblOutput);
2659 }
2660 
2661 
2662 
2664 {
2665  QAction *a = qobject_cast<QAction*>(sender());
2666  if (a) {
2667  slotSetDPI(a->data().toInt());
2668  }
2669 }
2670 
2671 
2673 {
2674  KLFStyle sty;
2675 
2676  sty.name = QString::null;
2677  sty.fg_color = u->colFg->color().rgb();
2678  QColor bgc = u->colBg->color();
2679  sty.bg_color = qRgba(bgc.red(), bgc.green(), bgc.blue(), u->chkBgTransparent->isChecked() ? 0 : 255 );
2680  sty.mathmode = (u->chkMathMode->isChecked() ? u->cbxMathMode->currentText() : "...");
2681  sty.preamble = u->txtPreamble->toPlainText();
2682  sty.dpi = u->spnDPI->value();
2683 
2684  if (u->gbxOverrideMargins->isChecked()) {
2685  sty.overrideBBoxExpand.top = u->spnMarginTop->valueInRefUnit();
2686  sty.overrideBBoxExpand.right = u->spnMarginRight->valueInRefUnit();
2687  sty.overrideBBoxExpand.bottom = u->spnMarginBottom->valueInRefUnit();
2688  sty.overrideBBoxExpand.left = u->spnMarginLeft->valueInRefUnit();
2689  }
2690 
2691  return sty;
2692 }
2693 
2695 {
2696  return u->txtLatex->font();
2697 }
2699 {
2700  return u->txtPreamble->font();
2701 }
2702 
2703 void KLFMainWin::slotLoadStyleAct()
2704 {
2705  QAction *a = qobject_cast<QAction*>(sender());
2706  if (a) {
2707  slotLoadStyle(a->data().toInt());
2708  }
2709 }
2710 
2712 {
2713  QColor cfg, cbg;
2714  cfg.setRgb(style.fg_color);
2715  cbg.setRgb(style.bg_color);
2716  u->colFg->setColor(cfg);
2717  u->colBg->setColor(cbg);
2718  u->chkBgTransparent->setChecked(qAlpha(style.bg_color) == 0);
2719  u->chkMathMode->setChecked(style.mathmode.simplified() != "...");
2720  if (style.mathmode.simplified() != "...")
2721  u->cbxMathMode->setEditText(style.mathmode);
2722  slotSetPreamble(style.preamble); // to preserve text edit undo/redo
2723  u->spnDPI->setValue(style.dpi);
2724 
2725  if (style.overrideBBoxExpand.valid()) {
2726  u->gbxOverrideMargins->setChecked(true);
2727  u->spnMarginTop->setValueInRefUnit(style.overrideBBoxExpand.top);
2728  u->spnMarginRight->setValueInRefUnit(style.overrideBBoxExpand.right);
2729  u->spnMarginBottom->setValueInRefUnit(style.overrideBBoxExpand.bottom);
2730  u->spnMarginLeft->setValueInRefUnit(style.overrideBBoxExpand.left);
2731  } else {
2732  u->gbxOverrideMargins->setChecked(false);
2733  }
2734 }
2735 
2737 {
2738  if (n < 0 || n >= (int)_styles.size())
2739  return; // let's not try to load an inexistant style...
2740 
2741  slotLoadStyle(_styles[n]);
2742 }
2744 {
2745  KLFStyle sty;
2746 
2747  QString name = QInputDialog::getText(this, tr("Enter Style Name"),
2748  tr("Enter new style name:"));
2749  if (name.isEmpty()) {
2750  return;
2751  }
2752 
2753  // check to see if style exists already
2754  int found_i = -1;
2755  for (int kl = 0; found_i == -1 && kl < _styles.size(); ++kl) {
2756  if (_styles[kl].name.trimmed() == name.trimmed()) {
2757  found_i = kl;
2758  // style exists already
2759  int r = QMessageBox::question(this, tr("Overwrite Style"),
2760  tr("Style name already exists. Do you want to overwrite?"),
2761  QMessageBox::Yes|QMessageBox::No|QMessageBox::Cancel, QMessageBox::No);
2762  switch (r) {
2763  case QMessageBox::No:
2764  slotSaveStyle(); // recurse, ask for new name.
2765  return; // and stop this function execution of course!
2766  case QMessageBox::Yes:
2767  break; // continue normally
2768  default:
2769  return; // forget everything; "Cancel"
2770  }
2771  }
2772  }
2773 
2774  sty = currentStyle();
2775  sty.name = name;
2776 
2777  if (found_i == -1)
2778  _styles.append(sty);
2779  else
2780  _styles[found_i] = sty;
2781 
2783 
2784  // auto-save our style list
2785  saveStyles();
2786 
2787  emit stylesChanged();
2788 }
2789 
2791 {
2792  mStyleManager->show();
2793 }
2794 
2795 
2797 {
2798  mSettingsDialog->show();
2799 }
2800 
2801 
2803 {
2804  if (_ignore_close_event) {
2805  // simple hide, not close
2806  hide();
2807 
2808  event->ignore();
2809  return;
2810  }
2811 
2812  event->accept();
2813  quit();
2814 }
2815 
2816 
2817 
2818 
QHash< QWidget *, bool > pSavedWindowShownStatus
Definition: klfmainwin.h:503
This resource is the Archive resource.
Definition: klflibbrowser.h:57
void updatePreviewBuilderThreadInput()
KLFBackend::klfInput collectInput(bool isFinal)
KLF_EXPORT void klf_reload_translations(QCoreApplication *app, const QString &currentLocale)
Definition: klfmain.cpp:396
void removeMessage(const QString &msgKey)
Definition: klfmainwin_p.h:211
static QList< QColor > colorList()
Instructs not to raise the tab during this call of openResource()
Definition: klflibbrowser.h:61
showText(const QPoint &pos, const QString &text, QWidget *w=0)
void registerOutputSaver(KLFAbstractOutputSaver *outputsaver)
showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect)
setHotSpot(const QPoint &hotspot)
bool menuExportProfileAffectsDrag
Definition: klfconfig.h:202
void registerHelpLinkAction(const QString &path, QObject *object, const char *member, bool wantUrlParam)
setPointSize(int pointSize)
cap(int nth=0)
setHeight(int height)
void slotStyleManager()
data(const QString &mimeType)
bool try_load_style_list(const QString &fileName)
Definition: klfmainwin.cpp:751
void getMissingCmdsFor(const QString &symbol, QStringList *missingCmds, QString *guiText, bool wantHtmlText=true)
void showSettingsHelpLinkAction(const QUrl &link)
contains(const Key &key)
setDefaultButton(QPushButton *button)
systemEnvironment()
fillRect(const QRectF &rectangle, const QBrush &brush)
void slotEnsurePreambleCmd(const QString &line)
void unregisterDataOpener(KLFAbstractDataOpener *dataopener)
virtual bool createSubResource(const QString &subResource, const QString &subResourceTitle)
Create a new sub-resource.
Definition: klflib.cpp:599
virtual QVariant subResourceProperty(const QString &subResource, int propId) const
Definition: klflib.cpp:528
void previewAvailable(const QImage &preview, bool latexerror)
QList< QColor > colorChooseWidgetRecent
Definition: klfconfig.h:187
QMenu * mStyleMenu
Definition: klfmainwin.h:452
QString _widgetstyle
Definition: klfmainwin.h:508
An export profile grouping several mime types.
Definition: klfmime.h:103
setRenderHint(RenderHint hint, bool on=true)
void timerEvent(QTimerEvent *e)
updateGeometry()
A structure that describes a query for query()
Definition: klflib.h:933
QFont applicationFont
Definition: klfconfig.h:179
QWaitCondition _condnewinfoavail
Definition: klfmainwin.h:203
static KLFMimeExportProfile findExportProfile(const QString &pname)
Definition: klfmime.cpp:287
bool menuExportProfileAffectsCopy
Definition: klfconfig.h:203
setColor(ColorGroup group, ColorRole role, const QColor &color)
cursorForPosition(const QPoint &pos)
addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment=0)
setMimeData(QMimeData *data)
static KLFLatexSymbolsCache * theCache()
QList< QColor > userColorList
Definition: klfconfig.h:186
QStringList mimeTypes() const
Definition: klfmime.cpp:203
void refreshShowCorrectClearButton()
Definition: klfmainwin.cpp:572
Sub-Resources may be assigned properties and values.
Definition: klflib.h:515
QStringList preamble
KLFConfig klfconfig
Definition: klfconfig.cpp:88
bool showHintPopups
Definition: klfconfig.h:193
bool openData(const QMimeData *mimeData, bool *openerFound=NULL)
bool checkExePaths()
Definition: klfconfig.cpp:382
bool glowEffect
Definition: klfconfig.h:197
double rborderoffset
Definition: klfconfig.h:228
void addWhatsNewText(const QString &htmlSnipplet)
bool event(QEvent *e)
KLFStyleManager * mStyleManager
Definition: klfmainwin.h:428
void slotSetLatex(const QString &latex)
struct KLFConfig::@1 UI
This resource is the History resource.
Definition: klflibbrowser.h:56
void slotEvaluate()
bool _evaloutput_uptodate
Definition: klfmainwin.h:465
virtual QByteArray data(const QString &key, const KLFBackend::klfOutput &klfoutput)=0
bool _ignore_close_event
Definition: klfmainwin.h:494
virtual bool locked() const
Is this resource is locked?
Definition: klflib.h:610
void slotSymbolsButtonRefreshState(bool on)
KLFLibResourceEngine * getOpenResource(const QUrl &url)
void refreshStylePopupMenus()
Definition: klfmainwin.cpp:711
KLFStyle currentStyle() const
queryItems()
setFile(const QString &file)
QList< KLFAbstractOutputSaver * > pOutputSavers
Definition: klfmainwin.h:513
virtual ~KLFMainWin()
Definition: klfmainwin.cpp:494
arg(const QString &a, int fieldWidth=0, const QChar &fillChar=QLatin1Char( ' ')
virtual bool saveToFile(const QString &key, const QString &fileName, const KLFBackend::klfOutput &output)=0
Resource &#39;Close&#39; GUI button is disabled (grayed)
Definition: klflibbrowser.h:54
setPixmap(const QPixmap &pixmap)
color(ColorGroup group, ColorRole role)
void displayError(const QString &errormsg)
removeAt(int i)
void unregisterOutputSaver(KLFAbstractOutputSaver *outputsaver)
setDragCursor(const QPixmap &cursor, Qt::DropAction action)
bool valid() const
QFont latexEditFont
Definition: klfconfig.h:180
QString latexWithCategoryTagsComments() const
Definition: klflib.h:90
setPen(const QPen &pen)
void slotSetDPI(int DPI)
virtual void addExtraText(const QString &htmlSnipplet)
Definition: klfmainwin_p.h:60
QHash< QWidget *, QRect > pLastWindowGeometries
Definition: klfmainwin.h:500
static QList< QColor > customColors()
virtual bool setSubResourceProperty(const QString &subResource, int propId, const QVariant &value)
Definition: klflib.cpp:593
#define klfDbg(streamableItems)
setAttribute(Qt::WidgetAttribute attribute, bool on=true)
void slotClearAll()
QList< HelpLinkAction > mHelpLinkActions
Definition: klfmainwin.h:444
virtual KLFLibResourceEngine * openResource(const QUrl &location, QObject *parent=NULL)=0
QColor glowEffectColor
Definition: klfconfig.h:198
fromImage(const QImage &image, Qt::ImageConversionFlags flags=Qt::AutoColor)
#define KLF_DEBUG_BLOCK(msg)
Qt::SortOrder orderDirection
Definition: klflib.h:950
QHash< QWidget *, bool > pLastWindowShownStatus
Definition: klfmainwin.h:499
setAlpha(int alpha)
void slotSetFgColor(const QColor &fgcolor)
QString name
void slotClearLatex()
virtual bool setViewType(const QString &viewType)
Definition: klflib.cpp:569
prepend(const QString &str)
bool thisVersionMajMinFirstRun
Definition: klfconfig.h:163
QFont preambleEditFont
Definition: klfconfig.h:181
static QString find_list_agreement(const QStringList &a, const QStringList &b)
void slotSetExportProfile(const QString &exportProfile)
virtual bool setTitle(const QString &title)
set a new resource title for this library resource
Definition: klflib.cpp:555
join(const QString &separator)
#define KLFERR_NOLATEXPROG
hasQueryItem(const QString &key)
void setTxtLatexFont(const QFont &f)
QStringList customMathModes
Definition: klfconfig.h:200
QString tempDir
Definition: klfconfig.h:220
void slotExpandOrShrink()
static QString kdelocate(const char *fname)
Definition: klfmainwin.cpp:732
void loadSettings()
Definition: klfmainwin.cpp:602
setRgb(int r, int g, int b, int a=255)
QString mathmode
setNamedColor(const QString &name)
KLFLibResourceEngine * mHistoryLibResource
Definition: klfmainwin.h:446
void refreshAllWindowStyleSheets()
static EntryMatchCondition mkMatchAll()
Definition: klflib.cpp:776
void slotSave(const QString &suggestedFname=QString::null)
homePath()
QString latex() const
Definition: klflib.h:82
bool restoreURLs
Definition: klfconfig.h:239
addAction(const QString &text)
bool outlineFonts
Definition: klfconfig.h:230
QList< QWidget * > pWindowList
Definition: klfmainwin.h:496
void hideEvent(QHideEvent *e)
void loadGuiState(const QVariantMap &state, bool openURLs=true)
void showExportMsgLabel(const QString &msg, int timeout=3000)
Definition: klfmainwin.cpp:695
void childEvent(QChildEvent *e)
movePosition(MoveOperation operation, MoveMode mode=MoveAnchor, int n=1)
setSpacing(int spacing)
void applicationLocaleChanged(const QString &newLocale)
#define KLF_ASSERT_NOT_NULL(ptr, msg, failaction)
Dialog that presents a selection of latex symbols to user.
bool openFiles(const QStringList &fileList)
replace(int position, int n, const QString &after)
The Latex Code of the equation.
Definition: klflib.h:62
struct KLFConfig::@0 Core
indexOf(const T &value, int from=0)
KLFPreviewBuilderThread(QObject *parent, KLFBackend::klfInput input, KLFBackend::klfSettings settings, int labelwidth, int labelheight)
Definition: klfmainwin.cpp:101
void slotSaveStyle()
KLFStyleList _styles
Definition: klfmainwin.h:448
start(Priority priority=InheritPriority)
setPath(const QString &path)
matchedLength()
virtual bool isReadOnly() const
query read-only state
Definition: klflib.h:595
static QList< KLFMimeExportProfile > exportProfileList()
Definition: klfmime.cpp:271
virtual void show()
Definition: klfmainwin_p.h:112
void slotActivateEditorSelectAll()
setPixelSize(int pixelSize)
QString execLatex
Definition: klfconfig.h:221
QList< QColor > colorChooseWidgetCustom
Definition: klfconfig.h:188
QString respectiveWinType(int k) const
Definition: klfmime.cpp:235
setMapping(QObject *sender, int id)
bool _firstshow
Definition: klfmainwin.h:455
setFont(const QFont &font)
double lborderoffset
Definition: klfconfig.h:226
void showWhatsNew()
showEvent(QShowEvent *event)
fromLocal8Bit(const char *str, int size=-1)
QList< KLFAbstractDataOpener * > pDataOpeners
Definition: klfmainwin.h:514
append(const T &value)
QHash< QWidget *, bool > currentWindowShownStatus(bool mainWindowToo=false)
fromUtf8(const char *str, int size=-1)
matches(const QKeySequence &seq)
void closeEvent(QCloseEvent *e)
KLFAboutDialog * mAboutDialog
Definition: klfmainwin.h:430
bool _loadedlibrary
Definition: klfmainwin.h:454
A settings dialog.
Definition: klfsettings.h:46
boundingRect(const QRectF &rectangle, int flags, const QString &text)
void retranslateUi(bool alsoBaseUi=true)
Definition: klfmainwin.cpp:482
QString lastSaveDir
Definition: klfconfig.h:184
KLF_EXPORT QVariant klfLoadVariantFromText(const QByteArray &stringdata, const char *dataTypeName, const char *listOrMapDataTypeName)
void setQuitOnClose(bool quitOnClose)
QLabel * mExportMsgLabel
Definition: klfmainwin.h:469
question(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
KLFBackend::klfOutput _output
Definition: klfmainwin.h:460
bool openLibFiles(const QStringList &files, bool showLibrary=true)
virtual int query(const QString &subResource, const Query &query, QueryResult *result)=0
query entries in this resource with specified property values
KLFLatexSymbol findSymbol(const QString &symbolCode)
setWindowTitle(const QString &title)
QString category() const
Definition: klflib.h:86
A helper class to export KLF output to other applications.
Definition: klfmime.h:55
hideEvent(QHideEvent *event)
virtual bool setLocked(bool locked)
Set the resource to be locked.
Definition: klflib.cpp:559
removeAllQueryItems(const QString &key)
setWidth(int width)
insertText(const QString &text)
QHash< QWidget *, bool > prepareAllWindowShownStatus(bool visibleStatus, bool mainWindowToo=false)
QSize previewTooltipMaxSize
Definition: klfconfig.h:182
bool openFile(const QString &file)
KLFBackend::klfSettings _settings
Definition: klfmainwin.h:199
KLFProgErr(QWidget *parent, QString errtext)
Definition: klfmainwin.cpp:77
Data can be stored in separate sub-resources.
Definition: klflib.h:508
removeAll(const T &value)
void startupFinished()
Definition: klfmainwin.cpp:517
unsigned long fg_color
startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive)
setScheme(const QString &scheme)
KLFBackend::klfSettings _settings
Definition: klfmainwin.h:457
virtual ~KLFPreviewBuilderThread()
Definition: klfmainwin.cpp:108
create(const QString &key)
void slotSetPreamble(const QString &preamble)
int ensureHomeConfigDir()
Definition: klfconfig.cpp:365
QString dragExportProfile
Definition: klfconfig.h:196
void insertSymbol(const KLFLatexSymbol &symbol)
setEscapeButton(QAbstractButton *button)
QString execGs
Definition: klfconfig.h:223
virtual void setDescriptiveText(const QString &labelText)
wait(QMutex *mutex, unsigned long time=ULONG_MAX)
drawText(const QPointF &position, const QString &text)
void stylesChanged()
unsigned long bg_color
virtual QFont txtLatexFont() const
static void showError(QWidget *parent, QString text)
Definition: klfmainwin.cpp:91
QString libraryFileName
Definition: klfconfig.h:168
setAlignment(int alignment)
KLFLatexSyntaxHighlighter * preambleSyntaxHighlighter()
void showEvent(QShowEvent *e)
bool useSystemAppFont
Definition: klfconfig.h:178
replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs=Qt::CaseSensitive)
virtual KLFLibResourceEngine * createResource(const QString &scheme, const Parameters &parameters, QObject *parent=NULL)
Create a new resource of given type and parameters.
Definition: klflib.cpp:1178
addSeparator()
const char * key
bool canOpenData(const QByteArray &data)
The Category to which eq. belongs (path-style string)
Definition: klflib.h:66
void setTxtPreambleFont(const QFont &f)
void helpLinkAction(const QUrl &link)
open(OpenMode mode)
#define KLFERR_NOEPSTOPDFPROG
QStringList execenv
Definition: klfconfig.h:225
void showAbout()
scheme()
QString execDvips
Definition: klfconfig.h:222
virtual QString defaultSubResource() const
Definition: klflib.cpp:504
KLFStyle style used.
Definition: klflib.h:68
#define KLF_DEBUG_TIME_BLOCK(msg)
A text edit field that edits latex code.
Definition: klflatexedit.h:51
bool clearLatexOnly
Definition: klfconfig.h:194
void showControl(int controlNum)
void alterSetting(altersetting_which, int ivalue)
getText(QWidget *parent, const QString &title, const QString &label, QLineEdit::EchoMode mode=QLineEdit::Normal, const QString &text=QString()
void applySettings(const KLFBackend::klfSettings &s)
setData(const QVariant &userData)
QSize _shrinkedsize
Definition: klfmainwin.h:481
virtual uint supportedFeatureFlags() const
List of features supported by this resource engine.
Definition: klflib.h:550
void addMessage(const QString &msgKey, const QString &msgText)
Definition: klfmainwin_p.h:203
QString description() const
Definition: klfmime.h:119
static void klf_set_window_geometry(QWidget *w, QRect g)
Definition: klfmainwin.cpp:61
#define KLF_FUNC_NAME
virtual QList< entryId > insertEntries(const QString &subResource, const KLFLibEntryList &entrylist)=0
Insert new entries in this resource.
void registerDataOpener(KLFAbstractDataOpener *dataopener)
virtual QStringList subResourceList() const
Definition: klflib.h:722
void setWidgetStyle(const QString &qtstyle)
setFixedSize(const QSize &s)
Tags about the equation (string)
Definition: klflib.h:67
KLFWhatsNewDialog * mWhatsNewDialog
Definition: klfmainwin.h:431
static QString guessLocalFileScheme(const QString &fileName)
#define KLF_DATA_STREAM_APP_VERSION
Current datastream compatibility klatexformula version.
Definition: klfmain.h:280
QString preamble
KLFSettings * mSettingsDialog
Definition: klfmainwin.h:429
invokeMethod(QObject *obj, const char *member, Qt::ConnectionType type, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0)
void slotSettings()
struct KLFConfig::@3 BackendSettings
void evaluateFinished(const KLFBackend::klfOutput &output)
void slotSetBgColor(const QColor &bgcolor)
BBoxExpand overrideBBoxExpand
QImage preview() const
Definition: klflib.h:84
setShown(bool shown)
void saveLibraryState()
static QStringList listSubResources(const QUrl &url)
Definition: klflib.cpp:1231
QString homeConfigDir
Definition: klfconfig.h:151
virtual ~KLFProgErr()
Definition: klfmainwin.cpp:86
bool openLibFile(const QString &file, bool showLibrary=true)
A structure that will hold the result of a query() query.
Definition: klflib.h:970
void restoreFromLibrary(const KLFLibEntry &entry, uint restoreflags)
bool loadNamedStyle(const QString &sty)
Definition: klfmainwin.cpp:590
static QList< QColor > recentColors()
void refreshWindowSizes()
Definition: klfmainwin.cpp:555
void slotExpand(bool expanded=true)
mid(int position, int n=-1)
void saveStyles()
Definition: klfmainwin.cpp:822
virtual QFont txtPreambleFont() const
static KLFMimeExporter * mimeExporterLookup(const QString &key)
Definition: klfmime.cpp:66
static QRect klf_get_window_geometry(QWidget *w)
Definition: klfmainwin.cpp:51
QList< QAction * > pExportProfileQuickMenuActionList
Definition: klfmainwin.h:479
activateWindow()
wait(unsigned long time=ULONG_MAX)
An entry (single formula) in the library.
Definition: klflib.h:55
void settingsChanged(const KLFBackend::klfSettings &settings, int labelwidth, int labelheight)
Definition: klfmainwin.cpp:188
scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode=Qt::IgnoreAspectRatio, Qt::TransformationMode transformMode=Qt::FastTransformation)
QList< int > wantedEntryProperties
Definition: klflib.h:951
KLFLatexEdit * latexEdit()
int writeToConfig()
Definition: klfconfig.cpp:609
void slotEvaluateAndSave(const QString &output, const QString &format)
void slotActivateEditor()
QString copyExportProfile
Definition: klfconfig.h:195
virtual bool hasSubResource(const QString &subResource) const
Definition: klflib.cpp:496
#define KLFERR_NODVIPSPROG
static KLFLibEngineFactory * findFactoryFor(const QUrl &url)
Definition: klflib.cpp:1163
KLFMainWinPopup * mPopup
Definition: klfmainwin.h:433
addItem(QLayoutItem *item, int row, int column, int rowSpan=1, int columnSpan=1, Qt::Alignment alignment=0)
const char * format
KLFLibBrowser * mLibBrowser
Definition: klfmainwin.h:426
void slotSymbols(bool showsymbs=true)
getSaveFileName(QWidget *parent=0, const QString &caption=QString()
critical(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
void showRealTimePreview(const QImage &preview, bool latexerror)
static KLFLibResourceEngine * openURL(const QUrl &location, QObject *parent=NULL)
Definition: klflib.cpp:1191
KLFLatexSymbols * mLatexSymbols
Definition: klfmainwin.h:427
bool canOpenFile(const QString &fileName)
virtual QList< KLFLibEntryWithId > allEntries(const QString &subResource, const QList< int > &wantedEntryProperties=QList< int >())=0
query all entries in this resource
void slotLibrary(bool showlib)
void insertDelimiter(const QString &delim, int charsBack=1)
static bool saveOutputToFile(const klfOutput &output, const QString &fileName, const QString &format=QString(), QString *errorString=NULL)
#define KLFERR_NOGSPROG
bool eventFilter(QObject *obj, QEvent *event)
void slotShowBigPreview()
void slotLibraryButtonRefreshState(bool on)
KLF_EXPORT QByteArray klfSaveVariantToText(const QVariant &value, bool saveListAndMapsAsXML)
fromLatin1(const char *str, int size=-1)
start(int msec)
addQueryItem(const QString &key, const QString &value)
warning(QWidget *parent, const QString &title, const QString &text, StandardButtons buttons=Ok, StandardButton defaultButton=NoButton)
indexOf(const QRegExp &rx, int from=0)
contains(const Key &key)
void loadLibrarySavedState()
KLF_EXPORT void klfDataStreamWriteHeader(QDataStream &stream, const QString headermagic)
Definition: klfmain.cpp:529
virtual void show()
Definition: klfmainwin_p.h:144
void slotDrag()
addButton(QAbstractButton *button, ButtonRole role)
KLFBackend::klfInput _input
Definition: klfmainwin.h:198
QSize labelOutputFixedSize
Definition: klfconfig.h:183
bool loadDefaultStyle()
Definition: klfmainwin.cpp:580
void slotLoadStyle(int stylenum)
filter(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive)
createElement(const QString &tagName)
void setApplicationLocale(const QString &locale)
An abstract resource engine.
Definition: klflib.h:440
isWidgetType()
KLFPreviewBuilderThread * mPreviewBuilderThread
Definition: klfmainwin.h:467
QString execEpstopdf
Definition: klfconfig.h:224
openUrl(const QUrl &url)
bool given as an int value
Definition: klfmainwin.h:254
The Date/Time at which the equation was evaluated.
Definition: klflib.h:63
struct KLFConfig::@4 LibraryBrowser
QSize _expandedsize
Definition: klfmainwin.h:482
void setWindowShownStatus(const QHash< QWidget *, bool > &windowshownflags)
QString libraryLibScheme
Definition: klfconfig.h:171
bool openResource(const QUrl &url, uint resourceRoleFlags=NoChangeFlag, const QString &viewTypeIdentifier=QString())
KLFLib::EntryMatchCondition matchCondition
Definition: klflib.h:946
void loadStyles()
Definition: klfmainwin.cpp:783
void saveSettings()
Definition: klfmainwin.cpp:621
bool inputChanged(const KLFBackend::klfInput &input)
Definition: klfmainwin.cpp:177
void slotSetMathMode(const QString &mathmode)
exactMatch(const QString &str)
event(QEvent *event)
indexOf(const QString &str, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive)
unsigned long bg_color
KLF_EXPORT bool klfDataStreamReadHeader(QDataStream &stream, const QStringList possibleHeaders, QString *readHeader, QString *readCompatKLFVersion)
Definition: klfmain.cpp:546
void slotCopy()
static klfOutput getLatexFormula(const klfInput &in, const klfSettings &settings)
double tborderoffset
Definition: klfconfig.h:227
QString tags() const
Definition: klflib.h:87
bool enableRealTimePreview
Definition: klfconfig.h:191
KLFLatexSyntaxHighlighter * syntaxHighlighter()
Ui::KLFMainWin * u
Definition: klfmainwin.h:424
QVariantMap saveGuiState()
queryItemValue(const QString &key)
bool _settings_altered
Definition: klfmainwin.h:458
toEncoded(FormattingOptions options=None)
KLF_EXPORT QDomElement klfSaveVariantMapToXML(const QVariantMap &vmap, QDomElement baseNode)
virtual entryId insertEntry(const QString &subResource, const KLFLibEntry &entry)
Insert an entry into this resource.
Definition: klflib.cpp:669
bool enableToolTipPreview
Definition: klfconfig.h:190
void loadLibrary()
Definition: klfmainwin.cpp:838
fromLocalFile(const QString &localFile)
int pExportMsgLabelTimerId
Definition: klfmainwin.h:471
toByteArray(int indent=1)
lastIndexOf(const QString &str, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive)
QStringList messageKeys()
Definition: klfmainwin_p.h:193
setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0)
unsigned long fg_color
double bborderoffset
Definition: klfconfig.h:229
KLF_EXPORT QVariantMap klfLoadVariantMapFromXML(const QDomElement &xmlNode)
void slotPresetDPISender()
int glowEffectRadius
Definition: klfconfig.h:199
KLFStyle style() const
Definition: klflib.h:88

Generated by doxygen 1.8.11