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>
67 using namespace lyx::support;
72 char const * const tex_graphics[] =
74 "default", "dvips", "dvitops", "emtex",
75 "ln", "oztex", "textures", "none", ""
79 char const * const tex_graphics_gui[] =
81 N_("Default"), "Dvips", "DVItoPS", "EmTeX",
82 "LN", "OzTeX", "Textures", N_("None"), ""
86 char const * const tex_fonts_roman[] =
88 "default", "cmr", "lmodern", "ae", "times", "palatino",
89 "charter", "newcent", "bookman", "utopia", "beraserif",
90 "ccfonts", "chancery", ""
94 char const * tex_fonts_roman_gui[] =
96 N_("Default"), N_("Computer Modern Roman"), N_("Latin Modern Roman"),
97 N_("AE (Almost European)"), N_("Times Roman"), N_("Palatino"),
98 N_("Bitstream Charter"), N_("New Century Schoolbook"), N_("Bookman"),
99 N_("Utopia"), N_("Bera Serif"), N_("Concrete Roman"), N_("Zapf Chancery"),
104 char const * const tex_fonts_sans[] =
106 "default", "cmss", "lmss", "helvet", "avant", "berasans", "cmbr", ""
110 char const * tex_fonts_sans_gui[] =
112 N_("Default"), N_("Computer Modern Sans"), N_("Latin Modern Sans"),
113 N_("Helvetica"), N_("Avant Garde"), N_("Bera Sans"), N_("CM Bright"), ""
117 char const * const tex_fonts_monospaced[] =
119 "default", "cmtt", "lmtt", "courier", "beramono", "luximono", "cmtl", ""
123 char const * tex_fonts_monospaced_gui[] =
125 N_("Default"), N_("Computer Modern Typewriter"),
126 N_("Latin Modern Typewriter"), N_("Courier"), N_("Bera Mono"),
127 N_("LuxiMono"), N_("CM Typewriter Light"), ""
131 vector<pair<string, QString> > pagestyles;
134 } // anonymous namespace
139 // used when sorting the textclass list.
140 class less_textclass_avail_desc
141 : public binary_function<string, string, int>
144 bool operator()(string const & lhs, string const & rhs) const
146 // Ordering criteria:
147 // 1. Availability of text class
148 // 2. Description (lexicographic)
149 LayoutFile const & tc1 = LayoutFileList::get()[lhs];
150 LayoutFile const & tc2 = LayoutFileList::get()[rhs];
151 return (tc1.isTeXClassAvailable() && !tc2.isTeXClassAvailable()) ||
152 (tc1.isTeXClassAvailable() == tc2.isTeXClassAvailable() &&
153 _(tc1.description()) < _(tc2.description()));
162 vector<string> getRequiredList(string const & modName)
164 LyXModule const * const mod = moduleList[modName];
166 return vector<string>(); //empty such thing
167 return mod->getRequiredModules();
171 vector<string> getExcludedList(string const & modName)
173 LyXModule const * const mod = moduleList[modName];
175 return vector<string>(); //empty such thing
176 return mod->getExcludedModules();
180 docstring getModuleDescription(string const & modName)
182 LyXModule const * const mod = moduleList[modName];
184 return _("Module not found!");
185 return _(mod->getDescription());
189 vector<string> getPackageList(string const & modName)
191 LyXModule const * const mod = moduleList[modName];
193 return vector<string>(); //empty such thing
194 return mod->getPackageList();
198 bool isModuleAvailable(string const & modName)
200 LyXModule * mod = moduleList[modName];
203 return mod->isAvailable();
206 } // anonymous namespace
209 /////////////////////////////////////////////////////////////////////
211 // ModuleSelectionManager
213 /////////////////////////////////////////////////////////////////////
215 /// SelectionManager for use with modules
216 class ModuleSelectionManager : public GuiSelectionManager
219 ModuleSelectionManager(
220 QListView * availableLV,
221 QListView * selectedLV,
225 QPushButton * downPB,
226 GuiIdListModel * availableModel,
227 GuiIdListModel * selectedModel)
228 : GuiSelectionManager(availableLV, selectedLV, addPB, delPB,
229 upPB, downPB, availableModel, selectedModel)
235 virtual void updateAddPB();
237 virtual void updateUpPB();
239 virtual void updateDownPB();
241 virtual void updateDelPB();
242 /// returns availableModel as a GuiIdListModel
243 GuiIdListModel * getAvailableModel()
245 return dynamic_cast<GuiIdListModel *>(availableModel);
247 /// returns selectedModel as a GuiIdListModel
248 GuiIdListModel * getSelectedModel()
250 return dynamic_cast<GuiIdListModel *>(selectedModel);
254 void ModuleSelectionManager::updateAddPB()
256 int const arows = availableModel->rowCount();
257 QModelIndexList const availSels =
258 availableLV->selectionModel()->selectedIndexes();
259 if (arows == 0 || availSels.isEmpty() || isSelected(availSels.first())) {
260 addPB->setEnabled(false);
264 QModelIndex const & idx = availableLV->selectionModel()->currentIndex();
265 string const modName = getAvailableModel()->getIDString(idx.row());
266 vector<string> reqs = getRequiredList(modName);
267 vector<string> excl = getExcludedList(modName);
269 if (reqs.empty() && excl.empty()) {
270 addPB->setEnabled(true);
274 int const srows = selectedModel->rowCount();
275 vector<string> selModList;
276 for (int i = 0; i < srows; ++i)
277 selModList.push_back(getSelectedModel()->getIDString(i));
279 vector<string>::const_iterator selModStart = selModList.begin();
280 vector<string>::const_iterator selModEnd = selModList.end();
282 //Check whether some required module is available
284 bool foundOne = false;
285 vector<string>::const_iterator it = reqs.begin();
286 vector<string>::const_iterator end = reqs.end();
287 for (; it != end; ++it) {
288 if (find(selModStart, selModEnd, *it) != selModEnd) {
294 addPB->setEnabled(false);
299 //Check whether any excluded module is being used
301 vector<string>::const_iterator it = excl.begin();
302 vector<string>::const_iterator end = excl.end();
303 for (; it != end; ++it) {
304 if (find(selModStart, selModEnd, *it) != selModEnd) {
305 addPB->setEnabled(false);
311 addPB->setEnabled(true);
315 void ModuleSelectionManager::updateDownPB()
317 int const srows = selectedModel->rowCount();
319 downPB->setEnabled(false);
322 QModelIndexList const selSels =
323 selectedLV->selectionModel()->selectedIndexes();
324 //disable if empty or last item is selected
325 if (selSels.empty() || selSels.first().row() == srows - 1) {
326 downPB->setEnabled(false);
329 //determine whether immediately succeding element requires this one
330 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
331 int curRow = curIdx.row();
332 if (curRow < 0 || curRow >= srows - 1) { //this shouldn't happen...
333 downPB->setEnabled(false);
336 string const curModName = getSelectedModel()->getIDString(curRow);
337 string const nextModName = getSelectedModel()->getIDString(curRow + 1);
339 vector<string> reqs = getRequiredList(nextModName);
341 //if it doesn't require anything....
343 downPB->setEnabled(true);
347 //FIXME This should perhaps be more flexible and check whether, even
348 //if this one is required, there is also an earlier one that is required.
349 //enable it if this module isn't required
351 find(reqs.begin(), reqs.end(), curModName) == reqs.end());
354 void ModuleSelectionManager::updateUpPB()
356 int const srows = selectedModel->rowCount();
358 upPB->setEnabled(false);
361 QModelIndexList const selSels =
362 selectedLV->selectionModel()->selectedIndexes();
363 //disable if empty or first item is selected
364 if (selSels.empty() || selSels.first().row() == 0) {
365 upPB->setEnabled(false);
369 //determine whether immediately preceding element is required by this one
370 QModelIndex const & curIdx = selectedLV->selectionModel()->currentIndex();
371 int curRow = curIdx.row();
372 if (curRow <= -1 || curRow > srows - 1) { //sanity check
373 downPB->setEnabled(false);
376 string const curModName = getSelectedModel()->getIDString(curRow);
377 vector<string> reqs = getRequiredList(curModName);
379 //if this one doesn't require anything....
381 upPB->setEnabled(true);
385 string preModName = getSelectedModel()->getIDString(curRow - 1);
387 //NOTE This is less flexible than it might be. You could check whether, even
388 //if this one is required, there is also an earlier one that is required.
389 //enable it if the preceding module isn't required
390 upPB->setEnabled(find(reqs.begin(), reqs.end(), preModName) == reqs.end());
393 void ModuleSelectionManager::updateDelPB()
395 int const srows = selectedModel->rowCount();
397 deletePB->setEnabled(false);
400 QModelIndexList const selSels =
401 selectedLV->selectionModel()->selectedIndexes();
402 if (selSels.empty() || selSels.first().row() < 0) {
403 deletePB->setEnabled(false);
407 //determine whether some LATER module requires this one
408 //NOTE Things are arranged so that this is the only way there
409 //can be a problem. At least, we hope so.
410 QModelIndex const & curIdx =
411 selectedLV->selectionModel()->currentIndex();
412 int const curRow = curIdx.row();
413 if (curRow < 0 || curRow >= srows) { //this shouldn't happen
414 deletePB->setEnabled(false);
418 QString const curModName = curIdx.data().toString();
420 //We're looking here for a reason NOT to enable the button. If we
421 //find one, we disable it and return. If we don't, we'll end up at
422 //the end of the function, and then we enable it.
423 for (int i = curRow + 1; i < srows; ++i) {
424 string const thisMod = getSelectedModel()->getIDString(i);
425 vector<string> reqs = getRequiredList(thisMod);
426 //does this one require us?
427 if (find(reqs.begin(), reqs.end(), fromqstr(curModName)) == reqs.end())
431 //OK, so this module requires us
432 //is there an EARLIER module that also satisfies the require?
433 //NOTE We demand that it be earlier to keep the list of modules
434 //consistent with the rule that a module must be proceeded by a
435 //required module. There would be more flexible ways to proceed,
436 //but that would be a lot more complicated, and the logic here is
437 //already complicated. (That's why I've left the debugging code.)
438 //lyxerr << "Testing " << thisMod << std::endl;
439 bool foundOne = false;
440 for (int j = 0; j < curRow; ++j) {
441 string const mod = getSelectedModel()->getIDString(j);
442 //lyxerr << "In loop: Testing " << mod << std::endl;
443 //do we satisfy the require?
444 if (find(reqs.begin(), reqs.end(), mod) != reqs.end()) {
445 //lyxerr << mod << " does the trick." << std::endl;
450 //did we find a module to satisfy the require?
452 //lyxerr << "No matching module found." << std::endl;
453 deletePB->setEnabled(false);
457 //lyxerr << "All's well that ends well." << std::endl;
458 deletePB->setEnabled(true);
462 /////////////////////////////////////////////////////////////////////
466 /////////////////////////////////////////////////////////////////////
468 PreambleModule::PreambleModule() : current_id_(0)
470 // This is not a memory leak. The object will be destroyed
472 (void) new LaTeXHighlighter(preambleTE->document());
473 setFocusProxy(preambleTE);
474 connect(preambleTE, SIGNAL(textChanged()), this, SIGNAL(changed()));
478 void PreambleModule::update(BufferParams const & params, BufferId id)
480 QString preamble = toqstr(params.preamble);
481 // Nothing to do if the params and preamble are unchanged.
482 if (id == current_id_
483 && preamble == preambleTE->document()->toPlainText())
486 QTextCursor cur = preambleTE->textCursor();
487 // Save the coords before switching to the new one.
488 preamble_coords_[current_id_] =
489 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
491 // Save the params address for further use.
493 preambleTE->document()->setPlainText(preamble);
494 Coords::const_iterator it = preamble_coords_.find(current_id_);
495 if (it == preamble_coords_.end())
496 // First time we open this one.
497 preamble_coords_[current_id_] = make_pair(0, 0);
499 // Restore saved coords.
500 QTextCursor cur = preambleTE->textCursor();
501 cur.setPosition(it->second.first);
502 preambleTE->setTextCursor(cur);
503 preambleTE->verticalScrollBar()->setValue(it->second.second);
508 void PreambleModule::apply(BufferParams & params)
510 params.preamble = fromqstr(preambleTE->document()->toPlainText());
514 void PreambleModule::closeEvent(QCloseEvent * e)
516 // Save the coords before closing.
517 QTextCursor cur = preambleTE->textCursor();
518 preamble_coords_[current_id_] =
519 make_pair(cur.position(), preambleTE->verticalScrollBar()->value());
524 /////////////////////////////////////////////////////////////////////
528 /////////////////////////////////////////////////////////////////////
531 GuiDocument::GuiDocument(GuiView & lv)
532 : GuiDialog(lv, "document", qt_("Document Settings"))
536 connect(okPB, SIGNAL(clicked()), this, SLOT(slotOK()));
537 connect(applyPB, SIGNAL(clicked()), this, SLOT(slotApply()));
538 connect(closePB, SIGNAL(clicked()), this, SLOT(slotClose()));
539 connect(restorePB, SIGNAL(clicked()), this, SLOT(slotRestore()));
541 connect(savePB, SIGNAL(clicked()), this, SLOT(saveDefaultClicked()));
542 connect(defaultPB, SIGNAL(clicked()), this, SLOT(useDefaultsClicked()));
544 // Manage the restore, ok, apply, restore and cancel/close buttons
545 bc().setPolicy(ButtonPolicy::NoRepeatedApplyReadOnlyPolicy);
547 bc().setApply(applyPB);
548 bc().setCancel(closePB);
549 bc().setRestore(restorePB);
551 textLayoutModule = new UiWidget<Ui::TextLayoutUi>;
553 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
554 this, SLOT(change_adaptor()));
555 connect(textLayoutModule->lspacingCO, SIGNAL(activated(int)),
556 this, SLOT(setLSpacing(int)));
557 connect(textLayoutModule->lspacingLE, SIGNAL(textChanged(const QString &)),
558 this, SLOT(change_adaptor()));
559 connect(textLayoutModule->skipRB, SIGNAL(clicked()),
560 this, SLOT(change_adaptor()));
561 connect(textLayoutModule->indentRB, SIGNAL(clicked()),
562 this, SLOT(change_adaptor()));
563 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
564 this, SLOT(change_adaptor()));
565 connect(textLayoutModule->skipLE, SIGNAL(textChanged(const QString &)),
566 this, SLOT(change_adaptor()));
567 connect(textLayoutModule->skipLengthCO, SIGNAL(activated(int)),
568 this, SLOT(change_adaptor()));
569 connect(textLayoutModule->skipCO, SIGNAL(activated(int)),
570 this, SLOT(setSkip(int)));
571 connect(textLayoutModule->skipRB, SIGNAL(toggled(bool)),
572 this, SLOT(enableSkip(bool)));
573 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
574 this, SLOT(change_adaptor()));
575 connect(textLayoutModule->twoColumnCB, SIGNAL(clicked()),
576 this, SLOT(setColSep()));
577 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
578 this, SLOT(change_adaptor()));
579 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
580 this, SLOT(change_adaptor()));
581 connect(textLayoutModule->bypassCB, SIGNAL(clicked()),
582 this, SLOT(setListingsMessage()));
583 connect(textLayoutModule->listingsED, SIGNAL(textChanged()),
584 this, SLOT(setListingsMessage()));
585 textLayoutModule->listingsTB->setPlainText(
586 qt_("Input listings parameters on the right. Enter ? for a list of parameters."));
587 textLayoutModule->lspacingLE->setValidator(new QDoubleValidator(
588 textLayoutModule->lspacingLE));
589 textLayoutModule->skipLE->setValidator(unsignedLengthValidator(
590 textLayoutModule->skipLE));
592 textLayoutModule->skipCO->addItem(qt_("SmallSkip"));
593 textLayoutModule->skipCO->addItem(qt_("MedSkip"));
594 textLayoutModule->skipCO->addItem(qt_("BigSkip"));
595 textLayoutModule->skipCO->addItem(qt_("Length"));
596 // remove the %-items from the unit choice
597 textLayoutModule->skipLengthCO->noPercents();
598 textLayoutModule->lspacingCO->insertItem(
599 Spacing::Single, qt_("Single"));
600 textLayoutModule->lspacingCO->insertItem(
601 Spacing::Onehalf, qt_("OneHalf"));
602 textLayoutModule->lspacingCO->insertItem(
603 Spacing::Double, qt_("Double"));
604 textLayoutModule->lspacingCO->insertItem(
605 Spacing::Other, qt_("Custom"));
607 // initialize the length validator
608 bc().addCheckedLineEdit(textLayoutModule->skipLE);
610 fontModule = new UiWidget<Ui::FontUi>;
612 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
613 this, SLOT(change_adaptor()));
614 connect(fontModule->fontsRomanCO, SIGNAL(activated(int)),
615 this, SLOT(romanChanged(int)));
616 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
617 this, SLOT(change_adaptor()));
618 connect(fontModule->fontsSansCO, SIGNAL(activated(int)),
619 this, SLOT(sansChanged(int)));
620 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
621 this, SLOT(change_adaptor()));
622 connect(fontModule->fontsTypewriterCO, SIGNAL(activated(int)),
623 this, SLOT(ttChanged(int)));
624 connect(fontModule->fontsDefaultCO, SIGNAL(activated(int)),
625 this, SLOT(change_adaptor()));
626 connect(fontModule->fontsizeCO, SIGNAL(activated(int)),
627 this, SLOT(change_adaptor()));
628 connect(fontModule->cjkFontLE, SIGNAL(textChanged(const QString &)),
629 this, SLOT(change_adaptor()));
630 connect(fontModule->scaleSansSB, SIGNAL(valueChanged(int)),
631 this, SLOT(change_adaptor()));
632 connect(fontModule->scaleTypewriterSB, SIGNAL(valueChanged(int)),
633 this, SLOT(change_adaptor()));
634 connect(fontModule->fontScCB, SIGNAL(clicked()),
635 this, SLOT(change_adaptor()));
636 connect(fontModule->fontOsfCB, SIGNAL(clicked()),
637 this, SLOT(change_adaptor()));
639 for (int n = 0; tex_fonts_roman[n][0]; ++n) {
640 QString font = qt_(tex_fonts_roman_gui[n]);
641 if (!isFontAvailable(tex_fonts_roman[n]))
642 font += qt_(" (not installed)");
643 fontModule->fontsRomanCO->addItem(font);
645 for (int n = 0; tex_fonts_sans[n][0]; ++n) {
646 QString font = qt_(tex_fonts_sans_gui[n]);
647 if (!isFontAvailable(tex_fonts_sans[n]))
648 font += qt_(" (not installed)");
649 fontModule->fontsSansCO->addItem(font);
651 for (int n = 0; tex_fonts_monospaced[n][0]; ++n) {
652 QString font = qt_(tex_fonts_monospaced_gui[n]);
653 if (!isFontAvailable(tex_fonts_monospaced[n]))
654 font += qt_(" (not installed)");
655 fontModule->fontsTypewriterCO->addItem(font);
658 fontModule->fontsizeCO->addItem(qt_("Default"));
659 fontModule->fontsizeCO->addItem(qt_("10"));
660 fontModule->fontsizeCO->addItem(qt_("11"));
661 fontModule->fontsizeCO->addItem(qt_("12"));
663 for (int n = 0; GuiDocument::fontfamilies_gui[n][0]; ++n)
664 fontModule->fontsDefaultCO->addItem(
665 qt_(GuiDocument::fontfamilies_gui[n]));
668 pageLayoutModule = new UiWidget<Ui::PageLayoutUi>;
670 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
671 this, SLOT(setCustomPapersize(int)));
672 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
673 this, SLOT(setCustomPapersize(int)));
674 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
675 this, SLOT(portraitChanged()));
676 connect(pageLayoutModule->papersizeCO, SIGNAL(activated(int)),
677 this, SLOT(change_adaptor()));
678 connect(pageLayoutModule->paperheightLE, SIGNAL(textChanged(const QString &)),
679 this, SLOT(change_adaptor()));
680 connect(pageLayoutModule->paperwidthLE, SIGNAL(textChanged(const QString &)),
681 this, SLOT(change_adaptor()));
682 connect(pageLayoutModule->paperwidthUnitCO, SIGNAL(activated(int)),
683 this, SLOT(change_adaptor()));
684 connect(pageLayoutModule->paperheightUnitCO, SIGNAL(activated(int)),
685 this, SLOT(change_adaptor()));
686 connect(pageLayoutModule->portraitRB, SIGNAL(clicked()),
687 this, SLOT(change_adaptor()));
688 connect(pageLayoutModule->landscapeRB, SIGNAL(clicked()),
689 this, SLOT(change_adaptor()));
690 connect(pageLayoutModule->facingPagesCB, SIGNAL(clicked()),
691 this, SLOT(change_adaptor()));
692 connect(pageLayoutModule->pagestyleCO, SIGNAL(activated(int)),
693 this, SLOT(change_adaptor()));
695 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
696 pageLayoutModule->pagestyleCO->addItem(qt_("empty"));
697 pageLayoutModule->pagestyleCO->addItem(qt_("plain"));
698 pageLayoutModule->pagestyleCO->addItem(qt_("headings"));
699 pageLayoutModule->pagestyleCO->addItem(qt_("fancy"));
700 bc().addCheckedLineEdit(pageLayoutModule->paperheightLE,
701 pageLayoutModule->paperheightL);
702 bc().addCheckedLineEdit(pageLayoutModule->paperwidthLE,
703 pageLayoutModule->paperwidthL);
706 QComboBox * cb = pageLayoutModule->papersizeCO;
707 cb->addItem(qt_("Default"));
708 cb->addItem(qt_("Custom"));
709 cb->addItem(qt_("US letter"));
710 cb->addItem(qt_("US legal"));
711 cb->addItem(qt_("US executive"));
712 cb->addItem(qt_("A3"));
713 cb->addItem(qt_("A4"));
714 cb->addItem(qt_("A5"));
715 cb->addItem(qt_("B3"));
716 cb->addItem(qt_("B4"));
717 cb->addItem(qt_("B5"));
718 // remove the %-items from the unit choice
719 pageLayoutModule->paperwidthUnitCO->noPercents();
720 pageLayoutModule->paperheightUnitCO->noPercents();
721 pageLayoutModule->paperheightLE->setValidator(unsignedLengthValidator(
722 pageLayoutModule->paperheightLE));
723 pageLayoutModule->paperwidthLE->setValidator(unsignedLengthValidator(
724 pageLayoutModule->paperwidthLE));
727 marginsModule = new UiWidget<Ui::MarginsUi>;
729 connect(marginsModule->marginCB, SIGNAL(toggled(bool)),
730 this, SLOT(setCustomMargins(bool)));
731 connect(marginsModule->marginCB, SIGNAL(clicked()),
732 this, SLOT(change_adaptor()));
733 connect(marginsModule->topLE, SIGNAL(textChanged(QString)),
734 this, SLOT(change_adaptor()));
735 connect(marginsModule->topUnit, SIGNAL(activated(int)),
736 this, SLOT(change_adaptor()));
737 connect(marginsModule->bottomLE, SIGNAL(textChanged(QString)),
738 this, SLOT(change_adaptor()));
739 connect(marginsModule->bottomUnit, SIGNAL(activated(int)),
740 this, SLOT(change_adaptor()));
741 connect(marginsModule->innerLE, SIGNAL(textChanged(QString)),
742 this, SLOT(change_adaptor()));
743 connect(marginsModule->innerUnit, SIGNAL(activated(int)),
744 this, SLOT(change_adaptor()));
745 connect(marginsModule->outerLE, SIGNAL(textChanged(QString)),
746 this, SLOT(change_adaptor()));
747 connect(marginsModule->outerUnit, SIGNAL(activated(int)),
748 this, SLOT(change_adaptor()));
749 connect(marginsModule->headheightLE, SIGNAL(textChanged(QString)),
750 this, SLOT(change_adaptor()));
751 connect(marginsModule->headheightUnit, SIGNAL(activated(int)),
752 this, SLOT(change_adaptor()));
753 connect(marginsModule->headsepLE, SIGNAL(textChanged(QString)),
754 this, SLOT(change_adaptor()));
755 connect(marginsModule->headsepUnit, SIGNAL(activated(int)),
756 this, SLOT(change_adaptor()));
757 connect(marginsModule->footskipLE, SIGNAL(textChanged(QString)),
758 this, SLOT(change_adaptor()));
759 connect(marginsModule->footskipUnit, SIGNAL(activated(int)),
760 this, SLOT(change_adaptor()));
761 connect(marginsModule->columnsepLE, SIGNAL(textChanged(QString)),
762 this, SLOT(change_adaptor()));
763 connect(marginsModule->columnsepUnit, SIGNAL(activated(int)),
764 this, SLOT(change_adaptor()));
765 marginsModule->topLE->setValidator(unsignedLengthValidator(
766 marginsModule->topLE));
767 marginsModule->bottomLE->setValidator(unsignedLengthValidator(
768 marginsModule->bottomLE));
769 marginsModule->innerLE->setValidator(unsignedLengthValidator(
770 marginsModule->innerLE));
771 marginsModule->outerLE->setValidator(unsignedLengthValidator(
772 marginsModule->outerLE));
773 marginsModule->headsepLE->setValidator(unsignedLengthValidator(
774 marginsModule->headsepLE));
775 marginsModule->headheightLE->setValidator(unsignedLengthValidator(
776 marginsModule->headheightLE));
777 marginsModule->footskipLE->setValidator(unsignedLengthValidator(
778 marginsModule->footskipLE));
779 marginsModule->columnsepLE->setValidator(unsignedLengthValidator(
780 marginsModule->columnsepLE));
782 bc().addCheckedLineEdit(marginsModule->topLE,
783 marginsModule->topL);
784 bc().addCheckedLineEdit(marginsModule->bottomLE,
785 marginsModule->bottomL);
786 bc().addCheckedLineEdit(marginsModule->innerLE,
787 marginsModule->innerL);
788 bc().addCheckedLineEdit(marginsModule->outerLE,
789 marginsModule->outerL);
790 bc().addCheckedLineEdit(marginsModule->headsepLE,
791 marginsModule->headsepL);
792 bc().addCheckedLineEdit(marginsModule->headheightLE,
793 marginsModule->headheightL);
794 bc().addCheckedLineEdit(marginsModule->footskipLE,
795 marginsModule->footskipL);
796 bc().addCheckedLineEdit(marginsModule->columnsepLE,
797 marginsModule->columnsepL);
800 langModule = new UiWidget<Ui::LanguageUi>;
802 connect(langModule->languageCO, SIGNAL(activated(int)),
803 this, SLOT(change_adaptor()));
804 connect(langModule->defaultencodingRB, SIGNAL(clicked()),
805 this, SLOT(change_adaptor()));
806 connect(langModule->otherencodingRB, SIGNAL(clicked()),
807 this, SLOT(change_adaptor()));
808 connect(langModule->encodingCO, SIGNAL(activated(int)),
809 this, SLOT(change_adaptor()));
810 connect(langModule->quoteStyleCO, SIGNAL(activated(int)),
811 this, SLOT(change_adaptor()));
813 QAbstractItemModel * language_model = guiApp->languageModel();
814 // FIXME: it would be nice if sorting was enabled/disabled via a checkbox.
815 language_model->sort(0);
816 langModule->languageCO->setModel(language_model);
818 // Always put the default encoding in the first position.
819 langModule->encodingCO->addItem(qt_("Language Default (no inputenc)"));
820 QStringList encodinglist;
821 Encodings::const_iterator it = encodings.begin();
822 Encodings::const_iterator const end = encodings.end();
823 for (; it != end; ++it)
824 encodinglist.append(qt_(it->guiName()));
826 langModule->encodingCO->addItems(encodinglist);
828 langModule->quoteStyleCO->addItem(qt_("``text''"));
829 langModule->quoteStyleCO->addItem(qt_("''text''"));
830 langModule->quoteStyleCO->addItem(qt_(",,text``"));
831 langModule->quoteStyleCO->addItem(qt_(",,text''"));
832 langModule->quoteStyleCO->addItem(qt_("<<text>>"));
833 langModule->quoteStyleCO->addItem(qt_(">>text<<"));
836 numberingModule = new UiWidget<Ui::NumberingUi>;
838 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
839 this, SLOT(change_adaptor()));
840 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
841 this, SLOT(change_adaptor()));
842 connect(numberingModule->depthSL, SIGNAL(valueChanged(int)),
843 this, SLOT(updateNumbering()));
844 connect(numberingModule->tocSL, SIGNAL(valueChanged(int)),
845 this, SLOT(updateNumbering()));
846 numberingModule->tocTW->setColumnCount(3);
847 numberingModule->tocTW->headerItem()->setText(0, qt_("Example"));
848 numberingModule->tocTW->headerItem()->setText(1, qt_("Numbered"));
849 numberingModule->tocTW->headerItem()->setText(2, qt_("Appears in TOC"));
852 biblioModule = new UiWidget<Ui::BiblioUi>;
853 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
854 biblioModule->citationStyleL, SLOT(setEnabled(bool)));
855 connect(biblioModule->citeNatbibRB, SIGNAL(toggled(bool)),
856 biblioModule->citeStyleCO, SLOT(setEnabled(bool)));
858 connect(biblioModule->citeDefaultRB, SIGNAL(clicked()),
859 this, SLOT(change_adaptor()));
860 connect(biblioModule->citeNatbibRB, SIGNAL(clicked()),
861 this, SLOT(change_adaptor()));
862 connect(biblioModule->citeStyleCO, SIGNAL(activated(int)),
863 this, SLOT(change_adaptor()));
864 connect(biblioModule->citeJurabibRB, SIGNAL(clicked()),
865 this, SLOT(change_adaptor()));
866 connect(biblioModule->bibtopicCB, SIGNAL(clicked()),
867 this, SLOT(change_adaptor()));
869 biblioModule->citeStyleCO->addItem(qt_("Author-year"));
870 biblioModule->citeStyleCO->addItem(qt_("Numerical"));
871 biblioModule->citeStyleCO->setCurrentIndex(0);
874 mathsModule = new UiWidget<Ui::MathsUi>;
875 connect(mathsModule->amsautoCB, SIGNAL(toggled(bool)),
876 mathsModule->amsCB, SLOT(setDisabled(bool)));
877 connect(mathsModule->esintautoCB, SIGNAL(toggled(bool)),
878 mathsModule->esintCB, SLOT(setDisabled(bool)));
880 connect(mathsModule->amsCB, SIGNAL(clicked()),
881 this, SLOT(change_adaptor()));
882 connect(mathsModule->amsautoCB, SIGNAL(clicked()),
883 this, SLOT(change_adaptor()));
884 connect(mathsModule->esintCB, SIGNAL(clicked()),
885 this, SLOT(change_adaptor()));
886 connect(mathsModule->esintautoCB, SIGNAL(clicked()),
887 this, SLOT(change_adaptor()));
889 latexModule = new UiWidget<Ui::LaTeXUi>;
891 connect(latexModule->optionsLE, SIGNAL(textChanged(QString)),
892 this, SLOT(change_adaptor()));
893 connect(latexModule->psdriverCO, SIGNAL(activated(int)),
894 this, SLOT(change_adaptor()));
895 connect(latexModule->classCO, SIGNAL(activated(int)),
896 this, SLOT(classChanged()));
897 connect(latexModule->classCO, SIGNAL(activated(int)),
898 this, SLOT(change_adaptor()));
899 connect(latexModule->layoutPB, SIGNAL(clicked()),
900 this, SLOT(browseLayout()));
901 connect(latexModule->layoutPB, SIGNAL(clicked()),
902 this, SLOT(change_adaptor()));
903 connect(latexModule->childDocGB, SIGNAL(clicked()),
904 this, SLOT(change_adaptor()));
905 connect(latexModule->childDocLE, SIGNAL(textChanged(QString)),
906 this, SLOT(change_adaptor()));
907 connect(latexModule->childDocPB, SIGNAL(clicked()),
908 this, SLOT(browseMaster()));
911 new ModuleSelectionManager(latexModule->availableLV,
912 latexModule->selectedLV,
913 latexModule->addPB, latexModule->deletePB,
914 latexModule->upPB, latexModule->downPB,
915 availableModel(), selectedModel());
916 connect(selectionManager, SIGNAL(updateHook()),
917 this, SLOT(updateModuleInfo()));
918 connect(selectionManager, SIGNAL(updateHook()),
919 this, SLOT(change_adaptor()));
921 // postscript drivers
922 for (int n = 0; tex_graphics[n][0]; ++n) {
923 QString enc = qt_(tex_graphics_gui[n]);
924 latexModule->psdriverCO->addItem(enc);
927 latexModule->classCO->setModel(&classes_model_);
928 LayoutFileList const & bcl = LayoutFileList::get();
929 vector<LayoutFileIndex> classList = bcl.classList();
930 sort(classList.begin(), classList.end(), less_textclass_avail_desc());
932 vector<LayoutFileIndex>::const_iterator cit = classList.begin();
933 vector<LayoutFileIndex>::const_iterator cen = classList.end();
934 for (int i = 0; cit != cen; ++cit, ++i) {
935 LayoutFile const & tc = bcl[*cit];
936 docstring item = (tc.isTeXClassAvailable()) ?
937 from_utf8(tc.description()) :
938 bformat(_("Unavailable: %1$s"), from_utf8(tc.description()));
939 classes_model_.insertRow(i, toqstr(item), *cit);
943 branchesModule = new GuiBranches;
944 connect(branchesModule, SIGNAL(changed()),
945 this, SLOT(change_adaptor()));
948 preambleModule = new PreambleModule;
949 connect(preambleModule, SIGNAL(changed()),
950 this, SLOT(change_adaptor()));
953 bulletsModule = new BulletsModule;
954 connect(bulletsModule, SIGNAL(changed()),
955 this, SLOT(change_adaptor()));
958 pdfSupportModule = new UiWidget<Ui::PDFSupportUi>;
960 connect(pdfSupportModule->use_hyperrefGB, SIGNAL(toggled(bool)),
961 this, SLOT(change_adaptor()));
962 connect(pdfSupportModule->titleLE, SIGNAL(textChanged(QString)),
963 this, SLOT(change_adaptor()));
964 connect(pdfSupportModule->authorLE, SIGNAL(textChanged(QString)),
965 this, SLOT(change_adaptor()));
966 connect(pdfSupportModule->subjectLE, SIGNAL(textChanged(QString)),
967 this, SLOT(change_adaptor()));
968 connect(pdfSupportModule->keywordsLE, SIGNAL(textChanged(QString)),
969 this, SLOT(change_adaptor()));
970 connect(pdfSupportModule->bookmarksGB, SIGNAL(toggled(bool)),
971 this, SLOT(change_adaptor()));
972 connect(pdfSupportModule->bookmarksnumberedCB, SIGNAL(toggled(bool)),
973 this, SLOT(change_adaptor()));
974 connect(pdfSupportModule->bookmarksopenGB, SIGNAL(toggled(bool)),
975 this, SLOT(change_adaptor()));
976 connect(pdfSupportModule->bookmarksopenlevelSB, SIGNAL(valueChanged(int)),
977 this, SLOT(change_adaptor()));
978 connect(pdfSupportModule->breaklinksCB, SIGNAL(toggled(bool)),
979 this, SLOT(change_adaptor()));
980 connect(pdfSupportModule->pdfborderCB, SIGNAL(toggled(bool)),
981 this, SLOT(change_adaptor()));
982 connect(pdfSupportModule->colorlinksCB, SIGNAL(toggled(bool)),
983 this, SLOT(change_adaptor()));
984 connect(pdfSupportModule->backrefCB, SIGNAL(toggled(bool)),
985 this, SLOT(change_adaptor()));
986 connect(pdfSupportModule->pdfusetitleCB, SIGNAL(toggled(bool)),
987 this, SLOT(change_adaptor()));
988 connect(pdfSupportModule->pagebackrefCB, SIGNAL(toggled(bool)),
989 this, SLOT(change_adaptor()));
990 connect(pdfSupportModule->fullscreenCB, SIGNAL(toggled(bool)),
991 this, SLOT(change_adaptor()));
992 connect(pdfSupportModule->optionsLE, SIGNAL(textChanged(QString)),
993 this, SLOT(change_adaptor()));
996 floatModule = new FloatPlacement;
997 connect(floatModule, SIGNAL(changed()),
998 this, SLOT(change_adaptor()));
1000 docPS->addPanel(latexModule, qt_("Document Class"));
1001 docPS->addPanel(fontModule, qt_("Fonts"));
1002 docPS->addPanel(textLayoutModule, qt_("Text Layout"));
1003 docPS->addPanel(pageLayoutModule, qt_("Page Layout"));
1004 docPS->addPanel(marginsModule, qt_("Page Margins"));
1005 docPS->addPanel(langModule, qt_("Language"));
1006 docPS->addPanel(numberingModule, qt_("Numbering & TOC"));
1007 docPS->addPanel(biblioModule, qt_("Bibliography"));
1008 docPS->addPanel(pdfSupportModule, qt_("PDF Properties"));
1009 docPS->addPanel(mathsModule, qt_("Math Options"));
1010 docPS->addPanel(floatModule, qt_("Float Placement"));
1011 docPS->addPanel(bulletsModule, qt_("Bullets"));
1012 docPS->addPanel(branchesModule, qt_("Branches"));
1013 docPS->addPanel(preambleModule, qt_("LaTeX Preamble"));
1014 docPS->setCurrentPanel(qt_("Document Class"));
1015 // FIXME: hack to work around resizing bug in Qt >= 4.2
1016 // bug verified with Qt 4.2.{0-3} (JSpitzm)
1017 #if QT_VERSION >= 0x040200
1018 docPS->updateGeometry();
1023 void GuiDocument::showPreamble()
1025 docPS->setCurrentPanel(qt_("LaTeX Preamble"));
1029 void GuiDocument::saveDefaultClicked()
1035 void GuiDocument::useDefaultsClicked()
1041 void GuiDocument::change_adaptor()
1047 QString GuiDocument::validateListingsParameters()
1049 // use a cache here to avoid repeated validation
1050 // of the same parameters
1051 static string param_cache;
1052 static QString msg_cache;
1054 if (textLayoutModule->bypassCB->isChecked())
1057 string params = fromqstr(textLayoutModule->listingsED->toPlainText());
1058 if (params != param_cache) {
1059 param_cache = params;
1060 msg_cache = toqstr(InsetListingsParams(params).validate());
1066 void GuiDocument::setListingsMessage()
1068 static bool isOK = true;
1069 QString msg = validateListingsParameters();
1070 if (msg.isEmpty()) {
1074 // listingsTB->setTextColor("black");
1075 textLayoutModule->listingsTB->setPlainText(
1076 qt_("Input listings parameters on the right. "
1077 "Enter ? for a list of parameters."));
1080 // listingsTB->setTextColor("red");
1081 textLayoutModule->listingsTB->setPlainText(msg);
1086 void GuiDocument::setLSpacing(int item)
1088 textLayoutModule->lspacingLE->setEnabled(item == 3);
1092 void GuiDocument::setSkip(int item)
1094 bool const enable = (item == 3);
1095 textLayoutModule->skipLE->setEnabled(enable);
1096 textLayoutModule->skipLengthCO->setEnabled(enable);
1100 void GuiDocument::enableSkip(bool skip)
1102 textLayoutModule->skipCO->setEnabled(skip);
1103 textLayoutModule->skipLE->setEnabled(skip);
1104 textLayoutModule->skipLengthCO->setEnabled(skip);
1106 setSkip(textLayoutModule->skipCO->currentIndex());
1109 void GuiDocument::portraitChanged()
1111 setMargins(pageLayoutModule->papersizeCO->currentIndex());
1114 void GuiDocument::setMargins(bool custom)
1116 marginsModule->marginCB->setChecked(custom);
1117 setCustomMargins(custom);
1121 void GuiDocument::setCustomPapersize(int papersize)
1123 bool const custom = (papersize == 1);
1125 pageLayoutModule->paperwidthL->setEnabled(custom);
1126 pageLayoutModule->paperwidthLE->setEnabled(custom);
1127 pageLayoutModule->paperwidthUnitCO->setEnabled(custom);
1128 pageLayoutModule->paperheightL->setEnabled(custom);
1129 pageLayoutModule->paperheightLE->setEnabled(custom);
1130 pageLayoutModule->paperheightLE->setFocus();
1131 pageLayoutModule->paperheightUnitCO->setEnabled(custom);
1135 void GuiDocument::setColSep()
1137 setCustomMargins(marginsModule->marginCB->checkState() == Qt::Checked);
1141 void GuiDocument::setCustomMargins(bool custom)
1143 marginsModule->topL->setEnabled(!custom);
1144 marginsModule->topLE->setEnabled(!custom);
1145 marginsModule->topUnit->setEnabled(!custom);
1147 marginsModule->bottomL->setEnabled(!custom);
1148 marginsModule->bottomLE->setEnabled(!custom);
1149 marginsModule->bottomUnit->setEnabled(!custom);
1151 marginsModule->innerL->setEnabled(!custom);
1152 marginsModule->innerLE->setEnabled(!custom);
1153 marginsModule->innerUnit->setEnabled(!custom);
1155 marginsModule->outerL->setEnabled(!custom);
1156 marginsModule->outerLE->setEnabled(!custom);
1157 marginsModule->outerUnit->setEnabled(!custom);
1159 marginsModule->headheightL->setEnabled(!custom);
1160 marginsModule->headheightLE->setEnabled(!custom);
1161 marginsModule->headheightUnit->setEnabled(!custom);
1163 marginsModule->headsepL->setEnabled(!custom);
1164 marginsModule->headsepLE->setEnabled(!custom);
1165 marginsModule->headsepUnit->setEnabled(!custom);
1167 marginsModule->footskipL->setEnabled(!custom);
1168 marginsModule->footskipLE->setEnabled(!custom);
1169 marginsModule->footskipUnit->setEnabled(!custom);
1171 bool const enableColSep = !custom &&
1172 textLayoutModule->twoColumnCB->checkState() == Qt::Checked;
1173 marginsModule->columnsepL->setEnabled(enableColSep);
1174 marginsModule->columnsepLE->setEnabled(enableColSep);
1175 marginsModule->columnsepUnit->setEnabled(enableColSep);
1179 void GuiDocument::updateFontsize(string const & items, string const & sel)
1181 fontModule->fontsizeCO->clear();
1182 fontModule->fontsizeCO->addItem(qt_("Default"));
1184 for (int n = 0; !token(items,'|',n).empty(); ++n)
1185 fontModule->fontsizeCO->
1186 addItem(toqstr(token(items,'|',n)));
1188 for (int n = 0; n < fontModule->fontsizeCO->count(); ++n) {
1189 if (fromqstr(fontModule->fontsizeCO->itemText(n)) == sel) {
1190 fontModule->fontsizeCO->setCurrentIndex(n);
1197 void GuiDocument::romanChanged(int item)
1199 string const font = tex_fonts_roman[item];
1200 fontModule->fontScCB->setEnabled(providesSC(font));
1201 fontModule->fontOsfCB->setEnabled(providesOSF(font));
1205 void GuiDocument::sansChanged(int item)
1207 string const font = tex_fonts_sans[item];
1208 bool scaleable = providesScale(font);
1209 fontModule->scaleSansSB->setEnabled(scaleable);
1210 fontModule->scaleSansLA->setEnabled(scaleable);
1214 void GuiDocument::ttChanged(int item)
1216 string const font = tex_fonts_monospaced[item];
1217 bool scaleable = providesScale(font);
1218 fontModule->scaleTypewriterSB->setEnabled(scaleable);
1219 fontModule->scaleTypewriterLA->setEnabled(scaleable);
1223 void GuiDocument::updatePagestyle(string const & items, string const & sel)
1226 pageLayoutModule->pagestyleCO->clear();
1227 pageLayoutModule->pagestyleCO->addItem(qt_("Default"));
1229 for (int n = 0; !token(items, '|', n).empty(); ++n) {
1230 string style = token(items, '|', n);
1231 QString style_gui = qt_(style);
1232 pagestyles.push_back(pair<string, QString>(style, style_gui));
1233 pageLayoutModule->pagestyleCO->addItem(style_gui);
1236 if (sel == "default") {
1237 pageLayoutModule->pagestyleCO->setCurrentIndex(0);
1243 for (size_t i = 0; i < pagestyles.size(); ++i)
1244 if (pagestyles[i].first == sel)
1245 nn = pageLayoutModule->pagestyleCO->findText(pagestyles[i].second);
1248 pageLayoutModule->pagestyleCO->setCurrentIndex(nn);
1252 void GuiDocument::browseLayout()
1254 QString const label1 = qt_("Layouts|#o#O");
1255 QString const dir1 = toqstr(lyxrc.document_path);
1256 QStringList const filter(qt_("LyX Layout (*.layout)"));
1257 QString file = browseRelFile(QString(), bufferFilepath(),
1258 qt_("Local layout file"), filter, false,
1261 if (!file.endsWith(".layout"))
1264 FileName layoutFile = support::makeAbsPath(fromqstr(file),
1265 fromqstr(bufferFilepath()));
1267 int const ret = Alert::prompt(_("Local layout file"),
1268 _("The layout file you have selected is a local layout\n"
1269 "file, not one in the system or user directory. Your\n"
1270 "document may not work with this layout if you do not\n"
1271 "keep the layout file in the document directory."),
1272 1, 1, _("&Set Layout"), _("&Cancel"));
1276 // load the layout file
1277 LayoutFileList & bcl = LayoutFileList::get();
1278 string classname = layoutFile.onlyFileName();
1279 // this will update an existing layout if that layout has been loaded before.
1280 LayoutFileIndex name = bcl.addLocalLayout(
1281 classname.substr(0, classname.size() - 7),
1282 layoutFile.onlyPath().absFilename());
1285 Alert::error(_("Error"),
1286 _("Unable to read local layout file."));
1290 // do not trigger classChanged if there is no change.
1291 if (latexModule->classCO->currentText() == toqstr(name))
1295 int idx = latexModule->classCO->findText(toqstr(name));
1297 classes_model_.insertRow(0, toqstr(name), name);
1298 latexModule->classCO->setCurrentIndex(0);
1300 latexModule->classCO->setCurrentIndex(idx);
1306 void GuiDocument::browseMaster()
1308 QString const title = qt_("Select master document");
1309 QString const dir1 = toqstr(lyxrc.document_path);
1310 QString const old = latexModule->childDocLE->text();
1311 QString const docpath = toqstr(support::onlyPath(buffer().absFileName()));
1312 QStringList const filter(qt_("LyX Files (*.lyx)"));
1313 QString file = browseRelFile(old, docpath, title, filter, false,
1314 qt_("Documents|#o#O"), toqstr(lyxrc.document_path));
1316 latexModule->childDocLE->setText(file);
1320 void GuiDocument::classChanged()
1322 int idx = latexModule->classCO->currentIndex();
1325 string const classname = classes_model_.getIDString(idx);
1327 // FIXME Note that by doing things this way, we load the TextClass
1328 // as soon as it is selected. So, if you use the scroll wheel when
1329 // sitting on the combo box, we'll load a lot of TextClass objects
1330 // very quickly. This could be changed.
1331 if (!bp_.setBaseClass(classname)) {
1332 Alert::error(_("Error"), _("Unable to set document class."));
1335 if (lyxrc.auto_reset_options) {
1336 if (applyPB->isEnabled()) {
1337 int const ret = Alert::prompt(_("Unapplied changes"),
1338 _("Some changes in the dialog were not yet applied.\n"
1339 "If you do not apply now, they will be lost after this action."),
1340 1, 1, _("&Apply"), _("&Dismiss"));
1344 bp_.useClassDefaults();
1345 paramsToDialog(bp_);
1347 // FIXME There's a little bug here connected with auto_reset, namely,
1348 // that, if the preceding is skipped and the user has changed the
1349 // modules before changing the class, those changes will be lost on
1350 // update. But maybe that's what we want?
1351 updateSelectedModules();
1356 // This is an insanely complicated attempt to make this sort of thing
1357 // work with RTL languages.
1358 docstring formatStrVec(vector<string> const & v, docstring const & s)
1360 //this mess formats the list as "v[0], v[1], ..., [s] v[n]"
1364 return from_ascii(v[0]);
1365 if (v.size() == 2) {
1366 docstring retval = _("%1$s and %2$s");
1367 retval = subst(retval, _("and"), s);
1368 return bformat(retval, from_ascii(v[0]), from_ascii(v[1]));
1370 // The idea here is to format all but the last two items...
1371 int const vSize = v.size();
1372 docstring t2 = _("%1$s, %2$s");
1373 docstring retval = from_ascii(v[0]);
1374 for (int i = 1; i < vSize - 2; ++i)
1375 retval = bformat(t2, retval, from_ascii(v[i]));
1376 //...and then to plug them, and the last two, into this schema
1377 docstring t = _("%1$s, %2$s, and %3$s");
1378 t = subst(t, _("and"), s);
1379 return bformat(t, retval, from_ascii(v[vSize - 2]), from_ascii(v[vSize - 1]));
1382 vector<string> idsToNames(vector<string> const & idList)
1384 vector<string> retval;
1385 vector<string>::const_iterator it = idList.begin();
1386 vector<string>::const_iterator end = idList.end();
1387 for (; it != end; ++it) {
1388 LyXModule const * const mod = moduleList[*it];
1390 retval.push_back(*it + " (Unavailable)");
1392 retval.push_back(mod->getName());
1399 void GuiDocument::updateModuleInfo()
1401 selectionManager->update();
1403 //Module description
1404 bool const focusOnSelected = selectionManager->selectedFocused();
1405 QListView const * const lv =
1406 focusOnSelected ? latexModule->selectedLV : latexModule->availableLV;
1407 if (lv->selectionModel()->selectedIndexes().isEmpty()) {
1408 latexModule->infoML->document()->clear();
1411 QModelIndex const & idx = lv->selectionModel()->currentIndex();
1412 GuiIdListModel const & idModel =
1413 focusOnSelected ? modules_sel_model_ : modules_av_model_;
1414 string const modName = idModel.getIDString(idx.row());
1415 docstring desc = getModuleDescription(modName);
1417 vector<string> pkgList = getPackageList(modName);
1418 docstring pkgdesc = formatStrVec(pkgList, _("and"));
1419 if (!pkgdesc.empty()) {
1422 desc += bformat(_("Package(s) required: %1$s."), pkgdesc);
1425 pkgList = getRequiredList(modName);
1426 if (!pkgList.empty()) {
1427 vector<string> const reqDescs = idsToNames(pkgList);
1428 pkgdesc = formatStrVec(reqDescs, _("or"));
1431 desc += bformat(_("Module required: %1$s."), pkgdesc);
1434 pkgList = getExcludedList(modName);
1435 if (!pkgList.empty()) {
1436 vector<string> const reqDescs = idsToNames(pkgList);
1437 pkgdesc = formatStrVec(reqDescs, _( "and"));
1440 desc += bformat(_("Modules excluded: %1$s."), pkgdesc);
1443 if (!isModuleAvailable(modName)) {
1446 desc += _("WARNING: Some packages are unavailable!");
1449 latexModule->infoML->document()->setPlainText(toqstr(desc));
1453 void GuiDocument::updateNumbering()
1455 DocumentClass const & tclass = bp_.documentClass();
1457 numberingModule->tocTW->setUpdatesEnabled(false);
1458 numberingModule->tocTW->clear();
1460 int const depth = numberingModule->depthSL->value();
1461 int const toc = numberingModule->tocSL->value();
1462 QString const no = qt_("No");
1463 QString const yes = qt_("Yes");
1464 QTreeWidgetItem * item = 0;
1466 DocumentClass::const_iterator lit = tclass.begin();
1467 DocumentClass::const_iterator len = tclass.end();
1468 for (; lit != len; ++lit) {
1469 int const toclevel = lit->toclevel;
1470 if (toclevel != Layout::NOT_IN_TOC && lit->labeltype == LABEL_COUNTER) {
1471 item = new QTreeWidgetItem(numberingModule->tocTW);
1472 item->setText(0, toqstr(translateIfPossible(lit->name())));
1473 item->setText(1, (toclevel <= depth) ? yes : no);
1474 item->setText(2, (toclevel <= toc) ? yes : no);
1478 numberingModule->tocTW->setUpdatesEnabled(true);
1479 numberingModule->tocTW->update();
1483 void GuiDocument::apply(BufferParams & params)
1486 preambleModule->apply(params);
1489 params.setCiteEngine(ENGINE_BASIC);
1491 if (biblioModule->citeNatbibRB->isChecked()) {
1492 bool const use_numerical_citations =
1493 biblioModule->citeStyleCO->currentIndex();
1494 if (use_numerical_citations)
1495 params.setCiteEngine(ENGINE_NATBIB_NUMERICAL);
1497 params.setCiteEngine(ENGINE_NATBIB_AUTHORYEAR);
1499 } else if (biblioModule->citeJurabibRB->isChecked())
1500 params.setCiteEngine(ENGINE_JURABIB);
1502 params.use_bibtopic =
1503 biblioModule->bibtopicCB->isChecked();
1505 // language & quotes
1506 if (langModule->defaultencodingRB->isChecked()) {
1507 params.inputenc = "auto";
1509 int i = langModule->encodingCO->currentIndex();
1511 params.inputenc = "default";
1513 QString const enc_gui =
1514 langModule->encodingCO->currentText();
1515 Encodings::const_iterator it = encodings.begin();
1516 Encodings::const_iterator const end = encodings.end();
1518 for (; it != end; ++it) {
1519 if (qt_(it->guiName()) == enc_gui) {
1520 params.inputenc = it->latexName();
1526 // should not happen
1527 lyxerr << "GuiDocument::apply: Unknown encoding! Resetting to default" << endl;
1528 params.inputenc = "default";
1533 InsetQuotes::QuoteLanguage lga = InsetQuotes::EnglishQuotes;
1534 switch (langModule->quoteStyleCO->currentIndex()) {
1536 lga = InsetQuotes::EnglishQuotes;
1539 lga = InsetQuotes::SwedishQuotes;
1542 lga = InsetQuotes::GermanQuotes;
1545 lga = InsetQuotes::PolishQuotes;
1548 lga = InsetQuotes::FrenchQuotes;
1551 lga = InsetQuotes::DanishQuotes;
1554 params.quotes_language = lga;
1556 QString const lang = langModule->languageCO->itemData(
1557 langModule->languageCO->currentIndex()).toString();
1558 params.language = lyx::languages.getLanguage(fromqstr(lang));
1561 if (params.documentClass().hasTocLevels()) {
1562 params.tocdepth = numberingModule->tocSL->value();
1563 params.secnumdepth = numberingModule->depthSL->value();
1567 params.user_defined_bullet(0) = bulletsModule->bullet(0);
1568 params.user_defined_bullet(1) = bulletsModule->bullet(1);
1569 params.user_defined_bullet(2) = bulletsModule->bullet(2);
1570 params.user_defined_bullet(3) = bulletsModule->bullet(3);
1573 params.graphicsDriver =
1574 tex_graphics[latexModule->psdriverCO->currentIndex()];
1577 int idx = latexModule->classCO->currentIndex();
1579 string const classname = classes_model_.getIDString(idx);
1580 params.setBaseClass(classname);
1584 params.clearLayoutModules();
1585 int const srows = modules_sel_model_.rowCount();
1586 vector<string> selModList;
1587 for (int i = 0; i < srows; ++i)
1588 params.addLayoutModule(modules_sel_model_.getIDString(i));
1589 // update the list of removed modules
1590 params.clearRemovedModules();
1591 set<string> const & reqmods = params.baseClass()->defaultModules();
1592 set<string>::const_iterator rit = reqmods.begin();
1593 set<string>::const_iterator ren = reqmods.end();
1594 // check each of the required modules
1595 for (; rit != ren; rit++) {
1596 vector<string>::const_iterator mit = params.getModules().begin();
1597 vector<string>::const_iterator men = params.getModules().end();
1599 for (; mit != men; mit++) {
1606 // the module isn't present so must have been removed by the user
1607 params.addRemovedModule(*rit);
1611 if (mathsModule->amsautoCB->isChecked()) {
1612 params.use_amsmath = BufferParams::package_auto;
1614 if (mathsModule->amsCB->isChecked())
1615 params.use_amsmath = BufferParams::package_on;
1617 params.use_amsmath = BufferParams::package_off;
1620 if (mathsModule->esintautoCB->isChecked())
1621 params.use_esint = BufferParams::package_auto;
1623 if (mathsModule->esintCB->isChecked())
1624 params.use_esint = BufferParams::package_on;
1626 params.use_esint = BufferParams::package_off;
1629 if (pageLayoutModule->pagestyleCO->currentIndex() == 0)
1630 params.pagestyle = "default";
1632 QString style_gui = pageLayoutModule->pagestyleCO->currentText();
1633 for (size_t i = 0; i != pagestyles.size(); ++i)
1634 if (pagestyles[i].second == style_gui)
1635 params.pagestyle = pagestyles[i].first;
1638 switch (textLayoutModule->lspacingCO->currentIndex()) {
1640 params.spacing().set(Spacing::Single);
1643 params.spacing().set(Spacing::Onehalf);
1646 params.spacing().set(Spacing::Double);
1649 params.spacing().set(Spacing::Other,
1650 fromqstr(textLayoutModule->lspacingLE->text()));
1654 if (textLayoutModule->twoColumnCB->isChecked())
1659 // text should have passed validation
1660 params.listings_params =
1661 InsetListingsParams(fromqstr(textLayoutModule->listingsED->toPlainText())).params();
1663 if (textLayoutModule->indentRB->isChecked())
1664 params.paragraph_separation = BufferParams::ParagraphIndentSeparation;
1666 params.paragraph_separation = BufferParams::ParagraphSkipSeparation;
1668 switch (textLayoutModule->skipCO->currentIndex()) {
1670 params.setDefSkip(VSpace(VSpace::SMALLSKIP));
1673 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1676 params.setDefSkip(VSpace(VSpace::BIGSKIP));
1681 widgetsToLength(textLayoutModule->skipLE,
1682 textLayoutModule->skipLengthCO)
1684 params.setDefSkip(vs);
1688 // DocumentDefskipCB assures that this never happens
1689 // so Assert then !!! - jbl
1690 params.setDefSkip(VSpace(VSpace::MEDSKIP));
1695 fromqstr(latexModule->optionsLE->text());
1697 if (latexModule->childDocGB->isChecked())
1699 fromqstr(latexModule->childDocLE->text());
1701 params.master = string();
1703 params.float_placement = floatModule->get();
1707 tex_fonts_roman[fontModule->fontsRomanCO->currentIndex()];
1710 tex_fonts_sans[fontModule->fontsSansCO->currentIndex()];
1712 params.fontsTypewriter =
1713 tex_fonts_monospaced[fontModule->fontsTypewriterCO->currentIndex()];
1716 fromqstr(fontModule->cjkFontLE->text());
1718 params.fontsSansScale = fontModule->scaleSansSB->value();
1720 params.fontsTypewriterScale = fontModule->scaleTypewriterSB->value();
1722 params.fontsSC = fontModule->fontScCB->isChecked();
1724 params.fontsOSF = fontModule->fontOsfCB->isChecked();
1726 params.fontsDefaultFamily = GuiDocument::fontfamilies[
1727 fontModule->fontsDefaultCO->currentIndex()];
1729 if (fontModule->fontsizeCO->currentIndex() == 0)
1730 params.fontsize = "default";
1733 fromqstr(fontModule->fontsizeCO->currentText());
1736 params.papersize = PAPER_SIZE(
1737 pageLayoutModule->papersizeCO->currentIndex());
1739 // custom, A3, B3 and B4 paper sizes need geometry
1740 int psize = pageLayoutModule->papersizeCO->currentIndex();
1741 bool geom_papersize = (psize == 1 || psize == 5 || psize == 8 || psize == 9);
1743 params.paperwidth = widgetsToLength(pageLayoutModule->paperwidthLE,
1744 pageLayoutModule->paperwidthUnitCO);
1746 params.paperheight = widgetsToLength(pageLayoutModule->paperheightLE,
1747 pageLayoutModule->paperheightUnitCO);
1749 if (pageLayoutModule->facingPagesCB->isChecked())
1750 params.sides = TwoSides;
1752 params.sides = OneSide;
1754 if (pageLayoutModule->landscapeRB->isChecked())
1755 params.orientation = ORIENTATION_LANDSCAPE;
1757 params.orientation = ORIENTATION_PORTRAIT;
1760 params.use_geometry = !marginsModule->marginCB->isChecked()
1763 Ui::MarginsUi const * m = marginsModule;
1765 params.leftmargin = widgetsToLength(m->innerLE, m->innerUnit);
1766 params.topmargin = widgetsToLength(m->topLE, m->topUnit);
1767 params.rightmargin = widgetsToLength(m->outerLE, m->outerUnit);
1768 params.bottommargin = widgetsToLength(m->bottomLE, m->bottomUnit);
1769 params.headheight = widgetsToLength(m->headheightLE, m->headheightUnit);
1770 params.headsep = widgetsToLength(m->headsepLE, m->headsepUnit);
1771 params.footskip = widgetsToLength(m->footskipLE, m->footskipUnit);
1772 params.columnsep = widgetsToLength(m->columnsepLE, m->columnsepUnit);
1774 branchesModule->apply(params);
1777 PDFOptions & pdf = params.pdfoptions();
1778 pdf.use_hyperref = pdfSupportModule->use_hyperrefGB->isChecked();
1779 pdf.title = fromqstr(pdfSupportModule->titleLE->text());
1780 pdf.author = fromqstr(pdfSupportModule->authorLE->text());
1781 pdf.subject = fromqstr(pdfSupportModule->subjectLE->text());
1782 pdf.keywords = fromqstr(pdfSupportModule->keywordsLE->text());
1784 pdf.bookmarks = pdfSupportModule->bookmarksGB->isChecked();
1785 pdf.bookmarksnumbered = pdfSupportModule->bookmarksnumberedCB->isChecked();
1786 pdf.bookmarksopen = pdfSupportModule->bookmarksopenGB->isChecked();
1787 pdf.bookmarksopenlevel = pdfSupportModule->bookmarksopenlevelSB->value();
1789 pdf.breaklinks = pdfSupportModule->breaklinksCB->isChecked();
1790 pdf.pdfborder = pdfSupportModule->pdfborderCB->isChecked();
1791 pdf.pdfusetitle = pdfSupportModule->pdfusetitleCB->isChecked();
1792 pdf.colorlinks = pdfSupportModule->colorlinksCB->isChecked();
1793 pdf.backref = pdfSupportModule->backrefCB->isChecked();
1794 pdf.pagebackref = pdfSupportModule->pagebackrefCB->isChecked();
1795 if (pdfSupportModule->fullscreenCB->isChecked())
1796 pdf.pagemode = pdf.pagemode_fullscreen;
1798 pdf.pagemode.clear();
1799 pdf.quoted_options = pdf.quoted_options_check(
1800 fromqstr(pdfSupportModule->optionsLE->text()));
1804 void GuiDocument::paramsToDialog(BufferParams const & params)
1806 // set the default unit
1807 Length::UNIT defaultUnit = Length::CM;
1808 switch (lyxrc.default_papersize) {
1809 case PAPER_DEFAULT: break;
1811 case PAPER_USLETTER:
1813 case PAPER_USEXECUTIVE:
1814 defaultUnit = Length::IN;
1823 defaultUnit = Length::CM;
1830 preambleModule->update(params, id());
1833 biblioModule->citeDefaultRB->setChecked(
1834 params.citeEngine() == ENGINE_BASIC);
1836 biblioModule->citeNatbibRB->setChecked(
1837 params.citeEngine() == ENGINE_NATBIB_NUMERICAL ||
1838 params.citeEngine() == ENGINE_NATBIB_AUTHORYEAR);
1840 biblioModule->citeStyleCO->setCurrentIndex(
1841 params.citeEngine() == ENGINE_NATBIB_NUMERICAL);
1843 biblioModule->citeJurabibRB->setChecked(
1844 params.citeEngine() == ENGINE_JURABIB);
1846 biblioModule->bibtopicCB->setChecked(
1847 params.use_bibtopic);
1849 // language & quotes
1850 int const pos = langModule->languageCO->findData(toqstr(
1851 params.language->lang()));
1852 langModule->languageCO->setCurrentIndex(pos);
1854 langModule->quoteStyleCO->setCurrentIndex(
1855 params.quotes_language);
1857 bool default_enc = true;
1858 if (params.inputenc != "auto") {
1859 default_enc = false;
1860 if (params.inputenc == "default") {
1861 langModule->encodingCO->setCurrentIndex(0);
1864 Encodings::const_iterator it = encodings.begin();
1865 Encodings::const_iterator const end = encodings.end();
1866 for (; it != end; ++it) {
1867 if (it->latexName() == params.inputenc) {
1868 enc_gui = it->guiName();
1872 int const i = langModule->encodingCO->findText(
1875 langModule->encodingCO->setCurrentIndex(i);
1877 // unknown encoding. Set to default.
1881 langModule->defaultencodingRB->setChecked(default_enc);
1882 langModule->otherencodingRB->setChecked(!default_enc);
1885 int const min_toclevel = documentClass().min_toclevel();
1886 int const max_toclevel = documentClass().max_toclevel();
1887 if (documentClass().hasTocLevels()) {
1888 numberingModule->setEnabled(true);
1889 numberingModule->depthSL->setMinimum(min_toclevel - 1);
1890 numberingModule->depthSL->setMaximum(max_toclevel);
1891 numberingModule->depthSL->setValue(params.secnumdepth);
1892 numberingModule->tocSL->setMaximum(min_toclevel - 1);
1893 numberingModule->tocSL->setMaximum(max_toclevel);
1894 numberingModule->tocSL->setValue(params.tocdepth);
1897 numberingModule->setEnabled(false);
1898 numberingModule->tocTW->clear();
1902 bulletsModule->setBullet(0, params.user_defined_bullet(0));
1903 bulletsModule->setBullet(1, params.user_defined_bullet(1));
1904 bulletsModule->setBullet(2, params.user_defined_bullet(2));
1905 bulletsModule->setBullet(3, params.user_defined_bullet(3));
1906 bulletsModule->init();
1909 int nitem = findToken(tex_graphics, params.graphicsDriver);
1911 latexModule->psdriverCO->setCurrentIndex(nitem);
1914 mathsModule->amsCB->setChecked(
1915 params.use_amsmath == BufferParams::package_on);
1916 mathsModule->amsautoCB->setChecked(
1917 params.use_amsmath == BufferParams::package_auto);
1919 mathsModule->esintCB->setChecked(
1920 params.use_esint == BufferParams::package_on);
1921 mathsModule->esintautoCB->setChecked(
1922 params.use_esint == BufferParams::package_auto);
1924 switch (params.spacing().getSpace()) {
1925 case Spacing::Other: nitem = 3; break;
1926 case Spacing::Double: nitem = 2; break;
1927 case Spacing::Onehalf: nitem = 1; break;
1928 case Spacing::Default: case Spacing::Single: nitem = 0; break;
1932 string const & layoutID = params.baseClassID();
1933 setLayoutComboByIDString(layoutID);
1935 updatePagestyle(documentClass().opt_pagestyle(),
1938 textLayoutModule->lspacingCO->setCurrentIndex(nitem);
1939 if (params.spacing().getSpace() == Spacing::Other) {
1940 textLayoutModule->lspacingLE->setText(
1941 toqstr(params.spacing().getValueAsString()));
1945 if (params.paragraph_separation == BufferParams::ParagraphIndentSeparation)
1946 textLayoutModule->indentRB->setChecked(true);
1948 textLayoutModule->skipRB->setChecked(true);
1951 switch (params.getDefSkip().kind()) {
1952 case VSpace::SMALLSKIP:
1955 case VSpace::MEDSKIP:
1958 case VSpace::BIGSKIP:
1961 case VSpace::LENGTH:
1964 string const length = params.getDefSkip().asLyXCommand();
1965 lengthToWidgets(textLayoutModule->skipLE,
1966 textLayoutModule->skipLengthCO,
1967 length, defaultUnit);
1974 textLayoutModule->skipCO->setCurrentIndex(skip);
1977 textLayoutModule->twoColumnCB->setChecked(
1978 params.columns == 2);
1980 // break listings_params to multiple lines
1982 InsetListingsParams(params.listings_params).separatedParams();
1983 textLayoutModule->listingsED->setPlainText(toqstr(lstparams));
1985 if (!params.options.empty()) {
1986 latexModule->optionsLE->setText(
1987 toqstr(params.options));
1989 latexModule->optionsLE->setText(QString());
1992 if (!params.master.empty()) {
1993 latexModule->childDocGB->setChecked(true);
1994 latexModule->childDocLE->setText(
1995 toqstr(params.master));
1997 latexModule->childDocLE->setText(QString());
1998 latexModule->childDocGB->setChecked(false);
2001 floatModule->set(params.float_placement);
2004 updateFontsize(documentClass().opt_fontsize(),
2007 int n = findToken(tex_fonts_roman, params.fontsRoman);
2009 fontModule->fontsRomanCO->setCurrentIndex(n);
2013 n = findToken(tex_fonts_sans, params.fontsSans);
2015 fontModule->fontsSansCO->setCurrentIndex(n);
2019 n = findToken(tex_fonts_monospaced, params.fontsTypewriter);
2021 fontModule->fontsTypewriterCO->setCurrentIndex(n);
2025 if (!params.fontsCJK.empty())
2026 fontModule->cjkFontLE->setText(
2027 toqstr(params.fontsCJK));
2029 fontModule->cjkFontLE->setText(QString());
2031 fontModule->fontScCB->setChecked(params.fontsSC);
2032 fontModule->fontOsfCB->setChecked(params.fontsOSF);
2033 fontModule->scaleSansSB->setValue(params.fontsSansScale);
2034 fontModule->scaleTypewriterSB->setValue(params.fontsTypewriterScale);
2035 n = findToken(GuiDocument::fontfamilies, params.fontsDefaultFamily);
2037 fontModule->fontsDefaultCO->setCurrentIndex(n);
2040 int const psize = params.papersize;
2041 pageLayoutModule->papersizeCO->setCurrentIndex(psize);
2042 setCustomPapersize(psize);
2044 bool const landscape =
2045 params.orientation == ORIENTATION_LANDSCAPE;
2046 pageLayoutModule->landscapeRB->setChecked(landscape);
2047 pageLayoutModule->portraitRB->setChecked(!landscape);
2049 pageLayoutModule->facingPagesCB->setChecked(
2050 params.sides == TwoSides);
2053 lengthToWidgets(pageLayoutModule->paperwidthLE,
2054 pageLayoutModule->paperwidthUnitCO, params.paperwidth, defaultUnit);
2056 lengthToWidgets(pageLayoutModule->paperheightLE,
2057 pageLayoutModule->paperheightUnitCO, params.paperheight, defaultUnit);
2060 Ui::MarginsUi * m = marginsModule;
2062 setMargins(!params.use_geometry);
2064 lengthToWidgets(m->topLE, m->topUnit,
2065 params.topmargin, defaultUnit);
2067 lengthToWidgets(m->bottomLE, m->bottomUnit,
2068 params.bottommargin, defaultUnit);
2070 lengthToWidgets(m->innerLE, m->innerUnit,
2071 params.leftmargin, defaultUnit);
2073 lengthToWidgets(m->outerLE, m->outerUnit,
2074 params.rightmargin, defaultUnit);
2076 lengthToWidgets(m->headheightLE, m->headheightUnit,
2077 params.headheight, defaultUnit);
2079 lengthToWidgets(m->headsepLE, m->headsepUnit,
2080 params.headsep, defaultUnit);
2082 lengthToWidgets(m->footskipLE, m->footskipUnit,
2083 params.footskip, defaultUnit);
2085 lengthToWidgets(m->columnsepLE, m->columnsepUnit,
2086 params.columnsep, defaultUnit);
2088 branchesModule->update(params);
2091 PDFOptions const & pdf = params.pdfoptions();
2092 pdfSupportModule->use_hyperrefGB->setChecked(pdf.use_hyperref);
2093 pdfSupportModule->titleLE->setText(toqstr(pdf.title));
2094 pdfSupportModule->authorLE->setText(toqstr(pdf.author));
2095 pdfSupportModule->subjectLE->setText(toqstr(pdf.subject));
2096 pdfSupportModule->keywordsLE->setText(toqstr(pdf.keywords));
2098 pdfSupportModule->bookmarksGB->setChecked(pdf.bookmarks);
2099 pdfSupportModule->bookmarksnumberedCB->setChecked(pdf.bookmarksnumbered);
2100 pdfSupportModule->bookmarksopenGB->setChecked(pdf.bookmarksopen);
2102 pdfSupportModule->bookmarksopenlevelSB->setValue(pdf.bookmarksopenlevel);
2104 pdfSupportModule->breaklinksCB->setChecked(pdf.breaklinks);
2105 pdfSupportModule->pdfborderCB->setChecked(pdf.pdfborder);
2106 pdfSupportModule->pdfusetitleCB->setChecked(pdf.pdfusetitle);
2107 pdfSupportModule->colorlinksCB->setChecked(pdf.colorlinks);
2108 pdfSupportModule->backrefCB->setChecked(pdf.backref);
2109 pdfSupportModule->pagebackrefCB->setChecked(pdf.pagebackref);
2110 pdfSupportModule->fullscreenCB->setChecked
2111 (pdf.pagemode == pdf.pagemode_fullscreen);
2113 pdfSupportModule->optionsLE->setText(
2114 toqstr(pdf.quoted_options));
2118 void GuiDocument::applyView()
2124 void GuiDocument::saveDocDefault()
2126 // we have to apply the params first
2132 void GuiDocument::updateAvailableModules()
2134 modules_av_model_.clear();
2135 vector<modInfoStruct> const & modInfoList = getModuleInfo();
2136 int const mSize = modInfoList.size();
2137 for (int i = 0; i != mSize; ++i) {
2138 modInfoStruct const & modInfo = modInfoList[i];
2139 modules_av_model_.insertRow(i, modInfo.name, modInfo.id,
2140 modInfo.description);
2145 void GuiDocument::updateSelectedModules()
2147 // and selected ones, too
2148 modules_sel_model_.clear();
2149 vector<modInfoStruct> const selModList = getSelectedModules();
2150 int const sSize = selModList.size();
2151 for (int i = 0; i != sSize; ++i) {
2152 modInfoStruct const & modInfo = selModList[i];
2153 modules_sel_model_.insertRow(i, modInfo.name, modInfo.id,
2154 modInfo.description);
2159 void GuiDocument::updateContents()
2161 // Nothing to do here as the document settings is not cursor dependant.
2166 void GuiDocument::useClassDefaults()
2168 if (applyPB->isEnabled()) {
2169 int const ret = Alert::prompt(_("Unapplied changes"),
2170 _("Some changes in the dialog were not yet applied.\n"
2171 "If you do not apply now, they will be lost after this action."),
2172 1, 1, _("&Apply"), _("&Dismiss"));
2177 int idx = latexModule->classCO->currentIndex();
2178 string const classname = classes_model_.getIDString(idx);
2179 if (!bp_.setBaseClass(classname)) {
2180 Alert::error(_("Error"), _("Unable to set document class."));
2183 bp_.useClassDefaults();
2184 paramsToDialog(bp_);
2188 void GuiDocument::setLayoutComboByIDString(std::string const & idString)
2190 int idx = classes_model_.findIDString(idString);
2192 Alert::warning(_("Can't set layout!"),
2193 bformat(_("Unable to set layout for ID: %1$s"), from_utf8(idString)));
2195 latexModule->classCO->setCurrentIndex(idx);
2199 bool GuiDocument::isValid()
2201 return validateListingsParameters().isEmpty()
2202 && (textLayoutModule->skipCO->currentIndex() != 3
2203 || !textLayoutModule->skipLE->text().isEmpty());
2207 char const * const GuiDocument::fontfamilies[5] = {
2208 "default", "rmdefault", "sfdefault", "ttdefault", ""
2212 char const * GuiDocument::fontfamilies_gui[5] = {
2213 N_("Default"), N_("Roman"), N_("Sans Serif"), N_("Typewriter"), ""
2217 bool GuiDocument::initialiseParams(string const &)
2219 BufferView const * view = bufferview();
2221 bp_ = BufferParams();
2222 paramsToDialog(bp_);
2225 bp_ = view->buffer().params();
2227 updateAvailableModules();
2228 updateSelectedModules();
2229 //FIXME It'd be nice to make sure here that the selected
2230 //modules are consistent: That required modules are actually
2231 //selected, and that we don't have conflicts. If so, we could
2232 //at least pop up a warning.
2233 paramsToDialog(bp_);
2238 void GuiDocument::clearParams()
2240 bp_ = BufferParams();
2244 BufferId GuiDocument::id() const
2246 BufferView const * const view = bufferview();
2247 return view? &view->buffer() : 0;
2251 vector<GuiDocument::modInfoStruct> const & GuiDocument::getModuleInfo()
2253 return moduleNames_;
2257 vector<GuiDocument::modInfoStruct> const GuiDocument::getSelectedModules()
2259 vector<string> const & mods = params().getModules();
2260 vector<string>::const_iterator it = mods.begin();
2261 vector<string>::const_iterator end = mods.end();
2262 vector<modInfoStruct> mInfo;
2263 for (; it != end; ++it) {
2266 LyXModule * mod = moduleList[*it];
2268 m.name = qt_(mod->getName());
2270 m.name = toqstr(*it) + toqstr(" (") + qt_("Not Found") + toqstr(")");
2277 DocumentClass const & GuiDocument::documentClass() const
2279 return bp_.documentClass();
2283 static void dispatch_bufferparams(Dialog const & dialog,
2284 BufferParams const & bp, FuncCode lfun)
2287 ss << "\\begin_header\n";
2289 ss << "\\end_header\n";
2290 dialog.dispatch(FuncRequest(lfun, ss.str()));
2294 void GuiDocument::dispatchParams()
2296 // This must come first so that a language change is correctly noticed
2299 // Apply the BufferParams. Note that this will set the base class
2300 // and then update the buffer's layout.
2301 dispatch_bufferparams(*this, params(), LFUN_BUFFER_PARAMS_APPLY);
2303 if (!params().master.empty()) {
2304 FileName const master_file = support::makeAbsPath(params().master,
2305 support::onlyPath(buffer().absFileName()));
2306 if (isLyXFilename(master_file.absFilename())) {
2307 Buffer * master = checkAndLoadLyXFile(master_file);
2308 const_cast<Buffer &>(buffer()).setParent(master);
2312 // Generate the colours requested by each new branch.
2313 BranchList & branchlist = params().branchlist();
2314 if (!branchlist.empty()) {
2315 BranchList::const_iterator it = branchlist.begin();
2316 BranchList::const_iterator const end = branchlist.end();
2317 for (; it != end; ++it) {
2318 docstring const & current_branch = it->branch();
2319 Branch const * branch = branchlist.find(current_branch);
2320 string const x11hexname = X11hexname(branch->color());
2321 // display the new color
2322 docstring const str = current_branch + ' ' + from_ascii(x11hexname);
2323 dispatch(FuncRequest(LFUN_SET_COLOR, str));
2326 // Open insets of selected branches, close deselected ones
2327 dispatch(FuncRequest(LFUN_ALL_INSETS_TOGGLE,
2330 // FIXME: If we used an LFUN, we would not need those two lines:
2331 BufferView * bv = const_cast<BufferView *>(bufferview());
2332 bv->processUpdateFlags(Update::Force | Update::FitCursor);
2336 void GuiDocument::setLanguage() const
2338 Language const * const newL = bp_.language;
2339 if (buffer().params().language == newL)
2342 string const & lang_name = newL->lang();
2343 dispatch(FuncRequest(LFUN_BUFFER_LANGUAGE, lang_name));
2347 void GuiDocument::saveAsDefault() const
2349 dispatch_bufferparams(*this, params(), LFUN_BUFFER_SAVE_AS_DEFAULT);
2353 bool GuiDocument::isFontAvailable(string const & font) const
2355 if (font == "default" || font == "cmr"
2356 || font == "cmss" || font == "cmtt")
2357 // these are standard
2359 if (font == "lmodern" || font == "lmss" || font == "lmtt")
2360 return LaTeXFeatures::isAvailable("lmodern");
2361 if (font == "times" || font == "palatino"
2362 || font == "helvet" || font == "courier")
2363 return LaTeXFeatures::isAvailable("psnfss");
2364 if (font == "cmbr" || font == "cmtl")
2365 return LaTeXFeatures::isAvailable("cmbright");
2366 if (font == "utopia")
2367 return LaTeXFeatures::isAvailable("utopia")
2368 || LaTeXFeatures::isAvailable("fourier");
2369 if (font == "beraserif" || font == "berasans"
2370 || font == "beramono")
2371 return LaTeXFeatures::isAvailable("bera");
2372 return LaTeXFeatures::isAvailable(font);
2376 bool GuiDocument::providesOSF(string const & font) const
2379 return isFontAvailable("eco");
2380 if (font == "palatino")
2381 return isFontAvailable("mathpazo");
2386 bool GuiDocument::providesSC(string const & font) const
2388 if (font == "palatino")
2389 return isFontAvailable("mathpazo");
2390 if (font == "utopia")
2391 return isFontAvailable("fourier");
2396 bool GuiDocument::providesScale(string const & font) const
2398 return font == "helvet" || font == "luximono"
2399 || font == "berasans" || font == "beramono";
2403 void GuiDocument::loadModuleInfo()
2405 moduleNames_.clear();
2406 LyXModuleList::const_iterator it = moduleList.begin();
2407 LyXModuleList::const_iterator end = moduleList.end();
2408 for (; it != end; ++it) {
2411 m.name = qt_(it->getName());
2412 // this is supposed to give us the first sentence of the description
2413 QString desc = qt_(it->getDescription());
2414 int const pos = desc.indexOf(".");
2416 desc.truncate(pos + 1);
2417 m.description = desc;
2418 moduleNames_.push_back(m);
2423 Dialog * createGuiDocument(GuiView & lv) { return new GuiDocument(lv); }
2426 } // namespace frontend
2429 #include "GuiDocument_moc.cpp"