1 /**
2 * \file GuiDocument.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
5 *
6 * \author Edwin Leuven
7 * \author Richard Heck (modules)
8 *
9 * Full author contact details are available in file CREDITS.
10 */
11
12 #include <config.h>
13
14 #include "GuiDocument.h"
15
16 #include "CategorizedCombo.h"
17 #include "GuiApplication.h"
18 #include "GuiBranches.h"
19 #include "GuiIndices.h"
20 #include "GuiSelectionManager.h"
21 #include "LaTeXHighlighter.h"
22 #include "LengthCombo.h"
23 #include "PanelStack.h"
24 #include "Validator.h"
25
26 #include "LayoutFile.h"
27 #include "BranchList.h"
28 #include "buffer_funcs.h"
29 #include "Buffer.h"
30 #include "BufferParams.h"
31 #include "BufferView.h"
32 #include "CiteEnginesList.h"
33 #include "Color.h"
34 #include "ColorCache.h"
35 #include "Converter.h"
36 #include "Cursor.h"
37 #include "Encoding.h"
38 #include "FloatPlacement.h"
39 #include "Format.h"
40 #include "FuncRequest.h"
41 #include "IndicesList.h"
42 #include "Language.h"
43 #include "LaTeXFeatures.h"
44 #include "LaTeXFonts.h"
45 #include "Layout.h"
46 #include "LayoutEnums.h"
47 #include "LayoutModuleList.h"
48 #include "LyXRC.h"
49 #include "ModuleList.h"
50 #include "OutputParams.h"
51 #include "PDFOptions.h"
52 #include "qt_helpers.h"
53 #include "Session.h"
54 #include "Spacing.h"
55 #include "TextClass.h"
56 #include "Undo.h"
57 #include "VSpace.h"
58
59 #include "insets/InsetListingsParams.h"
60
61 #include "support/debug.h"
62 #include "support/docstream.h"
63 #include "support/FileName.h"
64 #include "support/filetools.h"
65 #include "support/gettext.h"
66 #include "support/lassert.h"
67 #include "support/lstrings.h"
68 #include "support/TempFile.h"
69
70 #include "frontends/alert.h"
71
72 #include <QAbstractItemModel>
73 #include <QButtonGroup>
74 #include <QColor>
75 #include <QColorDialog>
76 #include <QCloseEvent>
77 #include <QFontDatabase>
78 #include <QHeaderView>
79 #include <QScrollBar>
80 #include <QTextBoundaryFinder>
81 #include <QTextCursor>
82
83 #include <sstream>
84 #include <vector>
85
86 #ifdef IN
87 #undef IN
88 #endif
89
90
91 // a style sheet for buttons
92 // this is for example used for the background color setting button
colorButtonStyleSheet(QColor const & bgColor)93 static inline QString colorButtonStyleSheet(QColor const & bgColor)
94 {
95 if (bgColor.isValid()) {
96 QString rc = QLatin1String("background-color:");
97 rc += bgColor.name();
98 return rc;
99 }
100 return QString();
101 }
102
103
104 using namespace std;
105 using namespace lyx::support;
106
107
108 namespace {
109
110 char const * const tex_graphics[] =
111 {
112 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
113 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
114 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
115 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
116 "xetex", "none", ""
117 };
118
119
120 char const * const tex_graphics_gui[] =
121 {
122 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
123 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
124 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
125 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
126 "XeTeX", N_("None"), ""
127 };
128
129
130 char const * backref_opts[] =
131 {
132 "false", "section", "slide", "page", ""
133 };
134
135
136 char const * backref_opts_gui[] =
137 {
138 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
139 };
140
141
142 char const * lst_packages[] =
143 {
144 "Listings", "Minted", ""
145 };
146
147
148 vector<string> engine_types_;
149 vector<pair<string, QString> > pagestyles;
150
151 QMap<QString, QString> rmfonts_;
152 QMap<QString, QString> sffonts_;
153 QMap<QString, QString> ttfonts_;
154 QMap<QString, QString> mathfonts_;
155
156
157 } // anonymous namespace
158
159 namespace lyx {
160
161 RGBColor set_backgroundcolor;
162 bool is_backgroundcolor;
163 RGBColor set_fontcolor;
164 bool is_fontcolor;
165 RGBColor set_notefontcolor;
166 RGBColor set_boxbgcolor;
167 bool forced_fontspec_activation;
168
169 namespace {
170 // used when sorting the textclass list.
171 class less_textclass_avail_desc
172 : public binary_function<string, string, int>
173 {
174 public:
operator ()(string const & lhs,string const & rhs) const175 bool operator()(string const & lhs, string const & rhs) const
176 {
177 // Ordering criteria:
178 // 1. Availability of text class
179 // 2. Description (lexicographic)
180 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
181 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
182 int const order = compare_no_case(
183 translateIfPossible(from_utf8(tc1.description())),
184 translateIfPossible(from_utf8(tc2.description())));
185 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
186 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() && order < 0);
187 }
188 };
189
190 } // namespace
191
192 namespace frontend {
193 namespace {
194
getRequiredList(string const & modName)195 vector<string> getRequiredList(string const & modName)
196 {
197 LyXModule const * const mod = theModuleList[modName];
198 if (!mod)
199 return vector<string>(); //empty such thing
200 return mod->getRequiredModules();
201 }
202
203
getExcludedList(string const & modName)204 vector<string> getExcludedList(string const & modName)
205 {
206 LyXModule const * const mod = theModuleList[modName];
207 if (!mod)
208 return vector<string>(); //empty such thing
209 return mod->getExcludedModules();
210 }
211
212
getModuleCategory(string const & modName)213 docstring getModuleCategory(string const & modName)
214 {
215 LyXModule const * const mod = theModuleList[modName];
216 if (!mod)
217 return docstring();
218 return from_utf8(mod->category());
219 }
220
221
getModuleDescription(string const & modName)222 docstring getModuleDescription(string const & modName)
223 {
224 LyXModule const * const mod = theModuleList[modName];
225 if (!mod)
226 return _("Module not found!");
227 // FIXME Unicode
228 return translateIfPossible(from_utf8(mod->getDescription()));
229 }
230
231
getPackageList(string const & modName)232 vector<string> getPackageList(string const & modName)
233 {
234 LyXModule const * const mod = theModuleList[modName];
235 if (!mod)
236 return vector<string>(); //empty such thing
237 return mod->getPackageList();
238 }
239
240
isModuleAvailable(string const & modName)241 bool isModuleAvailable(string const & modName)
242 {
243 LyXModule const * const mod = theModuleList[modName];
244 if (!mod)
245 return false;
246 return mod->isAvailable();
247 }
248
249 } // anonymous namespace
250
251
252 /////////////////////////////////////////////////////////////////////
253 //
254 // ModuleSelectionManager
255 //
256 /////////////////////////////////////////////////////////////////////
257
258 /// SelectionManager for use with modules
259 class ModuleSelectionManager : public GuiSelectionManager
260 {
261 public:
262 ///
ModuleSelectionManager(QObject * parent,QTreeView * availableLV,QListView * selectedLV,QPushButton * addPB,QPushButton * delPB,QPushButton * upPB,QPushButton * downPB,GuiIdListModel * availableModel,GuiIdListModel * selectedModel,GuiDocument const * container)263 ModuleSelectionManager(QObject * parent,
264 QTreeView * availableLV,
265 QListView * selectedLV,
266 QPushButton * addPB,
267 QPushButton * delPB,
268 QPushButton * upPB,
269 QPushButton * downPB,
270 GuiIdListModel * availableModel,
271 GuiIdListModel * selectedModel,
272 GuiDocument const * container)
273 : GuiSelectionManager(parent, availableLV, selectedLV, addPB, delPB,
274 upPB, downPB, availableModel, selectedModel),
275 container_(container)
276 {}
277 ///
updateProvidedModules(LayoutModuleList const & pm)278 void updateProvidedModules(LayoutModuleList const & pm)
279 { provided_modules_ = pm.list(); }
280 ///
updateExcludedModules(LayoutModuleList const & em)281 void updateExcludedModules(LayoutModuleList const & em)
282 { excluded_modules_ = em.list(); }
283 private:
284 ///
285 virtual void updateAddPB();
286 ///
287 virtual void updateUpPB();
288 ///
289 virtual void updateDownPB();
290 ///
291 virtual void updateDelPB();
292 /// returns availableModel as a GuiIdListModel
getAvailableModel()293 GuiIdListModel * getAvailableModel()
294 {
295 return dynamic_cast<GuiIdListModel *>(availableModel);
296 }
297 /// returns selectedModel as a GuiIdListModel
getSelectedModel()298 GuiIdListModel * getSelectedModel()
299 {
300 return dynamic_cast<GuiIdListModel *>(selectedModel);
301 }
302 /// keeps a list of the modules the text class provides
303 list<string> provided_modules_;
304 /// similarly...
305 list<string> excluded_modules_;
306 ///
307 GuiDocument const * container_;
308 };
309
updateAddPB()310 void ModuleSelectionManager::updateAddPB()
311 {
312 int const arows = availableModel->rowCount();
313 QModelIndexList const avail_sels =
314 availableLV->selectionModel()->selectedIndexes();
315
316 // disable if there aren't any modules (?), if none of them is chosen
317 // in the dialog, or if the chosen one is already selected for use.
318 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
319 addPB->setEnabled(false);
320 return;
321 }
322
323 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
324 string const modname = getAvailableModel()->getIDString(idx.row());
325
326 bool const enable =
327 container_->params().layoutModuleCanBeAdded(modname);
328 addPB->setEnabled(enable);
329 }
330
331
updateDownPB()332 void ModuleSelectionManager::updateDownPB()
333 {
334 int const srows = selectedModel->rowCount();
335 if (srows == 0) {
336 downPB->setEnabled(false);
337 return;
338 }
339 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
340 int const curRow = curidx.row();
341 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
342 downPB->setEnabled(false);
343 return;
344 }
345
346 // determine whether immediately succeding element requires this one
347 string const curmodname = getSelectedModel()->getIDString(curRow);
348 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
349
350 vector<string> reqs = getRequiredList(nextmodname);
351
352 // if it doesn't require anything....
353 if (reqs.empty()) {
354 downPB->setEnabled(true);
355 return;
356 }
357
358 // Enable it if this module isn't required.
359 // FIXME This should perhaps be more flexible and check whether, even
360 // if the next one is required, there is also an earlier one that will do.
361 downPB->setEnabled(
362 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
363 }
364
updateUpPB()365 void ModuleSelectionManager::updateUpPB()
366 {
367 int const srows = selectedModel->rowCount();
368 if (srows == 0) {
369 upPB->setEnabled(false);
370 return;
371 }
372
373 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
374 int curRow = curIdx.row();
375 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
376 upPB->setEnabled(false);
377 return;
378 }
379 string const curmodname = getSelectedModel()->getIDString(curRow);
380
381 // determine whether immediately preceding element is required by this one
382 vector<string> reqs = getRequiredList(curmodname);
383
384 // if this one doesn't require anything....
385 if (reqs.empty()) {
386 upPB->setEnabled(true);
387 return;
388 }
389
390
391 // Enable it if the preceding module isn't required.
392 // NOTE This is less flexible than it might be. We could check whether, even
393 // if the previous one is required, there is an earlier one that would do.
394 string const premod = getSelectedModel()->getIDString(curRow - 1);
395 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
396 }
397
updateDelPB()398 void ModuleSelectionManager::updateDelPB()
399 {
400 int const srows = selectedModel->rowCount();
401 if (srows == 0) {
402 deletePB->setEnabled(false);
403 return;
404 }
405
406 QModelIndex const & curidx =
407 selectedLV->selectionModel()->currentIndex();
408 int const curRow = curidx.row();
409 if (curRow < 0 || curRow >= srows) { // invalid index?
410 deletePB->setEnabled(false);
411 return;
412 }
413
414 string const curmodname = getSelectedModel()->getIDString(curRow);
415
416 // We're looking here for a reason NOT to enable the button. If we
417 // find one, we disable it and return. If we don't, we'll end up at
418 // the end of the function, and then we enable it.
419 for (int i = curRow + 1; i < srows; ++i) {
420 string const thisMod = getSelectedModel()->getIDString(i);
421 vector<string> reqs = getRequiredList(thisMod);
422 //does this one require us?
423 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
424 //no...
425 continue;
426
427 // OK, so this module requires us
428 // is there an EARLIER module that also satisfies the require?
429 // NOTE We demand that it be earlier to keep the list of modules
430 // consistent with the rule that a module must be proceeded by a
431 // required module. There would be more flexible ways to proceed,
432 // but that would be a lot more complicated, and the logic here is
433 // already complicated. (That's why I've left the debugging code.)
434 // lyxerr << "Testing " << thisMod << endl;
435 bool foundone = false;
436 for (int j = 0; j < curRow; ++j) {
437 string const mod = getSelectedModel()->getIDString(j);
438 // lyxerr << "In loop: Testing " << mod << endl;
439 // do we satisfy the require?
440 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
441 // lyxerr << mod << " does the trick." << endl;
442 foundone = true;
443 break;
444 }
445 }
446 // did we find a module to satisfy the require?
447 if (!foundone) {
448 // lyxerr << "No matching module found." << endl;
449 deletePB->setEnabled(false);
450 return;
451 }
452 }
453 // lyxerr << "All's well that ends well." << endl;
454 deletePB->setEnabled(true);
455 }
456
457
458 /////////////////////////////////////////////////////////////////////
459 //
460 // PreambleModule
461 //
462 /////////////////////////////////////////////////////////////////////
463
PreambleModule(QWidget * parent)464 PreambleModule::PreambleModule(QWidget * parent)
465 : UiWidget<Ui::PreambleUi>(parent), current_id_(0)
466 {
467 // This is not a memory leak. The object will be destroyed
468 // with this.
469 // @ is letter in the LyX user preamble
470 (void) new LaTeXHighlighter(preambleTE->document(), true);
471 preambleTE->setFont(guiApp->typewriterSystemFont());
472 preambleTE->setWordWrapMode(QTextOption::NoWrap);
473 setFocusProxy(preambleTE);
474 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
475 connect(findLE, SIGNAL(textEdited(const QString &)), this, SLOT(checkFindButton()));
476 connect(findButtonPB, SIGNAL(clicked()), this, SLOT(findText()));
477 connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
478 connect(findLE, SIGNAL(returnPressed()), this, SLOT(findText()));
479 checkFindButton();
480 // https://stackoverflow.com/questions/13027091/how-to-override-tab-width-in-qt
481 const int tabStop = 4;
482 QFontMetrics metrics(preambleTE->currentFont());
483 preambleTE->setTabStopWidth(tabStop * metrics.width(' '));
484 }
485
486
checkFindButton()487 void PreambleModule::checkFindButton()
488 {
489 findButtonPB->setEnabled(!findLE->text().isEmpty());
490 }
491
492
findText()493 void PreambleModule::findText()
494 {
495 bool const found = preambleTE->find(findLE->text());
496 if (!found) {
497 // wrap
498 QTextCursor qtcur = preambleTE->textCursor();
499 qtcur.movePosition(QTextCursor::Start);
500 preambleTE->setTextCursor(qtcur);
501 preambleTE->find(findLE->text());
502 }
503 }
504
505
update(BufferParams const & params,BufferId id)506 void PreambleModule::update(BufferParams const & params, BufferId id)
507 {
508 QString preamble = toqstr(params.preamble);
509 // Nothing to do if the params and preamble are unchanged.
510 if (id == current_id_
511 && preamble == preambleTE->document()->toPlainText())
512 return;
513
514 QTextCursor cur = preambleTE->textCursor();
515 // Save the coords before switching to the new one.
516 preamble_coords_[current_id_] =
517 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
518
519 // Save the params address for further use.
520 current_id_ = id;
521 preambleTE->document()->setPlainText(preamble);
522 Coords::const_iterator it = preamble_coords_.find(current_id_);
523 if (it == preamble_coords_.end())
524 // First time we open this one.
525 preamble_coords_[current_id_] = make_pair(0, 0);
526 else {
527 // Restore saved coords.
528 QTextCursor cur = preambleTE->textCursor();
529 cur.setPosition(it->second.first);
530 preambleTE->setTextCursor(cur);
531 preambleTE->verticalScrollBar()->setValue(it->second.second);
532 }
533 }
534
535
apply(BufferParams & params)536 void PreambleModule::apply(BufferParams & params)
537 {
538 params.preamble = qstring_to_ucs4(preambleTE->document()->toPlainText());
539 }
540
541
closeEvent(QCloseEvent * e)542 void PreambleModule::closeEvent(QCloseEvent * e)
543 {
544 // Save the coords before closing.
545 QTextCursor cur = preambleTE->textCursor();
546 preamble_coords_[current_id_] =
547 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
548 e->accept();
549 }
550
551
editExternal()552 void PreambleModule::editExternal() {
553 if (!current_id_)
554 return;
555
556 if (tempfile_) {
557 preambleTE->setReadOnly(false);
558 FileName const tempfilename = tempfile_->name();
559 docstring const s = tempfilename.fileContents("UTF-8");
560 preambleTE->document()->setPlainText(toqstr(s));
561 tempfile_.reset();
562 editPB->setText(qt_("&Edit"));
563 changed();
564 return;
565 }
566
567 string const format =
568 current_id_->params().documentClass().outputFormat();
569 string const ext = theFormats().extension(format);
570 tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
571 FileName const tempfilename = tempfile_->name();
572 string const name = tempfilename.toFilesystemEncoding();
573 ofdocstream os(name.c_str());
574 os << qstring_to_ucs4(preambleTE->document()->toPlainText());
575 os.close();
576 preambleTE->setReadOnly(true);
577 theFormats().edit(*current_id_, tempfilename, format);
578 editPB->setText(qt_("&End Edit"));
579 changed();
580 }
581
582 /////////////////////////////////////////////////////////////////////
583 //
584 // LocalLayout
585 //
586 /////////////////////////////////////////////////////////////////////
587
588
LocalLayout(QWidget * parent)589 LocalLayout::LocalLayout(QWidget * parent)
590 : UiWidget<Ui::LocalLayoutUi>(parent), current_id_(0), validated_(false)
591 {
592 locallayoutTE->setFont(guiApp->typewriterSystemFont());
593 locallayoutTE->setWordWrapMode(QTextOption::NoWrap);
594 connect(locallayoutTE, SIGNAL(textChanged()), this, SLOT(textChanged()));
595 connect(validatePB, SIGNAL(clicked()), this, SLOT(validatePressed()));
596 connect(convertPB, SIGNAL(clicked()), this, SLOT(convertPressed()));
597 connect(editPB, SIGNAL(clicked()), this, SLOT(editExternal()));
598 }
599
600
update(BufferParams const & params,BufferId id)601 void LocalLayout::update(BufferParams const & params, BufferId id)
602 {
603 QString layout = toqstr(params.getLocalLayout(false));
604 // Nothing to do if the params and preamble are unchanged.
605 if (id == current_id_
606 && layout == locallayoutTE->document()->toPlainText())
607 return;
608
609 // Save the params address for further use.
610 current_id_ = id;
611 locallayoutTE->document()->setPlainText(layout);
612 validate();
613 }
614
615
apply(BufferParams & params)616 void LocalLayout::apply(BufferParams & params)
617 {
618 docstring const layout =
619 qstring_to_ucs4(locallayoutTE->document()->toPlainText());
620 params.setLocalLayout(layout, false);
621 }
622
623
hideConvert()624 void LocalLayout::hideConvert()
625 {
626 convertPB->setEnabled(false);
627 convertLB->setText("");
628 convertPB->hide();
629 convertLB->hide();
630 }
631
632
textChanged()633 void LocalLayout::textChanged()
634 {
635 // Flashy red bold text
636 static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
637 "%1</p>");
638 static const QString message = ivpar.arg(qt_("Validation required!"));
639 string const layout =
640 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
641
642 if (layout.empty()) {
643 validated_ = true;
644 validatePB->setEnabled(false);
645 validLB->setText("");
646 hideConvert();
647 changed();
648 } else if (!validatePB->isEnabled()) {
649 // if that's already enabled, we shouldn't need to do anything.
650 validated_ = false;
651 validLB->setText(message);
652 validatePB->setEnabled(true);
653 hideConvert();
654 changed();
655 }
656 }
657
658
convert()659 void LocalLayout::convert() {
660 string const layout =
661 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
662 string const newlayout = TextClass::convert(layout);
663 if (!newlayout.empty())
664 locallayoutTE->setPlainText(toqstr(newlayout));
665 validate();
666 }
667
668
convertPressed()669 void LocalLayout::convertPressed() {
670 convert();
671 hideConvert();
672 changed();
673 }
674
675
validate()676 void LocalLayout::validate() {
677 // Bold text
678 static const QString vpar("<p style=\"font-weight: bold; text-align:left\">%1</p>");
679 // Flashy red bold text
680 static const QString ivpar("<p style=\"color: #c00000; font-weight: bold; text-align:left\">"
681 "%1</p>");
682 string const layout =
683 fromqstr(locallayoutTE->document()->toPlainText().trimmed());
684 if (!layout.empty()) {
685 TextClass::ReturnValues const ret = TextClass::validate(layout);
686 validated_ = (ret == TextClass::OK) || (ret == TextClass::OK_OLDFORMAT);
687 validatePB->setEnabled(false);
688 validLB->setText(validated_ ? vpar.arg(qt_("Layout is valid!"))
689 : ivpar.arg(qt_("Layout is invalid!")));
690 if (ret == TextClass::OK_OLDFORMAT) {
691 convertPB->show();
692 // Testing conversion to LYXFILE_LAYOUT_FORMAT at this point
693 // already.
694 if (TextClass::convert(layout).empty()) {
695 // Conversion failed. If LAYOUT_FORMAT > LYXFILE_LAYOUT_FORMAT,
696 // then maybe the layout is still valid, but its format is more
697 // recent than LYXFILE_LAYOUT_FORMAT. However, if LAYOUT_FORMAT
698 // == LYXFILE_LAYOUT_FORMAT then something is definitely wrong.
699 convertPB->setEnabled(false);
700 const QString text = (LAYOUT_FORMAT == LYXFILE_LAYOUT_FORMAT)
701 ? ivpar.arg(qt_("Conversion to current format impossible!"))
702 : vpar.arg(qt_("Conversion to current stable format "
703 "impossible."));
704 convertLB->setText(text);
705 } else {
706 convertPB->setEnabled(true);
707 convertLB->setText(qt_("Convert to current format"));
708 }
709 convertLB->show();
710 } else {
711 convertPB->hide();
712 convertLB->hide();
713 }
714 }
715 }
716
717
validatePressed()718 void LocalLayout::validatePressed() {
719 validate();
720 changed();
721 }
722
723
editExternal()724 void LocalLayout::editExternal() {
725 if (!current_id_)
726 return;
727
728 if (tempfile_) {
729 locallayoutTE->setReadOnly(false);
730 FileName const tempfilename = tempfile_->name();
731 docstring const s = tempfilename.fileContents("UTF-8");
732 locallayoutTE->document()->setPlainText(toqstr(s));
733 tempfile_.reset();
734 editPB->setText(qt_("&Edit"));
735 changed();
736 return;
737 }
738
739 string const format =
740 current_id_->params().documentClass().outputFormat();
741 string const ext = theFormats().extension(format);
742 tempfile_.reset(new TempFile("preamble_editXXXXXX." + ext));
743 FileName const tempfilename = tempfile_->name();
744 string const name = tempfilename.toFilesystemEncoding();
745 ofdocstream os(name.c_str());
746 os << qstring_to_ucs4(locallayoutTE->document()->toPlainText());
747 os.close();
748 locallayoutTE->setReadOnly(true);
749 theFormats().edit(*current_id_, tempfilename, format);
750 editPB->setText(qt_("&End Edit"));
751 validatePB->setEnabled(false);
752 hideConvert();
753 changed();
754 }
755
756 /////////////////////////////////////////////////////////////////////
757 //
758 // DocumentDialog
759 //
760 /////////////////////////////////////////////////////////////////////
761
762
GuiDocument(GuiView & lv)763 GuiDocument::GuiDocument(GuiView & lv)
764 : GuiDialog(lv, "document", qt_("Document Settings")),
765 biblioChanged_(false), nonModuleChanged_(false),
766 modulesChanged_(false), shellescapeChanged_(false)
767 {
768 setupUi(this);
769
770 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
771 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
772 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
773 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
774
775 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
776 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
777
778 // Manage the restore, ok, apply, restore and cancel/close buttons
779 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
780 bc().setOK(okPB);
781 bc().setApply(applyPB);
782 bc().setCancel(closePB);
783 bc().setRestore(restorePB);
784
785
786 // text layout
787 textLayoutModule = new UiWidget<Ui::TextLayoutUi>(this);
788 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
789 this, SLOT(change_adaptor()));
790 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
791 this, SLOT(setLSpacing(int)));
792 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
793 this, SLOT(change_adaptor()));
794
795 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
796 this, SLOT(change_adaptor()));
797 connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
798 textLayoutModule->indentCO, SLOT(setEnabled(bool)));
799 connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
800 this, SLOT(change_adaptor()));
801 connect(textLayoutModule->indentCO, SIGNAL(activated(int)),
802 this, SLOT(setIndent(int)));
803 connect(textLayoutModule->indentLE, SIGNAL(textChanged(const QString &)),
804 this, SLOT(change_adaptor()));
805 connect(textLayoutModule->indentLengthCO, SIGNAL(activated(int)),
806 this, SLOT(change_adaptor()));
807
808 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
809 this, SLOT(change_adaptor()));
810 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
811 textLayoutModule->skipCO, SLOT(setEnabled(bool)));
812 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
813 this, SLOT(change_adaptor()));
814 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
815 this, SLOT(setSkip(int)));
816 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
817 this, SLOT(change_adaptor()));
818 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
819 this, SLOT(change_adaptor()));
820
821 connect(textLayoutModule->indentRB, SIGNAL(toggled(bool)),
822 this, SLOT(enableIndent(bool)));
823 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
824 this, SLOT(enableSkip(bool)));
825
826 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
827 this, SLOT(change_adaptor()));
828 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
829 this, SLOT(setColSep()));
830 connect(textLayoutModule->justCB, SIGNAL(clicked()),
831 this, SLOT(change_adaptor()));
832
833 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
834 textLayoutModule->lspacingLE));
835 textLayoutModule->indentLE->setValidator(new LengthValidator(
836 textLayoutModule->indentLE));
837 textLayoutModule->skipLE->setValidator(new LengthValidator(
838 textLayoutModule->skipLE));
839
840 textLayoutModule->indentCO->addItem(qt_("Default"));
841 textLayoutModule->indentCO->addItem(qt_("Custom"));
842 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
843 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
844 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
845 textLayoutModule->skipCO->addItem(qt_("Custom"));
846 textLayoutModule->lspacingCO->insertItem(
847 Spacing::Single, qt_("Single"));
848 textLayoutModule->lspacingCO->insertItem(
849 Spacing::Onehalf, qt_("OneHalf"));
850 textLayoutModule->lspacingCO->insertItem(
851 Spacing::Double, qt_("Double"));
852 textLayoutModule->lspacingCO->insertItem(
853 Spacing::Other, qt_("Custom"));
854 // initialize the length validator
855 bc().addCheckedLineEdit(textLayoutModule->indentLE);
856 bc().addCheckedLineEdit(textLayoutModule->skipLE);
857
858
859 // master/child handling
860 masterChildModule = new UiWidget<Ui::MasterChildUi>(this);
861
862 connect(masterChildModule->childrenTW, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
863 this, SLOT(includeonlyClicked(QTreeWidgetItem *, int)));
864 connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
865 masterChildModule->childrenTW, SLOT(setEnabled(bool)));
866 connect(masterChildModule->includeonlyRB, SIGNAL(toggled(bool)),
867 masterChildModule->maintainAuxCB, SLOT(setEnabled(bool)));
868 connect(masterChildModule->includeallRB, SIGNAL(clicked()),
869 this, SLOT(change_adaptor()));
870 connect(masterChildModule->includeonlyRB, SIGNAL(clicked()),
871 this, SLOT(change_adaptor()));
872 connect(masterChildModule->maintainAuxCB, SIGNAL(clicked()),
873 this, SLOT(change_adaptor()));
874 masterChildModule->childrenTW->setColumnCount(2);
875 masterChildModule->childrenTW->headerItem()->setText(0, qt_("Child Document"));
876 masterChildModule->childrenTW->headerItem()->setText(1, qt_("Include to Output"));
877 masterChildModule->childrenTW->resizeColumnToContents(1);
878 masterChildModule->childrenTW->resizeColumnToContents(2);
879
880
881 // Formats
882 outputModule = new UiWidget<Ui::OutputUi>(this);
883
884 connect(outputModule->defaultFormatCO, SIGNAL(activated(int)),
885 this, SLOT(change_adaptor()));
886 connect(outputModule->mathimgSB, SIGNAL(valueChanged(double)),
887 this, SLOT(change_adaptor()));
888 connect(outputModule->strictCB, SIGNAL(stateChanged(int)),
889 this, SLOT(change_adaptor()));
890 connect(outputModule->cssCB, SIGNAL(stateChanged(int)),
891 this, SLOT(change_adaptor()));
892 connect(outputModule->mathoutCB, SIGNAL(currentIndexChanged(int)),
893 this, SLOT(change_adaptor()));
894
895 connect(outputModule->shellescapeCB, SIGNAL(stateChanged(int)),
896 this, SLOT(shellescapeChanged()));
897 connect(outputModule->outputsyncCB, SIGNAL(clicked()),
898 this, SLOT(change_adaptor()));
899 connect(outputModule->synccustomCB, SIGNAL(editTextChanged(QString)),
900 this, SLOT(change_adaptor()));
901 outputModule->synccustomCB->addItem("");
902 outputModule->synccustomCB->addItem("\\synctex=1");
903 outputModule->synccustomCB->addItem("\\synctex=-1");
904 outputModule->synccustomCB->addItem("\\usepackage[active]{srcltx}");
905
906 outputModule->synccustomCB->setValidator(new NoNewLineValidator(
907 outputModule->synccustomCB));
908
909 connect(outputModule->saveTransientPropertiesCB, SIGNAL(clicked()),
910 this, SLOT(change_adaptor()));
911
912 // fonts
913 fontModule = new FontModule(this);
914 connect(fontModule->osFontsCB, SIGNAL(clicked()),
915 this, SLOT(change_adaptor()));
916 connect(fontModule->osFontsCB, SIGNAL(toggled(bool)),
917 this, SLOT(osFontsChanged(bool)));
918 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
919 this, SLOT(change_adaptor()));
920 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
921 this, SLOT(romanChanged(int)));
922 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
923 this, SLOT(change_adaptor()));
924 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
925 this, SLOT(sansChanged(int)));
926 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
927 this, SLOT(change_adaptor()));
928 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
929 this, SLOT(ttChanged(int)));
930 connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
931 this, SLOT(change_adaptor()));
932 connect(fontModule->fontsMathCO, SIGNAL(activated(int)),
933 this, SLOT(mathFontChanged(int)));
934 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
935 this, SLOT(change_adaptor()));
936 connect(fontModule->fontencCO, SIGNAL(activated(int)),
937 this, SLOT(change_adaptor()));
938 connect(fontModule->fontencCO, SIGNAL(activated(int)),
939 this, SLOT(fontencChanged(int)));
940 connect(fontModule->fontencLE, SIGNAL(textChanged(const QString &)),
941 this, SLOT(change_adaptor()));
942 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
943 this, SLOT(change_adaptor()));
944 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
945 this, SLOT(change_adaptor()));
946 connect(fontModule->microtypeCB, SIGNAL(clicked()),
947 this, SLOT(change_adaptor()));
948 connect(fontModule->dashesCB, SIGNAL(clicked()),
949 this, SLOT(change_adaptor()));
950 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
951 this, SLOT(change_adaptor()));
952 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
953 this, SLOT(change_adaptor()));
954 connect(fontModule->fontScCB, SIGNAL(clicked()),
955 this, SLOT(change_adaptor()));
956 connect(fontModule->fontScCB, SIGNAL(toggled(bool)),
957 this, SLOT(fontScToggled(bool)));
958 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
959 this, SLOT(change_adaptor()));
960 connect(fontModule->fontOsfCB, SIGNAL(toggled(bool)),
961 this, SLOT(fontOsfToggled(bool)));
962
963 fontModule->fontencLE->setValidator(new NoNewLineValidator(
964 fontModule->fontencLE));
965 fontModule->cjkFontLE->setValidator(new NoNewLineValidator(
966 fontModule->cjkFontLE));
967
968 updateFontlist();
969
970 fontModule->fontsizeCO->addItem(qt_("Default"));
971 fontModule->fontsizeCO->addItem(qt_("10"));
972 fontModule->fontsizeCO->addItem(qt_("11"));
973 fontModule->fontsizeCO->addItem(qt_("12"));
974
975 fontModule->fontencCO->addItem(qt_("Default"), QString("global"));
976 fontModule->fontencCO->addItem(qt_("Custom"), QString("custom"));
977 fontModule->fontencCO->addItem(qt_("None (no fontenc)"), QString("default"));
978
979 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
980 fontModule->fontsDefaultCO->addItem(
981 qt_(GuiDocument::fontfamilies_gui[n]));
982
983 if (!LaTeXFeatures::isAvailable("fontspec"))
984 fontModule->osFontsCB->setToolTip(
985 qt_("Use OpenType and TrueType fonts directly (requires XeTeX or LuaTeX)\n"
986 "You need to install the package \"fontspec\" to use this feature"));
987
988
989 // page layout
990 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>(this);
991 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
992 this, SLOT(papersizeChanged(int)));
993 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
994 this, SLOT(papersizeChanged(int)));
995 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
996 this, SLOT(change_adaptor()));
997 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
998 this, SLOT(change_adaptor()));
999 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
1000 this, SLOT(change_adaptor()));
1001 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
1002 this, SLOT(change_adaptor()));
1003 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
1004 this, SLOT(change_adaptor()));
1005 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
1006 this, SLOT(change_adaptor()));
1007 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
1008 this, SLOT(change_adaptor()));
1009 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
1010 this, SLOT(change_adaptor()));
1011 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
1012 this, SLOT(change_adaptor()));
1013 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
1014 this, SLOT(change_adaptor()));
1015
1016 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1017 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
1018 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
1019 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
1020 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
1021 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
1022 pageLayoutModule->paperheightL);
1023 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
1024 pageLayoutModule->paperwidthL);
1025
1026 QComboBox * cb = pageLayoutModule->papersizeCO;
1027 cb->addItem(qt_("Default"));
1028 cb->addItem(qt_("Custom"));
1029 cb->addItem(qt_("US letter"));
1030 cb->addItem(qt_("US legal"));
1031 cb->addItem(qt_("US executive"));
1032 cb->addItem(qt_("A0"));
1033 cb->addItem(qt_("A1"));
1034 cb->addItem(qt_("A2"));
1035 cb->addItem(qt_("A3"));
1036 cb->addItem(qt_("A4"));
1037 cb->addItem(qt_("A5"));
1038 cb->addItem(qt_("A6"));
1039 cb->addItem(qt_("B0"));
1040 cb->addItem(qt_("B1"));
1041 cb->addItem(qt_("B2"));
1042 cb->addItem(qt_("B3"));
1043 cb->addItem(qt_("B4"));
1044 cb->addItem(qt_("B5"));
1045 cb->addItem(qt_("B6"));
1046 cb->addItem(qt_("C0"));
1047 cb->addItem(qt_("C1"));
1048 cb->addItem(qt_("C2"));
1049 cb->addItem(qt_("C3"));
1050 cb->addItem(qt_("C4"));
1051 cb->addItem(qt_("C5"));
1052 cb->addItem(qt_("C6"));
1053 cb->addItem(qt_("JIS B0"));
1054 cb->addItem(qt_("JIS B1"));
1055 cb->addItem(qt_("JIS B2"));
1056 cb->addItem(qt_("JIS B3"));
1057 cb->addItem(qt_("JIS B4"));
1058 cb->addItem(qt_("JIS B5"));
1059 cb->addItem(qt_("JIS B6"));
1060 // remove the %-items from the unit choice
1061 pageLayoutModule->paperwidthUnitCO->noPercents();
1062 pageLayoutModule->paperheightUnitCO->noPercents();
1063 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
1064 pageLayoutModule->paperheightLE));
1065 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
1066 pageLayoutModule->paperwidthLE));
1067
1068
1069 // margins
1070 marginsModule = new UiWidget<Ui::MarginsUi>(this);
1071 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
1072 this, SLOT(setCustomMargins(bool)));
1073 connect(marginsModule->marginCB, SIGNAL(clicked()),
1074 this, SLOT(change_adaptor()));
1075 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
1076 this, SLOT(change_adaptor()));
1077 connect(marginsModule->topUnit, SIGNAL(activated(int)),
1078 this, SLOT(change_adaptor()));
1079 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
1080 this, SLOT(change_adaptor()));
1081 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
1082 this, SLOT(change_adaptor()));
1083 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
1084 this, SLOT(change_adaptor()));
1085 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
1086 this, SLOT(change_adaptor()));
1087 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
1088 this, SLOT(change_adaptor()));
1089 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
1090 this, SLOT(change_adaptor()));
1091 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
1092 this, SLOT(change_adaptor()));
1093 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
1094 this, SLOT(change_adaptor()));
1095 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
1096 this, SLOT(change_adaptor()));
1097 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
1098 this, SLOT(change_adaptor()));
1099 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
1100 this, SLOT(change_adaptor()));
1101 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
1102 this, SLOT(change_adaptor()));
1103 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
1104 this, SLOT(change_adaptor()));
1105 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
1106 this, SLOT(change_adaptor()));
1107 marginsModule->topLE->setValidator(new LengthValidator(
1108 marginsModule->topLE));
1109 marginsModule->bottomLE->setValidator(new LengthValidator(
1110 marginsModule->bottomLE));
1111 marginsModule->innerLE->setValidator(new LengthValidator(
1112 marginsModule->innerLE));
1113 marginsModule->outerLE->setValidator(new LengthValidator(
1114 marginsModule->outerLE));
1115 marginsModule->headsepLE->setValidator(new LengthValidator(
1116 marginsModule->headsepLE));
1117 marginsModule->headheightLE->setValidator(new LengthValidator(
1118 marginsModule->headheightLE));
1119 marginsModule->footskipLE->setValidator(new LengthValidator(
1120 marginsModule->footskipLE));
1121 marginsModule->columnsepLE->setValidator(new LengthValidator(
1122 marginsModule->columnsepLE));
1123
1124 bc().addCheckedLineEdit(marginsModule->topLE,
1125 marginsModule->topL);
1126 bc().addCheckedLineEdit(marginsModule->bottomLE,
1127 marginsModule->bottomL);
1128 bc().addCheckedLineEdit(marginsModule->innerLE,
1129 marginsModule->innerL);
1130 bc().addCheckedLineEdit(marginsModule->outerLE,
1131 marginsModule->outerL);
1132 bc().addCheckedLineEdit(marginsModule->headsepLE,
1133 marginsModule->headsepL);
1134 bc().addCheckedLineEdit(marginsModule->headheightLE,
1135 marginsModule->headheightL);
1136 bc().addCheckedLineEdit(marginsModule->footskipLE,
1137 marginsModule->footskipL);
1138 bc().addCheckedLineEdit(marginsModule->columnsepLE,
1139 marginsModule->columnsepL);
1140
1141
1142 // language & quote
1143 langModule = new UiWidget<Ui::LanguageUi>(this);
1144 connect(langModule->languageCO, SIGNAL(activated(int)),
1145 this, SLOT(change_adaptor()));
1146 connect(langModule->languageCO, SIGNAL(activated(int)),
1147 this, SLOT(languageChanged(int)));
1148 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
1149 this, SLOT(change_adaptor()));
1150 connect(langModule->otherencodingRB, SIGNAL(clicked()),
1151 this, SLOT(change_adaptor()));
1152 connect(langModule->encodingCO, SIGNAL(activated(int)),
1153 this, SLOT(change_adaptor()));
1154 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
1155 this, SLOT(change_adaptor()));
1156 connect(langModule->languagePackageCO, SIGNAL(activated(int)),
1157 this, SLOT(change_adaptor()));
1158 connect(langModule->languagePackageLE, SIGNAL(textChanged(QString)),
1159 this, SLOT(change_adaptor()));
1160 connect(langModule->languagePackageCO, SIGNAL(currentIndexChanged(int)),
1161 this, SLOT(languagePackageChanged(int)));
1162 connect(langModule->dynamicQuotesCB, SIGNAL(clicked()),
1163 this, SLOT(change_adaptor()));
1164
1165 langModule->languagePackageLE->setValidator(new NoNewLineValidator(
1166 langModule->languagePackageLE));
1167
1168 QAbstractItemModel * language_model = guiApp->languageModel();
1169 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
1170 language_model->sort(0);
1171 langModule->languageCO->setModel(language_model);
1172 langModule->languageCO->setModelColumn(0);
1173
1174 // Always put the default encoding in the first position.
1175 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
1176 QStringList encodinglist;
1177 for (auto const & encvar : encodings) {
1178 if (!encvar.unsafe() && !encvar.guiName().empty())
1179 encodinglist.append(qt_(encvar.guiName()));
1180 }
1181 encodinglist.sort();
1182 langModule->encodingCO->addItems(encodinglist);
1183
1184 langModule->languagePackageCO->addItem(
1185 qt_("Default"), toqstr("default"));
1186 langModule->languagePackageCO->addItem(
1187 qt_("Automatic"), toqstr("auto"));
1188 langModule->languagePackageCO->addItem(
1189 qt_("Always Babel"), toqstr("babel"));
1190 langModule->languagePackageCO->addItem(
1191 qt_("Custom"), toqstr("custom"));
1192 langModule->languagePackageCO->addItem(
1193 qt_("None[[language package]]"), toqstr("none"));
1194
1195
1196 // color
1197 colorModule = new UiWidget<Ui::ColorUi>(this);
1198 connect(colorModule->fontColorPB, SIGNAL(clicked()),
1199 this, SLOT(changeFontColor()));
1200 connect(colorModule->delFontColorTB, SIGNAL(clicked()),
1201 this, SLOT(deleteFontColor()));
1202 connect(colorModule->noteFontColorPB, SIGNAL(clicked()),
1203 this, SLOT(changeNoteFontColor()));
1204 connect(colorModule->delNoteFontColorTB, SIGNAL(clicked()),
1205 this, SLOT(deleteNoteFontColor()));
1206 connect(colorModule->backgroundPB, SIGNAL(clicked()),
1207 this, SLOT(changeBackgroundColor()));
1208 connect(colorModule->delBackgroundTB, SIGNAL(clicked()),
1209 this, SLOT(deleteBackgroundColor()));
1210 connect(colorModule->boxBackgroundPB, SIGNAL(clicked()),
1211 this, SLOT(changeBoxBackgroundColor()));
1212 connect(colorModule->delBoxBackgroundTB, SIGNAL(clicked()),
1213 this, SLOT(deleteBoxBackgroundColor()));
1214
1215
1216 // numbering
1217 numberingModule = new UiWidget<Ui::NumberingUi>(this);
1218 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1219 this, SLOT(change_adaptor()));
1220 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1221 this, SLOT(change_adaptor()));
1222 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
1223 this, SLOT(updateNumbering()));
1224 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
1225 this, SLOT(updateNumbering()));
1226 numberingModule->tocTW->setColumnCount(3);
1227 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
1228 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
1229 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
1230 setSectionResizeMode(numberingModule->tocTW->header(), QHeaderView::ResizeToContents);
1231
1232 // biblio
1233 biblioModule = new UiWidget<Ui::BiblioUi>(this);
1234 connect(biblioModule->citeEngineCO, SIGNAL(activated(int)),
1235 this, SLOT(citeEngineChanged(int)));
1236 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
1237 this, SLOT(citeStyleChanged()));
1238 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
1239 this, SLOT(biblioChanged()));
1240 connect(biblioModule->bibunitsCO, SIGNAL(activated(int)),
1241 this, SLOT(biblioChanged()));
1242 connect(biblioModule->bibtexCO, SIGNAL(activated(int)),
1243 this, SLOT(bibtexChanged(int)));
1244 connect(biblioModule->bibtexOptionsLE, SIGNAL(textChanged(QString)),
1245 this, SLOT(biblioChanged()));
1246 connect(biblioModule->citePackageOptionsLE, SIGNAL(textChanged(QString)),
1247 this, SLOT(biblioChanged()));
1248 connect(biblioModule->defaultBiblioCO, SIGNAL(activated(int)),
1249 this, SLOT(biblioChanged()));
1250 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1251 this, SLOT(biblioChanged()));
1252 connect(biblioModule->defaultBiblioCO, SIGNAL(editTextChanged(QString)),
1253 this, SLOT(updateResetDefaultBiblio()));
1254 connect(biblioModule->biblatexBbxCO, SIGNAL(activated(int)),
1255 this, SLOT(biblioChanged()));
1256 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1257 this, SLOT(biblioChanged()));
1258 connect(biblioModule->biblatexBbxCO, SIGNAL(editTextChanged(QString)),
1259 this, SLOT(updateResetDefaultBiblio()));
1260 connect(biblioModule->biblatexCbxCO, SIGNAL(activated(int)),
1261 this, SLOT(biblioChanged()));
1262 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1263 this, SLOT(biblioChanged()));
1264 connect(biblioModule->biblatexCbxCO, SIGNAL(editTextChanged(QString)),
1265 this, SLOT(updateResetDefaultBiblio()));
1266 connect(biblioModule->rescanBibliosPB, SIGNAL(clicked()),
1267 this, SLOT(rescanBibFiles()));
1268 connect(biblioModule->resetDefaultBiblioPB, SIGNAL(clicked()),
1269 this, SLOT(resetDefaultBibfile()));
1270 connect(biblioModule->resetCbxPB, SIGNAL(clicked()),
1271 this, SLOT(resetDefaultCbxBibfile()));
1272 connect(biblioModule->resetBbxPB, SIGNAL(clicked()),
1273 this, SLOT(resetDefaultBbxBibfile()));
1274 connect(biblioModule->matchBbxPB, SIGNAL(clicked()),
1275 this, SLOT(matchBiblatexStyles()));
1276
1277 biblioModule->citeEngineCO->clear();
1278 for (LyXCiteEngine const & cet : theCiteEnginesList) {
1279 biblioModule->citeEngineCO->addItem(qt_(cet.getName()), toqstr(cet.getID()));
1280 int const i = biblioModule->citeEngineCO->findData(toqstr(cet.getID()));
1281 biblioModule->citeEngineCO->setItemData(i, qt_(cet.getDescription()),
1282 Qt::ToolTipRole);
1283 }
1284
1285 biblioModule->bibtexOptionsLE->setValidator(new NoNewLineValidator(
1286 biblioModule->bibtexOptionsLE));
1287 biblioModule->defaultBiblioCO->lineEdit()->setValidator(new NoNewLineValidator(
1288 biblioModule->defaultBiblioCO->lineEdit()));
1289 biblioModule->citePackageOptionsLE->setValidator(new NoNewLineValidator(
1290 biblioModule->citePackageOptionsLE));
1291
1292 // NOTE: we do not provide "custom" here for security reasons!
1293 biblioModule->bibtexCO->clear();
1294 biblioModule->bibtexCO->addItem(qt_("Default"), QString("default"));
1295 for (set<string>::const_iterator it = lyxrc.bibtex_alternatives.begin();
1296 it != lyxrc.bibtex_alternatives.end(); ++it) {
1297 QString const command = toqstr(*it).left(toqstr(*it).indexOf(" "));
1298 biblioModule->bibtexCO->addItem(command, command);
1299 }
1300
1301
1302 // indices
1303 indicesModule = new GuiIndices;
1304 connect(indicesModule, SIGNAL(changed()),
1305 this, SLOT(change_adaptor()));
1306
1307
1308 // maths
1309 mathsModule = new UiWidget<Ui::MathsUi>(this);
1310 QStringList headers;
1311 headers << qt_("Package") << qt_("Load automatically")
1312 << qt_("Load always") << qt_("Do not load");
1313 mathsModule->packagesTW->setHorizontalHeaderLabels(headers);
1314 setSectionResizeMode(mathsModule->packagesTW->horizontalHeader(), QHeaderView::Stretch);
1315 map<string, string> const & packages = BufferParams::auto_packages();
1316 mathsModule->packagesTW->setRowCount(packages.size());
1317 int packnum = 0;
1318 for (map<string, string>::const_iterator it = packages.begin();
1319 it != packages.end(); ++it) {
1320 docstring const package = from_ascii(it->first);
1321 QString autoTooltip = qt_(it->second);
1322 QString alwaysTooltip;
1323 if (package == "amsmath")
1324 alwaysTooltip =
1325 qt_("The AMS LaTeX packages are always used");
1326 else
1327 alwaysTooltip = toqstr(bformat(
1328 _("The LaTeX package %1$s is always used"),
1329 package));
1330 QString neverTooltip;
1331 if (package == "amsmath")
1332 neverTooltip =
1333 qt_("The AMS LaTeX packages are never used");
1334 else
1335 neverTooltip = toqstr(bformat(
1336 _("The LaTeX package %1$s is never used"),
1337 package));
1338 QRadioButton * autoRB = new QRadioButton(mathsModule);
1339 QRadioButton * alwaysRB = new QRadioButton(mathsModule);
1340 QRadioButton * neverRB = new QRadioButton(mathsModule);
1341 QButtonGroup * packageGroup = new QButtonGroup(mathsModule);
1342 packageGroup->addButton(autoRB);
1343 packageGroup->addButton(alwaysRB);
1344 packageGroup->addButton(neverRB);
1345 autoRB->setToolTip(autoTooltip);
1346 alwaysRB->setToolTip(alwaysTooltip);
1347 neverRB->setToolTip(neverTooltip);
1348
1349 // Pack the buttons in a layout in order to get proper alignment
1350 QWidget * autoRBWidget = new QWidget();
1351 QHBoxLayout * autoRBLayout = new QHBoxLayout(autoRBWidget);
1352 autoRBLayout->addWidget(autoRB);
1353 autoRBLayout->setAlignment(Qt::AlignCenter);
1354 autoRBLayout->setContentsMargins(0, 0, 0, 0);
1355 autoRBWidget->setLayout(autoRBLayout);
1356
1357 QWidget * alwaysRBWidget = new QWidget();
1358 QHBoxLayout * alwaysRBLayout = new QHBoxLayout(alwaysRBWidget);
1359 alwaysRBLayout->addWidget(alwaysRB);
1360 alwaysRBLayout->setAlignment(Qt::AlignCenter);
1361 alwaysRBLayout->setContentsMargins(0, 0, 0, 0);
1362 alwaysRBWidget->setLayout(alwaysRBLayout);
1363
1364 QWidget * neverRBWidget = new QWidget();
1365 QHBoxLayout * neverRBLayout = new QHBoxLayout(neverRBWidget);
1366 neverRBLayout->addWidget(neverRB);
1367 neverRBLayout->setAlignment(Qt::AlignCenter);
1368 neverRBLayout->setContentsMargins(0, 0, 0, 0);
1369 neverRBWidget->setLayout(neverRBLayout);
1370
1371 QTableWidgetItem * pack = new QTableWidgetItem(toqstr(package));
1372
1373 mathsModule->packagesTW->setItem(packnum, 0, pack);
1374 mathsModule->packagesTW->setCellWidget(packnum, 1, autoRBWidget);
1375 mathsModule->packagesTW->setCellWidget(packnum, 2, alwaysRBWidget);
1376 mathsModule->packagesTW->setCellWidget(packnum, 3, neverRBWidget);
1377
1378 connect(autoRB, SIGNAL(clicked()),
1379 this, SLOT(change_adaptor()));
1380 connect(alwaysRB, SIGNAL(clicked()),
1381 this, SLOT(change_adaptor()));
1382 connect(neverRB, SIGNAL(clicked()),
1383 this, SLOT(change_adaptor()));
1384 ++packnum;
1385 }
1386 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1387 this, SLOT(allPackagesAuto()));
1388 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1389 this, SLOT(allPackagesAlways()));
1390 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1391 this, SLOT(allPackagesNot()));
1392 connect(mathsModule->allPackagesAutoPB, SIGNAL(clicked()),
1393 this, SLOT(change_adaptor()));
1394 connect(mathsModule->allPackagesAlwaysPB, SIGNAL(clicked()),
1395 this, SLOT(change_adaptor()));
1396 connect(mathsModule->allPackagesNotPB, SIGNAL(clicked()),
1397 this, SLOT(change_adaptor()));
1398 connect(mathsModule->MathNumberingPosCO, SIGNAL(activated(int)),
1399 this, SLOT(change_adaptor()));
1400
1401 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1402 this, SLOT(change_adaptor()));
1403 connect(mathsModule->MathIndentCB, SIGNAL(toggled(bool)),
1404 this, SLOT(allowMathIndent()));
1405 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1406 this, SLOT(change_adaptor()));
1407 connect(mathsModule->MathIndentCO, SIGNAL(activated(int)),
1408 this, SLOT(enableMathIndent(int)));
1409 connect(mathsModule->MathIndentLE, SIGNAL(textChanged(const QString &)),
1410 this, SLOT(change_adaptor()));
1411 connect(mathsModule->MathIndentLengthCO, SIGNAL(activated(int)),
1412 this, SLOT(change_adaptor()));
1413
1414
1415 mathsModule->MathIndentCO->addItem(qt_("Default"));
1416 mathsModule->MathIndentCO->addItem(qt_("Custom"));
1417 mathsModule->MathIndentLE->setValidator(new LengthValidator(
1418 mathsModule->MathIndentLE));
1419 // initialize the length validator
1420 bc().addCheckedLineEdit(mathsModule->MathIndentLE);
1421 mathsModule->MathNumberingPosCO->addItem(qt_("Left"));
1422 mathsModule->MathNumberingPosCO->addItem(qt_("Default"));
1423 mathsModule->MathNumberingPosCO->addItem(qt_("Right"));
1424 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
1425
1426
1427 // latex class
1428 latexModule = new UiWidget<Ui::LaTeXUi>(this);
1429 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
1430 this, SLOT(change_adaptor()));
1431 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
1432 this, SLOT(change_adaptor()));
1433 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
1434 this, SLOT(change_adaptor()));
1435 connect(latexModule->classCO, SIGNAL(activated(int)),
1436 this, SLOT(classChanged_adaptor()));
1437 connect(latexModule->classCO, SIGNAL(activated(int)),
1438 this, SLOT(change_adaptor()));
1439 connect(latexModule->layoutPB, SIGNAL(clicked()),
1440 this, SLOT(browseLayout()));
1441 connect(latexModule->layoutPB, SIGNAL(clicked()),
1442 this, SLOT(change_adaptor()));
1443 connect(latexModule->childDocGB, SIGNAL(clicked()),
1444 this, SLOT(change_adaptor()));
1445 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
1446 this, SLOT(change_adaptor()));
1447 connect(latexModule->childDocPB, SIGNAL(clicked()),
1448 this, SLOT(browseMaster()));
1449 connect(latexModule->suppressDateCB, SIGNAL(clicked()),
1450 this, SLOT(change_adaptor()));
1451 connect(latexModule->refstyleCB, SIGNAL(clicked()),
1452 this, SLOT(change_adaptor()));
1453
1454 latexModule->optionsLE->setValidator(new NoNewLineValidator(
1455 latexModule->optionsLE));
1456 latexModule->childDocLE->setValidator(new NoNewLineValidator(
1457 latexModule->childDocLE));
1458
1459 // postscript drivers
1460 for (int n = 0; tex_graphics[n][0]; ++n) {
1461 QString enc = qt_(tex_graphics_gui[n]);
1462 latexModule->psdriverCO->addItem(enc);
1463 }
1464 // latex classes
1465 LayoutFileList const & bcl = LayoutFileList::get();
1466 vector<LayoutFileIndex> classList = bcl.classList();
1467 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
1468
1469 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
1470 vector<LayoutFileIndex>::const_iterator cen = classList.end();
1471 for (int i = 0; cit != cen; ++cit, ++i) {
1472 LayoutFile const & tc = bcl[*cit];
1473 bool const available = tc.isTeXClassAvailable();
1474 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
1475 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
1476 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
1477 if (!available) {
1478 docstring const output_type = (tc.outputType() == lyx::DOCBOOK) ? _("DocBook") : _("LaTeX");
1479 tooltip += '\n' + toqstr(bformat(_("Class not found by LyX. "
1480 "Please check if you have the matching %1$s class "
1481 "and all required packages (%2$s) installed."),
1482 output_type, from_utf8(tc.prerequisites(", "))));
1483 }
1484 latexModule->classCO->addItemSort(toqstr(tc.name()),
1485 toqstr(guiname),
1486 toqstr(translateIfPossible(from_utf8(tc.category()))),
1487 tooltip,
1488 true, true, true, available);
1489 }
1490
1491
1492 // branches
1493 branchesModule = new GuiBranches(this);
1494 connect(branchesModule, SIGNAL(changed()),
1495 this, SLOT(change_adaptor()));
1496 connect(branchesModule, SIGNAL(renameBranches(docstring const &, docstring const &)),
1497 this, SLOT(branchesRename(docstring const &, docstring const &)));
1498 connect(branchesModule, SIGNAL(okPressed()), this, SLOT(slotOK()));
1499 updateUnknownBranches();
1500
1501
1502 // preamble
1503 preambleModule = new PreambleModule(this);
1504 connect(preambleModule, SIGNAL(changed()),
1505 this, SLOT(change_adaptor()));
1506
1507 localLayout = new LocalLayout(this);
1508 connect(localLayout, SIGNAL(changed()),
1509 this, SLOT(change_adaptor()));
1510
1511
1512 // bullets
1513 bulletsModule = new BulletsModule(this);
1514 connect(bulletsModule, SIGNAL(changed()),
1515 this, SLOT(change_adaptor()));
1516
1517
1518 // Modules
1519 modulesModule = new UiWidget<Ui::ModulesUi>(this);
1520 modulesModule->availableLV->header()->setVisible(false);
1521 setSectionResizeMode(modulesModule->availableLV->header(), QHeaderView::ResizeToContents);
1522 modulesModule->availableLV->header()->setStretchLastSection(false);
1523 selectionManager =
1524 new ModuleSelectionManager(this, modulesModule->availableLV,
1525 modulesModule->selectedLV,
1526 modulesModule->addPB,
1527 modulesModule->deletePB,
1528 modulesModule->upPB,
1529 modulesModule->downPB,
1530 availableModel(), selectedModel(), this);
1531 connect(selectionManager, SIGNAL(updateHook()),
1532 this, SLOT(updateModuleInfo()));
1533 connect(selectionManager, SIGNAL(selectionChanged()),
1534 this, SLOT(modulesChanged()));
1535
1536
1537 // PDF support
1538 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>(this);
1539 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
1540 this, SLOT(change_adaptor()));
1541 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
1542 this, SLOT(change_adaptor()));
1543 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
1544 this, SLOT(change_adaptor()));
1545 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
1546 this, SLOT(change_adaptor()));
1547 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
1548 this, SLOT(change_adaptor()));
1549 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
1550 this, SLOT(change_adaptor()));
1551 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
1552 this, SLOT(change_adaptor()));
1553 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
1554 this, SLOT(change_adaptor()));
1555 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
1556 this, SLOT(change_adaptor()));
1557 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
1558 this, SLOT(change_adaptor()));
1559 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
1560 this, SLOT(change_adaptor()));
1561 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
1562 this, SLOT(change_adaptor()));
1563 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
1564 this, SLOT(change_adaptor()));
1565 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
1566 this, SLOT(change_adaptor()));
1567 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
1568 this, SLOT(change_adaptor()));
1569 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
1570 this, SLOT(change_adaptor()));
1571
1572 pdfSupportModule->titleLE->setValidator(new NoNewLineValidator(
1573 pdfSupportModule->titleLE));
1574 pdfSupportModule->authorLE->setValidator(new NoNewLineValidator(
1575 pdfSupportModule->authorLE));
1576 pdfSupportModule->subjectLE->setValidator(new NoNewLineValidator(
1577 pdfSupportModule->subjectLE));
1578 pdfSupportModule->keywordsLE->setValidator(new NoNewLineValidator(
1579 pdfSupportModule->keywordsLE));
1580 pdfSupportModule->optionsLE->setValidator(new NoNewLineValidator(
1581 pdfSupportModule->optionsLE));
1582
1583 for (int i = 0; backref_opts[i][0]; ++i)
1584 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
1585
1586
1587 // float
1588 floatModule = new FloatPlacement;
1589 connect(floatModule, SIGNAL(changed()),
1590 this, SLOT(change_adaptor()));
1591
1592
1593 // listings
1594 listingsModule = new UiWidget<Ui::ListingsSettingsUi>(this);
1595 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1596 this, SLOT(change_adaptor()));
1597 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1598 this, SLOT(change_adaptor()));
1599 connect(listingsModule->bypassCB, SIGNAL(clicked()),
1600 this, SLOT(setListingsMessage()));
1601 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1602 this, SLOT(change_adaptor()));
1603 connect(listingsModule->packageCO, SIGNAL(activated(int)),
1604 this, SLOT(listingsPackageChanged(int)));
1605 connect(listingsModule->listingsED, SIGNAL(textChanged()),
1606 this, SLOT(setListingsMessage()));
1607 listingsModule->listingsTB->setPlainText(
1608 qt_("Input listings parameters below. Enter ? for a list of parameters."));
1609
1610 for (int i = 0; lst_packages[i][0]; ++i)
1611 listingsModule->packageCO->addItem(lst_packages[i]);
1612
1613
1614 // add the panels
1615 docPS->addPanel(latexModule, N_("Document Class"));
1616 docPS->addPanel(masterChildModule, N_("Child Documents"));
1617 docPS->addPanel(modulesModule, N_("Modules"));
1618 docPS->addPanel(localLayout, N_("Local Layout"));
1619 docPS->addPanel(fontModule, N_("Fonts"));
1620 docPS->addPanel(textLayoutModule, N_("Text Layout"));
1621 docPS->addPanel(pageLayoutModule, N_("Page Layout"));
1622 docPS->addPanel(marginsModule, N_("Page Margins"));
1623 docPS->addPanel(langModule, N_("Language"));
1624 docPS->addPanel(colorModule, N_("Colors"));
1625 docPS->addPanel(numberingModule, N_("Numbering & TOC"));
1626 docPS->addPanel(biblioModule, N_("Bibliography"));
1627 docPS->addPanel(indicesModule, N_("Indexes"));
1628 docPS->addPanel(pdfSupportModule, N_("PDF Properties"));
1629 docPS->addPanel(mathsModule, N_("Math Options"));
1630 docPS->addPanel(floatModule, N_("Float Placement"));
1631 docPS->addPanel(listingsModule, N_("Listings[[inset]]"));
1632 docPS->addPanel(bulletsModule, N_("Bullets"));
1633 docPS->addPanel(branchesModule, N_("Branches"));
1634 docPS->addPanel(outputModule, N_("Formats[[output]]"));
1635 docPS->addPanel(preambleModule, N_("LaTeX Preamble"));
1636 docPS->setCurrentPanel("Document Class");
1637 // FIXME: hack to work around resizing bug in Qt >= 4.2
1638 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1639 #if QT_VERSION >= 0x040200
1640 docPS->updateGeometry();
1641 #endif
1642 }
1643
1644
onBufferViewChanged()1645 void GuiDocument::onBufferViewChanged()
1646 {
1647 if (isVisibleView())
1648 initialiseParams("");
1649 }
1650
1651
saveDefaultClicked()1652 void GuiDocument::saveDefaultClicked()
1653 {
1654 saveDocDefault();
1655 }
1656
1657
useDefaultsClicked()1658 void GuiDocument::useDefaultsClicked()
1659 {
1660 useClassDefaults();
1661 }
1662
1663
change_adaptor()1664 void GuiDocument::change_adaptor()
1665 {
1666 nonModuleChanged_ = true;
1667 changed();
1668 }
1669
1670
shellescapeChanged()1671 void GuiDocument::shellescapeChanged()
1672 {
1673 shellescapeChanged_ = true;
1674 changed();
1675 }
1676
1677
slotApply()1678 void GuiDocument::slotApply()
1679 {
1680 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1681 bool wasclean = buffer().isClean();
1682 GuiDialog::slotApply();
1683 if (wasclean && only_shellescape_changed)
1684 buffer().markClean();
1685 modulesChanged_ = false;
1686 }
1687
1688
slotOK()1689 void GuiDocument::slotOK()
1690 {
1691 bool only_shellescape_changed = !nonModuleChanged_ && !modulesChanged_;
1692 bool wasclean = buffer().isClean();
1693 GuiDialog::slotOK();
1694 if (wasclean && only_shellescape_changed)
1695 buffer().markClean();
1696 modulesChanged_ = false;
1697 }
1698
1699
includeonlyClicked(QTreeWidgetItem * item,int)1700 void GuiDocument::includeonlyClicked(QTreeWidgetItem * item, int)
1701 {
1702 if (item == 0)
1703 return;
1704
1705 string child = fromqstr(item->text(0));
1706 if (child.empty())
1707 return;
1708
1709 if (std::find(includeonlys_.begin(),
1710 includeonlys_.end(), child) != includeonlys_.end())
1711 includeonlys_.remove(child);
1712 else
1713 includeonlys_.push_back(child);
1714
1715 updateIncludeonlys();
1716 change_adaptor();
1717 }
1718
1719
validateListingsParameters()1720 QString GuiDocument::validateListingsParameters()
1721 {
1722 if (listingsModule->bypassCB->isChecked())
1723 return QString();
1724 string const package =
1725 lst_packages[listingsModule->packageCO->currentIndex()];
1726 string params = fromqstr(listingsModule->listingsED->toPlainText());
1727 InsetListingsParams lstparams(params);
1728 lstparams.setMinted(package == "Minted");
1729 return toqstr(lstparams.validate());
1730 }
1731
1732
setListingsMessage()1733 void GuiDocument::setListingsMessage()
1734 {
1735 // FIXME THREAD
1736 static bool isOK = true;
1737 QString msg = validateListingsParameters();
1738 if (msg.isEmpty()) {
1739 if (isOK)
1740 return;
1741 isOK = true;
1742 // listingsTB->setTextColor("black");
1743 listingsModule->listingsTB->setPlainText(
1744 qt_("Input listings parameters below. "
1745 "Enter ? for a list of parameters."));
1746 } else {
1747 isOK = false;
1748 // listingsTB->setTextColor("red");
1749 listingsModule->listingsTB->setPlainText(msg);
1750 }
1751 }
1752
1753
listingsPackageChanged(int index)1754 void GuiDocument::listingsPackageChanged(int index)
1755 {
1756 string const package = lst_packages[index];
1757 if (package == "Minted" && lyxrc.pygmentize_command.empty()) {
1758 Alert::warning(_("Pygments driver command not found!"),
1759 _("The driver command necessary to use the minted package\n"
1760 "(pygmentize) has not been found. Make sure you have\n"
1761 "the python-pygments module installed or, if the driver\n"
1762 "is named differently, to add the following line to the\n"
1763 "document preamble:\n\n"
1764 "\\AtBeginDocument{\\renewcommand{\\MintedPygmentize}{driver}}\n\n"
1765 "where 'driver' is name of the driver command."));
1766 }
1767 }
1768
1769
setLSpacing(int item)1770 void GuiDocument::setLSpacing(int item)
1771 {
1772 textLayoutModule->lspacingLE->setEnabled(item == 3);
1773 }
1774
1775
setIndent(int item)1776 void GuiDocument::setIndent(int item)
1777 {
1778 bool const enable = (item == 1);
1779 textLayoutModule->indentLE->setEnabled(enable);
1780 textLayoutModule->indentLengthCO->setEnabled(enable);
1781 textLayoutModule->skipLE->setEnabled(false);
1782 textLayoutModule->skipLengthCO->setEnabled(false);
1783 isValid();
1784 }
1785
1786
enableIndent(bool indent)1787 void GuiDocument::enableIndent(bool indent)
1788 {
1789 textLayoutModule->skipLE->setEnabled(!indent);
1790 textLayoutModule->skipLengthCO->setEnabled(!indent);
1791 if (indent)
1792 setIndent(textLayoutModule->indentCO->currentIndex());
1793 }
1794
1795
setSkip(int item)1796 void GuiDocument::setSkip(int item)
1797 {
1798 bool const enable = (item == 3);
1799 textLayoutModule->skipLE->setEnabled(enable);
1800 textLayoutModule->skipLengthCO->setEnabled(enable);
1801 isValid();
1802 }
1803
1804
enableSkip(bool skip)1805 void GuiDocument::enableSkip(bool skip)
1806 {
1807 textLayoutModule->indentLE->setEnabled(!skip);
1808 textLayoutModule->indentLengthCO->setEnabled(!skip);
1809 if (skip)
1810 setSkip(textLayoutModule->skipCO->currentIndex());
1811 }
1812
allowMathIndent()1813 void GuiDocument::allowMathIndent() {
1814 // only disable when not checked, checked does not always allow enabling
1815 if (!mathsModule->MathIndentCB->isChecked()) {
1816 mathsModule->MathIndentLE->setEnabled(false);
1817 mathsModule->MathIndentLengthCO->setEnabled(false);
1818 }
1819 if (mathsModule->MathIndentCB->isChecked()
1820 && mathsModule->MathIndentCO->currentIndex() == 1) {
1821 mathsModule->MathIndentLE->setEnabled(true);
1822 mathsModule->MathIndentLengthCO->setEnabled(true);
1823 }
1824 isValid();
1825 }
1826
enableMathIndent(int item)1827 void GuiDocument::enableMathIndent(int item)
1828 {
1829 bool const enable = (item == 1);
1830 mathsModule->MathIndentLE->setEnabled(enable);
1831 mathsModule->MathIndentLengthCO->setEnabled(enable);
1832 isValid();
1833 }
1834
1835
setMargins()1836 void GuiDocument::setMargins()
1837 {
1838 bool const extern_geometry =
1839 documentClass().provides("geometry");
1840 marginsModule->marginCB->setEnabled(!extern_geometry);
1841 if (extern_geometry) {
1842 marginsModule->marginCB->setChecked(false);
1843 setCustomMargins(true);
1844 } else {
1845 marginsModule->marginCB->setChecked(!bp_.use_geometry);
1846 setCustomMargins(!bp_.use_geometry);
1847 }
1848 }
1849
1850
papersizeChanged(int paper_size)1851 void GuiDocument::papersizeChanged(int paper_size)
1852 {
1853 setCustomPapersize(paper_size == 1);
1854 }
1855
1856
setCustomPapersize(bool custom)1857 void GuiDocument::setCustomPapersize(bool custom)
1858 {
1859 pageLayoutModule->paperwidthL->setEnabled(custom);
1860 pageLayoutModule->paperwidthLE->setEnabled(custom);
1861 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1862 pageLayoutModule->paperheightL->setEnabled(custom);
1863 pageLayoutModule->paperheightLE->setEnabled(custom);
1864 pageLayoutModule->paperheightLE->setFocus();
1865 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1866 }
1867
1868
setColSep()1869 void GuiDocument::setColSep()
1870 {
1871 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1872 }
1873
1874
setCustomMargins(bool custom)1875 void GuiDocument::setCustomMargins(bool custom)
1876 {
1877 marginsModule->topL->setEnabled(!custom);
1878 marginsModule->topLE->setEnabled(!custom);
1879 marginsModule->topUnit->setEnabled(!custom);
1880
1881 marginsModule->bottomL->setEnabled(!custom);
1882 marginsModule->bottomLE->setEnabled(!custom);
1883 marginsModule->bottomUnit->setEnabled(!custom);
1884
1885 marginsModule->innerL->setEnabled(!custom);
1886 marginsModule->innerLE->setEnabled(!custom);
1887 marginsModule->innerUnit->setEnabled(!custom);
1888
1889 marginsModule->outerL->setEnabled(!custom);
1890 marginsModule->outerLE->setEnabled(!custom);
1891 marginsModule->outerUnit->setEnabled(!custom);
1892
1893 marginsModule->headheightL->setEnabled(!custom);
1894 marginsModule->headheightLE->setEnabled(!custom);
1895 marginsModule->headheightUnit->setEnabled(!custom);
1896
1897 marginsModule->headsepL->setEnabled(!custom);
1898 marginsModule->headsepLE->setEnabled(!custom);
1899 marginsModule->headsepUnit->setEnabled(!custom);
1900
1901 marginsModule->footskipL->setEnabled(!custom);
1902 marginsModule->footskipLE->setEnabled(!custom);
1903 marginsModule->footskipUnit->setEnabled(!custom);
1904
1905 bool const enableColSep = !custom &&
1906 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1907 marginsModule->columnsepL->setEnabled(enableColSep);
1908 marginsModule->columnsepLE->setEnabled(enableColSep);
1909 marginsModule->columnsepUnit->setEnabled(enableColSep);
1910 }
1911
1912
changeBackgroundColor()1913 void GuiDocument::changeBackgroundColor()
1914 {
1915 QColor const & newColor = QColorDialog::getColor(
1916 rgb2qcolor(set_backgroundcolor), asQWidget());
1917 if (!newColor.isValid())
1918 return;
1919 // set the button color and text
1920 colorModule->backgroundPB->setStyleSheet(
1921 colorButtonStyleSheet(newColor));
1922 colorModule->backgroundPB->setText(qt_("&Change..."));
1923 // save color
1924 set_backgroundcolor = rgbFromHexName(fromqstr(newColor.name()));
1925 is_backgroundcolor = true;
1926 change_adaptor();
1927 }
1928
1929
deleteBackgroundColor()1930 void GuiDocument::deleteBackgroundColor()
1931 {
1932 // set the button color back to default by setting an empty StyleSheet
1933 colorModule->backgroundPB->setStyleSheet(QLatin1String(""));
1934 // change button text
1935 colorModule->backgroundPB->setText(qt_("&Default..."));
1936 // save default color (white)
1937 set_backgroundcolor = rgbFromHexName("#ffffff");
1938 is_backgroundcolor = false;
1939 change_adaptor();
1940 }
1941
1942
changeFontColor()1943 void GuiDocument::changeFontColor()
1944 {
1945 QColor const & newColor = QColorDialog::getColor(
1946 rgb2qcolor(set_fontcolor), asQWidget());
1947 if (!newColor.isValid())
1948 return;
1949 // set the button color and text
1950 colorModule->fontColorPB->setStyleSheet(
1951 colorButtonStyleSheet(newColor));
1952 colorModule->fontColorPB->setText(qt_("&Change..."));
1953 // save color
1954 set_fontcolor = rgbFromHexName(fromqstr(newColor.name()));
1955 is_fontcolor = true;
1956 change_adaptor();
1957 }
1958
1959
deleteFontColor()1960 void GuiDocument::deleteFontColor()
1961 {
1962 // set the button color back to default by setting an empty StyleSheet
1963 colorModule->fontColorPB->setStyleSheet(QLatin1String(""));
1964 // change button text
1965 colorModule->fontColorPB->setText(qt_("&Default..."));
1966 // save default color (black)
1967 set_fontcolor = rgbFromHexName("#000000");
1968 is_fontcolor = false;
1969 change_adaptor();
1970 }
1971
1972
changeNoteFontColor()1973 void GuiDocument::changeNoteFontColor()
1974 {
1975 QColor const & newColor = QColorDialog::getColor(
1976 rgb2qcolor(set_notefontcolor), asQWidget());
1977 if (!newColor.isValid())
1978 return;
1979 // set the button color
1980 colorModule->noteFontColorPB->setStyleSheet(
1981 colorButtonStyleSheet(newColor));
1982 // save color
1983 set_notefontcolor = rgbFromHexName(fromqstr(newColor.name()));
1984 change_adaptor();
1985 }
1986
1987
deleteNoteFontColor()1988 void GuiDocument::deleteNoteFontColor()
1989 {
1990 // set the button color back to pref
1991 theApp()->getRgbColor(Color_greyedouttext, set_notefontcolor);
1992 colorModule->noteFontColorPB->setStyleSheet(
1993 colorButtonStyleSheet(rgb2qcolor(set_notefontcolor)));
1994 change_adaptor();
1995 }
1996
1997
changeBoxBackgroundColor()1998 void GuiDocument::changeBoxBackgroundColor()
1999 {
2000 QColor const & newColor = QColorDialog::getColor(
2001 rgb2qcolor(set_boxbgcolor), asQWidget());
2002 if (!newColor.isValid())
2003 return;
2004 // set the button color
2005 colorModule->boxBackgroundPB->setStyleSheet(
2006 colorButtonStyleSheet(newColor));
2007 // save color
2008 set_boxbgcolor = rgbFromHexName(fromqstr(newColor.name()));
2009 change_adaptor();
2010 }
2011
2012
deleteBoxBackgroundColor()2013 void GuiDocument::deleteBoxBackgroundColor()
2014 {
2015 // set the button color back to pref
2016 theApp()->getRgbColor(Color_shadedbg, set_boxbgcolor);
2017 colorModule->boxBackgroundPB->setStyleSheet(
2018 colorButtonStyleSheet(rgb2qcolor(set_boxbgcolor)));
2019 change_adaptor();
2020 }
2021
2022
updateQuoteStyles(bool const set)2023 void GuiDocument::updateQuoteStyles(bool const set)
2024 {
2025 Language const * lang = lyx::languages.getLanguage(
2026 fromqstr(langModule->languageCO->itemData(
2027 langModule->languageCO->currentIndex()).toString()));
2028
2029 InsetQuotesParams::QuoteStyle def = bp_.getQuoteStyle(lang->quoteStyle());
2030
2031 langModule->quoteStyleCO->clear();
2032
2033 bool has_default = false;
2034 for (int i = 0; i < quoteparams.stylescount(); ++i) {
2035 InsetQuotesParams::QuoteStyle qs = InsetQuotesParams::QuoteStyle(i);
2036 if (qs == InsetQuotesParams::DynamicQuotes)
2037 continue;
2038 bool const langdef = (qs == def);
2039 if (langdef) {
2040 // add the default style on top
2041 langModule->quoteStyleCO->insertItem(0,
2042 toqstr(quoteparams.getGuiLabel(qs, langdef)), qs);
2043 has_default = true;
2044 }
2045 else
2046 langModule->quoteStyleCO->addItem(
2047 toqstr(quoteparams.getGuiLabel(qs, langdef)), qs);
2048 }
2049 if (set && has_default)
2050 // (re)set to the default style
2051 langModule->quoteStyleCO->setCurrentIndex(0);
2052 }
2053
2054
languageChanged(int i)2055 void GuiDocument::languageChanged(int i)
2056 {
2057 // some languages only work with polyglossia
2058 Language const * lang = lyx::languages.getLanguage(
2059 fromqstr(langModule->languageCO->itemData(i).toString()));
2060 if (lang->babel().empty() && !lang->polyglossia().empty()) {
2061 // If we force to switch fontspec on, store
2062 // current state (#8717)
2063 if (fontModule->osFontsCB->isEnabled())
2064 forced_fontspec_activation =
2065 !fontModule->osFontsCB->isChecked();
2066 fontModule->osFontsCB->setChecked(true);
2067 fontModule->osFontsCB->setEnabled(false);
2068 }
2069 else {
2070 fontModule->osFontsCB->setEnabled(true);
2071 // If we have forced to switch fontspec on,
2072 // restore previous state (#8717)
2073 if (forced_fontspec_activation)
2074 fontModule->osFontsCB->setChecked(false);
2075 forced_fontspec_activation = false;
2076 }
2077
2078 // set appropriate quotation mark style
2079 updateQuoteStyles(true);
2080 }
2081
2082
osFontsChanged(bool nontexfonts)2083 void GuiDocument::osFontsChanged(bool nontexfonts)
2084 {
2085 bool const tex_fonts = !nontexfonts;
2086 // store current fonts
2087 QString const font_roman = fontModule->fontsRomanCO->itemData(
2088 fontModule->fontsRomanCO->currentIndex()).toString();
2089 QString const font_sans = fontModule->fontsSansCO->itemData(
2090 fontModule->fontsSansCO->currentIndex()).toString();
2091 QString const font_typewriter = fontModule->fontsTypewriterCO->itemData(
2092 fontModule->fontsTypewriterCO->currentIndex()).toString();
2093 QString const font_math = fontModule->fontsMathCO->itemData(
2094 fontModule->fontsMathCO->currentIndex()).toString();
2095 int const font_sf_scale = fontModule->scaleSansSB->value();
2096 int const font_tt_scale = fontModule->scaleTypewriterSB->value();
2097
2098 updateFontlist();
2099 // store default format
2100 QString const dformat = outputModule->defaultFormatCO->itemData(
2101 outputModule->defaultFormatCO->currentIndex()).toString();
2102 updateDefaultFormat();
2103 // try to restore default format
2104 int index = outputModule->defaultFormatCO->findData(dformat);
2105 // set to default if format is not found
2106 if (index == -1)
2107 index = 0;
2108 outputModule->defaultFormatCO->setCurrentIndex(index);
2109
2110 // try to restore fonts which were selected two toggles ago
2111 index = fontModule->fontsRomanCO->findData(fontModule->font_roman);
2112 if (index != -1)
2113 fontModule->fontsRomanCO->setCurrentIndex(index);
2114 index = fontModule->fontsSansCO->findData(fontModule->font_sans);
2115 if (index != -1)
2116 fontModule->fontsSansCO->setCurrentIndex(index);
2117 index = fontModule->fontsTypewriterCO->findData(fontModule->font_typewriter);
2118 if (index != -1)
2119 fontModule->fontsTypewriterCO->setCurrentIndex(index);
2120 index = fontModule->fontsMathCO->findData(fontModule->font_math);
2121 if (index != -1)
2122 fontModule->fontsMathCO->setCurrentIndex(index);
2123 // save fonts for next next toggle
2124 fontModule->font_roman = font_roman;
2125 fontModule->font_sans = font_sans;
2126 fontModule->font_typewriter = font_typewriter;
2127 fontModule->font_math = font_math;
2128 fontModule->font_sf_scale = font_sf_scale;
2129 fontModule->font_tt_scale = font_tt_scale;
2130
2131 langModule->encodingCO->setEnabled(tex_fonts &&
2132 !langModule->defaultencodingRB->isChecked());
2133 langModule->defaultencodingRB->setEnabled(tex_fonts);
2134 langModule->otherencodingRB->setEnabled(tex_fonts);
2135
2136 fontModule->fontsDefaultCO->setEnabled(tex_fonts);
2137 fontModule->fontsDefaultLA->setEnabled(tex_fonts);
2138 fontModule->cjkFontLE->setEnabled(tex_fonts);
2139 fontModule->cjkFontLA->setEnabled(tex_fonts);
2140
2141 updateFontOptions();
2142
2143 fontModule->fontencLA->setEnabled(tex_fonts);
2144 fontModule->fontencCO->setEnabled(tex_fonts);
2145 if (!tex_fonts)
2146 fontModule->fontencLE->setEnabled(false);
2147 else
2148 fontencChanged(fontModule->fontencCO->currentIndex());
2149 }
2150
2151
mathFontChanged(int)2152 void GuiDocument::mathFontChanged(int)
2153 {
2154 updateFontOptions();
2155 }
2156
2157
fontOsfToggled(bool state)2158 void GuiDocument::fontOsfToggled(bool state)
2159 {
2160 if (fontModule->osFontsCB->isChecked())
2161 return;
2162 QString font = fontModule->fontsRomanCO->itemData(
2163 fontModule->fontsRomanCO->currentIndex()).toString();
2164 if (hasMonolithicExpertSet(font))
2165 fontModule->fontScCB->setChecked(state);
2166 }
2167
2168
fontScToggled(bool state)2169 void GuiDocument::fontScToggled(bool state)
2170 {
2171 if (fontModule->osFontsCB->isChecked())
2172 return;
2173 QString font = fontModule->fontsRomanCO->itemData(
2174 fontModule->fontsRomanCO->currentIndex()).toString();
2175 if (hasMonolithicExpertSet(font))
2176 fontModule->fontOsfCB->setChecked(state);
2177 }
2178
2179
updateFontOptions()2180 void GuiDocument::updateFontOptions()
2181 {
2182 bool const tex_fonts = !fontModule->osFontsCB->isChecked();
2183 QString font;
2184 if (tex_fonts)
2185 font = fontModule->fontsSansCO->itemData(
2186 fontModule->fontsSansCO->currentIndex()).toString();
2187 bool scaleable = providesScale(font);
2188 fontModule->scaleSansSB->setEnabled(scaleable);
2189 fontModule->scaleSansLA->setEnabled(scaleable);
2190 if (tex_fonts)
2191 font = fontModule->fontsTypewriterCO->itemData(
2192 fontModule->fontsTypewriterCO->currentIndex()).toString();
2193 scaleable = providesScale(font);
2194 fontModule->scaleTypewriterSB->setEnabled(scaleable);
2195 fontModule->scaleTypewriterLA->setEnabled(scaleable);
2196 if (tex_fonts)
2197 font = fontModule->fontsRomanCO->itemData(
2198 fontModule->fontsRomanCO->currentIndex()).toString();
2199 fontModule->fontScCB->setEnabled(providesSC(font));
2200 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2201 updateMathFonts(font);
2202 }
2203
2204
updateFontsize(string const & items,string const & sel)2205 void GuiDocument::updateFontsize(string const & items, string const & sel)
2206 {
2207 fontModule->fontsizeCO->clear();
2208 fontModule->fontsizeCO->addItem(qt_("Default"));
2209
2210 for (int n = 0; !token(items,'|',n).empty(); ++n)
2211 fontModule->fontsizeCO->
2212 addItem(toqstr(token(items,'|',n)));
2213
2214 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
2215 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
2216 fontModule->fontsizeCO->setCurrentIndex(n);
2217 break;
2218 }
2219 }
2220 }
2221
2222
ot1() const2223 bool GuiDocument::ot1() const
2224 {
2225 QString const fontenc =
2226 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
2227 return (fontenc == "default"
2228 || (fontenc == "global" && (lyxrc.fontenc == "default" || lyxrc.fontenc == "OT1"))
2229 || (fontenc == "custom" && fontModule->fontencLE->text() == "OT1"));
2230 }
2231
2232
completeFontset() const2233 bool GuiDocument::completeFontset() const
2234 {
2235 return (fontModule->fontsSansCO->itemData(
2236 fontModule->fontsSansCO->currentIndex()).toString() == "default"
2237 && fontModule->fontsSansCO->itemData(
2238 fontModule->fontsTypewriterCO->currentIndex()).toString() == "default");
2239 }
2240
2241
noMathFont() const2242 bool GuiDocument::noMathFont() const
2243 {
2244 return (fontModule->fontsMathCO->itemData(
2245 fontModule->fontsMathCO->currentIndex()).toString() == "default");
2246 }
2247
2248
updateTexFonts()2249 void GuiDocument::updateTexFonts()
2250 {
2251 LaTeXFonts::TexFontMap texfontmap = theLaTeXFonts().getLaTeXFonts();
2252
2253 LaTeXFonts::TexFontMap::const_iterator it = texfontmap.begin();
2254 LaTeXFonts::TexFontMap::const_iterator end = texfontmap.end();
2255 for (; it != end; ++it) {
2256 LaTeXFont lf = it->second;
2257 if (lf.name().empty()) {
2258 LYXERR0("Error: Unnamed font: " << it->first);
2259 continue;
2260 }
2261 docstring const family = lf.family();
2262 docstring guiname = translateIfPossible(lf.guiname());
2263 if (!lf.available(ot1(), noMathFont()))
2264 guiname += _(" (not installed)");
2265 if (family == "rm")
2266 rmfonts_.insert(toqstr(guiname), toqstr(it->first));
2267 else if (family == "sf")
2268 sffonts_.insert(toqstr(guiname), toqstr(it->first));
2269 else if (family == "tt")
2270 ttfonts_.insert(toqstr(guiname), toqstr(it->first));
2271 else if (family == "math")
2272 mathfonts_.insert(toqstr(guiname), toqstr(it->first));
2273 }
2274 }
2275
2276
updateFontlist()2277 void GuiDocument::updateFontlist()
2278 {
2279 fontModule->fontsRomanCO->clear();
2280 fontModule->fontsSansCO->clear();
2281 fontModule->fontsTypewriterCO->clear();
2282 fontModule->fontsMathCO->clear();
2283
2284 // With fontspec (XeTeX, LuaTeX), we have access to all system fonts, but not the LaTeX fonts
2285 if (fontModule->osFontsCB->isChecked()) {
2286 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2287 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2288 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2289 QString unimath = qt_("Non-TeX Fonts Default");
2290 if (!LaTeXFeatures::isAvailable("unicode-math"))
2291 unimath += qt_(" (not available)");
2292 fontModule->fontsMathCO->addItem(qt_("Class Default (TeX Fonts)"), QString("auto"));
2293 fontModule->fontsMathCO->addItem(unimath, QString("default"));
2294
2295 QFontDatabase fontdb;
2296 QStringList families(fontdb.families());
2297 for (QStringList::Iterator it = families.begin(); it != families.end(); ++it) {
2298 fontModule->fontsRomanCO->addItem(*it, *it);
2299 fontModule->fontsSansCO->addItem(*it, *it);
2300 fontModule->fontsTypewriterCO->addItem(*it, *it);
2301 }
2302 return;
2303 }
2304
2305 if (rmfonts_.empty())
2306 updateTexFonts();
2307
2308 fontModule->fontsRomanCO->addItem(qt_("Default"), QString("default"));
2309 QMap<QString, QString>::const_iterator rmi = rmfonts_.constBegin();
2310 while (rmi != rmfonts_.constEnd()) {
2311 fontModule->fontsRomanCO->addItem(rmi.key(), rmi.value());
2312 ++rmi;
2313 }
2314
2315 fontModule->fontsSansCO->addItem(qt_("Default"), QString("default"));
2316 QMap<QString, QString>::const_iterator sfi = sffonts_.constBegin();
2317 while (sfi != sffonts_.constEnd()) {
2318 fontModule->fontsSansCO->addItem(sfi.key(), sfi.value());
2319 ++sfi;
2320 }
2321
2322 fontModule->fontsTypewriterCO->addItem(qt_("Default"), QString("default"));
2323 QMap<QString, QString>::const_iterator tti = ttfonts_.constBegin();
2324 while (tti != ttfonts_.constEnd()) {
2325 fontModule->fontsTypewriterCO->addItem(tti.key(), tti.value());
2326 ++tti;
2327 }
2328
2329 fontModule->fontsMathCO->addItem(qt_("Automatic"), QString("auto"));
2330 fontModule->fontsMathCO->addItem(qt_("Class Default"), QString("default"));
2331 QMap<QString, QString>::const_iterator mmi = mathfonts_.constBegin();
2332 while (mmi != mathfonts_.constEnd()) {
2333 fontModule->fontsMathCO->addItem(mmi.key(), mmi.value());
2334 ++mmi;
2335 }
2336 }
2337
2338
fontencChanged(int item)2339 void GuiDocument::fontencChanged(int item)
2340 {
2341 fontModule->fontencLE->setEnabled(
2342 fontModule->fontencCO->itemData(item).toString() == "custom");
2343 // The availability of TeX fonts depends on the font encoding
2344 updateTexFonts();
2345 updateFontOptions();
2346 }
2347
2348
updateMathFonts(QString const & rm)2349 void GuiDocument::updateMathFonts(QString const & rm)
2350 {
2351 if (fontModule->osFontsCB->isChecked())
2352 return;
2353 QString const math =
2354 fontModule->fontsMathCO->itemData(fontModule->fontsMathCO->currentIndex()).toString();
2355 int const i = fontModule->fontsMathCO->findData("default");
2356 if (providesNoMath(rm) && i == -1)
2357 fontModule->fontsMathCO->insertItem(1, qt_("Class Default"), QString("default"));
2358 else if (!providesNoMath(rm) && i != -1) {
2359 int const c = fontModule->fontsMathCO->currentIndex();
2360 fontModule->fontsMathCO->removeItem(i);
2361 if (c == i)
2362 fontModule->fontsMathCO->setCurrentIndex(0);
2363 }
2364 }
2365
2366
romanChanged(int item)2367 void GuiDocument::romanChanged(int item)
2368 {
2369 if (fontModule->osFontsCB->isChecked())
2370 return;
2371 QString const font =
2372 fontModule->fontsRomanCO->itemData(item).toString();
2373 fontModule->fontScCB->setEnabled(providesSC(font));
2374 fontModule->fontOsfCB->setEnabled(providesOSF(font));
2375 updateMathFonts(font);
2376 }
2377
2378
sansChanged(int item)2379 void GuiDocument::sansChanged(int item)
2380 {
2381 if (fontModule->osFontsCB->isChecked())
2382 return;
2383 QString const font =
2384 fontModule->fontsSansCO->itemData(item).toString();
2385 bool scaleable = providesScale(font);
2386 fontModule->scaleSansSB->setEnabled(scaleable);
2387 fontModule->scaleSansLA->setEnabled(scaleable);
2388 }
2389
2390
ttChanged(int item)2391 void GuiDocument::ttChanged(int item)
2392 {
2393 if (fontModule->osFontsCB->isChecked())
2394 return;
2395 QString const font =
2396 fontModule->fontsTypewriterCO->itemData(item).toString();
2397 bool scaleable = providesScale(font);
2398 fontModule->scaleTypewriterSB->setEnabled(scaleable);
2399 fontModule->scaleTypewriterLA->setEnabled(scaleable);
2400 }
2401
2402
updatePagestyle(string const & items,string const & sel)2403 void GuiDocument::updatePagestyle(string const & items, string const & sel)
2404 {
2405 pagestyles.clear();
2406 pageLayoutModule->pagestyleCO->clear();
2407 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
2408
2409 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2410 string style = token(items, '|', n);
2411 QString style_gui = qt_(style);
2412 pagestyles.push_back(pair<string, QString>(style, style_gui));
2413 pageLayoutModule->pagestyleCO->addItem(style_gui);
2414 }
2415
2416 if (sel == "default") {
2417 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
2418 return;
2419 }
2420
2421 int nn = 0;
2422
2423 for (size_t i = 0; i < pagestyles.size(); ++i)
2424 if (pagestyles[i].first == sel)
2425 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
2426
2427 if (nn > 0)
2428 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
2429 }
2430
2431
browseLayout()2432 void GuiDocument::browseLayout()
2433 {
2434 QString const label1 = qt_("Layouts|#o#O");
2435 QString const dir1 = toqstr(lyxrc.document_path);
2436 QStringList const filter(qt_("LyX Layout (*.layout)"));
2437 QString file = browseRelToParent(QString(), bufferFilePath(),
2438 qt_("Local layout file"), filter, false,
2439 label1, dir1);
2440
2441 if (!file.endsWith(".layout"))
2442 return;
2443
2444 FileName layoutFile = support::makeAbsPath(fromqstr(file),
2445 fromqstr(bufferFilePath()));
2446
2447 int const ret = Alert::prompt(_("Local layout file"),
2448 _("The layout file you have selected is a local layout\n"
2449 "file, not one in the system or user directory.\n"
2450 "Your document will not work with this layout if you\n"
2451 "move the layout file to a different directory."),
2452 1, 1, _("&Set Layout"), _("&Cancel"));
2453 if (ret == 1)
2454 return;
2455
2456 // load the layout file
2457 LayoutFileList & bcl = LayoutFileList::get();
2458 string classname = layoutFile.onlyFileName();
2459 // this will update an existing layout if that layout has been loaded before.
2460 LayoutFileIndex name = support::onlyFileName(bcl.addLocalLayout(
2461 classname.substr(0, classname.size() - 7),
2462 layoutFile.onlyPath().absFileName()));
2463
2464 if (name.empty()) {
2465 Alert::error(_("Error"),
2466 _("Unable to read local layout file."));
2467 return;
2468 }
2469
2470 const_cast<Buffer &>(buffer()).setLayoutPos(layoutFile.onlyPath().absFileName());
2471
2472 // do not trigger classChanged if there is no change.
2473 if (latexModule->classCO->currentText() == toqstr(name))
2474 return;
2475
2476 // add to combo box
2477 bool const avail = latexModule->classCO->set(toqstr(name));
2478 if (!avail) {
2479 LayoutFile const & tc = bcl[name];
2480 docstring const guiname = translateIfPossible(from_utf8(tc.description()));
2481 // tooltip sensu "KOMA-Script Article [Class 'scrartcl']"
2482 QString tooltip = toqstr(bformat(_("%1$s [Class '%2$s']"), guiname, from_utf8(tc.latexname())));
2483 tooltip += '\n' + qt_("This is a local layout file.");
2484 latexModule->classCO->addItemSort(toqstr(tc.name()), toqstr(guiname),
2485 toqstr(translateIfPossible(from_utf8(tc.category()))),
2486 tooltip,
2487 true, true, true, true);
2488 latexModule->classCO->set(toqstr(name));
2489 }
2490
2491 classChanged();
2492 }
2493
2494
browseMaster()2495 void GuiDocument::browseMaster()
2496 {
2497 QString const title = qt_("Select master document");
2498 QString const dir1 = toqstr(lyxrc.document_path);
2499 QString const old = latexModule->childDocLE->text();
2500 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
2501 QStringList const filter(qt_("LyX Files (*.lyx)"));
2502 QString file = browseRelToSub(old, docpath, title, filter, false,
2503 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
2504
2505 if (!file.isEmpty())
2506 latexModule->childDocLE->setText(file);
2507 }
2508
2509
classChanged_adaptor()2510 void GuiDocument::classChanged_adaptor()
2511 {
2512 const_cast<Buffer &>(buffer()).setLayoutPos(string());
2513 classChanged();
2514 }
2515
2516
classChanged()2517 void GuiDocument::classChanged()
2518 {
2519 int idx = latexModule->classCO->currentIndex();
2520 if (idx < 0)
2521 return;
2522 string const classname = fromqstr(latexModule->classCO->getData(idx));
2523
2524 if (applyPB->isEnabled()) {
2525 int const ret = Alert::prompt(_("Unapplied changes"),
2526 _("Some changes in the dialog were not yet applied.\n"
2527 "If you do not apply now, they will be lost after this action."),
2528 1, 1, _("&Apply"), _("&Dismiss"));
2529 if (ret == 0)
2530 applyView();
2531 }
2532
2533 // We load the TextClass as soon as it is selected. This is
2534 // necessary so that other options in the dialog can be updated
2535 // according to the new class. Note, however, that, if you use
2536 // the scroll wheel when sitting on the combo box, we'll load a
2537 // lot of TextClass objects very quickly....
2538 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
2539 Alert::error(_("Error"), _("Unable to set document class."));
2540 return;
2541 }
2542 if (lyxrc.auto_reset_options)
2543 bp_.useClassDefaults();
2544
2545 // With the introduction of modules came a distinction between the base
2546 // class and the document class. The former corresponds to the main layout
2547 // file; the latter is that plus the modules (or the document-specific layout,
2548 // or whatever else there could be). Our parameters come from the document
2549 // class. So when we set the base class, we also need to recreate the document
2550 // class. Otherwise, we still have the old one.
2551 bp_.makeDocumentClass();
2552 paramsToDialog();
2553 }
2554
2555
languagePackageChanged(int i)2556 void GuiDocument::languagePackageChanged(int i)
2557 {
2558 langModule->languagePackageLE->setEnabled(
2559 langModule->languagePackageCO->itemData(i).toString() == "custom");
2560 }
2561
2562
biblioChanged()2563 void GuiDocument::biblioChanged()
2564 {
2565 biblioChanged_ = true;
2566 change_adaptor();
2567 }
2568
2569
checkPossibleCiteEngines()2570 void GuiDocument::checkPossibleCiteEngines()
2571 {
2572 // Check if the class provides a specific engine,
2573 // and if so, enforce this.
2574 string force_engine;
2575 if (documentClass().provides("natbib")
2576 || documentClass().provides("natbib-internal"))
2577 force_engine = "natbib";
2578 else if (documentClass().provides("jurabib"))
2579 force_engine = "jurabib";
2580 else if (documentClass().provides("biblatex"))
2581 force_engine = "biblatex";
2582 else if (documentClass().provides("biblatex-natbib"))
2583 force_engine = "biblatex-natbib";
2584
2585 if (!force_engine.empty())
2586 biblioModule->citeEngineCO->setCurrentIndex(
2587 biblioModule->citeEngineCO->findData(toqstr(force_engine)));
2588 biblioModule->citeEngineCO->setEnabled(force_engine.empty());
2589 }
2590
2591
rescanBibFiles()2592 void GuiDocument::rescanBibFiles()
2593 {
2594 if (isBiblatex())
2595 rescanTexStyles("bbx cbx");
2596 else
2597 rescanTexStyles("bst");
2598 }
2599
2600
resetDefaultBibfile(string const & which)2601 void GuiDocument::resetDefaultBibfile(string const & which)
2602 {
2603 QString const engine =
2604 biblioModule->citeEngineCO->itemData(
2605 biblioModule->citeEngineCO->currentIndex()).toString();
2606
2607 CiteEngineType const cet =
2608 CiteEngineType(biblioModule->citeStyleCO->itemData(
2609 biblioModule->citeStyleCO->currentIndex()).toInt());
2610
2611 updateDefaultBiblio(theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet), which);
2612 }
2613
2614
resetDefaultBbxBibfile()2615 void GuiDocument::resetDefaultBbxBibfile()
2616 {
2617 resetDefaultBibfile("bbx");
2618 }
2619
2620
resetDefaultCbxBibfile()2621 void GuiDocument::resetDefaultCbxBibfile()
2622 {
2623 resetDefaultBibfile("cbx");
2624 }
2625
2626
citeEngineChanged(int n)2627 void GuiDocument::citeEngineChanged(int n)
2628 {
2629 QString const engine =
2630 biblioModule->citeEngineCO->itemData(n).toString();
2631
2632 vector<string> const engs =
2633 theCiteEnginesList[fromqstr(engine)]->getEngineType();
2634
2635 updateCiteStyles(engs);
2636 updateEngineDependends();
2637 resetDefaultBibfile();
2638 biblioChanged();
2639 }
2640
2641
updateEngineDependends()2642 void GuiDocument::updateEngineDependends()
2643 {
2644 bool const biblatex = isBiblatex();
2645
2646 // These are only useful with BibTeX
2647 biblioModule->defaultBiblioCO->setEnabled(!biblatex);
2648 biblioModule->bibtexStyleLA->setEnabled(!biblatex);
2649 biblioModule->resetDefaultBiblioPB->setEnabled(!biblatex);
2650 biblioModule->bibtopicCB->setEnabled(!biblatex);
2651
2652 // These are only useful with Biblatex
2653 biblioModule->biblatexBbxCO->setEnabled(biblatex);
2654 biblioModule->biblatexBbxLA->setEnabled(biblatex);
2655 biblioModule->biblatexCbxCO->setEnabled(biblatex);
2656 biblioModule->biblatexCbxLA->setEnabled(biblatex);
2657 biblioModule->resetBbxPB->setEnabled(biblatex);
2658 biblioModule->resetCbxPB->setEnabled(biblatex);
2659 biblioModule->matchBbxPB->setEnabled(biblatex);
2660
2661 // These are useful with biblatex, jurabib and natbib
2662 QString const engine =
2663 biblioModule->citeEngineCO->itemData(
2664 biblioModule->citeEngineCO->currentIndex()).toString();
2665 LyXCiteEngine const * ce = theCiteEnginesList[fromqstr(engine)];
2666
2667 bool const citepack = ce->requires("biblatex.sty") || ce->requires("jurabib.sty")
2668 || ce->requires("natbib.sty");
2669 biblioModule->citePackageOptionsLE->setEnabled(citepack);
2670 biblioModule->citePackageOptionsL->setEnabled(citepack);
2671 }
2672
2673
citeStyleChanged()2674 void GuiDocument::citeStyleChanged()
2675 {
2676 QString const engine =
2677 biblioModule->citeEngineCO->itemData(
2678 biblioModule->citeEngineCO->currentIndex()).toString();
2679 QString const currentDef = isBiblatex() ?
2680 biblioModule->biblatexBbxCO->currentText()
2681 : biblioModule->defaultBiblioCO->currentText();
2682 if (theCiteEnginesList[fromqstr(engine)]->isDefaultBiblio(fromqstr(currentDef)))
2683 resetDefaultBibfile();
2684
2685 biblioChanged();
2686 }
2687
2688
bibtexChanged(int n)2689 void GuiDocument::bibtexChanged(int n)
2690 {
2691 biblioModule->bibtexOptionsLE->setEnabled(
2692 biblioModule->bibtexCO->itemData(n).toString() != "default");
2693 biblioChanged();
2694 }
2695
2696
updateCiteStyles(vector<string> const & engs,CiteEngineType const & sel)2697 void GuiDocument::updateCiteStyles(vector<string> const & engs, CiteEngineType const & sel)
2698 {
2699 biblioModule->citeStyleCO->clear();
2700
2701 vector<string>::const_iterator it = engs.begin();
2702 vector<string>::const_iterator end = engs.end();
2703 for (; it != end; ++it) {
2704 if (*it == "default")
2705 biblioModule->citeStyleCO->addItem(qt_("Basic numerical"),
2706 ENGINE_TYPE_DEFAULT);
2707 else if (*it == "authoryear")
2708 biblioModule->citeStyleCO->addItem(qt_("Author-year"),
2709 ENGINE_TYPE_AUTHORYEAR);
2710 else if (*it == "numerical")
2711 biblioModule->citeStyleCO->addItem(qt_("Author-number"),
2712 ENGINE_TYPE_NUMERICAL);
2713 }
2714 int i = biblioModule->citeStyleCO->findData(sel);
2715 if (biblioModule->citeStyleCO->findData(sel) == -1)
2716 i = 0;
2717 biblioModule->citeStyleCO->setCurrentIndex(i);
2718
2719 biblioModule->citationStyleL->setEnabled(engs.size() > 1);
2720 biblioModule->citeStyleCO->setEnabled(engs.size() > 1);
2721 }
2722
2723
updateEngineType(string const & items,CiteEngineType const & sel)2724 void GuiDocument::updateEngineType(string const & items, CiteEngineType const & sel)
2725 {
2726 engine_types_.clear();
2727
2728 int nn = 0;
2729
2730 for (int n = 0; !token(items, '|', n).empty(); ++n) {
2731 nn += 1;
2732 string style = token(items, '|', n);
2733 engine_types_.push_back(style);
2734 }
2735
2736 updateCiteStyles(engine_types_, sel);
2737 }
2738
2739
2740 namespace {
2741 // FIXME unicode
2742 // both of these should take a vector<docstring>
2743
2744 // This is an insanely complicated attempt to make this sort of thing
2745 // work with RTL languages.
formatStrVec(vector<string> const & v,docstring const & s)2746 docstring formatStrVec(vector<string> const & v, docstring const & s)
2747 {
2748 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
2749 if (v.empty())
2750 return docstring();
2751 if (v.size() == 1)
2752 return translateIfPossible(from_utf8(v[0]));
2753 if (v.size() == 2) {
2754 docstring retval = _("%1$s and %2$s");
2755 retval = subst(retval, _("and"), s);
2756 return bformat(retval, translateIfPossible(from_utf8(v[0])),
2757 translateIfPossible(from_utf8(v[1])));
2758 }
2759 // The idea here is to format all but the last two items...
2760 int const vSize = v.size();
2761 docstring t2 = _("%1$s, %2$s");
2762 docstring retval = translateIfPossible(from_utf8(v[0]));
2763 for (int i = 1; i < vSize - 2; ++i)
2764 retval = bformat(t2, retval, translateIfPossible(from_utf8(v[i])));
2765 //...and then to plug them, and the last two, into this schema
2766 docstring t = _("%1$s, %2$s, and %3$s");
2767 t = subst(t, _("and"), s);
2768 return bformat(t, retval, translateIfPossible(from_utf8(v[vSize - 2])),
2769 translateIfPossible(from_utf8(v[vSize - 1])));
2770 }
2771
idsToNames(vector<string> const & idList)2772 vector<string> idsToNames(vector<string> const & idList)
2773 {
2774 vector<string> retval;
2775 vector<string>::const_iterator it = idList.begin();
2776 vector<string>::const_iterator end = idList.end();
2777 for (; it != end; ++it) {
2778 LyXModule const * const mod = theModuleList[*it];
2779 if (!mod)
2780 retval.push_back(to_utf8(bformat(_("%1$s (unavailable)"),
2781 translateIfPossible(from_utf8(*it)))));
2782 else
2783 retval.push_back(mod->getName());
2784 }
2785 return retval;
2786 }
2787 } // end anonymous namespace
2788
2789
modulesToParams(BufferParams & bp)2790 void GuiDocument::modulesToParams(BufferParams & bp)
2791 {
2792 // update list of loaded modules
2793 bp.clearLayoutModules();
2794 int const srows = modules_sel_model_.rowCount();
2795 for (int i = 0; i < srows; ++i)
2796 bp.addLayoutModule(modules_sel_model_.getIDString(i));
2797
2798 // update the list of removed modules
2799 bp.clearRemovedModules();
2800 LayoutModuleList const & reqmods = bp.baseClass()->defaultModules();
2801 list<string>::const_iterator rit = reqmods.begin();
2802 list<string>::const_iterator ren = reqmods.end();
2803
2804 // check each of the default modules
2805 for (; rit != ren; ++rit) {
2806 list<string>::const_iterator mit = bp.getModules().begin();
2807 list<string>::const_iterator men = bp.getModules().end();
2808 bool found = false;
2809 for (; mit != men; ++mit) {
2810 if (*rit == *mit) {
2811 found = true;
2812 break;
2813 }
2814 }
2815 if (!found) {
2816 // the module isn't present so must have been removed by the user
2817 bp.addRemovedModule(*rit);
2818 }
2819 }
2820 }
2821
modulesChanged()2822 void GuiDocument::modulesChanged()
2823 {
2824 modulesToParams(bp_);
2825
2826 if (applyPB->isEnabled() && (nonModuleChanged_ || shellescapeChanged_)) {
2827 int const ret = Alert::prompt(_("Unapplied changes"),
2828 _("Some changes in the dialog were not yet applied.\n"
2829 "If you do not apply now, they will be lost after this action."),
2830 1, 1, _("&Apply"), _("&Dismiss"));
2831 if (ret == 0)
2832 applyView();
2833 }
2834
2835 modulesChanged_ = true;
2836 bp_.makeDocumentClass();
2837 paramsToDialog();
2838 changed();
2839 }
2840
2841
updateModuleInfo()2842 void GuiDocument::updateModuleInfo()
2843 {
2844 selectionManager->update();
2845
2846 //Module description
2847 bool const focus_on_selected = selectionManager->selectedFocused();
2848 QAbstractItemView * lv;
2849 if (focus_on_selected)
2850 lv = modulesModule->selectedLV;
2851 else
2852 lv = modulesModule->availableLV;
2853 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
2854 modulesModule->infoML->document()->clear();
2855 return;
2856 }
2857 QModelIndex const & idx = lv->selectionModel()->currentIndex();
2858 GuiIdListModel const & id_model =
2859 focus_on_selected ? modules_sel_model_ : modules_av_model_;
2860 string const modName = id_model.getIDString(idx.row());
2861 docstring desc = getModuleDescription(modName);
2862
2863 LayoutModuleList const & provmods = bp_.baseClass()->providedModules();
2864 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
2865 if (!desc.empty())
2866 desc += "\n";
2867 desc += _("Module provided by document class.");
2868 }
2869
2870 docstring cat = getModuleCategory(modName);
2871 if (!cat.empty()) {
2872 if (!desc.empty())
2873 desc += "\n";
2874 desc += bformat(_("Category: %1$s."), cat);
2875 }
2876
2877 vector<string> pkglist = getPackageList(modName);
2878 docstring pkgdesc = formatStrVec(pkglist, _("and"));
2879 if (!pkgdesc.empty()) {
2880 if (!desc.empty())
2881 desc += "\n";
2882 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
2883 }
2884
2885 pkglist = getRequiredList(modName);
2886 if (!pkglist.empty()) {
2887 vector<string> const reqdescs = idsToNames(pkglist);
2888 pkgdesc = formatStrVec(reqdescs, _("or"));
2889 if (!desc.empty())
2890 desc += "\n";
2891 desc += bformat(_("Modules required: %1$s."), pkgdesc);
2892 }
2893
2894 pkglist = getExcludedList(modName);
2895 if (!pkglist.empty()) {
2896 vector<string> const reqdescs = idsToNames(pkglist);
2897 pkgdesc = formatStrVec(reqdescs, _( "and"));
2898 if (!desc.empty())
2899 desc += "\n";
2900 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
2901 }
2902
2903 if (!desc.empty())
2904 desc += "\n";
2905 desc += bformat(_("Filename: %1$s.module."), from_utf8(modName));
2906
2907 if (!isModuleAvailable(modName)) {
2908 if (!desc.empty())
2909 desc += "\n";
2910 desc += _("WARNING: Some required packages are unavailable!");
2911 }
2912
2913 modulesModule->infoML->document()->setPlainText(toqstr(desc));
2914 }
2915
2916
updateNumbering()2917 void GuiDocument::updateNumbering()
2918 {
2919 DocumentClass const & tclass = documentClass();
2920
2921 numberingModule->tocTW->setUpdatesEnabled(false);
2922 numberingModule->tocTW->clear();
2923
2924 int const depth = numberingModule->depthSL->value();
2925 int const toc = numberingModule->tocSL->value();
2926 QString const no = qt_("No");
2927 QString const yes = qt_("Yes");
2928 QTreeWidgetItem * item = 0;
2929
2930 DocumentClass::const_iterator lit = tclass.begin();
2931 DocumentClass::const_iterator len = tclass.end();
2932 for (; lit != len; ++lit) {
2933 int const toclevel = lit->toclevel;
2934 if (toclevel != Layout::NOT_IN_TOC && !lit->counter.empty()) {
2935 item = new QTreeWidgetItem(numberingModule->tocTW);
2936 item->setText(0, toqstr(translateIfPossible(lit->name())));
2937 item->setText(1, (toclevel <= depth) ? yes : no);
2938 item->setText(2, (toclevel <= toc) ? yes : no);
2939 }
2940 }
2941
2942 numberingModule->tocTW->setUpdatesEnabled(true);
2943 numberingModule->tocTW->update();
2944 }
2945
2946
updateDefaultFormat()2947 void GuiDocument::updateDefaultFormat()
2948 {
2949 if (!bufferview())
2950 return;
2951 // make a copy in order to consider unapplied changes
2952 BufferParams param_copy = buffer().params();
2953 param_copy.useNonTeXFonts = fontModule->osFontsCB->isChecked();
2954 int const idx = latexModule->classCO->currentIndex();
2955 if (idx >= 0) {
2956 string const classname = fromqstr(latexModule->classCO->getData(idx));
2957 param_copy.setBaseClass(classname, buffer().layoutPos());
2958 param_copy.makeDocumentClass(true);
2959 }
2960 outputModule->defaultFormatCO->blockSignals(true);
2961 outputModule->defaultFormatCO->clear();
2962 outputModule->defaultFormatCO->addItem(qt_("Default"),
2963 QVariant(QString("default")));
2964 FormatList const & formats =
2965 param_copy.exportableFormats(true);
2966 for (Format const * f : formats)
2967 outputModule->defaultFormatCO->addItem
2968 (toqstr(translateIfPossible(f->prettyname())),
2969 QVariant(toqstr(f->name())));
2970 outputModule->defaultFormatCO->blockSignals(false);
2971 }
2972
2973
isChildIncluded(string const & child)2974 bool GuiDocument::isChildIncluded(string const & child)
2975 {
2976 if (includeonlys_.empty())
2977 return false;
2978 return (std::find(includeonlys_.begin(),
2979 includeonlys_.end(), child) != includeonlys_.end());
2980 }
2981
2982
applyView()2983 void GuiDocument::applyView()
2984 {
2985 // preamble
2986 preambleModule->apply(bp_);
2987 localLayout->apply(bp_);
2988
2989 // date
2990 bp_.suppress_date = latexModule->suppressDateCB->isChecked();
2991 bp_.use_refstyle = latexModule->refstyleCB->isChecked();
2992
2993 // biblio
2994 string const engine =
2995 fromqstr(biblioModule->citeEngineCO->itemData(
2996 biblioModule->citeEngineCO->currentIndex()).toString());
2997 bp_.setCiteEngine(engine);
2998
2999 CiteEngineType const style = CiteEngineType(biblioModule->citeStyleCO->itemData(
3000 biblioModule->citeStyleCO->currentIndex()).toInt());
3001 if (theCiteEnginesList[engine]->hasEngineType(style))
3002 bp_.setCiteEngineType(style);
3003 else
3004 bp_.setCiteEngineType(ENGINE_TYPE_DEFAULT);
3005
3006 bp_.splitbib(biblioModule->bibtopicCB->isChecked());
3007
3008 bp_.multibib = fromqstr(biblioModule->bibunitsCO->itemData(
3009 biblioModule->bibunitsCO->currentIndex()).toString());
3010
3011 bp_.setDefaultBiblioStyle(fromqstr(biblioModule->defaultBiblioCO->currentText()));
3012
3013 bp_.biblatex_bibstyle = fromqstr(biblioModule->biblatexBbxCO->currentText());
3014 bp_.biblatex_citestyle = fromqstr(biblioModule->biblatexCbxCO->currentText());
3015 bp_.biblio_opts = fromqstr(biblioModule->citePackageOptionsLE->text());
3016
3017 string const bibtex_command =
3018 fromqstr(biblioModule->bibtexCO->itemData(
3019 biblioModule->bibtexCO->currentIndex()).toString());
3020 string const bibtex_options =
3021 fromqstr(biblioModule->bibtexOptionsLE->text());
3022 if (bibtex_command == "default" || bibtex_options.empty())
3023 bp_.bibtex_command = bibtex_command;
3024 else
3025 bp_.bibtex_command = bibtex_command + " " + bibtex_options;
3026
3027 if (biblioChanged_) {
3028 buffer().invalidateBibinfoCache();
3029 buffer().removeBiblioTempFiles();
3030 }
3031
3032 // Indices
3033 indicesModule->apply(bp_);
3034
3035 // language & quotes
3036 if (langModule->defaultencodingRB->isChecked()) {
3037 bp_.inputenc = "auto";
3038 } else {
3039 int i = langModule->encodingCO->currentIndex();
3040 if (i == 0)
3041 bp_.inputenc = "default";
3042 else {
3043 QString const enc_gui =
3044 langModule->encodingCO->currentText();
3045 Encodings::const_iterator it = encodings.begin();
3046 Encodings::const_iterator const end = encodings.end();
3047 bool found = false;
3048 for (; it != end; ++it) {
3049 if (qt_(it->guiName()) == enc_gui &&
3050 !it->unsafe()) {
3051 bp_.inputenc = it->name();
3052 found = true;
3053 break;
3054 }
3055 }
3056 if (!found) {
3057 // should not happen
3058 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
3059 bp_.inputenc = "default";
3060 }
3061 }
3062 }
3063
3064 bp_.quotes_style = (InsetQuotesParams::QuoteStyle) langModule->quoteStyleCO->itemData(
3065 langModule->quoteStyleCO->currentIndex()).toInt();
3066 bp_.dynamic_quotes = langModule->dynamicQuotesCB->isChecked();
3067
3068 QString const langname = langModule->languageCO->itemData(
3069 langModule->languageCO->currentIndex()).toString();
3070 Language const * newlang = lyx::languages.getLanguage(fromqstr(langname));
3071 Cursor & cur = const_cast<BufferView *>(bufferview())->cursor();
3072 // If current cursor language was the document language, then update it too.
3073 if (cur.current_font.language() == bp_.language) {
3074 cur.current_font.setLanguage(newlang);
3075 cur.real_current_font.setLanguage(newlang);
3076 }
3077 bp_.language = newlang;
3078
3079 QString const pack = langModule->languagePackageCO->itemData(
3080 langModule->languagePackageCO->currentIndex()).toString();
3081 if (pack == "custom")
3082 bp_.lang_package =
3083 fromqstr(langModule->languagePackageLE->text());
3084 else
3085 bp_.lang_package = fromqstr(pack);
3086
3087 //color
3088 bp_.backgroundcolor = set_backgroundcolor;
3089 bp_.isbackgroundcolor = is_backgroundcolor;
3090 bp_.fontcolor = set_fontcolor;
3091 bp_.isfontcolor = is_fontcolor;
3092 bp_.notefontcolor = set_notefontcolor;
3093 bp_.boxbgcolor = set_boxbgcolor;
3094
3095 // numbering
3096 if (bp_.documentClass().hasTocLevels()) {
3097 bp_.tocdepth = numberingModule->tocSL->value();
3098 bp_.secnumdepth = numberingModule->depthSL->value();
3099 }
3100
3101 // bullets
3102 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
3103 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
3104 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
3105 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
3106
3107 // packages
3108 bp_.graphics_driver =
3109 tex_graphics[latexModule->psdriverCO->currentIndex()];
3110
3111 // text layout
3112 int idx = latexModule->classCO->currentIndex();
3113 if (idx >= 0) {
3114 string const classname = fromqstr(latexModule->classCO->getData(idx));
3115 bp_.setBaseClass(classname, buffer().layoutPos());
3116 }
3117
3118 // Modules
3119 modulesToParams(bp_);
3120
3121 // Math
3122 map<string, string> const & packages = BufferParams::auto_packages();
3123 for (map<string, string>::const_iterator it = packages.begin();
3124 it != packages.end(); ++it) {
3125 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3126 if (!item)
3127 continue;
3128 int row = mathsModule->packagesTW->row(item);
3129
3130 QRadioButton * rb =
3131 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3132 if (rb->isChecked()) {
3133 bp_.use_package(it->first, BufferParams::package_auto);
3134 continue;
3135 }
3136 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3137 if (rb->isChecked()) {
3138 bp_.use_package(it->first, BufferParams::package_on);
3139 continue;
3140 }
3141 rb = (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3142 if (rb->isChecked())
3143 bp_.use_package(it->first, BufferParams::package_off);
3144 }
3145 // if math is indented
3146 bp_.is_math_indent = mathsModule->MathIndentCB->isChecked();
3147 if (bp_.is_math_indent) {
3148 // if formulas are indented
3149 switch (mathsModule->MathIndentCO->currentIndex()) {
3150 case 0:
3151 bp_.setMathIndent(Length());
3152 break;
3153 case 1: {
3154 Length mathindent(widgetsToLength(mathsModule->MathIndentLE,
3155 mathsModule->MathIndentLengthCO));
3156 bp_.setMathIndent(mathindent);
3157 break;
3158 }
3159 default:
3160 // this should never happen
3161 bp_.setMathIndent(Length());
3162 break;
3163 }
3164 }
3165 switch (mathsModule->MathNumberingPosCO->currentIndex()) {
3166 case 0:
3167 bp_.math_numbering_side = BufferParams::LEFT;
3168 break;
3169 case 1:
3170 bp_.math_numbering_side = BufferParams::DEFAULT;
3171 break;
3172 case 2:
3173 bp_.math_numbering_side = BufferParams::RIGHT;
3174 break;
3175 default:
3176 // this should never happen
3177 bp_.math_numbering_side = BufferParams::DEFAULT;
3178 break;
3179 }
3180
3181 // Page Layout
3182 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
3183 bp_.pagestyle = "default";
3184 else {
3185 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
3186 for (size_t i = 0; i != pagestyles.size(); ++i)
3187 if (pagestyles[i].second == style_gui)
3188 bp_.pagestyle = pagestyles[i].first;
3189 }
3190
3191 // Text Layout
3192 switch (textLayoutModule->lspacingCO->currentIndex()) {
3193 case 0:
3194 bp_.spacing().set(Spacing::Single);
3195 break;
3196 case 1:
3197 bp_.spacing().set(Spacing::Onehalf);
3198 break;
3199 case 2:
3200 bp_.spacing().set(Spacing::Double);
3201 break;
3202 case 3: {
3203 string s = widgetToDoubleStr(textLayoutModule->lspacingLE);
3204 if (s.empty())
3205 bp_.spacing().set(Spacing::Single);
3206 else
3207 bp_.spacing().set(Spacing::Other, s);
3208 break;
3209 }
3210 }
3211
3212 if (textLayoutModule->twoColumnCB->isChecked())
3213 bp_.columns = 2;
3214 else
3215 bp_.columns = 1;
3216
3217 bp_.justification = textLayoutModule->justCB->isChecked();
3218
3219 if (textLayoutModule->indentRB->isChecked()) {
3220 // if paragraphs are separated by an indentation
3221 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
3222 switch (textLayoutModule->indentCO->currentIndex()) {
3223 case 0:
3224 bp_.setParIndent(Length());
3225 break;
3226 case 1: {
3227 Length parindent(widgetsToLength(textLayoutModule->indentLE,
3228 textLayoutModule->indentLengthCO));
3229 bp_.setParIndent(parindent);
3230 break;
3231 }
3232 default:
3233 // this should never happen
3234 bp_.setParIndent(Length());
3235 break;
3236 }
3237 } else {
3238 // if paragraphs are separated by a skip
3239 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
3240 switch (textLayoutModule->skipCO->currentIndex()) {
3241 case 0:
3242 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
3243 break;
3244 case 1:
3245 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3246 break;
3247 case 2:
3248 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
3249 break;
3250 case 3:
3251 {
3252 VSpace vs = VSpace(
3253 widgetsToLength(textLayoutModule->skipLE,
3254 textLayoutModule->skipLengthCO)
3255 );
3256 bp_.setDefSkip(vs);
3257 break;
3258 }
3259 default:
3260 // this should never happen
3261 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
3262 break;
3263 }
3264 }
3265
3266 bp_.options =
3267 fromqstr(latexModule->optionsLE->text());
3268
3269 bp_.use_default_options =
3270 latexModule->defaultOptionsCB->isChecked();
3271
3272 if (latexModule->childDocGB->isChecked())
3273 bp_.master =
3274 fromqstr(latexModule->childDocLE->text());
3275 else
3276 bp_.master = string();
3277
3278 // Master/Child
3279 bp_.clearIncludedChildren();
3280 if (masterChildModule->includeonlyRB->isChecked()) {
3281 list<string>::const_iterator it = includeonlys_.begin();
3282 for (; it != includeonlys_.end() ; ++it) {
3283 bp_.addIncludedChildren(*it);
3284 }
3285 }
3286 bp_.maintain_unincluded_children =
3287 masterChildModule->maintainAuxCB->isChecked();
3288
3289 // Float Placement
3290 bp_.float_placement = floatModule->get();
3291
3292 // Listings
3293 // text should have passed validation
3294 idx = listingsModule->packageCO->currentIndex();
3295 bp_.use_minted = string(lst_packages[idx]) == "Minted";
3296 bp_.listings_params =
3297 InsetListingsParams(fromqstr(listingsModule->listingsED->toPlainText())).params();
3298
3299 // Formats
3300 bp_.default_output_format = fromqstr(outputModule->defaultFormatCO->itemData(
3301 outputModule->defaultFormatCO->currentIndex()).toString());
3302
3303 bool const nontexfonts = fontModule->osFontsCB->isChecked();
3304 bp_.useNonTeXFonts = nontexfonts;
3305
3306 bp_.shell_escape = outputModule->shellescapeCB->isChecked();
3307 if (!bp_.shell_escape)
3308 theSession().shellescapeFiles().remove(buffer().absFileName());
3309 else if (!theSession().shellescapeFiles().find(buffer().absFileName()))
3310 theSession().shellescapeFiles().insert(buffer().absFileName());
3311 Buffer & buf = const_cast<Buffer &>(buffer());
3312 buf.params().shell_escape = bp_.shell_escape;
3313
3314 bp_.output_sync = outputModule->outputsyncCB->isChecked();
3315
3316 bp_.output_sync_macro = fromqstr(outputModule->synccustomCB->currentText());
3317
3318 int mathfmt = outputModule->mathoutCB->currentIndex();
3319 if (mathfmt == -1)
3320 mathfmt = 0;
3321 BufferParams::MathOutput const mo =
3322 static_cast<BufferParams::MathOutput>(mathfmt);
3323 bp_.html_math_output = mo;
3324 bp_.html_be_strict = outputModule->strictCB->isChecked();
3325 bp_.html_css_as_file = outputModule->cssCB->isChecked();
3326 bp_.html_math_img_scale = outputModule->mathimgSB->value();
3327 bp_.display_pixel_ratio = theGuiApp()->pixelRatio();
3328
3329 bp_.save_transient_properties =
3330 outputModule->saveTransientPropertiesCB->isChecked();
3331
3332 // fonts
3333 bp_.fonts_roman[nontexfonts] =
3334 fromqstr(fontModule->fontsRomanCO->
3335 itemData(fontModule->fontsRomanCO->currentIndex()).toString());
3336 bp_.fonts_roman[!nontexfonts] = fromqstr(fontModule->font_roman);
3337
3338 bp_.fonts_sans[nontexfonts] =
3339 fromqstr(fontModule->fontsSansCO->
3340 itemData(fontModule->fontsSansCO->currentIndex()).toString());
3341 bp_.fonts_sans[!nontexfonts] = fromqstr(fontModule->font_sans);
3342
3343 bp_.fonts_typewriter[nontexfonts] =
3344 fromqstr(fontModule->fontsTypewriterCO->
3345 itemData(fontModule->fontsTypewriterCO->currentIndex()).toString());
3346 bp_.fonts_typewriter[!nontexfonts] = fromqstr(fontModule->font_typewriter);
3347
3348 bp_.fonts_math[nontexfonts] =
3349 fromqstr(fontModule->fontsMathCO->
3350 itemData(fontModule->fontsMathCO->currentIndex()).toString());
3351 bp_.fonts_math[!nontexfonts] = fromqstr(fontModule->font_math);
3352
3353 QString const fontenc =
3354 fontModule->fontencCO->itemData(fontModule->fontencCO->currentIndex()).toString();
3355 if (fontenc == "custom")
3356 bp_.fontenc = fromqstr(fontModule->fontencLE->text());
3357 else
3358 bp_.fontenc = fromqstr(fontenc);
3359
3360 bp_.fonts_cjk =
3361 fromqstr(fontModule->cjkFontLE->text());
3362
3363 bp_.use_microtype = fontModule->microtypeCB->isChecked();
3364 bp_.use_dash_ligatures = !fontModule->dashesCB->isChecked();
3365
3366 bp_.fonts_sans_scale[nontexfonts] = fontModule->scaleSansSB->value();
3367 bp_.fonts_sans_scale[!nontexfonts] = fontModule->font_sf_scale;
3368
3369 bp_.fonts_typewriter_scale[nontexfonts] = fontModule->scaleTypewriterSB->value();
3370 bp_.fonts_typewriter_scale[!nontexfonts] = fontModule->font_tt_scale;
3371
3372 bp_.fonts_expert_sc = fontModule->fontScCB->isChecked();
3373
3374 bp_.fonts_old_figures = fontModule->fontOsfCB->isChecked();
3375
3376 if (nontexfonts)
3377 bp_.fonts_default_family = "default";
3378 else
3379 bp_.fonts_default_family = GuiDocument::fontfamilies[
3380 fontModule->fontsDefaultCO->currentIndex()];
3381
3382 if (fontModule->fontsizeCO->currentIndex() == 0)
3383 bp_.fontsize = "default";
3384 else
3385 bp_.fontsize =
3386 fromqstr(fontModule->fontsizeCO->currentText());
3387
3388 // paper
3389 bp_.papersize = PAPER_SIZE(
3390 pageLayoutModule->papersizeCO->currentIndex());
3391
3392 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
3393 pageLayoutModule->paperwidthUnitCO);
3394
3395 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
3396 pageLayoutModule->paperheightUnitCO);
3397
3398 if (pageLayoutModule->facingPagesCB->isChecked())
3399 bp_.sides = TwoSides;
3400 else
3401 bp_.sides = OneSide;
3402
3403 if (pageLayoutModule->landscapeRB->isChecked())
3404 bp_.orientation = ORIENTATION_LANDSCAPE;
3405 else
3406 bp_.orientation = ORIENTATION_PORTRAIT;
3407
3408 // margins
3409 bp_.use_geometry = !marginsModule->marginCB->isChecked();
3410
3411 Ui::MarginsUi const * m = marginsModule;
3412
3413 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
3414 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
3415 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
3416 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
3417 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
3418 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
3419 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
3420 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
3421
3422 // branches
3423 branchesModule->apply(bp_);
3424
3425 // PDF support
3426 PDFOptions & pdf = bp_.pdfoptions();
3427 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
3428 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
3429 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
3430 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
3431 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
3432
3433 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
3434 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
3435 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
3436 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
3437
3438 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
3439 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
3440 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
3441 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
3442 pdf.backref =
3443 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
3444 if (pdfSupportModule->fullscreenCB->isChecked())
3445 pdf.pagemode = pdf.pagemode_fullscreen;
3446 else
3447 pdf.pagemode.clear();
3448 pdf.quoted_options = pdf.quoted_options_check(
3449 fromqstr(pdfSupportModule->optionsLE->text()));
3450
3451 // reset trackers
3452 nonModuleChanged_ = false;
3453 shellescapeChanged_ = false;
3454 }
3455
3456
paramsToDialog()3457 void GuiDocument::paramsToDialog()
3458 {
3459 // set the default unit
3460 Length::UNIT const default_unit = Length::defaultUnit();
3461
3462 // preamble
3463 preambleModule->update(bp_, id());
3464 localLayout->update(bp_, id());
3465
3466 // date
3467 latexModule->suppressDateCB->setChecked(bp_.suppress_date);
3468 latexModule->refstyleCB->setChecked(bp_.use_refstyle);
3469
3470 // biblio
3471 string const cite_engine = bp_.citeEngine().list().front();
3472
3473 biblioModule->citeEngineCO->setCurrentIndex(
3474 biblioModule->citeEngineCO->findData(toqstr(cite_engine)));
3475
3476 updateEngineType(documentClass().opt_enginetype(),
3477 bp_.citeEngineType());
3478
3479 checkPossibleCiteEngines();
3480
3481 biblioModule->citeStyleCO->setCurrentIndex(
3482 biblioModule->citeStyleCO->findData(bp_.citeEngineType()));
3483
3484 biblioModule->bibtopicCB->setChecked(bp_.splitbib());
3485
3486 biblioModule->bibunitsCO->clear();
3487 biblioModule->bibunitsCO->addItem(qt_("No"), QString());
3488 if (documentClass().hasLaTeXLayout("part"))
3489 biblioModule->bibunitsCO->addItem(qt_("per part"), toqstr("part"));
3490 if (documentClass().hasLaTeXLayout("chapter"))
3491 biblioModule->bibunitsCO->addItem(qt_("per chapter"), toqstr("chapter"));
3492 if (documentClass().hasLaTeXLayout("section"))
3493 biblioModule->bibunitsCO->addItem(qt_("per section"), toqstr("section"));
3494 if (documentClass().hasLaTeXLayout("subsection"))
3495 biblioModule->bibunitsCO->addItem(qt_("per subsection"), toqstr("subsection"));
3496 biblioModule->bibunitsCO->addItem(qt_("per child document"), toqstr("child"));
3497
3498 int const mbpos = biblioModule->bibunitsCO->findData(toqstr(bp_.multibib));
3499 if (mbpos != -1)
3500 biblioModule->bibunitsCO->setCurrentIndex(mbpos);
3501 else
3502 biblioModule->bibunitsCO->setCurrentIndex(0);
3503
3504 updateEngineDependends();
3505
3506 if (isBiblatex()) {
3507 updateDefaultBiblio(bp_.biblatex_bibstyle, "bbx");
3508 updateDefaultBiblio(bp_.biblatex_citestyle, "cbx");
3509 } else
3510 updateDefaultBiblio(bp_.defaultBiblioStyle());
3511
3512 biblioModule->citePackageOptionsLE->setText(toqstr(bp_.biblio_opts));
3513
3514 string command;
3515 string options =
3516 split(bp_.bibtex_command, command, ' ');
3517
3518 int const bpos = biblioModule->bibtexCO->findData(toqstr(command));
3519 if (bpos != -1) {
3520 biblioModule->bibtexCO->setCurrentIndex(bpos);
3521 biblioModule->bibtexOptionsLE->setText(toqstr(options).trimmed());
3522 } else {
3523 // We reset to default if we do not know the specified compiler
3524 // This is for security reasons
3525 biblioModule->bibtexCO->setCurrentIndex(
3526 biblioModule->bibtexCO->findData(toqstr("default")));
3527 biblioModule->bibtexOptionsLE->clear();
3528 }
3529 biblioModule->bibtexOptionsLE->setEnabled(
3530 biblioModule->bibtexCO->currentIndex() != 0);
3531
3532 biblioChanged_ = false;
3533
3534 // indices
3535 // We may be called when there is no Buffer, e.g., when
3536 // the last view has just been closed.
3537 bool const isReadOnly = isBufferAvailable() ? buffer().isReadonly() : false;
3538 indicesModule->update(bp_, isReadOnly);
3539
3540 // language & quotes
3541 int const pos = langModule->languageCO->findData(toqstr(
3542 bp_.language->lang()));
3543 langModule->languageCO->setCurrentIndex(pos);
3544
3545 updateQuoteStyles();
3546
3547 langModule->quoteStyleCO->setCurrentIndex(
3548 langModule->quoteStyleCO->findData(bp_.quotes_style));
3549 langModule->dynamicQuotesCB->setChecked(bp_.dynamic_quotes);
3550
3551 bool default_enc = true;
3552 if (bp_.inputenc != "auto") {
3553 default_enc = false;
3554 if (bp_.inputenc == "default") {
3555 langModule->encodingCO->setCurrentIndex(0);
3556 } else {
3557 string enc_gui;
3558 Encodings::const_iterator it = encodings.begin();
3559 Encodings::const_iterator const end = encodings.end();
3560 for (; it != end; ++it) {
3561 if (it->name() == bp_.inputenc &&
3562 !it->unsafe()) {
3563 enc_gui = it->guiName();
3564 break;
3565 }
3566 }
3567 int const i = langModule->encodingCO->findText(
3568 qt_(enc_gui));
3569 if (i >= 0)
3570 langModule->encodingCO->setCurrentIndex(i);
3571 else
3572 // unknown encoding. Set to default.
3573 default_enc = true;
3574 }
3575 }
3576 langModule->defaultencodingRB->setChecked(default_enc);
3577 langModule->otherencodingRB->setChecked(!default_enc);
3578
3579 int const p = langModule->languagePackageCO->findData(toqstr(bp_.lang_package));
3580 if (p == -1) {
3581 langModule->languagePackageCO->setCurrentIndex(
3582 langModule->languagePackageCO->findData("custom"));
3583 langModule->languagePackageLE->setText(toqstr(bp_.lang_package));
3584 } else {
3585 langModule->languagePackageCO->setCurrentIndex(p);
3586 langModule->languagePackageLE->clear();
3587 }
3588
3589 //color
3590 if (bp_.isfontcolor) {
3591 colorModule->fontColorPB->setStyleSheet(
3592 colorButtonStyleSheet(rgb2qcolor(bp_.fontcolor)));
3593 }
3594 set_fontcolor = bp_.fontcolor;
3595 is_fontcolor = bp_.isfontcolor;
3596
3597 colorModule->noteFontColorPB->setStyleSheet(
3598 colorButtonStyleSheet(rgb2qcolor(bp_.notefontcolor)));
3599 set_notefontcolor = bp_.notefontcolor;
3600
3601 if (bp_.isbackgroundcolor) {
3602 colorModule->backgroundPB->setStyleSheet(
3603 colorButtonStyleSheet(rgb2qcolor(bp_.backgroundcolor)));
3604 }
3605 set_backgroundcolor = bp_.backgroundcolor;
3606 is_backgroundcolor = bp_.isbackgroundcolor;
3607
3608 colorModule->boxBackgroundPB->setStyleSheet(
3609 colorButtonStyleSheet(rgb2qcolor(bp_.boxbgcolor)));
3610 set_boxbgcolor = bp_.boxbgcolor;
3611
3612 // numbering
3613 int const min_toclevel = documentClass().min_toclevel();
3614 int const max_toclevel = documentClass().max_toclevel();
3615 if (documentClass().hasTocLevels()) {
3616 numberingModule->setEnabled(true);
3617 numberingModule->depthSL->setMinimum(min_toclevel - 1);
3618 numberingModule->depthSL->setMaximum(max_toclevel);
3619 numberingModule->depthSL->setValue(bp_.secnumdepth);
3620 numberingModule->tocSL->setMaximum(min_toclevel - 1);
3621 numberingModule->tocSL->setMaximum(max_toclevel);
3622 numberingModule->tocSL->setValue(bp_.tocdepth);
3623 updateNumbering();
3624 } else {
3625 numberingModule->setEnabled(false);
3626 numberingModule->tocTW->clear();
3627 }
3628
3629 // bullets
3630 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
3631 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
3632 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
3633 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
3634 bulletsModule->init();
3635
3636 // packages
3637 int nitem = findToken(tex_graphics, bp_.graphics_driver);
3638 if (nitem >= 0)
3639 latexModule->psdriverCO->setCurrentIndex(nitem);
3640 updateModuleInfo();
3641
3642 // math
3643 mathsModule->MathIndentCB->setChecked(bp_.is_math_indent);
3644 if (bp_.is_math_indent) {
3645 Length const mathindent = bp_.getMathIndent();
3646 int indent = 0;
3647 if (!mathindent.empty()) {
3648 lengthToWidgets(mathsModule->MathIndentLE,
3649 mathsModule->MathIndentLengthCO,
3650 mathindent, default_unit);
3651 indent = 1;
3652 }
3653 mathsModule->MathIndentCO->setCurrentIndex(indent);
3654 enableMathIndent(indent);
3655 }
3656 switch(bp_.math_numbering_side) {
3657 case BufferParams::LEFT:
3658 mathsModule->MathNumberingPosCO->setCurrentIndex(0);
3659 break;
3660 case BufferParams::DEFAULT:
3661 mathsModule->MathNumberingPosCO->setCurrentIndex(1);
3662 break;
3663 case BufferParams::RIGHT:
3664 mathsModule->MathNumberingPosCO->setCurrentIndex(2);
3665 }
3666
3667 map<string, string> const & packages = BufferParams::auto_packages();
3668 for (map<string, string>::const_iterator it = packages.begin();
3669 it != packages.end(); ++it) {
3670 QTableWidgetItem * item = mathsModule->packagesTW->findItems(toqstr(it->first), Qt::MatchExactly)[0];
3671 if (!item)
3672 continue;
3673 int row = mathsModule->packagesTW->row(item);
3674 switch (bp_.use_package(it->first)) {
3675 case BufferParams::package_off: {
3676 QRadioButton * rb =
3677 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 3)->layout()->itemAt(0)->widget();
3678 rb->setChecked(true);
3679 break;
3680 }
3681 case BufferParams::package_on: {
3682 QRadioButton * rb =
3683 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 2)->layout()->itemAt(0)->widget();
3684 rb->setChecked(true);
3685 break;
3686 }
3687 case BufferParams::package_auto: {
3688 QRadioButton * rb =
3689 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, 1)->layout()->itemAt(0)->widget();
3690 rb->setChecked(true);
3691 break;
3692 }
3693 }
3694 }
3695
3696 switch (bp_.spacing().getSpace()) {
3697 case Spacing::Other: nitem = 3; break;
3698 case Spacing::Double: nitem = 2; break;
3699 case Spacing::Onehalf: nitem = 1; break;
3700 case Spacing::Default: case Spacing::Single: nitem = 0; break;
3701 }
3702
3703 // text layout
3704 string const & layoutID = bp_.baseClassID();
3705 setLayoutComboByIDString(layoutID);
3706
3707 updatePagestyle(documentClass().opt_pagestyle(),
3708 bp_.pagestyle);
3709
3710 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
3711 if (bp_.spacing().getSpace() == Spacing::Other) {
3712 doubleToWidget(textLayoutModule->lspacingLE,
3713 bp_.spacing().getValueAsString());
3714 }
3715 setLSpacing(nitem);
3716
3717 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation) {
3718 textLayoutModule->indentRB->setChecked(true);
3719 string parindent = bp_.getParIndent().asString();
3720 int indent = 0;
3721 if (!parindent.empty()) {
3722 lengthToWidgets(textLayoutModule->indentLE,
3723 textLayoutModule->indentLengthCO,
3724 parindent, default_unit);
3725 indent = 1;
3726 }
3727 textLayoutModule->indentCO->setCurrentIndex(indent);
3728 setIndent(indent);
3729 } else {
3730 textLayoutModule->skipRB->setChecked(true);
3731 int skip = 0;
3732 switch (bp_.getDefSkip().kind()) {
3733 case VSpace::SMALLSKIP:
3734 skip = 0;
3735 break;
3736 case VSpace::MEDSKIP:
3737 skip = 1;
3738 break;
3739 case VSpace::BIGSKIP:
3740 skip = 2;
3741 break;
3742 case VSpace::LENGTH:
3743 {
3744 skip = 3;
3745 string const length = bp_.getDefSkip().asLyXCommand();
3746 lengthToWidgets(textLayoutModule->skipLE,
3747 textLayoutModule->skipLengthCO,
3748 length, default_unit);
3749 break;
3750 }
3751 default:
3752 skip = 0;
3753 break;
3754 }
3755 textLayoutModule->skipCO->setCurrentIndex(skip);
3756 setSkip(skip);
3757 }
3758
3759 textLayoutModule->twoColumnCB->setChecked(
3760 bp_.columns == 2);
3761 textLayoutModule->justCB->setChecked(bp_.justification);
3762
3763 if (!bp_.options.empty()) {
3764 latexModule->optionsLE->setText(
3765 toqstr(bp_.options));
3766 } else {
3767 latexModule->optionsLE->setText(QString());
3768 }
3769
3770 // latex
3771 latexModule->defaultOptionsCB->setChecked(
3772 bp_.use_default_options);
3773 updateSelectedModules();
3774 selectionManager->updateProvidedModules(
3775 bp_.baseClass()->providedModules());
3776 selectionManager->updateExcludedModules(
3777 bp_.baseClass()->excludedModules());
3778
3779 if (!documentClass().options().empty()) {
3780 latexModule->defaultOptionsLE->setText(
3781 toqstr(documentClass().options()));
3782 } else {
3783 latexModule->defaultOptionsLE->setText(
3784 toqstr(_("[No options predefined]")));
3785 }
3786
3787 latexModule->defaultOptionsLE->setEnabled(
3788 bp_.use_default_options
3789 && !documentClass().options().empty());
3790
3791 latexModule->defaultOptionsCB->setEnabled(
3792 !documentClass().options().empty());
3793
3794 if (!bp_.master.empty()) {
3795 latexModule->childDocGB->setChecked(true);
3796 latexModule->childDocLE->setText(
3797 toqstr(bp_.master));
3798 } else {
3799 latexModule->childDocLE->setText(QString());
3800 latexModule->childDocGB->setChecked(false);
3801 }
3802
3803 // Master/Child
3804 if (!bufferview() || !buffer().hasChildren()) {
3805 masterChildModule->childrenTW->clear();
3806 includeonlys_.clear();
3807 docPS->showPanel("Child Documents", false);
3808 if (docPS->isCurrentPanel("Child Documents"))
3809 docPS->setCurrentPanel("Document Class");
3810 } else {
3811 docPS->showPanel("Child Documents", true);
3812 masterChildModule->setEnabled(true);
3813 includeonlys_ = bp_.getIncludedChildren();
3814 updateIncludeonlys();
3815 }
3816 masterChildModule->maintainAuxCB->setChecked(
3817 bp_.maintain_unincluded_children);
3818
3819 // Float Settings
3820 floatModule->set(bp_.float_placement);
3821
3822 // ListingsSettings
3823 // break listings_params to multiple lines
3824 string lstparams =
3825 InsetListingsParams(bp_.listings_params).separatedParams();
3826 listingsModule->listingsED->setPlainText(toqstr(lstparams));
3827 int nn = findToken(lst_packages, bp_.use_minted ? "Minted" : "Listings");
3828 if (nn >= 0)
3829 listingsModule->packageCO->setCurrentIndex(nn);
3830
3831
3832 // Fonts
3833 // some languages only work with polyglossia/XeTeX
3834 Language const * lang = lyx::languages.getLanguage(
3835 fromqstr(langModule->languageCO->itemData(
3836 langModule->languageCO->currentIndex()).toString()));
3837 bool const need_fontspec =
3838 lang->babel().empty() && !lang->polyglossia().empty();
3839 bool const os_fonts_available =
3840 bp_.baseClass()->outputType() == lyx::LATEX
3841 && LaTeXFeatures::isAvailable("fontspec");
3842 fontModule->osFontsCB->setEnabled(os_fonts_available && !need_fontspec);
3843 fontModule->osFontsCB->setChecked(
3844 (os_fonts_available && bp_.useNonTeXFonts) || need_fontspec);
3845 updateFontsize(documentClass().opt_fontsize(),
3846 bp_.fontsize);
3847
3848 QString font = toqstr(bp_.fontsRoman());
3849 int rpos = fontModule->fontsRomanCO->findData(font);
3850 if (rpos == -1) {
3851 rpos = fontModule->fontsRomanCO->count();
3852 fontModule->fontsRomanCO->addItem(font + qt_(" (not installed)"), font);
3853 }
3854 fontModule->fontsRomanCO->setCurrentIndex(rpos);
3855 fontModule->font_roman = toqstr(bp_.fonts_roman[!bp_.useNonTeXFonts]);
3856
3857 font = toqstr(bp_.fontsSans());
3858 int spos = fontModule->fontsSansCO->findData(font);
3859 if (spos == -1) {
3860 spos = fontModule->fontsSansCO->count();
3861 fontModule->fontsSansCO->addItem(font + qt_(" (not installed)"), font);
3862 }
3863 fontModule->fontsSansCO->setCurrentIndex(spos);
3864 fontModule->font_sans = toqstr(bp_.fonts_sans[!bp_.useNonTeXFonts]);
3865
3866 font = toqstr(bp_.fontsTypewriter());
3867 int tpos = fontModule->fontsTypewriterCO->findData(font);
3868 if (tpos == -1) {
3869 tpos = fontModule->fontsTypewriterCO->count();
3870 fontModule->fontsTypewriterCO->addItem(font + qt_(" (not installed)"), font);
3871 }
3872 fontModule->fontsTypewriterCO->setCurrentIndex(tpos);
3873 fontModule->font_typewriter = toqstr(bp_.fonts_typewriter[!bp_.useNonTeXFonts]);
3874
3875 font = toqstr(bp_.fontsMath());
3876 int mpos = fontModule->fontsMathCO->findData(font);
3877 if (mpos == -1) {
3878 mpos = fontModule->fontsMathCO->count();
3879 fontModule->fontsMathCO->addItem(font + qt_(" (not installed)"), font);
3880 }
3881 fontModule->fontsMathCO->setCurrentIndex(mpos);
3882 fontModule->font_math = toqstr(bp_.fonts_math[!bp_.useNonTeXFonts]);
3883
3884 if (bp_.useNonTeXFonts && os_fonts_available) {
3885 fontModule->fontencLA->setEnabled(false);
3886 fontModule->fontencCO->setEnabled(false);
3887 fontModule->fontencLE->setEnabled(false);
3888 } else {
3889 fontModule->fontencLA->setEnabled(true);
3890 fontModule->fontencCO->setEnabled(true);
3891 fontModule->fontencLE->setEnabled(true);
3892 romanChanged(rpos);
3893 sansChanged(spos);
3894 ttChanged(tpos);
3895 }
3896
3897 if (!bp_.fonts_cjk.empty())
3898 fontModule->cjkFontLE->setText(
3899 toqstr(bp_.fonts_cjk));
3900 else
3901 fontModule->cjkFontLE->setText(QString());
3902
3903 fontModule->microtypeCB->setChecked(bp_.use_microtype);
3904 fontModule->dashesCB->setChecked(!bp_.use_dash_ligatures);
3905
3906 fontModule->fontScCB->setChecked(bp_.fonts_expert_sc);
3907 fontModule->fontOsfCB->setChecked(bp_.fonts_old_figures);
3908 fontModule->scaleSansSB->setValue(bp_.fontsSansScale());
3909 fontModule->font_sf_scale = bp_.fonts_sans_scale[!bp_.useNonTeXFonts];
3910 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale());
3911 fontModule->font_tt_scale = bp_.fonts_typewriter_scale[!bp_.useNonTeXFonts];
3912
3913 nn = findToken(GuiDocument::fontfamilies, bp_.fonts_default_family);
3914 if (nn >= 0)
3915 fontModule->fontsDefaultCO->setCurrentIndex(nn);
3916
3917 if (bp_.fontenc == "global" || bp_.fontenc == "default") {
3918 fontModule->fontencCO->setCurrentIndex(
3919 fontModule->fontencCO->findData(toqstr(bp_.fontenc)));
3920 fontModule->fontencLE->setEnabled(false);
3921 } else {
3922 fontModule->fontencCO->setCurrentIndex(1);
3923 fontModule->fontencLE->setText(toqstr(bp_.fontenc));
3924 }
3925
3926 // Formats
3927 // This must be set _after_ fonts since updateDefaultFormat()
3928 // checks osFontsCB settings.
3929 // update combobox with formats
3930 updateDefaultFormat();
3931 int index = outputModule->defaultFormatCO->findData(toqstr(
3932 bp_.default_output_format));
3933 // set to default if format is not found
3934 if (index == -1)
3935 index = 0;
3936 outputModule->defaultFormatCO->setCurrentIndex(index);
3937
3938 outputModule->shellescapeCB->setChecked(bp_.shell_escape);
3939 outputModule->outputsyncCB->setChecked(bp_.output_sync);
3940 outputModule->synccustomCB->setEditText(toqstr(bp_.output_sync_macro));
3941
3942 outputModule->mathimgSB->setValue(bp_.html_math_img_scale);
3943 outputModule->mathoutCB->setCurrentIndex(bp_.html_math_output);
3944 outputModule->strictCB->setChecked(bp_.html_be_strict);
3945 outputModule->cssCB->setChecked(bp_.html_css_as_file);
3946
3947 outputModule->saveTransientPropertiesCB
3948 ->setChecked(bp_.save_transient_properties);
3949
3950 // paper
3951 bool const extern_geometry =
3952 documentClass().provides("geometry");
3953 int const psize = bp_.papersize;
3954 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
3955 setCustomPapersize(!extern_geometry && psize == 1);
3956 pageLayoutModule->papersizeCO->setEnabled(!extern_geometry);
3957
3958 bool const landscape =
3959 bp_.orientation == ORIENTATION_LANDSCAPE;
3960 pageLayoutModule->landscapeRB->setChecked(landscape);
3961 pageLayoutModule->portraitRB->setChecked(!landscape);
3962 pageLayoutModule->landscapeRB->setEnabled(!extern_geometry);
3963 pageLayoutModule->portraitRB->setEnabled(!extern_geometry);
3964
3965 pageLayoutModule->facingPagesCB->setChecked(
3966 bp_.sides == TwoSides);
3967
3968 lengthToWidgets(pageLayoutModule->paperwidthLE,
3969 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, default_unit);
3970 lengthToWidgets(pageLayoutModule->paperheightLE,
3971 pageLayoutModule->paperheightUnitCO, bp_.paperheight, default_unit);
3972
3973 // margins
3974 Ui::MarginsUi * m = marginsModule;
3975
3976 setMargins();
3977
3978 lengthToWidgets(m->topLE, m->topUnit,
3979 bp_.topmargin, default_unit);
3980
3981 lengthToWidgets(m->bottomLE, m->bottomUnit,
3982 bp_.bottommargin, default_unit);
3983
3984 lengthToWidgets(m->innerLE, m->innerUnit,
3985 bp_.leftmargin, default_unit);
3986
3987 lengthToWidgets(m->outerLE, m->outerUnit,
3988 bp_.rightmargin, default_unit);
3989
3990 lengthToWidgets(m->headheightLE, m->headheightUnit,
3991 bp_.headheight, default_unit);
3992
3993 lengthToWidgets(m->headsepLE, m->headsepUnit,
3994 bp_.headsep, default_unit);
3995
3996 lengthToWidgets(m->footskipLE, m->footskipUnit,
3997 bp_.footskip, default_unit);
3998
3999 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
4000 bp_.columnsep, default_unit);
4001
4002 // branches
4003 updateUnknownBranches();
4004 branchesModule->update(bp_);
4005
4006 // PDF support
4007 PDFOptions const & pdf = bp_.pdfoptions();
4008 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
4009 if (bp_.documentClass().provides("hyperref"))
4010 pdfSupportModule->use_hyperrefGB->setTitle(qt_("C&ustomize Hyperref Options"));
4011 else
4012 pdfSupportModule->use_hyperrefGB->setTitle(qt_("&Use Hyperref Support"));
4013 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
4014 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
4015 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
4016 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
4017
4018 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
4019 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
4020 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
4021
4022 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
4023
4024 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
4025 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
4026 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
4027 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
4028
4029 nn = findToken(backref_opts, pdf.backref);
4030 if (nn >= 0)
4031 pdfSupportModule->backrefCO->setCurrentIndex(nn);
4032
4033 pdfSupportModule->fullscreenCB->setChecked
4034 (pdf.pagemode == pdf.pagemode_fullscreen);
4035
4036 pdfSupportModule->optionsLE->setText(
4037 toqstr(pdf.quoted_options));
4038
4039 // Make sure that the bc is in the INITIAL state
4040 if (bc().policy().buttonStatus(ButtonPolicy::RESTORE))
4041 bc().restore();
4042
4043 // clear changed branches cache
4044 changedBranches_.clear();
4045
4046 // reset trackers
4047 nonModuleChanged_ = false;
4048 shellescapeChanged_ = false;
4049 }
4050
4051
saveDocDefault()4052 void GuiDocument::saveDocDefault()
4053 {
4054 // we have to apply the params first
4055 applyView();
4056 saveAsDefault();
4057 }
4058
4059
updateAvailableModules()4060 void GuiDocument::updateAvailableModules()
4061 {
4062 modules_av_model_.clear();
4063 list<modInfoStruct> modInfoList = getModuleInfo();
4064 // Sort names according to the locale
4065 modInfoList.sort([](modInfoStruct const & a, modInfoStruct const & b) {
4066 return 0 < b.name.localeAwareCompare(a.name);
4067 });
4068 int i = 0;
4069 for (modInfoStruct const & m : modInfoList) {
4070 modules_av_model_.insertRow(i, m.name, m.id, m.description);
4071 ++i;
4072 }
4073 }
4074
4075
updateSelectedModules()4076 void GuiDocument::updateSelectedModules()
4077 {
4078 modules_sel_model_.clear();
4079 list<modInfoStruct> const selModList = getSelectedModules();
4080 int i = 0;
4081 for (modInfoStruct const & m : selModList) {
4082 modules_sel_model_.insertRow(i, m.name, m.id, m.description);
4083 ++i;
4084 }
4085 }
4086
4087
updateIncludeonlys()4088 void GuiDocument::updateIncludeonlys()
4089 {
4090 masterChildModule->childrenTW->clear();
4091 QString const no = qt_("No");
4092 QString const yes = qt_("Yes");
4093
4094 if (includeonlys_.empty()) {
4095 masterChildModule->includeallRB->setChecked(true);
4096 masterChildModule->childrenTW->setEnabled(false);
4097 masterChildModule->maintainAuxCB->setEnabled(false);
4098 } else {
4099 masterChildModule->includeonlyRB->setChecked(true);
4100 masterChildModule->childrenTW->setEnabled(true);
4101 masterChildModule->maintainAuxCB->setEnabled(true);
4102 }
4103 ListOfBuffers children = buffer().getChildren();
4104 ListOfBuffers::const_iterator it = children.begin();
4105 ListOfBuffers::const_iterator end = children.end();
4106 bool has_unincluded = false;
4107 bool all_unincluded = true;
4108 for (; it != end; ++it) {
4109 QTreeWidgetItem * item = new QTreeWidgetItem(masterChildModule->childrenTW);
4110 // FIXME Unicode
4111 string const name =
4112 to_utf8(makeRelPath(from_utf8((*it)->fileName().absFileName()),
4113 from_utf8(buffer().filePath())));
4114 item->setText(0, toqstr(name));
4115 item->setText(1, isChildIncluded(name) ? yes : no);
4116 if (!isChildIncluded(name))
4117 has_unincluded = true;
4118 else
4119 all_unincluded = false;
4120 }
4121 // Both if all childs are included and if none is included
4122 // is equal to "include all" (i.e., omit \includeonly).
4123 // Thus, reset the GUI.
4124 if (!has_unincluded || all_unincluded) {
4125 masterChildModule->includeallRB->setChecked(true);
4126 masterChildModule->childrenTW->setEnabled(false);
4127 includeonlys_.clear();
4128 }
4129 // If all are included, we need to update again.
4130 if (!has_unincluded)
4131 updateIncludeonlys();
4132 }
4133
4134
isBiblatex() const4135 bool GuiDocument::isBiblatex() const
4136 {
4137 QString const engine =
4138 biblioModule->citeEngineCO->itemData(
4139 biblioModule->citeEngineCO->currentIndex()).toString();
4140
4141 // this can happen if the cite engine is unknown, which can happen
4142 // if one is using a file that came from someone else, etc. in that
4143 // case, we crash if we proceed.
4144 if (engine.isEmpty())
4145 return false;
4146
4147 return theCiteEnginesList[fromqstr(engine)]->getCiteFramework() == "biblatex";
4148 }
4149
4150
updateDefaultBiblio(string const & style,string const & which)4151 void GuiDocument::updateDefaultBiblio(string const & style,
4152 string const & which)
4153 {
4154 QString const bibstyle = toqstr(style);
4155 biblioModule->defaultBiblioCO->clear();
4156
4157 int item_nr = -1;
4158
4159 if (isBiblatex()) {
4160 if (which != "cbx") {
4161 // First the bbx styles
4162 biblioModule->biblatexBbxCO->clear();
4163 QStringList str = texFileList("bbxFiles.lst");
4164 // test whether we have a valid list, otherwise run rescan
4165 if (str.isEmpty()) {
4166 rescanTexStyles("bbx");
4167 str = texFileList("bbxFiles.lst");
4168 }
4169 for (int i = 0; i != str.size(); ++i)
4170 str[i] = onlyFileName(str[i]);
4171 // sort on filename only (no path)
4172 str.sort();
4173
4174 for (int i = 0; i != str.count(); ++i) {
4175 QString item = changeExtension(str[i], "");
4176 if (item == bibstyle)
4177 item_nr = i;
4178 biblioModule->biblatexBbxCO->addItem(item);
4179 }
4180
4181 if (item_nr == -1 && !bibstyle.isEmpty()) {
4182 biblioModule->biblatexBbxCO->addItem(bibstyle);
4183 item_nr = biblioModule->biblatexBbxCO->count() - 1;
4184 }
4185
4186 if (item_nr != -1)
4187 biblioModule->biblatexBbxCO->setCurrentIndex(item_nr);
4188 else
4189 biblioModule->biblatexBbxCO->clearEditText();
4190 }
4191
4192 if (which != "bbx") {
4193 // now the cbx styles
4194 biblioModule->biblatexCbxCO->clear();
4195 QStringList str = texFileList("cbxFiles.lst");
4196 // test whether we have a valid list, otherwise run rescan
4197 if (str.isEmpty()) {
4198 rescanTexStyles("cbx");
4199 str = texFileList("cbxFiles.lst");
4200 }
4201 for (int i = 0; i != str.size(); ++i)
4202 str[i] = onlyFileName(str[i]);
4203 // sort on filename only (no path)
4204 str.sort();
4205
4206 for (int i = 0; i != str.count(); ++i) {
4207 QString item = changeExtension(str[i], "");
4208 if (item == bibstyle)
4209 item_nr = i;
4210 biblioModule->biblatexCbxCO->addItem(item);
4211 }
4212
4213 if (item_nr == -1 && !bibstyle.isEmpty()) {
4214 biblioModule->biblatexCbxCO->addItem(bibstyle);
4215 item_nr = biblioModule->biblatexCbxCO->count() - 1;
4216 }
4217
4218 if (item_nr != -1)
4219 biblioModule->biblatexCbxCO->setCurrentIndex(item_nr);
4220 else
4221 biblioModule->biblatexCbxCO->clearEditText();
4222 }
4223 } else {// BibTeX
4224 biblioModule->biblatexBbxCO->clear();
4225 biblioModule->biblatexCbxCO->clear();
4226 QStringList str = texFileList("bstFiles.lst");
4227 // test whether we have a valid list, otherwise run rescan
4228 if (str.isEmpty()) {
4229 rescanTexStyles("bst");
4230 str = texFileList("bstFiles.lst");
4231 }
4232 for (int i = 0; i != str.size(); ++i)
4233 str[i] = onlyFileName(str[i]);
4234 // sort on filename only (no path)
4235 str.sort();
4236
4237 for (int i = 0; i != str.count(); ++i) {
4238 QString item = changeExtension(str[i], "");
4239 if (item == bibstyle)
4240 item_nr = i;
4241 biblioModule->defaultBiblioCO->addItem(item);
4242 }
4243
4244 if (item_nr == -1 && !bibstyle.isEmpty()) {
4245 biblioModule->defaultBiblioCO->addItem(bibstyle);
4246 item_nr = biblioModule->defaultBiblioCO->count() - 1;
4247 }
4248
4249 if (item_nr != -1)
4250 biblioModule->defaultBiblioCO->setCurrentIndex(item_nr);
4251 else
4252 biblioModule->defaultBiblioCO->clearEditText();
4253 }
4254
4255 updateResetDefaultBiblio();
4256 }
4257
4258
updateResetDefaultBiblio()4259 void GuiDocument::updateResetDefaultBiblio()
4260 {
4261 QString const engine =
4262 biblioModule->citeEngineCO->itemData(
4263 biblioModule->citeEngineCO->currentIndex()).toString();
4264 CiteEngineType const cet =
4265 CiteEngineType(biblioModule->citeStyleCO->itemData(
4266 biblioModule->citeStyleCO->currentIndex()).toInt());
4267
4268 string const defbib = theCiteEnginesList[fromqstr(engine)]->getDefaultBiblio(cet);
4269 if (isBiblatex()) {
4270 QString const bbx = biblioModule->biblatexBbxCO->currentText();
4271 QString const cbx = biblioModule->biblatexCbxCO->currentText();
4272 biblioModule->resetCbxPB->setEnabled(defbib != fromqstr(cbx));
4273 biblioModule->resetBbxPB->setEnabled(defbib != fromqstr(bbx));
4274 biblioModule->matchBbxPB->setEnabled(bbx != cbx && !cbx.isEmpty()
4275 && biblioModule->biblatexBbxCO->findText(cbx) != -1);
4276 } else
4277 biblioModule->resetDefaultBiblioPB->setEnabled(
4278 defbib != fromqstr(biblioModule->defaultBiblioCO->currentText()));
4279 }
4280
4281
matchBiblatexStyles()4282 void GuiDocument::matchBiblatexStyles()
4283 {
4284 updateDefaultBiblio(fromqstr(biblioModule->biblatexCbxCO->currentText()), "bbx");
4285 biblioChanged();
4286 }
4287
4288
updateContents()4289 void GuiDocument::updateContents()
4290 {
4291 // Nothing to do here as the document settings is not cursor dependant.
4292 return;
4293 }
4294
4295
useClassDefaults()4296 void GuiDocument::useClassDefaults()
4297 {
4298 if (applyPB->isEnabled()) {
4299 int const ret = Alert::prompt(_("Unapplied changes"),
4300 _("Some changes in the dialog were not yet applied.\n"
4301 "If you do not apply now, they will be lost after this action."),
4302 1, 1, _("&Apply"), _("&Dismiss"));
4303 if (ret == 0)
4304 applyView();
4305 }
4306
4307 int idx = latexModule->classCO->currentIndex();
4308 string const classname = fromqstr(latexModule->classCO->getData(idx));
4309 if (!bp_.setBaseClass(classname, buffer().layoutPos())) {
4310 Alert::error(_("Error"), _("Unable to set document class."));
4311 return;
4312 }
4313 bp_.useClassDefaults();
4314 paramsToDialog();
4315 changed();
4316 }
4317
4318
setLayoutComboByIDString(string const & idString)4319 void GuiDocument::setLayoutComboByIDString(string const & idString)
4320 {
4321 if (!latexModule->classCO->set(toqstr(idString)))
4322 Alert::warning(_("Can't set layout!"),
4323 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
4324 }
4325
4326
isValid()4327 bool GuiDocument::isValid()
4328 {
4329 return
4330 validateListingsParameters().isEmpty() &&
4331 localLayout->isValid() &&
4332 !localLayout->editing() &&
4333 !preambleModule->editing() &&
4334 (
4335 // if we're asking for skips between paragraphs
4336 !textLayoutModule->skipRB->isChecked() ||
4337 // then either we haven't chosen custom
4338 textLayoutModule->skipCO->currentIndex() != 3 ||
4339 // or else a length has been given
4340 !textLayoutModule->skipLE->text().isEmpty()
4341 ) &&
4342 (
4343 // if we're asking for indentation
4344 !textLayoutModule->indentRB->isChecked() ||
4345 // then either we haven't chosen custom
4346 textLayoutModule->indentCO->currentIndex() != 1 ||
4347 // or else a length has been given
4348 !textLayoutModule->indentLE->text().isEmpty()
4349 ) &&
4350 (
4351 // if we're asking for math indentation
4352 !mathsModule->MathIndentCB->isChecked() ||
4353 // then either we haven't chosen custom
4354 mathsModule->MathIndentCO->currentIndex() != 1 ||
4355 // or else a length has been given
4356 !mathsModule->MathIndentLE->text().isEmpty()
4357 );
4358 }
4359
4360
4361 char const * const GuiDocument::fontfamilies[5] = {
4362 "default", "rmdefault", "sfdefault", "ttdefault", ""
4363 };
4364
4365
4366 char const * GuiDocument::fontfamilies_gui[5] = {
4367 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
4368 };
4369
4370
initialiseParams(string const &)4371 bool GuiDocument::initialiseParams(string const &)
4372 {
4373 BufferView const * view = bufferview();
4374 if (!view) {
4375 bp_ = BufferParams();
4376 paramsToDialog();
4377 return true;
4378 }
4379 bp_ = view->buffer().params();
4380 loadModuleInfo();
4381 updateAvailableModules();
4382 //FIXME It'd be nice to make sure here that the selected
4383 //modules are consistent: That required modules are actually
4384 //selected, and that we don't have conflicts. If so, we could
4385 //at least pop up a warning.
4386 paramsToDialog();
4387 return true;
4388 }
4389
4390
clearParams()4391 void GuiDocument::clearParams()
4392 {
4393 bp_ = BufferParams();
4394 }
4395
4396
id() const4397 BufferId GuiDocument::id() const
4398 {
4399 BufferView const * const view = bufferview();
4400 return view? &view->buffer() : 0;
4401 }
4402
4403
getModuleInfo()4404 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
4405 {
4406 return moduleNames_;
4407 }
4408
4409
4410 list<GuiDocument::modInfoStruct> const
makeModuleInfo(LayoutModuleList const & mods)4411 GuiDocument::makeModuleInfo(LayoutModuleList const & mods)
4412 {
4413 list<modInfoStruct> mInfo;
4414 for (string const & name : mods) {
4415 modInfoStruct m;
4416 LyXModule const * const mod = theModuleList[name];
4417 if (mod)
4418 m = modInfo(*mod);
4419 else {
4420 m.id = name;
4421 m.name = toqstr(name + " (") + qt_("Not Found") + toqstr(")");
4422 }
4423 mInfo.push_back(m);
4424 }
4425 return mInfo;
4426 }
4427
4428
getSelectedModules()4429 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
4430 {
4431 return makeModuleInfo(params().getModules());
4432 }
4433
4434
getProvidedModules()4435 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
4436 {
4437 return makeModuleInfo(params().baseClass()->providedModules());
4438 }
4439
4440
documentClass() const4441 DocumentClass const & GuiDocument::documentClass() const
4442 {
4443 return bp_.documentClass();
4444 }
4445
4446
dispatch_bufferparams(Dialog const & dialog,BufferParams const & bp,FuncCode lfun,Buffer const * buf)4447 static void dispatch_bufferparams(Dialog const & dialog,
4448 BufferParams const & bp, FuncCode lfun, Buffer const * buf)
4449 {
4450 ostringstream ss;
4451 ss << "\\begin_header\n";
4452 bp.writeFile(ss, buf);
4453 ss << "\\end_header\n";
4454 dialog.dispatch(FuncRequest(lfun, ss.str()));
4455 }
4456
4457
dispatchParams()4458 void GuiDocument::dispatchParams()
4459 {
4460 // We need a non-const buffer object.
4461 Buffer & buf = const_cast<BufferView *>(bufferview())->buffer();
4462 // There may be several undo records; group them (bug #8998)
4463 // This handles undo groups automagically
4464 UndoGroupHelper ugh(&buf);
4465
4466 // This must come first so that a language change is correctly noticed
4467 setLanguage();
4468
4469 // We need to load the master before we formally update the params,
4470 // since otherwise we run updateBuffer, etc, before the child's master
4471 // has been set.
4472 if (!params().master.empty()) {
4473 FileName const master_file = support::makeAbsPath(params().master,
4474 support::onlyPath(buffer().absFileName()));
4475 if (isLyXFileName(master_file.absFileName())) {
4476 Buffer * master = checkAndLoadLyXFile(master_file);
4477 if (master) {
4478 if (master->isChild(const_cast<Buffer *>(&buffer())))
4479 const_cast<Buffer &>(buffer()).setParent(master);
4480 else
4481 Alert::warning(_("Assigned master does not include this file"),
4482 bformat(_("You must include this file in the document\n"
4483 "'%1$s' in order to use the master document\n"
4484 "feature."), from_utf8(params().master)));
4485 } else
4486 Alert::warning(_("Could not load master"),
4487 bformat(_("The master document '%1$s'\n"
4488 "could not be loaded."),
4489 from_utf8(params().master)));
4490 }
4491 }
4492
4493 // Apply the BufferParams. Note that this will set the base class
4494 // and then update the buffer's layout.
4495 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY, &buffer());
4496
4497 // Generate the colours requested by each new branch.
4498 BranchList & branchlist = params().branchlist();
4499 if (!branchlist.empty()) {
4500 BranchList::const_iterator it = branchlist.begin();
4501 BranchList::const_iterator const end = branchlist.end();
4502 for (; it != end; ++it) {
4503 docstring const & current_branch = it->branch();
4504 Branch const * branch = branchlist.find(current_branch);
4505 string const x11hexname = X11hexname(branch->color());
4506 // display the new color
4507 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
4508 dispatch(FuncRequest(LFUN_SET_COLOR, str));
4509 }
4510 }
4511 // rename branches in the document
4512 executeBranchRenaming();
4513 // and clear changed branches cache
4514 changedBranches_.clear();
4515
4516 // Generate the colours requested by indices.
4517 IndicesList & indiceslist = params().indiceslist();
4518 if (!indiceslist.empty()) {
4519 IndicesList::const_iterator it = indiceslist.begin();
4520 IndicesList::const_iterator const end = indiceslist.end();
4521 for (; it != end; ++it) {
4522 docstring const & current_index = it->shortcut();
4523 Index const * index = indiceslist.findShortcut(current_index);
4524 string const x11hexname = X11hexname(index->color());
4525 // display the new color
4526 docstring const str = current_index + ' ' + from_ascii(x11hexname);
4527 dispatch(FuncRequest(LFUN_SET_COLOR, str));
4528 }
4529 }
4530 // FIXME LFUN
4531 // If we used an LFUN, we would not need these two lines:
4532 BufferView * bv = const_cast<BufferView *>(bufferview());
4533 bv->processUpdateFlags(Update::Force | Update::FitCursor);
4534 }
4535
4536
setLanguage() const4537 void GuiDocument::setLanguage() const
4538 {
4539 Language const * const newL = bp_.language;
4540 if (buffer().params().language == newL)
4541 return;
4542
4543 string const & lang_name = newL->lang();
4544 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
4545 }
4546
4547
saveAsDefault() const4548 void GuiDocument::saveAsDefault() const
4549 {
4550 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT, &buffer());
4551 }
4552
4553
providesOSF(QString const & font) const4554 bool GuiDocument::providesOSF(QString const & font) const
4555 {
4556 if (fontModule->osFontsCB->isChecked())
4557 // FIXME: we should check if the fonts really
4558 // have OSF support. But how?
4559 return true;
4560 return theLaTeXFonts().getLaTeXFont(
4561 qstring_to_ucs4(font)).providesOSF(ot1(),
4562 completeFontset(),
4563 noMathFont());
4564 }
4565
4566
providesSC(QString const & font) const4567 bool GuiDocument::providesSC(QString const & font) const
4568 {
4569 if (fontModule->osFontsCB->isChecked())
4570 return false;
4571 return theLaTeXFonts().getLaTeXFont(
4572 qstring_to_ucs4(font)).providesSC(ot1(),
4573 completeFontset(),
4574 noMathFont());
4575 }
4576
4577
providesScale(QString const & font) const4578 bool GuiDocument::providesScale(QString const & font) const
4579 {
4580 if (fontModule->osFontsCB->isChecked())
4581 return true;
4582 return theLaTeXFonts().getLaTeXFont(
4583 qstring_to_ucs4(font)).providesScale(ot1(),
4584 completeFontset(),
4585 noMathFont());
4586 }
4587
4588
providesNoMath(QString const & font) const4589 bool GuiDocument::providesNoMath(QString const & font) const
4590 {
4591 if (fontModule->osFontsCB->isChecked())
4592 return false;
4593 return theLaTeXFonts().getLaTeXFont(
4594 qstring_to_ucs4(font)).providesNoMath(ot1(),
4595 completeFontset());
4596 }
4597
4598
hasMonolithicExpertSet(QString const & font) const4599 bool GuiDocument::hasMonolithicExpertSet(QString const & font) const
4600 {
4601 if (fontModule->osFontsCB->isChecked())
4602 return false;
4603 return theLaTeXFonts().getLaTeXFont(
4604 qstring_to_ucs4(font)).hasMonolithicExpertSet(ot1(),
4605 completeFontset(),
4606 noMathFont());
4607 }
4608
4609
4610 //static
modInfo(LyXModule const & mod)4611 GuiDocument::modInfoStruct GuiDocument::modInfo(LyXModule const & mod)
4612 {
4613 // FIXME Unicode: docstrings would be better for these parameters but this
4614 // change requires a lot of others
4615 modInfoStruct m;
4616 m.id = mod.getID();
4617 m.name = toqstr(translateIfPossible(from_utf8(mod.getName())));
4618 QString desc = toqstr(translateIfPossible(from_utf8(mod.getDescription())));
4619 // Find the first sentence of the description
4620 QTextBoundaryFinder bf(QTextBoundaryFinder::Sentence, desc);
4621 int pos = bf.toNextBoundary();
4622 if (pos > 0)
4623 desc.truncate(pos);
4624 QString modulename = QString(qt_("(Module name: %1)")).arg(toqstr(m.id));
4625 // Tooltip is the desc followed by the module name
4626 m.description = QString("%1<i>%2</i>")
4627 .arg(desc.isEmpty() ? QString() : QString("<p>%1</p>").arg(desc),
4628 modulename);
4629 return m;
4630 }
4631
4632
loadModuleInfo()4633 void GuiDocument::loadModuleInfo()
4634 {
4635 moduleNames_.clear();
4636 for (LyXModule const & mod : theModuleList)
4637 if (mod.category().substr(0, 8) != "Citation")
4638 moduleNames_.push_back(modInfo(mod));
4639 }
4640
4641
updateUnknownBranches()4642 void GuiDocument::updateUnknownBranches()
4643 {
4644 if (!bufferview())
4645 return;
4646 list<docstring> used_branches;
4647 buffer().getUsedBranches(used_branches);
4648 list<docstring>::const_iterator it = used_branches.begin();
4649 QStringList unknown_branches;
4650 for (; it != used_branches.end() ; ++it) {
4651 if (!buffer().params().branchlist().find(*it))
4652 unknown_branches.append(toqstr(*it));
4653 }
4654 branchesModule->setUnknownBranches(unknown_branches);
4655 }
4656
4657
branchesRename(docstring const & oldname,docstring const & newname)4658 void GuiDocument::branchesRename(docstring const & oldname, docstring const & newname)
4659 {
4660 map<docstring, docstring>::iterator it = changedBranches_.begin();
4661 for (; it != changedBranches_.end() ; ++it) {
4662 if (it->second == oldname) {
4663 // branch has already been renamed
4664 it->second = newname;
4665 return;
4666 }
4667 }
4668 // store new name
4669 changedBranches_[oldname] = newname;
4670 }
4671
4672
executeBranchRenaming() const4673 void GuiDocument::executeBranchRenaming() const
4674 {
4675 map<docstring, docstring>::const_iterator it = changedBranches_.begin();
4676 for (; it != changedBranches_.end() ; ++it) {
4677 docstring const arg = '"' + it->first + '"' + " " + '"' + it->second + '"';
4678 dispatch(FuncRequest(LFUN_BRANCHES_RENAME, arg));
4679 }
4680 }
4681
4682
allPackagesAuto()4683 void GuiDocument::allPackagesAuto()
4684 {
4685 allPackages(1);
4686 }
4687
4688
allPackagesAlways()4689 void GuiDocument::allPackagesAlways()
4690 {
4691 allPackages(2);
4692 }
4693
4694
allPackagesNot()4695 void GuiDocument::allPackagesNot()
4696 {
4697 allPackages(3);
4698 }
4699
4700
allPackages(int col)4701 void GuiDocument::allPackages(int col)
4702 {
4703 for (int row = 0; row < mathsModule->packagesTW->rowCount(); ++row) {
4704 QRadioButton * rb =
4705 (QRadioButton*)mathsModule->packagesTW->cellWidget(row, col)->layout()->itemAt(0)->widget();
4706 rb->setChecked(true);
4707 }
4708 }
4709
4710
createGuiDocument(GuiView & lv)4711 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
4712
4713
4714 } // namespace frontend
4715 } // namespace lyx
4716
4717 #include "moc_GuiDocument.cpp"
4718