Skip to content

Commit

Permalink
+ issue #1038: Improve and show List properties in Tree View
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Dec 16, 2014
1 parent f37a752 commit 5aac822
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 8 deletions.
193 changes: 186 additions & 7 deletions src/Gui/Widgets.cpp
Expand Up @@ -980,9 +980,173 @@ void StatusWidget::adjustPosition(QWidget* w)

// --------------------------------------------------------------------

class LineNumberArea : public QWidget
{
public:
LineNumberArea(PropertyListEditor *editor) : QWidget(editor) {
codeEditor = editor;
}

QSize sizeHint() const {
return QSize(codeEditor->lineNumberAreaWidth(), 0);
}

protected:
void paintEvent(QPaintEvent *event) {
codeEditor->lineNumberAreaPaintEvent(event);
}

private:
PropertyListEditor *codeEditor;
};

PropertyListEditor::PropertyListEditor(QWidget *parent) : QPlainTextEdit(parent)
{
lineNumberArea = new LineNumberArea(this);

connect(this, SIGNAL(blockCountChanged(int)),
this, SLOT(updateLineNumberAreaWidth(int)));
connect(this, SIGNAL(updateRequest(QRect,int)),
this, SLOT(updateLineNumberArea(QRect,int)));
connect(this, SIGNAL(cursorPositionChanged()),
this, SLOT(highlightCurrentLine()));

updateLineNumberAreaWidth(0);
highlightCurrentLine();
}

int PropertyListEditor::lineNumberAreaWidth()
{
int digits = 1;
int max = qMax(1, blockCount());
while (max >= 10) {
max /= 10;
++digits;
}

int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;

return space;
}

void PropertyListEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
{
setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
}

void PropertyListEditor::updateLineNumberArea(const QRect &rect, int dy)
{
if (dy)
lineNumberArea->scroll(0, dy);
else
lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());

if (rect.contains(viewport()->rect()))
updateLineNumberAreaWidth(0);
}

void PropertyListEditor::resizeEvent(QResizeEvent *e)
{
QPlainTextEdit::resizeEvent(e);

QRect cr = contentsRect();
lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
}

void PropertyListEditor::highlightCurrentLine()
{
QList<QTextEdit::ExtraSelection> extraSelections;
if (!isReadOnly()) {
QTextEdit::ExtraSelection selection;

QColor lineColor = QColor(Qt::yellow).lighter(160);

selection.format.setBackground(lineColor);
selection.format.setProperty(QTextFormat::FullWidthSelection, true);
selection.cursor = textCursor();
selection.cursor.clearSelection();
extraSelections.append(selection);
}

setExtraSelections(extraSelections);
}

void PropertyListEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
{
QPainter painter(lineNumberArea);
painter.fillRect(event->rect(), Qt::lightGray);

QTextBlock block = firstVisibleBlock();
int blockNumber = block.blockNumber();
int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
int bottom = top + (int) blockBoundingRect(block).height();

while (block.isValid() && top <= event->rect().bottom()) {
if (block.isVisible() && bottom >= event->rect().top()) {
QString number = QString::number(blockNumber + 1);
painter.setPen(Qt::black);
painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
Qt::AlignRight, number);
}

block = block.next();
top = bottom;
bottom = top + (int) blockBoundingRect(block).height();
++blockNumber;
}
}

class PropertyListDialog : public QDialog
{
int type;

public:
PropertyListDialog(int type, QWidget* parent) : QDialog(parent),type(type)
{
}

void accept()
{
PropertyListEditor* edit = this->findChild<PropertyListEditor*>();
QStringList lines;
if (edit) {
QString inputText = edit->toPlainText();
lines = inputText.split(QString::fromLatin1("\n"));
}

if (type == 1) { // floats
bool ok;
int line=1;
for (QStringList::iterator it = lines.begin(); it != lines.end(); ++it, ++line) {
it->toDouble(&ok);
if (!ok) {
QMessageBox::critical(this, tr("Invalid input"), tr("Input in line %1 is not a number").arg(line));
return;
}
}
}
else if (type == 2) { // integers
bool ok;
int line=1;
for (QStringList::iterator it = lines.begin(); it != lines.end(); ++it, ++line) {
it->toInt(&ok);
if (!ok) {
QMessageBox::critical(this, tr("Invalid input"), tr("Input in line %1 is not a number").arg(line));
return;
}
}
}

QDialog::accept();
}
};

// --------------------------------------------------------------------

