9#include <QAbstractTextDocumentLayout>
11#include <QApplication>
20#include <QTextDocumentFragment>
23#include <QtGui/private/qtextdocument_p.h>
30 setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding));
32 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
33 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
35 QAbstractTextDocumentLayout *docLayout = document()->documentLayout();
36 connect(docLayout, &QAbstractTextDocumentLayout::documentSizeChanged,
37 this, &ExpandingTextEdit::updateHeight);
38 connect(
this, &QTextEdit::cursorPositionChanged,
39 this, &ExpandingTextEdit::reallyEnsureCursorVisible);
41 m_minimumHeight = qRound(docLayout->documentSize().height()) + frameWidth() * 2;
46 m_minimumHeight = qRound(documentSize.height()) + frameWidth() * 2;
52 return QSize(100, m_minimumHeight);
57 return QSize(100, m_minimumHeight);
62 QObject *ancestor = parent();
64 QScrollArea *scrollArea = qobject_cast<QScrollArea*>(ancestor);
66 (scrollArea->verticalScrollBarPolicy() != Qt::ScrollBarAlwaysOff &&
67 scrollArea->horizontalScrollBarPolicy() != Qt::ScrollBarAlwaysOff)) {
68 const QRect &r = cursorRect();
69 const QPoint &c = mapTo(scrollArea->widget(), r.center());
70 scrollArea->ensureVisible(c.x(), c.y());
73 ancestor = ancestor->parent();
80 setLineWrapMode(QTextEdit::WidgetWidth);
81 setAcceptRichText(
false);
84 QPalette p = palette();
85 p.setColor(QPalette::Disabled, QPalette::Base, p.color(QPalette::Active, QPalette::Base));
90 m_highlighter =
new MessageHighlighter(
this);
95 emit editorDestroyed();
101 static int framed = frameStyle();
102 static Qt::FocusPolicy defaultFocus = focusPolicy();
105 setFrameStyle(framed);
106 setFocusPolicy(defaultFocus);
108 setFrameStyle(QFrame::NoFrame | QFrame::Plain);
109 setFocusPolicy(Qt::NoFocus);
112 setReadOnly(!editable);
119 bool oldBlockState = blockSignals(
true);
120 document()->setUndoRedoEnabled(
false);
121 ExpandingTextEdit::setPlainText(text);
123 m_highlighter->rehighlight();
124 document()->setUndoRedoEnabled(
true);
125 blockSignals(oldBlockState);
127 ExpandingTextEdit::setPlainText(text);
133 QTextOption option = document()->defaultTextOption();
135 option.setFlags(option.flags()
136 | QTextOption::ShowLineAndParagraphSeparators
137 | QTextOption::ShowTabsAndSpaces);
139 option.setFlags(option.flags()
140 & ~QTextOption::ShowLineAndParagraphSeparators
141 & ~QTextOption::ShowTabsAndSpaces);
143 document()->setDefaultTextOption(option);
146FormWidget::FormWidget(
const QString &label,
bool isEditable, QWidget *parent)
148 m_hideWhenEmpty(
false)
150 QVBoxLayout *layout =
new QVBoxLayout;
151 layout->setContentsMargins(QMargins());
153 m_label =
new QLabel(
this);
156 m_label->setFont(fnt);
157 m_label->setText(label);
158 layout->addWidget(m_label);
160 m_editor =
new FormatTextEdit(
this);
163 layout->addWidget(m_editor);
167 connect(m_editor, &QTextEdit::textChanged,
168 this, &FormWidget::slotTextChanged);
169 connect(m_editor, &QTextEdit::selectionChanged,
170 this, &FormWidget::slotSelectionChanged);
171 connect(m_editor, &QTextEdit::cursorPositionChanged,
172 this, &FormWidget::cursorPositionChanged);
177 emit textChanged(m_editor);
182 emit selectionChanged(m_editor);
187 m_editor->setPlainText(text, userAction);
189 setHidden(text.isEmpty());
195 m_editor->setReadOnly(!enable);
196 m_label->setEnabled(enable);
207 QBoxLayout *box =
new QVBoxLayout;
208 box->setContentsMargins(QMargins());
210 box->addWidget(wrapee, 0, Qt::AlignBottom);
212 relator->installEventFilter(
this);
218 if (event->type() == QEvent::Resize) {
219 QWidget *relator =
static_cast<QWidget *>(object);
220 setFixedHeight(relator->height());
228 m_hideWhenEmpty(
false),
229 m_multiEnabled(
false),
230 m_plusIcon(QIcon(QLatin1String(
":/images/plus.png"))),
231 m_minusIcon(QIcon(QLatin1String(
":/images/minus.png")))
233 m_label =
new QLabel(
this);
236 m_label->setFont(fnt);
237 m_label->setText(label);
239 m_plusButtons.append(
240 new ButtonWrapper(makeButton(m_plusIcon, &FormMultiWidget::plusButtonClicked), 0));
245 QAbstractButton *btn =
new QToolButton(
this);
247 btn->setFixedSize(icon.availableSizes().first() );
248 btn->setFocusPolicy(Qt::NoFocus);
255 m_editors.insert(idx, editor);
257 m_minusButtons.insert(idx, makeButton(m_minusIcon, &FormMultiWidget::minusButtonClicked));
258 m_plusButtons.insert(idx + 1,
259 new ButtonWrapper(makeButton(m_plusIcon, &FormMultiWidget::plusButtonClicked), editor));
261 connect(editor, &QTextEdit::textChanged,
262 this, &FormMultiWidget::slotTextChanged);
263 connect(editor, &QTextEdit::selectionChanged,
264 this, &FormMultiWidget::slotSelectionChanged);
265 connect(editor, &QTextEdit::cursorPositionChanged,
266 this, &FormMultiWidget::cursorPositionChanged);
267 editor->installEventFilter(
this);
269 emit editorCreated(editor);
275 while (m_editors.at(i) != watched)
276 if (++i >= m_editors.size())
278 if (event->type() == QEvent::FocusOut) {
279 m_minusButtons.at(i)->setToolTip(QString());
280 m_plusButtons.at(i)->setToolTip(QString());
281 m_plusButtons.at(i + 1)->setToolTip(QString());
282 }
else if (event->type() == QEvent::FocusIn) {
283 m_minusButtons.at(i)->setToolTip( tr(
"Alt+Delete"));
284 m_plusButtons.at(i)->setToolTip( tr(
"Shift+Alt+Insert"));
285 m_plusButtons.at(i + 1)->setToolTip( tr(
"Alt+Insert"));
286 }
else if (event->type() == QEvent::KeyPress) {
287 QKeyEvent *ke =
static_cast<QKeyEvent *>(event);
288 if (ke->modifiers() & Qt::AltModifier) {
289 if (ke->key() == Qt::Key_Delete) {
292 }
else if (ke->key() == Qt::Key_Insert) {
293 if (!(ke->modifiers() & Qt::ShiftModifier))
307 QGridLayout *layout =
new QGridLayout;
308 layout->setContentsMargins(QMargins());
311 bool variants = m_multiEnabled && m_label->isEnabled();
313 layout->addWidget(m_label, 0, 0, 1, variants ? 2 : 1);
316 QVBoxLayout *layoutForPlusButtons =
new QVBoxLayout;
317 layoutForPlusButtons->setContentsMargins(QMargins());
318 for (
int i = 0; i < m_plusButtons.size(); ++i)
319 layoutForPlusButtons->addWidget(m_plusButtons.at(i), Qt::AlignTop);
320 layout->addLayout(layoutForPlusButtons, 1, 0, Qt::AlignTop);
322 const int minimumRowHeight = m_plusButtons.at(0)->sizeHint().height() / 2.0;
323 QGridLayout *layoutForLabels =
new QGridLayout;
324 layoutForLabels->setContentsMargins(QMargins());
325 layoutForLabels->setRowMinimumHeight(0, minimumRowHeight);
326 for (
int j = 0; j < m_editors.size(); ++j) {
327 layoutForLabels->addWidget(m_editors.at(j), 1 + j, 0, Qt::AlignVCenter);
328 layoutForLabels->addWidget(m_minusButtons.at(j), 1 + j, 1, Qt::AlignVCenter);
330 layoutForLabels->setRowMinimumHeight(m_editors.size() + 1, minimumRowHeight);
331 layout->addLayout(layoutForLabels, 1, 1, Qt::AlignTop);
333 for (
int k = 0; k < m_editors.size(); ++k)
334 layout->addWidget(m_editors.at(k), 1 + k, 0, Qt::AlignVCenter);
337 for (
int i = 0; i < m_plusButtons.size(); ++i)
338 m_plusButtons.at(i)->setVisible(variants);
339 for (
int j = 0; j < m_minusButtons.size(); ++j)
340 m_minusButtons.at(j)->setVisible(variants);
347 emit textChanged(
static_cast<QTextEdit *>(sender()));
352 emit selectionChanged(
static_cast<QTextEdit *>(sender()));
357 QStringList texts = text.split(QChar(Translator::BinaryVariantSeparator), Qt::KeepEmptyParts);
359 while (m_editors.size() > texts.size()) {
360 delete m_minusButtons.takeLast();
361 delete m_plusButtons.takeLast();
362 delete m_editors.takeLast();
364 while (m_editors.size() < texts.size())
365 addEditor(m_editors.size());
368 for (
int i = 0; i < texts.size(); ++i)
370 m_editors.at(i)->setPlainText(texts.at(i), userAction);
373 setHidden(text.isEmpty());
381 QChar *uc = txt.data();
382 QChar *e = uc + txt.size();
384 for (; uc != e; ++uc) {
385 switch (uc->unicode()) {
388 case QChar::ParagraphSeparator:
389 case QChar::LineSeparator:
390 *uc = QLatin1Char(
'\n');
400 for (
int i = 0; i < m_editors.size(); ++i) {
402 ret += QChar(Translator::BinaryVariantSeparator);
403 ret += toPlainText(m_editors.at(i)->document()->toRawText());
411 for (
int i = 0; i < m_editors.size(); ++i)
412 m_editors.at(i)->setReadOnly(!enable);
413 m_label->setEnabled(enable);
420 m_multiEnabled = enable;
421 if (m_label->isEnabled())
428 while (m_minusButtons.at(i) != sender())
435 QWidget *btn =
static_cast<QAbstractButton *>(sender())->parentWidget();
437 while (m_plusButtons.at(i) != btn)
444 if (m_editors.size() == 1) {
446 QTextCursor c = m_editors.first()->textCursor();
447 c.select(QTextCursor::Document);
448 c.removeSelectedText();
450 if (!m_editors.at(idx)->toPlainText().isEmpty()) {
451 if (QMessageBox::question(topLevelWidget(), tr(
"Confirmation - Qt Linguist"),
452 tr(
"Delete non-empty length variant?"),
453 QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes)
457 delete m_editors.takeAt(idx);
458 delete m_minusButtons.takeAt(idx);
459 delete m_plusButtons.takeAt(idx + 1);
461 emit textChanged(m_editors.at((m_editors.size() == idx) ? idx - 1 : idx));
469 emit textChanged(m_editors.at(idx));
QSize minimumSizeHint() const override
QSize sizeHint() const override
void setVisualizeWhitespace(bool value)
void setEditable(bool editable)
Combined button and popup list for selecting options.