2 * \file GuiDocument.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
7 * \author Richard Heck (modules)
9 * Full author contact details are available in file CREDITS.
14 #include "GuiDocument.h"
16 #include "GuiApplication.h"
17 #include "GuiBranches.h"
18 #include "GuiSelectionManager.h"
19 #include "LaTeXHighlighter.h"
20 #include "LengthCombo.h"
21 #include "PanelStack.h"
22 #include "Validator.h"
24 #include "LayoutFile.h"
25 #include "BranchList.h"
26 #include "buffer_funcs.h"
28 #include "BufferParams.h"
29 #include "BufferView.h"
32 #include "FloatPlacement.h"
33 #include "FuncRequest.h"
35 #include "LaTeXFeatures.h"
37 #include "LyXRC.h" // defaultUnit
38 #include "ModuleList.h"
39 #include "OutputParams.h"
40 #include "PDFOptions.h"
41 #include "qt_helpers.h"
44 #include "insets/InsetListingsParams.h"
46 #include "support/debug.h"
47 #include "support/FileName.h"
48 #include "support/filetools.h"
49 #include "support/gettext.h"
50 #include "support/lstrings.h"
52 #include "frontends/alert.h"
54 #include <QAbstractItemModel>
55 #include <QCloseEvent>
57 #include <QTextCursor>
68 using namespace lyx::support;
73 char const * const tex_graphics[] =
75 "default", "dvialw", "dvilaser", "dvipdf", "dvipdfm", "dvipdfmx",
76 "dvips", "dvipsone", "dvitops", "dviwin", "dviwindo", "dvi2ps", "emtex",
77 "ln", "oztex", "pctexhp", "pctexps", "pctexwin", "pctex32", "pdftex",
78 "psprint", "pubps", "tcidvi", "textures", "truetex", "vtex", "xdvi",
83 char const * const tex_graphics_gui[] =
85 N_("Default"), "dvialw", "DviLaser", "dvipdf", "DVIPDFM", "DVIPDFMx",
86 "Dvips", "DVIPSONE", "DVItoPS", "DVIWIN", "DVIWindo", "dvi2ps", "EmTeX",
87 "LN", "OzTeX", "pctexhp", "pctexps", "pctexwin", "PCTeX32", "pdfTeX",
88 "psprint", "pubps", "tcidvi", "Textures", "TrueTeX", "VTeX", "xdvi",
89 "XeTeX", N_("None"), ""
93 char const * const tex_fonts_roman[] =
95 "default", "cmr", "lmodern", "ae", "times", "palatino",
96 "charter", "newcent", "bookman", "utopia", "beraserif",
97 "ccfonts", "chancery", ""
101 char const * tex_fonts_roman_gui[] =
103 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
104 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
105 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
106 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
111 char const * const tex_fonts_sans[] =
113 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
117 char const * tex_fonts_sans_gui[] =
119 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
120 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
124 char const * const tex_fonts_monospaced[] =
126 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
130 char const * tex_fonts_monospaced_gui[] =
132 N_("Default"), N_("Computer Modern Typewriter"),
133 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
134 N_("LuxiMono"), N_("CM Typewriter Light"), ""
138 char const * backref_opts[] =
140 "false", "section", "slide", "page", ""
144 char const * backref_opts_gui[] =
146 N_("Off"), N_("Section"), N_("Slide"), N_("Page"), ""
150 vector<pair<string, QString> > pagestyles;
153 } // anonymous namespace
158 // used when sorting the textclass list.
159 class less_textclass_avail_desc
160 : public binary_function<string, string, int>
163 bool operator()(string const & lhs, string const & rhs) const
165 // Ordering criteria:
166 // 1. Availability of text class
167 // 2. Description (lexicographic)
168 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
169 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
170 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
171 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
172 translateIfPossible(from_utf8(tc1.description()))
173 < translateIfPossible(from_utf8(tc2.description())));
182 vector<string> getRequiredList(string const & modName)
184 LyXModule const * const mod = moduleList[modName];
186 return vector<string>(); //empty such thing
187 return mod->getRequiredModules();
191 vector<string> getExcludedList(string const & modName)
193 LyXModule const * const mod = moduleList[modName];
195 return vector<string>(); //empty such thing
196 return mod->getExcludedModules();
200 docstring getModuleDescription(string const & modName)
202 LyXModule const * const mod = moduleList[modName];
204 return _("Module not found!");
205 return translateIfPossible(from_utf8(mod->getDescription()));
209 vector<string> getPackageList(string const & modName)
211 LyXModule const * const mod = moduleList[modName];
213 return vector<string>(); //empty such thing
214 return mod->getPackageList();
218 bool isModuleAvailable(string const & modName)
220 LyXModule * mod = moduleList[modName];
223 return mod->isAvailable();
226 } // anonymous namespace
229 /////////////////////////////////////////////////////////////////////
231 // ModuleSelectionManager
233 /////////////////////////////////////////////////////////////////////
235 /// SelectionManager for use with modules
236 class ModuleSelectionManager : public GuiSelectionManager
240 ModuleSelectionManager(
241 QListView * availableLV,
242 QListView * selectedLV,
246 QPushButton * downPB,
247 GuiIdListModel * availableModel,
248 GuiIdListModel * selectedModel,
249 GuiDocument const * container)
250 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
251 upPB, downPB, availableModel, selectedModel), container_(container)
254 void updateProvidedModules(std::list<std::string> const & pm)
255 { provided_modules_ = pm; }
257 void updateExcludedModules(std::list<std::string> const & em)
258 { excluded_modules_ = em; }
261 virtual void updateAddPB();
263 virtual void updateUpPB();
265 virtual void updateDownPB();
267 virtual void updateDelPB();
268 /// returns availableModel as a GuiIdListModel
269 GuiIdListModel * getAvailableModel()
271 return dynamic_cast<GuiIdListModel *>(availableModel);
273 /// returns selectedModel as a GuiIdListModel
274 GuiIdListModel * getSelectedModel()
276 return dynamic_cast<GuiIdListModel *>(selectedModel);
278 /// keeps a list of the modules the text class provides
279 std::list<std::string> provided_modules_;
281 std::list<std::string> excluded_modules_;
283 GuiDocument const * container_;
286 void ModuleSelectionManager::updateAddPB()
288 int const arows = availableModel->rowCount();
289 QModelIndexList const avail_sels =
290 availableLV->selectionModel()->selectedIndexes();
292 // disable if there aren't any modules (?), if none of them is chosen
293 // in the dialog, or if the chosen one is already selected for use.
294 if (arows == 0 || avail_sels.isEmpty() || isSelected(avail_sels.first())) {
295 addPB->setEnabled(false);
299 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
300 string const modname = getAvailableModel()->getIDString(idx.row());
303 container_->params().moduleCanBeAdded(modname);
304 addPB->setEnabled(enable);
308 void ModuleSelectionManager::updateDownPB()
310 int const srows = selectedModel->rowCount();
312 downPB->setEnabled(false);
315 QModelIndex const & curidx = selectedLV->selectionModel()->currentIndex();
316 int const curRow = curidx.row();
317 if (curRow < 0 || curRow >= srows - 1) { // invalid or last item
318 downPB->setEnabled(false);
322 // determine whether immediately succeding element requires this one
323 string const curmodname = getSelectedModel()->getIDString(curRow);
324 string const nextmodname = getSelectedModel()->getIDString(curRow + 1);
326 vector<string> reqs = getRequiredList(nextmodname);
328 // if it doesn't require anything....
330 downPB->setEnabled(true);
334 // Enable it if this module isn't required.
335 // FIXME This should perhaps be more flexible and check whether, even
336 // if the next one is required, there is also an earlier one that will do.
338 find(reqs.begin(), reqs.end(), curmodname) == reqs.end());
341 void ModuleSelectionManager::updateUpPB()
343 int const srows = selectedModel->rowCount();
345 upPB->setEnabled(false);
349 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
350 int curRow = curIdx.row();
351 if (curRow <= 0 || curRow > srows - 1) { // first item or invalid
352 upPB->setEnabled(false);
355 string const curmodname = getSelectedModel()->getIDString(curRow);
357 // determine whether immediately preceding element is required by this one
358 vector<string> reqs = getRequiredList(curmodname);
360 // if this one doesn't require anything....
362 upPB->setEnabled(true);
367 // Enable it if the preceding module isn't required.
368 // NOTE This is less flexible than it might be. We could check whether, even
369 // if the previous one is required, there is an earlier one that would do.
370 string const premod = getSelectedModel()->getIDString(curRow - 1);
371 upPB->setEnabled(find(reqs.begin(), reqs.end(), premod) == reqs.end());
374 void ModuleSelectionManager::updateDelPB()
376 int const srows = selectedModel->rowCount();
378 deletePB->setEnabled(false);
382 QModelIndex const & curidx =
383 selectedLV->selectionModel()->currentIndex();
384 int const curRow = curidx.row();
385 if (curRow < 0 || curRow >= srows) { // invalid index?
386 deletePB->setEnabled(false);
390 string const curmodname = getSelectedModel()->getIDString(curRow);
392 // We're looking here for a reason NOT to enable the button. If we
393 // find one, we disable it and return. If we don't, we'll end up at
394 // the end of the function, and then we enable it.
395 for (int i = curRow + 1; i < srows; ++i) {
396 string const thisMod = getSelectedModel()->getIDString(i);
397 vector<string> reqs = getRequiredList(thisMod);
398 //does this one require us?
399 if (find(reqs.begin(), reqs.end(), curmodname) == reqs.end())
403 // OK, so this module requires us
404 // is there an EARLIER module that also satisfies the require?
405 // NOTE We demand that it be earlier to keep the list of modules
406 // consistent with the rule that a module must be proceeded by a
407 // required module. There would be more flexible ways to proceed,
408 // but that would be a lot more complicated, and the logic here is
409 // already complicated. (That's why I've left the debugging code.)
410 // lyxerr << "Testing " << thisMod << std::endl;
411 bool foundone = false;
412 for (int j = 0; j < curRow; ++j) {
413 string const mod = getSelectedModel()->getIDString(j);
414 // lyxerr << "In loop: Testing " << mod << std::endl;
415 // do we satisfy the require?
416 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
417 // lyxerr << mod << " does the trick." << std::endl;
422 // did we find a module to satisfy the require?
424 // lyxerr << "No matching module found." << std::endl;
425 deletePB->setEnabled(false);
429 // lyxerr << "All's well that ends well." << std::endl;
430 deletePB->setEnabled(true);
434 /////////////////////////////////////////////////////////////////////
438 /////////////////////////////////////////////////////////////////////
440 PreambleModule::PreambleModule() : current_id_(0)
442 // This is not a memory leak. The object will be destroyed
444 (void) new LaTeXHighlighter(preambleTE->document());
445 setFocusProxy(preambleTE);
446 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
450 void PreambleModule::update(BufferParams const & params, BufferId id)
452 QString preamble = toqstr(params.preamble);
453 // Nothing to do if the params and preamble are unchanged.
454 if (id == current_id_
455 && preamble == preambleTE->document()->toPlainText())
458 QTextCursor cur = preambleTE->textCursor();
459 // Save the coords before switching to the new one.
460 preamble_coords_[current_id_] =
461 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
463 // Save the params address for further use.
465 preambleTE->document()->setPlainText(preamble);
466 Coords::const_iterator it = preamble_coords_.find(current_id_);
467 if (it == preamble_coords_.end())
468 // First time we open this one.
469 preamble_coords_[current_id_] = make_pair(0, 0);
471 // Restore saved coords.
472 QTextCursor cur = preambleTE->textCursor();
473 cur.setPosition(it->second.first);
474 preambleTE->setTextCursor(cur);
475 preambleTE->verticalScrollBar()->setValue(it->second.second);
480 void PreambleModule::apply(BufferParams & params)
482 params.preamble = fromqstr(preambleTE->document()->toPlainText());
486 void PreambleModule::closeEvent(QCloseEvent * e)
488 // Save the coords before closing.
489 QTextCursor cur = preambleTE->textCursor();
490 preamble_coords_[current_id_] =
491 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
496 /////////////////////////////////////////////////////////////////////
500 /////////////////////////////////////////////////////////////////////
503 GuiDocument::GuiDocument(GuiView & lv)
504 : GuiDialog(lv, "document", qt_("Document Settings"))
508 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
509 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
510 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
511 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
513 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
514 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
516 // Manage the restore, ok, apply, restore and cancel/close buttons
517 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
519 bc().setApply(applyPB);
520 bc().setCancel(closePB);
521 bc().setRestore(restorePB);
523 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
525 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
526 this, SLOT(change_adaptor()));
527 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
528 this, SLOT(setLSpacing(int)));
529 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
530 this, SLOT(change_adaptor()));
531 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
532 this, SLOT(change_adaptor()));
533 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
534 this, SLOT(change_adaptor()));
535 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
536 this, SLOT(change_adaptor()));
537 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
538 this, SLOT(change_adaptor()));
539 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
540 this, SLOT(change_adaptor()));
541 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
542 this, SLOT(setSkip(int)));
543 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
544 this, SLOT(enableSkip(bool)));
545 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
546 this, SLOT(change_adaptor()));
547 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
548 this, SLOT(setColSep()));
549 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
550 this, SLOT(change_adaptor()));
551 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
552 this, SLOT(change_adaptor()));
553 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
554 this, SLOT(setListingsMessage()));
555 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
556 this, SLOT(setListingsMessage()));
557 textLayoutModule->listingsTB->setPlainText(
558 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
559 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
560 textLayoutModule->lspacingLE));
561 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
562 textLayoutModule->skipLE));
564 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
565 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
566 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
567 textLayoutModule->skipCO->addItem(qt_("Length"));
568 // remove the %-items from the unit choice
569 textLayoutModule->skipLengthCO->noPercents();
570 textLayoutModule->lspacingCO->insertItem(
571 Spacing::Single, qt_("Single"));
572 textLayoutModule->lspacingCO->insertItem(
573 Spacing::Onehalf, qt_("OneHalf"));
574 textLayoutModule->lspacingCO->insertItem(
575 Spacing::Double, qt_("Double"));
576 textLayoutModule->lspacingCO->insertItem(
577 Spacing::Other, qt_("Custom"));
579 // initialize the length validator
580 bc().addCheckedLineEdit(textLayoutModule->skipLE);
582 fontModule = new UiWidget<Ui::FontUi>;
584 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
585 this, SLOT(change_adaptor()));
586 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
587 this, SLOT(romanChanged(int)));
588 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
589 this, SLOT(change_adaptor()));
590 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
591 this, SLOT(sansChanged(int)));
592 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
593 this, SLOT(change_adaptor()));
594 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
595 this, SLOT(ttChanged(int)));
596 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
597 this, SLOT(change_adaptor()));
598 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
599 this, SLOT(change_adaptor()));
600 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
601 this, SLOT(change_adaptor()));
602 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
603 this, SLOT(change_adaptor()));
604 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
605 this, SLOT(change_adaptor()));
606 connect(fontModule->fontScCB, SIGNAL(clicked()),
607 this, SLOT(change_adaptor()));
608 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
609 this, SLOT(change_adaptor()));
611 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
612 QString font = qt_(tex_fonts_roman_gui[n]);
613 if (!isFontAvailable(tex_fonts_roman[n]))
614 font += qt_(" (not installed)");
615 fontModule->fontsRomanCO->addItem(font);
617 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
618 QString font = qt_(tex_fonts_sans_gui[n]);
619 if (!isFontAvailable(tex_fonts_sans[n]))
620 font += qt_(" (not installed)");
621 fontModule->fontsSansCO->addItem(font);
623 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
624 QString font = qt_(tex_fonts_monospaced_gui[n]);
625 if (!isFontAvailable(tex_fonts_monospaced[n]))
626 font += qt_(" (not installed)");
627 fontModule->fontsTypewriterCO->addItem(font);
630 fontModule->fontsizeCO->addItem(qt_("Default"));
631 fontModule->fontsizeCO->addItem(qt_("10"));
632 fontModule->fontsizeCO->addItem(qt_("11"));
633 fontModule->fontsizeCO->addItem(qt_("12"));
635 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
636 fontModule->fontsDefaultCO->addItem(
637 qt_(GuiDocument::fontfamilies_gui[n]));
640 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
642 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
643 this, SLOT(setCustomPapersize(int)));
644 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
645 this, SLOT(setCustomPapersize(int)));
646 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
647 this, SLOT(portraitChanged()));
648 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
649 this, SLOT(change_adaptor()));
650 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
651 this, SLOT(change_adaptor()));
652 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
653 this, SLOT(change_adaptor()));
654 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
655 this, SLOT(change_adaptor()));
656 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
657 this, SLOT(change_adaptor()));
658 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
659 this, SLOT(change_adaptor()));
660 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
661 this, SLOT(change_adaptor()));
662 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
663 this, SLOT(change_adaptor()));
664 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
665 this, SLOT(change_adaptor()));
667 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
668 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
669 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
670 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
671 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
672 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
673 pageLayoutModule->paperheightL);
674 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
675 pageLayoutModule->paperwidthL);
678 QComboBox * cb = pageLayoutModule->papersizeCO;
679 cb->addItem(qt_("Default"));
680 cb->addItem(qt_("Custom"));
681 cb->addItem(qt_("US letter"));
682 cb->addItem(qt_("US legal"));
683 cb->addItem(qt_("US executive"));
684 cb->addItem(qt_("A3"));
685 cb->addItem(qt_("A4"));
686 cb->addItem(qt_("A5"));
687 cb->addItem(qt_("B3"));
688 cb->addItem(qt_("B4"));
689 cb->addItem(qt_("B5"));
690 // remove the %-items from the unit choice
691 pageLayoutModule->paperwidthUnitCO->noPercents();
692 pageLayoutModule->paperheightUnitCO->noPercents();
693 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
694 pageLayoutModule->paperheightLE));
695 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
696 pageLayoutModule->paperwidthLE));
699 marginsModule = new UiWidget<Ui::MarginsUi>;
701 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
702 this, SLOT(setCustomMargins(bool)));
703 connect(marginsModule->marginCB, SIGNAL(clicked()),
704 this, SLOT(change_adaptor()));
705 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
706 this, SLOT(change_adaptor()));
707 connect(marginsModule->topUnit, SIGNAL(activated(int)),
708 this, SLOT(change_adaptor()));
709 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
710 this, SLOT(change_adaptor()));
711 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
712 this, SLOT(change_adaptor()));
713 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
714 this, SLOT(change_adaptor()));
715 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
716 this, SLOT(change_adaptor()));
717 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
718 this, SLOT(change_adaptor()));
719 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
720 this, SLOT(change_adaptor()));
721 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
722 this, SLOT(change_adaptor()));
723 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
724 this, SLOT(change_adaptor()));
725 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
726 this, SLOT(change_adaptor()));
727 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
728 this, SLOT(change_adaptor()));
729 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
730 this, SLOT(change_adaptor()));
731 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
732 this, SLOT(change_adaptor()));
733 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
734 this, SLOT(change_adaptor()));
735 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
736 this, SLOT(change_adaptor()));
737 marginsModule->topLE->setValidator(unsignedLengthValidator(
738 marginsModule->topLE));
739 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
740 marginsModule->bottomLE));
741 marginsModule->innerLE->setValidator(unsignedLengthValidator(
742 marginsModule->innerLE));
743 marginsModule->outerLE->setValidator(unsignedLengthValidator(
744 marginsModule->outerLE));
745 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
746 marginsModule->headsepLE));
747 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
748 marginsModule->headheightLE));
749 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
750 marginsModule->footskipLE));
751 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
752 marginsModule->columnsepLE));
754 bc().addCheckedLineEdit(marginsModule->topLE,
755 marginsModule->topL);
756 bc().addCheckedLineEdit(marginsModule->bottomLE,
757 marginsModule->bottomL);
758 bc().addCheckedLineEdit(marginsModule->innerLE,
759 marginsModule->innerL);
760 bc().addCheckedLineEdit(marginsModule->outerLE,
761 marginsModule->outerL);
762 bc().addCheckedLineEdit(marginsModule->headsepLE,
763 marginsModule->headsepL);
764 bc().addCheckedLineEdit(marginsModule->headheightLE,
765 marginsModule->headheightL);
766 bc().addCheckedLineEdit(marginsModule->footskipLE,
767 marginsModule->footskipL);
768 bc().addCheckedLineEdit(marginsModule->columnsepLE,
769 marginsModule->columnsepL);
772 langModule = new UiWidget<Ui::LanguageUi>;
774 connect(langModule->languageCO, SIGNAL(activated(int)),
775 this, SLOT(change_adaptor()));
776 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
777 this, SLOT(change_adaptor()));
778 connect(langModule->otherencodingRB, SIGNAL(clicked()),
779 this, SLOT(change_adaptor()));
780 connect(langModule->encodingCO, SIGNAL(activated(int)),
781 this, SLOT(change_adaptor()));
782 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
783 this, SLOT(change_adaptor()));
785 QAbstractItemModel * language_model = guiApp->languageModel();
786 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
787 language_model->sort(0);
788 langModule->languageCO->setModel(language_model);
790 // Always put the default encoding in the first position.
791 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
792 QStringList encodinglist;
793 Encodings::const_iterator it = encodings.begin();
794 Encodings::const_iterator const end = encodings.end();
795 for (; it != end; ++it)
796 encodinglist.append(qt_(it->guiName()));
798 langModule->encodingCO->addItems(encodinglist);
800 langModule->quoteStyleCO->addItem(qt_("``text''"));
801 langModule->quoteStyleCO->addItem(qt_("''text''"));
802 langModule->quoteStyleCO->addItem(qt_(",,text``"));
803 langModule->quoteStyleCO->addItem(qt_(",,text''"));
804 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
805 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
808 numberingModule = new UiWidget<Ui::NumberingUi>;
810 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
811 this, SLOT(change_adaptor()));
812 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
813 this, SLOT(change_adaptor()));
814 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
815 this, SLOT(updateNumbering()));
816 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
817 this, SLOT(updateNumbering()));
818 numberingModule->tocTW->setColumnCount(3);
819 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
820 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
821 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
824 biblioModule = new UiWidget<Ui::BiblioUi>;
825 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
826 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
827 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
828 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
830 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
831 this, SLOT(change_adaptor()));
832 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
833 this, SLOT(change_adaptor()));
834 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
835 this, SLOT(change_adaptor()));
836 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
837 this, SLOT(change_adaptor()));
838 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
839 this, SLOT(change_adaptor()));
841 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
842 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
843 biblioModule->citeStyleCO->setCurrentIndex(0);
846 mathsModule = new UiWidget<Ui::MathsUi>;
847 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
848 mathsModule->amsCB, SLOT(setDisabled(bool)));
849 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
850 mathsModule->esintCB, SLOT(setDisabled(bool)));
852 connect(mathsModule->amsCB, SIGNAL(clicked()),
853 this, SLOT(change_adaptor()));
854 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
855 this, SLOT(change_adaptor()));
856 connect(mathsModule->esintCB, SIGNAL(clicked()),
857 this, SLOT(change_adaptor()));
858 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
859 this, SLOT(change_adaptor()));
861 latexModule = new UiWidget<Ui::LaTeXUi>;
863 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
864 this, SLOT(change_adaptor()));
865 connect(latexModule->defaultOptionsCB, SIGNAL(clicked()),
866 this, SLOT(change_adaptor()));
867 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
868 this, SLOT(change_adaptor()));
869 connect(latexModule->classCO, SIGNAL(activated(int)),
870 this, SLOT(classChanged()));
871 connect(latexModule->classCO, SIGNAL(activated(int)),
872 this, SLOT(change_adaptor()));
873 connect(latexModule->layoutPB, SIGNAL(clicked()),
874 this, SLOT(browseLayout()));
875 connect(latexModule->layoutPB, SIGNAL(clicked()),
876 this, SLOT(change_adaptor()));
877 connect(latexModule->childDocGB, SIGNAL(clicked()),
878 this, SLOT(change_adaptor()));
879 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
880 this, SLOT(change_adaptor()));
881 connect(latexModule->childDocPB, SIGNAL(clicked()),
882 this, SLOT(browseMaster()));
884 // postscript drivers
885 for (int n = 0; tex_graphics[n][0]; ++n) {
886 QString enc = qt_(tex_graphics_gui[n]);
887 latexModule->psdriverCO->addItem(enc);
890 latexModule->classCO->setModel(&classes_model_);
891 LayoutFileList const & bcl = LayoutFileList::get();
892 vector<LayoutFileIndex> classList = bcl.classList();
893 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
895 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
896 vector<LayoutFileIndex>::const_iterator cen = classList.end();
897 for (int i = 0; cit != cen; ++cit, ++i) {
898 LayoutFile const & tc = bcl[*cit];
899 docstring item = (tc.isTeXClassAvailable()) ?
900 from_utf8(tc.description()) :
901 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
902 classes_model_.insertRow(i, toqstr(item), *cit);
906 branchesModule = new GuiBranches;
907 connect(branchesModule, SIGNAL(changed()),
908 this, SLOT(change_adaptor()));
911 preambleModule = new PreambleModule;
912 connect(preambleModule, SIGNAL(changed()),
913 this, SLOT(change_adaptor()));
916 bulletsModule = new BulletsModule;
917 connect(bulletsModule, SIGNAL(changed()),
918 this, SLOT(change_adaptor()));
921 modulesModule = new UiWidget<Ui::ModulesUi>;
924 new ModuleSelectionManager(modulesModule->availableLV,
925 modulesModule->selectedLV,
926 modulesModule->addPB, modulesModule->deletePB,
927 modulesModule->upPB, modulesModule->downPB,
928 availableModel(), selectedModel(), this);
929 connect(selectionManager, SIGNAL(updateHook()),
930 this, SLOT(updateModuleInfo()));
931 connect(selectionManager, SIGNAL(updateHook()),
932 this, SLOT(change_adaptor()));
933 connect(selectionManager, SIGNAL(selectionChanged()),
934 this, SLOT(modulesChanged()));
937 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
939 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
940 this, SLOT(change_adaptor()));
941 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
942 this, SLOT(change_adaptor()));
943 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
944 this, SLOT(change_adaptor()));
945 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
946 this, SLOT(change_adaptor()));
947 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
948 this, SLOT(change_adaptor()));
949 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
950 this, SLOT(change_adaptor()));
951 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
952 this, SLOT(change_adaptor()));
953 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
954 this, SLOT(change_adaptor()));
955 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
956 this, SLOT(change_adaptor()));
957 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
958 this, SLOT(change_adaptor()));
959 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
960 this, SLOT(change_adaptor()));
961 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
962 this, SLOT(change_adaptor()));
963 connect(pdfSupportModule->backrefCO, SIGNAL(activated(int)),
964 this, SLOT(change_adaptor()));
965 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
966 this, SLOT(change_adaptor()));
967 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
968 this, SLOT(change_adaptor()));
969 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
970 this, SLOT(change_adaptor()));
972 for (int i = 0; backref_opts[i][0]; ++i)
973 pdfSupportModule->backrefCO->addItem(qt_(backref_opts_gui[i]));
976 floatModule = new FloatPlacement;
977 connect(floatModule, SIGNAL(changed()),
978 this, SLOT(change_adaptor()));
980 docPS->addPanel(latexModule, qt_("Document Class"));
981 docPS->addPanel(modulesModule, qt_("Modules"));
982 docPS->addPanel(fontModule, qt_("Fonts"));
983 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
984 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
985 docPS->addPanel(marginsModule, qt_("Page Margins"));
986 docPS->addPanel(langModule, qt_("Language"));
987 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
988 docPS->addPanel(biblioModule, qt_("Bibliography"));
989 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
990 docPS->addPanel(mathsModule, qt_("Math Options"));
991 docPS->addPanel(floatModule, qt_("Float Placement"));
992 docPS->addPanel(bulletsModule, qt_("Bullets"));
993 docPS->addPanel(branchesModule, qt_("Branches"));
994 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
995 docPS->setCurrentPanel(qt_("Document Class"));
996 // FIXME: hack to work around resizing bug in Qt >= 4.2
997 // bug verified with Qt 4.2.{0-3} (JSpitzm)
998 #if QT_VERSION >= 0x040200
999 docPS->updateGeometry();
1004 void GuiDocument::showPreamble()
1006 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1010 void GuiDocument::saveDefaultClicked()
1016 void GuiDocument::useDefaultsClicked()
1022 void GuiDocument::change_adaptor()
1028 QString GuiDocument::validateListingsParameters()
1030 // use a cache here to avoid repeated validation
1031 // of the same parameters
1032 static string param_cache;
1033 static QString msg_cache;
1035 if (textLayoutModule->bypassCB->isChecked())
1038 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1039 if (params != param_cache) {
1040 param_cache = params;
1041 msg_cache = toqstr(InsetListingsParams(params).validate());
1047 void GuiDocument::setListingsMessage()
1049 static bool isOK = true;
1050 QString msg = validateListingsParameters();
1051 if (msg.isEmpty()) {
1055 // listingsTB->setTextColor("black");
1056 textLayoutModule->listingsTB->setPlainText(
1057 qt_("Input listings parameters on the right. "
1058 "Enter ? for a list of parameters."));
1061 // listingsTB->setTextColor("red");
1062 textLayoutModule->listingsTB->setPlainText(msg);
1067 void GuiDocument::setLSpacing(int item)
1069 textLayoutModule->lspacingLE->setEnabled(item == 3);
1073 void GuiDocument::setSkip(int item)
1075 bool const enable = (item == 3);
1076 textLayoutModule->skipLE->setEnabled(enable);
1077 textLayoutModule->skipLengthCO->setEnabled(enable);
1081 void GuiDocument::enableSkip(bool skip)
1083 textLayoutModule->skipCO->setEnabled(skip);
1084 textLayoutModule->skipLE->setEnabled(skip);
1085 textLayoutModule->skipLengthCO->setEnabled(skip);
1087 setSkip(textLayoutModule->skipCO->currentIndex());
1090 void GuiDocument::portraitChanged()
1092 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1095 void GuiDocument::setMargins(bool custom)
1097 marginsModule->marginCB->setChecked(custom);
1098 setCustomMargins(custom);
1102 void GuiDocument::setCustomPapersize(int papersize)
1104 bool const custom = (papersize == 1);
1106 pageLayoutModule->paperwidthL->setEnabled(custom);
1107 pageLayoutModule->paperwidthLE->setEnabled(custom);
1108 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1109 pageLayoutModule->paperheightL->setEnabled(custom);
1110 pageLayoutModule->paperheightLE->setEnabled(custom);
1111 pageLayoutModule->paperheightLE->setFocus();
1112 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1116 void GuiDocument::setColSep()
1118 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1122 void GuiDocument::setCustomMargins(bool custom)
1124 marginsModule->topL->setEnabled(!custom);
1125 marginsModule->topLE->setEnabled(!custom);
1126 marginsModule->topUnit->setEnabled(!custom);
1128 marginsModule->bottomL->setEnabled(!custom);
1129 marginsModule->bottomLE->setEnabled(!custom);
1130 marginsModule->bottomUnit->setEnabled(!custom);
1132 marginsModule->innerL->setEnabled(!custom);
1133 marginsModule->innerLE->setEnabled(!custom);
1134 marginsModule->innerUnit->setEnabled(!custom);
1136 marginsModule->outerL->setEnabled(!custom);
1137 marginsModule->outerLE->setEnabled(!custom);
1138 marginsModule->outerUnit->setEnabled(!custom);
1140 marginsModule->headheightL->setEnabled(!custom);
1141 marginsModule->headheightLE->setEnabled(!custom);
1142 marginsModule->headheightUnit->setEnabled(!custom);
1144 marginsModule->headsepL->setEnabled(!custom);
1145 marginsModule->headsepLE->setEnabled(!custom);
1146 marginsModule->headsepUnit->setEnabled(!custom);
1148 marginsModule->footskipL->setEnabled(!custom);
1149 marginsModule->footskipLE->setEnabled(!custom);
1150 marginsModule->footskipUnit->setEnabled(!custom);
1152 bool const enableColSep = !custom &&
1153 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1154 marginsModule->columnsepL->setEnabled(enableColSep);
1155 marginsModule->columnsepLE->setEnabled(enableColSep);
1156 marginsModule->columnsepUnit->setEnabled(enableColSep);
1160 void GuiDocument::updateFontsize(string const & items, string const & sel)
1162 fontModule->fontsizeCO->clear();
1163 fontModule->fontsizeCO->addItem(qt_("Default"));
1165 for (int n = 0; !token(items,'|',n).empty(); ++n)
1166 fontModule->fontsizeCO->
1167 addItem(toqstr(token(items,'|',n)));
1169 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1170 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1171 fontModule->fontsizeCO->setCurrentIndex(n);
1178 void GuiDocument::romanChanged(int item)
1180 string const font = tex_fonts_roman[item];
1181 fontModule->fontScCB->setEnabled(providesSC(font));
1182 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1186 void GuiDocument::sansChanged(int item)
1188 string const font = tex_fonts_sans[item];
1189 bool scaleable = providesScale(font);
1190 fontModule->scaleSansSB->setEnabled(scaleable);
1191 fontModule->scaleSansLA->setEnabled(scaleable);
1195 void GuiDocument::ttChanged(int item)
1197 string const font = tex_fonts_monospaced[item];
1198 bool scaleable = providesScale(font);
1199 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1200 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1204 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1207 pageLayoutModule->pagestyleCO->clear();
1208 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1210 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1211 string style = token(items, '|', n);
1212 QString style_gui = qt_(style);
1213 pagestyles.push_back(pair<string, QString>(style, style_gui));
1214 pageLayoutModule->pagestyleCO->addItem(style_gui);
1217 if (sel == "default") {
1218 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1224 for (size_t i = 0; i < pagestyles.size(); ++i)
1225 if (pagestyles[i].first == sel)
1226 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1229 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1233 void GuiDocument::browseLayout()
1235 QString const label1 = qt_("Layouts|#o#O");
1236 QString const dir1 = toqstr(lyxrc.document_path);
1237 QStringList const filter(qt_("LyX Layout (*.layout)"));
1238 QString file = browseRelFile(QString(), bufferFilepath(),
1239 qt_("Local layout file"), filter, false,
1242 if (!file.endsWith(".layout"))
1245 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1246 fromqstr(bufferFilepath()));
1248 int const ret = Alert::prompt(_("Local layout file"),
1249 _("The layout file you have selected is a local layout\n"
1250 "file, not one in the system or user directory. Your\n"
1251 "document may not work with this layout if you do not\n"
1252 "keep the layout file in the document directory."),
1253 1, 1, _("&Set Layout"), _("&Cancel"));
1257 // load the layout file
1258 LayoutFileList & bcl = LayoutFileList::get();
1259 string classname = layoutFile.onlyFileName();
1260 // this will update an existing layout if that layout has been loaded before.
1261 LayoutFileIndex name = bcl.addLocalLayout(
1262 classname.substr(0, classname.size() - 7),
1263 layoutFile.onlyPath().absFilename());
1266 Alert::error(_("Error"),
1267 _("Unable to read local layout file."));
1271 // do not trigger classChanged if there is no change.
1272 if (latexModule->classCO->currentText() == toqstr(name))
1276 int idx = latexModule->classCO->findText(toqstr(name));
1278 classes_model_.insertRow(0, toqstr(name), name);
1279 latexModule->classCO->setCurrentIndex(0);
1281 latexModule->classCO->setCurrentIndex(idx);
1287 void GuiDocument::browseMaster()
1289 QString const title = qt_("Select master document");
1290 QString const dir1 = toqstr(lyxrc.document_path);
1291 QString const old = latexModule->childDocLE->text();
1292 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1293 QStringList const filter(qt_("LyX Files (*.lyx)"));
1294 QString file = browseRelFile(old, docpath, title, filter, false,
1295 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1297 latexModule->childDocLE->setText(file);
1301 void GuiDocument::classChanged()
1303 int idx = latexModule->classCO->currentIndex();
1306 string const classname = classes_model_.getIDString(idx);
1308 // check whether the selected modules have changed.
1309 bool modules_changed = false;
1310 unsigned int const srows = selectedModel()->rowCount();
1311 if (srows != bp_.getModules().size())
1312 modules_changed = true;
1314 list<string>::const_iterator mit = bp_.getModules().begin();
1315 list<string>::const_iterator men = bp_.getModules().end();
1316 for (unsigned int i = 0; i < srows && mit != men; ++i, ++mit)
1317 if (selectedModel()->getIDString(i) != *mit) {
1318 modules_changed = true;
1323 if (modules_changed || lyxrc.auto_reset_options) {
1324 if (applyPB->isEnabled()) {
1325 int const ret = Alert::prompt(_("Unapplied changes"),
1326 _("Some changes in the dialog were not yet applied.\n"
1327 "If you do not apply now, they will be lost after this action."),
1328 1, 1, _("&Apply"), _("&Dismiss"));
1334 // We load the TextClass as soon as it is selected. This is
1335 // necessary so that other options in the dialog can be updated
1336 // according to the new class. Note, however, that, if you use
1337 // the scroll wheel when sitting on the combo box, we'll load a
1338 // lot of TextClass objects very quickly....
1339 if (!bp_.setBaseClass(classname)) {
1340 Alert::error(_("Error"), _("Unable to set document class."));
1343 if (lyxrc.auto_reset_options)
1344 bp_.useClassDefaults();
1346 // With the introduction of modules came a distinction between the base
1347 // class and the document class. The former corresponds to the main layout
1348 // file; the latter is that plus the modules (or the document-specific layout,
1349 // or whatever else there could be). Our parameters come from the document
1350 // class. So when we set the base class, we also need to recreate the document
1351 // class. Otherwise, we still have the old one.
1352 bp_.makeDocumentClass();
1358 // This is an insanely complicated attempt to make this sort of thing
1359 // work with RTL languages.
1360 docstring formatStrVec(vector<string> const & v, docstring const & s)
1362 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1366 return from_ascii(v[0]);
1367 if (v.size() == 2) {
1368 docstring retval = _("%1$s and %2$s");
1369 retval = subst(retval, _("and"), s);
1370 return bformat(retval, from_ascii(v[0]), from_ascii(v[1]));
1372 // The idea here is to format all but the last two items...
1373 int const vSize = v.size();
1374 docstring t2 = _("%1$s, %2$s");
1375 docstring retval = from_ascii(v[0]);
1376 for (int i = 1; i < vSize - 2; ++i)
1377 retval = bformat(t2, retval, from_ascii(v[i]));
1378 //...and then to plug them, and the last two, into this schema
1379 docstring t = _("%1$s, %2$s, and %3$s");
1380 t = subst(t, _("and"), s);
1381 return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
1384 vector<string> idsToNames(vector<string> const & idList)
1386 vector<string> retval;
1387 vector<string>::const_iterator it = idList.begin();
1388 vector<string>::const_iterator end = idList.end();
1389 for (; it != end; ++it) {
1390 LyXModule const * const mod = moduleList[*it];
1392 retval.push_back(*it + " (Unavailable)");
1394 retval.push_back(mod->getName());
1401 void GuiDocument::modulesToParams(BufferParams & bp)
1403 // update list of loaded modules
1404 bp.clearLayoutModules();
1405 int const srows = modules_sel_model_.rowCount();
1406 for (int i = 0; i < srows; ++i)
1407 bp.addLayoutModule(modules_sel_model_.getIDString(i));
1409 // update the list of removed modules
1410 bp.clearRemovedModules();
1411 list<string> const & reqmods = bp.baseClass()->defaultModules();
1412 list<string>::const_iterator rit = reqmods.begin();
1413 list<string>::const_iterator ren = reqmods.end();
1415 // check each of the default modules
1416 for (; rit != ren; rit++) {
1417 list<string>::const_iterator mit = bp.getModules().begin();
1418 list<string>::const_iterator men = bp.getModules().end();
1420 for (; mit != men; mit++) {
1427 // the module isn't present so must have been removed by the user
1428 bp.addRemovedModule(*rit);
1433 void GuiDocument::modulesChanged()
1435 modulesToParams(bp_);
1436 bp_.makeDocumentClass();
1441 void GuiDocument::updateModuleInfo()
1443 selectionManager->update();
1445 //Module description
1446 bool const focus_on_selected = selectionManager->selectedFocused();
1447 QListView const * const lv =
1448 focus_on_selected ? modulesModule->selectedLV : modulesModule->availableLV;
1449 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1450 modulesModule->infoML->document()->clear();
1453 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1454 GuiIdListModel const & id_model =
1455 focus_on_selected ? modules_sel_model_ : modules_av_model_;
1456 string const modName = id_model.getIDString(idx.row());
1457 docstring desc = getModuleDescription(modName);
1459 list<string> const & provmods = bp_.baseClass()->providedModules();
1460 if (std::find(provmods.begin(), provmods.end(), modName) != provmods.end()) {
1463 desc += _("Module provided by document class.");
1466 vector<string> pkglist = getPackageList(modName);
1467 docstring pkgdesc = formatStrVec(pkglist, _("and"));
1468 if (!pkgdesc.empty()) {
1471 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1474 pkglist = getRequiredList(modName);
1475 if (!pkglist.empty()) {
1476 vector<string> const reqdescs = idsToNames(pkglist);
1477 pkgdesc = formatStrVec(reqdescs, _("or"));
1480 desc += bformat(_("Module required: %1$s."), pkgdesc);
1483 pkglist = getExcludedList(modName);
1484 if (!pkglist.empty()) {
1485 vector<string> const reqdescs = idsToNames(pkglist);
1486 pkgdesc = formatStrVec(reqdescs, _( "and"));
1489 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1492 if (!isModuleAvailable(modName)) {
1495 desc += _("WARNING: Some required packages are unavailable!");
1498 modulesModule->infoML->document()->setPlainText(toqstr(desc));
1502 void GuiDocument::updateNumbering()
1504 DocumentClass const & tclass = documentClass();
1506 numberingModule->tocTW->setUpdatesEnabled(false);
1507 numberingModule->tocTW->clear();
1509 int const depth = numberingModule->depthSL->value();
1510 int const toc = numberingModule->tocSL->value();
1511 QString const no = qt_("No");
1512 QString const yes = qt_("Yes");
1513 QTreeWidgetItem * item = 0;
1515 DocumentClass::const_iterator lit = tclass.begin();
1516 DocumentClass::const_iterator len = tclass.end();
1517 for (; lit != len; ++lit) {
1518 int const toclevel = lit->toclevel;
1519 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1520 item = new QTreeWidgetItem(numberingModule->tocTW);
1521 item->setText(0, toqstr(translateIfPossible(lit->name())));
1522 item->setText(1, (toclevel <= depth) ? yes : no);
1523 item->setText(2, (toclevel <= toc) ? yes : no);
1527 numberingModule->tocTW->setUpdatesEnabled(true);
1528 numberingModule->tocTW->update();
1532 void GuiDocument::applyView()
1535 preambleModule->apply(bp_);
1538 bp_.setCiteEngine(ENGINE_BASIC);
1540 if (biblioModule->citeNatbibRB->isChecked()) {
1541 bool const use_numerical_citations =
1542 biblioModule->citeStyleCO->currentIndex();
1543 if (use_numerical_citations)
1544 bp_.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1546 bp_.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1548 } else if (biblioModule->citeJurabibRB->isChecked())
1549 bp_.setCiteEngine(ENGINE_JURABIB);
1552 biblioModule->bibtopicCB->isChecked();
1554 // language & quotes
1555 if (langModule->defaultencodingRB->isChecked()) {
1556 bp_.inputenc = "auto";
1558 int i = langModule->encodingCO->currentIndex();
1560 bp_.inputenc = "default";
1562 QString const enc_gui =
1563 langModule->encodingCO->currentText();
1564 Encodings::const_iterator it = encodings.begin();
1565 Encodings::const_iterator const end = encodings.end();
1567 for (; it != end; ++it) {
1568 if (qt_(it->guiName()) == enc_gui) {
1569 bp_.inputenc = it->latexName();
1575 // should not happen
1576 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1577 bp_.inputenc = "default";
1582 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1583 switch (langModule->quoteStyleCO->currentIndex()) {
1585 lga = InsetQuotes::EnglishQuotes;
1588 lga = InsetQuotes::SwedishQuotes;
1591 lga = InsetQuotes::GermanQuotes;
1594 lga = InsetQuotes::PolishQuotes;
1597 lga = InsetQuotes::FrenchQuotes;
1600 lga = InsetQuotes::DanishQuotes;
1603 bp_.quotes_language = lga;
1605 QString const lang = langModule->languageCO->itemData(
1606 langModule->languageCO->currentIndex()).toString();
1607 bp_.language = lyx::languages.getLanguage(fromqstr(lang));
1610 if (bp_.documentClass().hasTocLevels()) {
1611 bp_.tocdepth = numberingModule->tocSL->value();
1612 bp_.secnumdepth = numberingModule->depthSL->value();
1616 bp_.user_defined_bullet(0) = bulletsModule->bullet(0);
1617 bp_.user_defined_bullet(1) = bulletsModule->bullet(1);
1618 bp_.user_defined_bullet(2) = bulletsModule->bullet(2);
1619 bp_.user_defined_bullet(3) = bulletsModule->bullet(3);
1622 bp_.graphicsDriver =
1623 tex_graphics[latexModule->psdriverCO->currentIndex()];
1626 int idx = latexModule->classCO->currentIndex();
1628 string const classname = classes_model_.getIDString(idx);
1629 bp_.setBaseClass(classname);
1633 modulesToParams(bp_);
1635 if (mathsModule->amsautoCB->isChecked()) {
1636 bp_.use_amsmath = BufferParams::package_auto;
1638 if (mathsModule->amsCB->isChecked())
1639 bp_.use_amsmath = BufferParams::package_on;
1641 bp_.use_amsmath = BufferParams::package_off;
1644 if (mathsModule->esintautoCB->isChecked())
1645 bp_.use_esint = BufferParams::package_auto;
1647 if (mathsModule->esintCB->isChecked())
1648 bp_.use_esint = BufferParams::package_on;
1650 bp_.use_esint = BufferParams::package_off;
1653 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1654 bp_.pagestyle = "default";
1656 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1657 for (size_t i = 0; i != pagestyles.size(); ++i)
1658 if (pagestyles[i].second == style_gui)
1659 bp_.pagestyle = pagestyles[i].first;
1662 switch (textLayoutModule->lspacingCO->currentIndex()) {
1664 bp_.spacing().set(Spacing::Single);
1667 bp_.spacing().set(Spacing::Onehalf);
1670 bp_.spacing().set(Spacing::Double);
1673 bp_.spacing().set(Spacing::Other,
1674 fromqstr(textLayoutModule->lspacingLE->text()));
1678 if (textLayoutModule->twoColumnCB->isChecked())
1683 // text should have passed validation
1684 bp_.listings_params =
1685 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1687 if (textLayoutModule->indentRB->isChecked())
1688 bp_.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1690 bp_.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1692 switch (textLayoutModule->skipCO->currentIndex()) {
1694 bp_.setDefSkip(VSpace(VSpace::SMALLSKIP));
1697 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1700 bp_.setDefSkip(VSpace(VSpace::BIGSKIP));
1705 widgetsToLength(textLayoutModule->skipLE,
1706 textLayoutModule->skipLengthCO)
1712 // DocumentDefskipCB assures that this never happens
1713 // so Assert then !!! - jbl
1714 bp_.setDefSkip(VSpace(VSpace::MEDSKIP));
1719 fromqstr(latexModule->optionsLE->text());
1721 bp_.use_default_options =
1722 latexModule->defaultOptionsCB->isChecked();
1724 if (latexModule->childDocGB->isChecked())
1726 fromqstr(latexModule->childDocLE->text());
1728 bp_.master = string();
1730 bp_.float_placement = floatModule->get();
1734 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1737 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1739 bp_.fontsTypewriter =
1740 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1743 fromqstr(fontModule->cjkFontLE->text());
1745 bp_.fontsSansScale = fontModule->scaleSansSB->value();
1747 bp_.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1749 bp_.fontsSC = fontModule->fontScCB->isChecked();
1751 bp_.fontsOSF = fontModule->fontOsfCB->isChecked();
1753 bp_.fontsDefaultFamily = GuiDocument::fontfamilies[
1754 fontModule->fontsDefaultCO->currentIndex()];
1756 if (fontModule->fontsizeCO->currentIndex() == 0)
1757 bp_.fontsize = "default";
1760 fromqstr(fontModule->fontsizeCO->currentText());
1763 bp_.papersize = PAPER_SIZE(
1764 pageLayoutModule->papersizeCO->currentIndex());
1766 // custom, A3, B3 and B4 paper sizes need geometry
1767 int psize = pageLayoutModule->papersizeCO->currentIndex();
1768 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1770 bp_.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1771 pageLayoutModule->paperwidthUnitCO);
1773 bp_.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1774 pageLayoutModule->paperheightUnitCO);
1776 if (pageLayoutModule->facingPagesCB->isChecked())
1777 bp_.sides = TwoSides;
1779 bp_.sides = OneSide;
1781 if (pageLayoutModule->landscapeRB->isChecked())
1782 bp_.orientation = ORIENTATION_LANDSCAPE;
1784 bp_.orientation = ORIENTATION_PORTRAIT;
1787 bp_.use_geometry = !marginsModule->marginCB->isChecked()
1790 Ui::MarginsUi const * m = marginsModule;
1792 bp_.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1793 bp_.topmargin = widgetsToLength(m->topLE, m->topUnit);
1794 bp_.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1795 bp_.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1796 bp_.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1797 bp_.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1798 bp_.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1799 bp_.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1801 branchesModule->apply(bp_);
1804 PDFOptions & pdf = bp_.pdfoptions();
1805 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1806 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1807 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1808 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1809 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1811 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1812 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1813 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1814 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1816 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1817 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1818 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1819 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1821 backref_opts[pdfSupportModule->backrefCO->currentIndex()];
1822 if (pdfSupportModule->fullscreenCB->isChecked())
1823 pdf.pagemode = pdf.pagemode_fullscreen;
1825 pdf.pagemode.clear();
1826 pdf.quoted_options = pdf.quoted_options_check(
1827 fromqstr(pdfSupportModule->optionsLE->text()));
1831 void GuiDocument::paramsToDialog()
1833 // set the default unit
1834 Length::UNIT defaultUnit = Length::CM;
1835 switch (lyxrc.default_papersize) {
1836 case PAPER_DEFAULT: break;
1838 case PAPER_USLETTER:
1840 case PAPER_USEXECUTIVE:
1841 defaultUnit = Length::IN;
1850 defaultUnit = Length::CM;
1857 preambleModule->update(bp_, id());
1860 biblioModule->citeDefaultRB->setChecked(
1861 bp_.citeEngine() == ENGINE_BASIC);
1863 biblioModule->citeNatbibRB->setChecked(
1864 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1865 bp_.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1867 biblioModule->citeStyleCO->setCurrentIndex(
1868 bp_.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1870 biblioModule->citeJurabibRB->setChecked(
1871 bp_.citeEngine() == ENGINE_JURABIB);
1873 biblioModule->bibtopicCB->setChecked(
1876 // language & quotes
1877 int const pos = langModule->languageCO->findData(toqstr(
1878 bp_.language->lang()));
1879 langModule->languageCO->setCurrentIndex(pos);
1881 langModule->quoteStyleCO->setCurrentIndex(
1882 bp_.quotes_language);
1884 bool default_enc = true;
1885 if (bp_.inputenc != "auto") {
1886 default_enc = false;
1887 if (bp_.inputenc == "default") {
1888 langModule->encodingCO->setCurrentIndex(0);
1891 Encodings::const_iterator it = encodings.begin();
1892 Encodings::const_iterator const end = encodings.end();
1893 for (; it != end; ++it) {
1894 if (it->latexName() == bp_.inputenc) {
1895 enc_gui = it->guiName();
1899 int const i = langModule->encodingCO->findText(
1902 langModule->encodingCO->setCurrentIndex(i);
1904 // unknown encoding. Set to default.
1908 langModule->defaultencodingRB->setChecked(default_enc);
1909 langModule->otherencodingRB->setChecked(!default_enc);
1912 int const min_toclevel = documentClass().min_toclevel();
1913 int const max_toclevel = documentClass().max_toclevel();
1914 if (documentClass().hasTocLevels()) {
1915 numberingModule->setEnabled(true);
1916 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1917 numberingModule->depthSL->setMaximum(max_toclevel);
1918 numberingModule->depthSL->setValue(bp_.secnumdepth);
1919 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1920 numberingModule->tocSL->setMaximum(max_toclevel);
1921 numberingModule->tocSL->setValue(bp_.tocdepth);
1924 numberingModule->setEnabled(false);
1925 numberingModule->tocTW->clear();
1929 bulletsModule->setBullet(0, bp_.user_defined_bullet(0));
1930 bulletsModule->setBullet(1, bp_.user_defined_bullet(1));
1931 bulletsModule->setBullet(2, bp_.user_defined_bullet(2));
1932 bulletsModule->setBullet(3, bp_.user_defined_bullet(3));
1933 bulletsModule->init();
1936 int nitem = findToken(tex_graphics, bp_.graphicsDriver);
1938 latexModule->psdriverCO->setCurrentIndex(nitem);
1941 mathsModule->amsCB->setChecked(
1942 bp_.use_amsmath == BufferParams::package_on);
1943 mathsModule->amsautoCB->setChecked(
1944 bp_.use_amsmath == BufferParams::package_auto);
1946 mathsModule->esintCB->setChecked(
1947 bp_.use_esint == BufferParams::package_on);
1948 mathsModule->esintautoCB->setChecked(
1949 bp_.use_esint == BufferParams::package_auto);
1951 switch (bp_.spacing().getSpace()) {
1952 case Spacing::Other: nitem = 3; break;
1953 case Spacing::Double: nitem = 2; break;
1954 case Spacing::Onehalf: nitem = 1; break;
1955 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1959 string const & layoutID = bp_.baseClassID();
1960 setLayoutComboByIDString(layoutID);
1962 updatePagestyle(documentClass().opt_pagestyle(),
1965 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1966 if (bp_.spacing().getSpace() == Spacing::Other) {
1967 textLayoutModule->lspacingLE->setText(
1968 toqstr(bp_.spacing().getValueAsString()));
1972 if (bp_.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1973 textLayoutModule->indentRB->setChecked(true);
1975 textLayoutModule->skipRB->setChecked(true);
1978 switch (bp_.getDefSkip().kind()) {
1979 case VSpace::SMALLSKIP:
1982 case VSpace::MEDSKIP:
1985 case VSpace::BIGSKIP:
1988 case VSpace::LENGTH:
1991 string const length = bp_.getDefSkip().asLyXCommand();
1992 lengthToWidgets(textLayoutModule->skipLE,
1993 textLayoutModule->skipLengthCO,
1994 length, defaultUnit);
2001 textLayoutModule->skipCO->setCurrentIndex(skip);
2004 textLayoutModule->twoColumnCB->setChecked(
2007 // break listings_params to multiple lines
2009 InsetListingsParams(bp_.listings_params).separatedParams();
2010 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
2012 if (!bp_.options.empty()) {
2013 latexModule->optionsLE->setText(
2014 toqstr(bp_.options));
2016 latexModule->optionsLE->setText(QString());
2020 latexModule->defaultOptionsCB->setChecked(
2021 bp_.use_default_options);
2022 updateSelectedModules();
2023 selectionManager->updateProvidedModules(
2024 bp_.baseClass()->providedModules());
2025 selectionManager->updateExcludedModules(
2026 bp_.baseClass()->excludedModules());
2028 if (!documentClass().options().empty()) {
2029 latexModule->defaultOptionsLE->setText(
2030 toqstr(documentClass().options()));
2032 latexModule->defaultOptionsLE->setText(
2033 toqstr(_("[No options predefined]")));
2036 latexModule->defaultOptionsLE->setEnabled(
2037 bp_.use_default_options
2038 && !documentClass().options().empty());
2040 latexModule->defaultOptionsCB->setEnabled(
2041 !documentClass().options().empty());
2043 if (!bp_.master.empty()) {
2044 latexModule->childDocGB->setChecked(true);
2045 latexModule->childDocLE->setText(
2046 toqstr(bp_.master));
2048 latexModule->childDocLE->setText(QString());
2049 latexModule->childDocGB->setChecked(false);
2052 floatModule->set(bp_.float_placement);
2055 updateFontsize(documentClass().opt_fontsize(),
2058 int n = findToken(tex_fonts_roman, bp_.fontsRoman);
2060 fontModule->fontsRomanCO->setCurrentIndex(n);
2064 n = findToken(tex_fonts_sans, bp_.fontsSans);
2066 fontModule->fontsSansCO->setCurrentIndex(n);
2070 n = findToken(tex_fonts_monospaced, bp_.fontsTypewriter);
2072 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2076 if (!bp_.fontsCJK.empty())
2077 fontModule->cjkFontLE->setText(
2078 toqstr(bp_.fontsCJK));
2080 fontModule->cjkFontLE->setText(QString());
2082 fontModule->fontScCB->setChecked(bp_.fontsSC);
2083 fontModule->fontOsfCB->setChecked(bp_.fontsOSF);
2084 fontModule->scaleSansSB->setValue(bp_.fontsSansScale);
2085 fontModule->scaleTypewriterSB->setValue(bp_.fontsTypewriterScale);
2086 n = findToken(GuiDocument::fontfamilies, bp_.fontsDefaultFamily);
2088 fontModule->fontsDefaultCO->setCurrentIndex(n);
2091 int const psize = bp_.papersize;
2092 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2093 setCustomPapersize(psize);
2095 bool const landscape =
2096 bp_.orientation == ORIENTATION_LANDSCAPE;
2097 pageLayoutModule->landscapeRB->setChecked(landscape);
2098 pageLayoutModule->portraitRB->setChecked(!landscape);
2100 pageLayoutModule->facingPagesCB->setChecked(
2101 bp_.sides == TwoSides);
2104 lengthToWidgets(pageLayoutModule->paperwidthLE,
2105 pageLayoutModule->paperwidthUnitCO, bp_.paperwidth, defaultUnit);
2107 lengthToWidgets(pageLayoutModule->paperheightLE,
2108 pageLayoutModule->paperheightUnitCO, bp_.paperheight, defaultUnit);
2111 Ui::MarginsUi * m = marginsModule;
2113 setMargins(!bp_.use_geometry);
2115 lengthToWidgets(m->topLE, m->topUnit,
2116 bp_.topmargin, defaultUnit);
2118 lengthToWidgets(m->bottomLE, m->bottomUnit,
2119 bp_.bottommargin, defaultUnit);
2121 lengthToWidgets(m->innerLE, m->innerUnit,
2122 bp_.leftmargin, defaultUnit);
2124 lengthToWidgets(m->outerLE, m->outerUnit,
2125 bp_.rightmargin, defaultUnit);
2127 lengthToWidgets(m->headheightLE, m->headheightUnit,
2128 bp_.headheight, defaultUnit);
2130 lengthToWidgets(m->headsepLE, m->headsepUnit,
2131 bp_.headsep, defaultUnit);
2133 lengthToWidgets(m->footskipLE, m->footskipUnit,
2134 bp_.footskip, defaultUnit);
2136 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2137 bp_.columnsep, defaultUnit);
2139 branchesModule->update(bp_);
2142 PDFOptions const & pdf = bp_.pdfoptions();
2143 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2144 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2145 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2146 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2147 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2149 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2150 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2151 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2153 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2155 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2156 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2157 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2158 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2160 n = findToken(backref_opts, pdf.backref);
2162 pdfSupportModule->backrefCO->setCurrentIndex(n);
2164 pdfSupportModule->fullscreenCB->setChecked
2165 (pdf.pagemode == pdf.pagemode_fullscreen);
2167 pdfSupportModule->optionsLE->setText(
2168 toqstr(pdf.quoted_options));
2172 void GuiDocument::saveDocDefault()
2174 // we have to apply the params first
2180 void GuiDocument::updateAvailableModules()
2182 modules_av_model_.clear();
2183 list<modInfoStruct> const & modInfoList = getModuleInfo();
2184 list<modInfoStruct>::const_iterator mit = modInfoList.begin();
2185 list<modInfoStruct>::const_iterator men = modInfoList.end();
2186 for (int i = 0; mit != men; ++mit, ++i)
2187 modules_av_model_.insertRow(i, mit->name, mit->id,
2192 void GuiDocument::updateSelectedModules()
2194 modules_sel_model_.clear();
2195 list<modInfoStruct> const selModList = getSelectedModules();
2196 list<modInfoStruct>::const_iterator mit = selModList.begin();
2197 list<modInfoStruct>::const_iterator men = selModList.end();
2198 for (int i = 0; mit != men; ++mit, ++i)
2199 modules_sel_model_.insertRow(i, mit->name, mit->id,
2204 void GuiDocument::updateContents()
2206 // Nothing to do here as the document settings is not cursor dependant.
2211 void GuiDocument::useClassDefaults()
2213 if (applyPB->isEnabled()) {
2214 int const ret = Alert::prompt(_("Unapplied changes"),
2215 _("Some changes in the dialog were not yet applied.\n"
2216 "If you do not apply now, they will be lost after this action."),
2217 1, 1, _("&Apply"), _("&Dismiss"));
2222 int idx = latexModule->classCO->currentIndex();
2223 string const classname = classes_model_.getIDString(idx);
2224 if (!bp_.setBaseClass(classname)) {
2225 Alert::error(_("Error"), _("Unable to set document class."));
2228 bp_.useClassDefaults();
2233 void GuiDocument::setLayoutComboByIDString(string const & idString)
2235 int idx = classes_model_.findIDString(idString);
2237 Alert::warning(_("Can't set layout!"),
2238 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2240 latexModule->classCO->setCurrentIndex(idx);
2244 bool GuiDocument::isValid()
2246 return validateListingsParameters().isEmpty()
2247 && (textLayoutModule->skipCO->currentIndex() != 3
2248 || !textLayoutModule->skipLE->text().isEmpty());
2252 char const * const GuiDocument::fontfamilies[5] = {
2253 "default", "rmdefault", "sfdefault", "ttdefault", ""
2257 char const * GuiDocument::fontfamilies_gui[5] = {
2258 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2262 bool GuiDocument::initialiseParams(string const &)
2264 BufferView const * view = bufferview();
2266 bp_ = BufferParams();
2270 bp_ = view->buffer().params();
2272 updateAvailableModules();
2273 //FIXME It'd be nice to make sure here that the selected
2274 //modules are consistent: That required modules are actually
2275 //selected, and that we don't have conflicts. If so, we could
2276 //at least pop up a warning.
2282 void GuiDocument::clearParams()
2284 bp_ = BufferParams();
2288 BufferId GuiDocument::id() const
2290 BufferView const * const view = bufferview();
2291 return view? &view->buffer() : 0;
2295 list<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2297 return moduleNames_;
2301 list<GuiDocument::modInfoStruct> const
2302 GuiDocument::makeModuleInfo(list<string> const & mods)
2304 list<string>::const_iterator it = mods.begin();
2305 list<string>::const_iterator end = mods.end();
2306 list<modInfoStruct> mInfo;
2307 for (; it != end; ++it) {
2310 LyXModule * mod = moduleList[*it];
2312 m.name = toqstr(translateIfPossible(from_utf8(mod->getName())));
2314 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2321 list<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2323 return makeModuleInfo(params().getModules());
2327 list<GuiDocument::modInfoStruct> const GuiDocument::getProvidedModules()
2329 return makeModuleInfo(params().baseClass()->providedModules());
2333 DocumentClass const & GuiDocument::documentClass() const
2335 return bp_.documentClass();
2339 static void dispatch_bufferparams(Dialog const & dialog,
2340 BufferParams const & bp, FuncCode lfun)
2343 ss << "\\begin_header\n";
2345 ss << "\\end_header\n";
2346 dialog.dispatch(FuncRequest(lfun, ss.str()));
2350 void GuiDocument::dispatchParams()
2352 // This must come first so that a language change is correctly noticed
2355 // Apply the BufferParams. Note that this will set the base class
2356 // and then update the buffer's layout.
2357 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2359 if (!params().master.empty()) {
2360 FileName const master_file = support::makeAbsPath(params().master,
2361 support::onlyPath(buffer().absFileName()));
2362 if (isLyXFilename(master_file.absFilename())) {
2363 Buffer * master = checkAndLoadLyXFile(master_file);
2364 const_cast<Buffer &>(buffer()).setParent(master);
2368 // Generate the colours requested by each new branch.
2369 BranchList & branchlist = params().branchlist();
2370 if (!branchlist.empty()) {
2371 BranchList::const_iterator it = branchlist.begin();
2372 BranchList::const_iterator const end = branchlist.end();
2373 for (; it != end; ++it) {
2374 docstring const & current_branch = it->branch();
2375 Branch const * branch = branchlist.find(current_branch);
2376 string const x11hexname = X11hexname(branch->color());
2377 // display the new color
2378 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2379 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2382 // Open insets of selected branches, close deselected ones
2383 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2386 // FIXME: If we used an LFUN, we would not need those two lines:
2387 BufferView * bv = const_cast<BufferView *>(bufferview());
2388 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2392 void GuiDocument::setLanguage() const
2394 Language const * const newL = bp_.language;
2395 if (buffer().params().language == newL)
2398 string const & lang_name = newL->lang();
2399 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2403 void GuiDocument::saveAsDefault() const
2405 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2409 bool GuiDocument::isFontAvailable(string const & font) const
2411 if (font == "default" || font == "cmr"
2412 || font == "cmss" || font == "cmtt")
2413 // these are standard
2415 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2416 return LaTeXFeatures::isAvailable("lmodern");
2417 if (font == "times" || font == "palatino"
2418 || font == "helvet" || font == "courier")
2419 return LaTeXFeatures::isAvailable("psnfss");
2420 if (font == "cmbr" || font == "cmtl")
2421 return LaTeXFeatures::isAvailable("cmbright");
2422 if (font == "utopia")
2423 return LaTeXFeatures::isAvailable("utopia")
2424 || LaTeXFeatures::isAvailable("fourier");
2425 if (font == "beraserif" || font == "berasans"
2426 || font == "beramono")
2427 return LaTeXFeatures::isAvailable("bera");
2428 return LaTeXFeatures::isAvailable(font);
2432 bool GuiDocument::providesOSF(string const & font) const
2435 return isFontAvailable("eco");
2436 if (font == "palatino")
2437 return isFontAvailable("mathpazo");
2442 bool GuiDocument::providesSC(string const & font) const
2444 if (font == "palatino")
2445 return isFontAvailable("mathpazo");
2446 if (font == "utopia")
2447 return isFontAvailable("fourier");
2452 bool GuiDocument::providesScale(string const & font) const
2454 return font == "helvet" || font == "luximono"
2455 || font == "berasans" || font == "beramono";
2459 void GuiDocument::loadModuleInfo()
2461 moduleNames_.clear();
2462 LyXModuleList::const_iterator it = moduleList.begin();
2463 LyXModuleList::const_iterator end = moduleList.end();
2464 for (; it != end; ++it) {
2467 m.name = toqstr(translateIfPossible(from_utf8(it->getName())));
2468 // this is supposed to give us the first sentence of the description
2469 QString desc = toqstr(translateIfPossible(from_utf8(it->getDescription())));
2470 int const pos = desc.indexOf(".");
2472 desc.truncate(pos + 1);
2473 m.description = desc;
2474 moduleNames_.push_back(m);
2479 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2482 } // namespace frontend
2485 #include "GuiDocument_moc.cpp"