LabelEditor::LabelEditor (QWidget * parent)
: QWidget(parent)
{
type = String;
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(2);
Expand All @@ -1008,30 +1172,40 @@ LabelEditor::~LabelEditor()

QString LabelEditor::text() const
{
return lineEdit->text();
return this->plainText;
}

void LabelEditor::setText(const QString& s)
{
lineEdit->setText(s);
this->plainText = s;

QStringList list = this->plainText.split(QString::fromLatin1("\n"));
QString text = QString::fromUtf8("[%1]").arg(list.join(QLatin1String(",")));
lineEdit->setText(text);
}

void LabelEditor::changeText()
{
QDialog dlg(this);
PropertyListDialog dlg(static_cast<int>(type), this);
dlg.setWindowTitle(tr("List"));
QVBoxLayout* hboxLayout = new QVBoxLayout(&dlg);
QDialogButtonBox* buttonBox = new QDialogButtonBox(&dlg);
buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);

QPlainTextEdit *edit = new QPlainTextEdit(&dlg);
edit->setPlainText(this->lineEdit->text());
PropertyListEditor *edit = new PropertyListEditor(&dlg);
edit->setPlainText(this->plainText);

hboxLayout->addWidget(edit);
hboxLayout->addWidget(buttonBox);
connect(buttonBox, SIGNAL(accepted()), &dlg, SLOT(accept()));
connect(buttonBox, SIGNAL(rejected()), &dlg, SLOT(reject()));
if (dlg.exec() == QDialog::Accepted) {
this->lineEdit->setText(edit->toPlainText());
QString inputText = edit->toPlainText();
this->plainText = inputText;

QStringList list = this->plainText.split(QString::fromLatin1("\n"));
QString text = QString::fromUtf8("[%1]").arg(list.join(QLatin1String(",")));
lineEdit->setText(text);
}
}

Expand All @@ -1054,4 +1228,9 @@ QString LabelEditor::buttonText() const
return button->text();
}

void LabelEditor::setInputType(InputType t)
{
this->type = t;
}

#include "moc_Widgets.cpp"
36 changes: 35 additions & 1 deletion src/Gui/Widgets.h
Expand Up @@ -30,6 +30,7 @@
#include <QLineEdit>
#include <QPointer>
#include <QPushButton>
#include <QPlainTextEdit>
#include <QBasicTimer>
#include <QTime>

Expand Down Expand Up @@ -341,6 +342,30 @@ class GuiExport StatusWidget : public QWidget

// ----------------------------------------------------------------------

class PropertyListEditor : public QPlainTextEdit
{
Q_OBJECT

public:
PropertyListEditor(QWidget *parent = 0);

void lineNumberAreaPaintEvent(QPaintEvent *event);
int lineNumberAreaWidth();

protected:
void resizeEvent(QResizeEvent *event);

private Q_SLOTS:
void updateLineNumberAreaWidth(int newBlockCount);
void highlightCurrentLine();
void updateLineNumberArea(const QRect &, int);

private:
QWidget *lineNumberArea;
};

// ----------------------------------------------------------------------

class GuiExport LabelEditor : public QWidget
{
Q_OBJECT
Expand All @@ -349,11 +374,13 @@ class GuiExport LabelEditor : public QWidget
Q_PROPERTY(QString buttonText READ buttonText WRITE setButtonText)

public:
enum InputType {String, Float, Integer};

LabelEditor (QWidget * parent = 0);
virtual ~LabelEditor();

/**
* Returns the filename.
* Returns the text.
*/
QString text() const;

Expand All @@ -362,6 +389,11 @@ class GuiExport LabelEditor : public QWidget
*/
QString buttonText() const;

/**
* Set the input type.
*/
void setInputType(InputType);

public Q_SLOTS:
virtual void setText(const QString &);
virtual void setButtonText (const QString &);
Expand All @@ -373,6 +405,8 @@ private Q_SLOTS:
void changeText();

private:
InputType type;
QString plainText;
QLineEdit *lineEdit;
QPushButton *button;
};
Expand Down
2 changes: 2 additions & 0 deletions src/Gui/propertyeditor/PropertyItem.cpp
Expand Up @@ -1853,6 +1853,7 @@ QWidget* PropertyFloatListItem::createEditor(QWidget* parent, const QObject* rec
{
Gui::LabelEditor* le = new Gui::LabelEditor(parent);
le->setAutoFillBackground(true);
le->setInputType(Gui::LabelEditor::Float);
QObject::connect(le, SIGNAL(textChanged(const QString&)), receiver, method);
return le;
}
Expand Down Expand Up @@ -1920,6 +1921,7 @@ QWidget* PropertyIntegerListItem::createEditor(QWidget* parent, const QObject* r
{
Gui::LabelEditor* le = new Gui::LabelEditor(parent);
le->setAutoFillBackground(true);
le->setInputType(Gui::LabelEditor::Integer);
QObject::connect(le, SIGNAL(textChanged(const QString&)), receiver, method);
return le;
}
Expand Down

0 comments on commit 5aac822

Please sign in to comment.