/**
* \file QParagraph.C
- * Copyright 2001 LyX Team
- * see the file COPYING
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
*
- * \author John Levon, moz@compsoc.man.ac.uk
+ * \author Edwin Leuven
+ *
+ * Full author contact details are available in file CREDITS
*/
#include <config.h>
-#include "QParagraphDialog.h"
+#ifdef __GNUG__
+#pragma implementation
+#endif
+#include "ControlParagraph.h"
#include "QParagraph.h"
-#include "Dialogs.h"
-#include "Liason.h"
-#include "gettext.h"
-#include "buffer.h"
-#include "QtLyXView.h"
-#include "lyxtext.h"
-#include "debug.h"
-#include "BufferView.h"
+#include "QParagraphDialog.h"
+#include "Qt2BC.h"
#include "ParagraphParameters.h"
+#include "lyxrc.h" // to set the deafult length values
+#include "gettext.h"
+#include "layout.h" // LyXAlignment
+#include "helper_funcs.h"
+#include "lyxgluelength.h"
+#include "vspace.h"
-using SigC::slot;
-using Liason::setMinibuffer;
-using std::endl;
+#include "support/lstrings.h"
+#include "support/LAssert.h"
+#include <qcombobox.h>
+#include <qlineedit.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <qtabwidget.h>
+#include <qbuttongroup.h>
-QParagraph::QParagraph(LyXView *v, Dialogs *d)
- : dialog_(0), lv_(v), d_(d), h_(0)
-{
- d->showParagraph.connect(slot(this, &QParagraph::show));
-}
+#include <functional>
+using std::vector;
+using std::bind2nd;
+using std::remove_if;
+
+typedef Qt2CB<ControlParagraph, Qt2DB<QParagraphDialog> > base_class;
-QParagraph::~QParagraph()
-{
- delete dialog_;
-}
+QParagraph::QParagraph()
+ : base_class(_("Paragraph Layout"))
+{}
-void QParagraph::update(bool switched)
+
+void QParagraph::build_dialog()
{
- if (switched) {
- hide();
- return;
+ // the tabbed folder
+ dialog_.reset(new QParagraphDialog(this));
+
+ // Create the contents of the unit choices
+ // Don't include the "%" terms...
+ units_ = getLatexUnits();
+ vector<string>::iterator del =
+ remove_if(units_.begin(), units_.end(),
+ bind2nd(contains_functor(), "%"));
+ units_.erase(del, units_.end());
+
+ for (vector<string>::const_iterator it = units_.begin();
+ it != units_.end(); ++it) {
+ dialog_->unitAbove->insertItem(it->c_str());
+ dialog_->unitBelow->insertItem(it->c_str());
}
- if (!lv_->view()->available())
- return;
+ // Manage the ok, apply, restore and cancel/close buttons
+ bc().setOK(dialog_->okPB);
+ bc().setApply(dialog_->applyPB);
+ bc().setCancel(dialog_->closePB);
+ bc().setRestore(dialog_->restorePB);
+ bc().addReadOnly(dialog_->paragraphTab);
+}
- Buffer * buf = lv_->view()->buffer();
- if (readonly!=buf->isReadonly()) {
- readonly = buf->isReadonly();
- dialog_->setReadOnly(readonly);
- }
+namespace {
- LyXText * text(lv_->view()->getLyXText());
- Paragraph * par = text->cursor.par();
-
- int align = par->getAlign();
-
- if (align==LYX_ALIGN_LAYOUT)
- align = textclasslist.Style(buf->params.textclass, par->getLayout()).align;
-
- ParagraphParameters * params = &(par->params());
-
- if (params->spaceTop().kind() == VSpace::LENGTH) {
- LyXGlueLength above = params->spaceTop().length();
- lyxerr[Debug::GUI] << "Reading above space : \"" << params->spaceTop().length().asString() << "\"" << endl;
- dialog_->setAboveLength(above.value(), above.plusValue(), above.minusValue(),
- above.unit(), above.plusUnit(), above.minusUnit());
- } else
- dialog_->setAboveLength(0.0, 0.0, 0.0, LyXLength::UNIT_NONE, LyXLength::UNIT_NONE, LyXLength::UNIT_NONE);
-
- if (params->spaceBottom().kind() == VSpace::LENGTH) {
- LyXGlueLength below = params->spaceBottom().length();
- lyxerr[Debug::GUI] << "Reading below space : \"" << params->spaceBottom().length().asString() << "\"" << endl;
- dialog_->setBelowLength(below.value(), below.plusValue(), below.minusValue(),
- below.unit(), below.plusUnit(), below.minusUnit());
- } else
- dialog_->setBelowLength(0.0, 0.0, 0.0, LyXLength::UNIT_NONE, LyXLength::UNIT_NONE, LyXLength::UNIT_NONE);
-
- dialog_->setLabelWidth(text->cursor.par()->getLabelWidthString().c_str());
- dialog_->setAlign(align);
- dialog_->setChecks(params->lineTop(), params->lineBottom(),
- params->pagebreakTop(), params->pagebreakBottom(), params->noindent());
- dialog_->setSpace(params->spaceTop().kind(), params->spaceBottom().kind(),
- params->spaceTop().keep(), params->spaceBottom().keep());
-
- // now the extras page
-
- LyXLength extrawidth;
- float val = 0.0;
- LyXLength::UNIT unit = LyXLength::CM;
- params = &(par->params());
- if (isValidLength(params->pextraWidth(), &extrawidth)) {
- lyxerr[Debug::GUI] << "Reading extra width \"" << extrawidth.asString() << "\"" << endl;
- val = extrawidth.value();
- unit = extrawidth.unit();
+VSpace setVSpaceFromWidgets(int spacing,
+ string value,
+ string unit,
+ bool keep)
+{
+ VSpace space;
+
+ switch (spacing) {
+ case 0:
+ space = VSpace(VSpace::NONE);
+ break;
+ case 1:
+ space = VSpace(VSpace::DEFSKIP);
+ break;
+ case 2:
+ space = VSpace(VSpace::SMALLSKIP);
+ break;
+ case 3:
+ space = VSpace(VSpace::MEDSKIP);
+ break;
+ case 4:
+ space = VSpace(VSpace::BIGSKIP);
+ break;
+ case 5:
+ space = VSpace(VSpace::VFILL);
+ break;
+ case 6:
+ string s;
+ string const length = trim(value);
+ if (isValidGlueLength(length)) {
+ s = length;
+ } else if (!length.empty()){
+ string u = trim(unit);
+ u = subst(u, "%%", "%");
+ s = length + u;
+ }
+ space = VSpace(LyXGlueLength(s));
+ break;
}
- lyxerr[Debug::GUI] << "Reading widthp \"" << params->pextraWidthp() << "\"" << endl;
+ space.setKeep(keep);
- dialog_->setExtra(val, unit, params->pextraWidthp(),
- params->pextraAlignment(),
- params->pextraHfill(),
- params->pextraStartMinipage(),
- static_cast<Paragraph::PEXTRA_TYPE>(params->pextraType()));
+ return space;
}
+} // namespace anon
+
void QParagraph::apply()
{
- if (readonly)
- return;
-
- VSpace spaceabove;
- VSpace spacebelow;
-
- if (dialog_->getSpaceAboveKind()==VSpace::LENGTH)
- spaceabove = VSpace(dialog_->getAboveLength());
- else
- spaceabove = VSpace(dialog_->getSpaceAboveKind());
-
- if (dialog_->getSpaceBelowKind()==VSpace::LENGTH)
- spacebelow = VSpace(dialog_->getBelowLength());
- else
- spacebelow = VSpace(dialog_->getSpaceBelowKind());
-
- spaceabove.setKeep(dialog_->getAboveKeep());
- spacebelow.setKeep(dialog_->getBelowKeep());
-
- lyxerr[Debug::GUI] << "Setting above space \"" << LyXGlueLength(spaceabove.length().asString()).asString() << "\"" << endl;
- lyxerr[Debug::GUI] << "Setting below space \"" << LyXGlueLength(spacebelow.length().asString()).asString() << "\"" << endl;
-
- LyXText * text(lv_->view()->getLyXText());
- text->setParagraph(lv_->view(),
- dialog_->getLineAbove(), dialog_->getLineBelow(),
- dialog_->getPagebreakAbove(), dialog_->getPagebreakBelow(),
- spaceabove, spacebelow, Spacing(), dialog_->getAlign(),
- dialog_->getLabelWidth(), dialog_->getNoIndent());
-
- // extra stuff
-
- string width("");
- string widthp("");
-
- LyXLength extrawidth(dialog_->getExtraWidth());
- if (extrawidth.unit()==LyXLength::UNIT_NONE) {
- widthp = dialog_->getExtraWidthPercent();
- } else
- width = extrawidth.asString();
+ ParagraphParameters & params = controller().params();
+
+ // SPACING ABOVE
+ // If a vspace kind is "Length" but there's no text in
+ // the input field, reset the kind to "None".
+ if (dialog_->spacingAbove->currentItem() == 5
+ && dialog_->valueAbove->text().isEmpty())
+ dialog_->spacingAbove->setCurrentItem(0);
+
+ VSpace const space_top =
+ setVSpaceFromWidgets(dialog_->spacingAbove->currentItem(),
+ dialog_->valueAbove->text().latin1(),
+ dialog_->unitAbove->currentText().latin1(),
+ dialog_->keepAbove->isChecked());
+
+ params.spaceTop(space_top);
+
+ // SPACING BELOW
+ if (dialog_->spacingBelow->currentItem() == 5
+ && dialog_->valueBelow->text().isEmpty())
+ dialog_->spacingBelow->setCurrentItem(0);
+
+ VSpace const space_bottom =
+ setVSpaceFromWidgets(dialog_->spacingBelow->currentItem(),
+ dialog_->valueBelow->text().latin1(),
+ dialog_->unitBelow->currentText().latin1(),
+ dialog_->keepBelow->isChecked());
+
+ params.spaceBottom(space_bottom);
+
+ // alignment
+ LyXAlignment align;
+ switch (dialog_->align->currentItem()) {
+ case 0:
+ align = LYX_ALIGN_BLOCK;
+ break;
+ case 1:
+ align = LYX_ALIGN_LEFT;
+ break;
+ case 2:
+ align = LYX_ALIGN_RIGHT;
+ break;
+ case 3:
+ align = LYX_ALIGN_CENTER;
+ break;
+ default:
+ align = LYX_ALIGN_BLOCK;
+ }
+ params.align(align);
+
+ // get spacing
+ Spacing::Space linespacing = Spacing::Default;
+ string other;
+ switch (dialog_->linespacing->currentItem()) {
+ case 0:
+ linespacing = Spacing::Default;
+ break;
+ case 1:
+ linespacing = Spacing::Single;
+ break;
+ case 2:
+ linespacing = Spacing::Onehalf;
+ break;
+ case 3:
+ linespacing = Spacing::Double;
+ break;
+ case 4:
+ linespacing = Spacing::Other;
+ other = dialog_->linespacingValue->text().latin1();
+ break;
+ }
- lyxerr[Debug::GUI] << "Setting extrawidth \"" << width << "\"" << endl;
- lyxerr[Debug::GUI] << "Setting percent extrawidth \"" << widthp << "\"" << endl;
+ Spacing const spacing(linespacing, other);
+ params.spacing(spacing);
- lv_->view()->update(text,
- BufferView::SELECT |
- BufferView::FITCUR |
- BufferView::CHANGE);
+ // lines and pagebreaks
+ params.lineTop(dialog_->lineAbove->isChecked());
+ params.lineBottom(dialog_->lineBelow->isChecked());
+ params.pagebreakTop(dialog_->pagebreakAbove->isChecked());
+ params.pagebreakBottom(dialog_->pagebreakBelow->isChecked());
+ // label width
+ params.labelWidthString(dialog_->labelWidth->text().latin1());
+ // indendation
+ params.noindent(dialog_->noindent->isChecked());
- lv_->buffer()->markDirty();
- setMinibuffer(lv_, _("Paragraph layout set"));
}
-void QParagraph::show()
-{
- if (!dialog_)
- dialog_ = new QParagraphDialog(this, 0,
- _("LyX: Paragraph Settings"),
- false);
-
- if (!dialog_->isVisible())
- h_ = d_->hideBufferDependent
- .connect(slot(this, &QParagraph::hide));
-
- dialog_->raise();
- dialog_->setActiveWindow();
- update();
+namespace {
- dialog_->show();
-}
-
-
-void QParagraph::close()
+void setWidgetsFromVSpace(VSpace const & space,
+ QComboBox * spacing,
+ QLineEdit * value,
+ QComboBox * unit,
+ QCheckBox * keep, vector<string> units_)
{
- h_.disconnect();
+ value->setText("");
+ value->setEnabled(false);
+ unit->setEnabled(false);
+
+ int item = 0;
+ switch (space.kind()) {
+ case VSpace::NONE:
+ item = 0;
+ break;
+ case VSpace::DEFSKIP:
+ item = 1;
+ break;
+ case VSpace::SMALLSKIP:
+ item = 2;
+ break;
+ case VSpace::MEDSKIP:
+ item = 3;
+ break;
+ case VSpace::BIGSKIP:
+ item = 4;
+ break;
+ case VSpace::VFILL:
+ item = 5;
+ break;
+ case VSpace::LENGTH:
+ item = 6;
+ value->setEnabled(true);
+ unit->setEnabled(true);
+ string length = space.length().asString();
+ string const default_unit =
+ (lyxrc.default_papersize > 3) ? "cm" : "in";
+ string supplied_unit = default_unit;
+ LyXLength len(length);
+ if ((isValidLength(length)
+ || isStrDbl(length)) && !len.zero()) {
+ ostringstream buffer;
+ buffer << len.value();
+ length = buffer.str();
+ supplied_unit = subst(stringFromUnit(len.unit()),
+ "%", "%%");
+ }
+
+ int unit_item = 0;
+ int i = 0;
+ for (vector<string>::const_iterator it = units_.begin();
+ it != units_.end(); ++it) {
+ if (*it == default_unit) {
+ unit_item = i;
+ }
+ if (*it == supplied_unit) {
+ unit_item = i;
+ break;
+ }
+ i += 1;
+ }
+ value->setText(length.c_str());
+ unit->setCurrentItem(unit_item);
+ break;
+ }
+ spacing->setCurrentItem(item);
+ keep->setChecked(space.keep());
}
+} // namespace anon
+
-void QParagraph::hide()
+void QParagraph::update_contents()
{
- dialog_->hide();
- close();
+ ParagraphParameters const & params = controller().params();
+
+ // label width
+ string const & labelwidth = params.labelWidthString();
+ dialog_->labelWidth->setText(labelwidth.c_str());
+ dialog_->labelwidthGB->setEnabled(
+ labelwidth != _("Senseless with this layout!"));
+
+ // alignment
+ int i;
+ switch (params.align()) {
+ case LYX_ALIGN_LEFT:
+ i = 1;
+ break;
+ case LYX_ALIGN_RIGHT:
+ i = 2;
+ break;
+ case LYX_ALIGN_CENTER:
+ i = 3;
+ break;
+ default:
+ i = 0;
+ break;
+ }
+ dialog_->align->setCurrentItem(i);
+
+
+ //LyXAlignment alignpos = controller().alignPossible();
+
+ // no inset-text-owned paragraph may have pagebreaks
+ bool ininset = controller().inInset();
+ dialog_->pagebreakAbove->setEnabled(!ininset);
+ dialog_->pagebreakBelow->setEnabled(!ininset);
+
+ // lines, pagebreaks and indent
+ dialog_->lineAbove->setChecked(params.lineTop());
+ dialog_->lineBelow->setChecked(params.lineBottom());
+ dialog_->pagebreakAbove->setChecked(params.pagebreakTop());
+ dialog_->pagebreakBelow->setChecked(params.pagebreakBottom());
+ dialog_->noindent->setChecked(params.noindent());
+
+ // linespacing
+ int linespacing;
+ Spacing const & space = params.spacing();
+ switch (space.getSpace()) {
+ case Spacing::Single:
+ linespacing = 1;
+ break;
+ case Spacing::Onehalf:
+ linespacing = 2;
+ break;
+ case Spacing::Double:
+ linespacing = 3;
+ break;
+ case Spacing::Other:
+ linespacing = 4;
+ break;
+ default:
+ linespacing = 0;
+ break;
+ }
+ dialog_->linespacing->setCurrentItem(linespacing);
+ if (space.getSpace() == Spacing::Other) {
+ string const sp = tostr(space.getValue());
+ dialog_->linespacingValue->setText(sp.c_str());
+ dialog_->linespacingValue->setEnabled(true);
+ } else {
+ dialog_->linespacingValue->setText("");
+ dialog_->linespacingValue->setEnabled(false);
+ }
+
+ // vspace top
+ setWidgetsFromVSpace(params.spaceTop(),
+ dialog_->spacingAbove,
+ dialog_->valueAbove,
+ dialog_->unitAbove,
+ dialog_->keepAbove,units_);
+
+ // vspace bottom
+ setWidgetsFromVSpace(params.spaceBottom(),
+ dialog_->spacingBelow,
+ dialog_->valueBelow,
+ dialog_->unitBelow,
+ dialog_->keepBelow,units_);
+
+ // no indent
+ dialog_->noindent->setChecked(params.noindent());
}